Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Install cargo-audit
uses: taiki-e/install-action@cargo-audit
- name: Install cargo-deny
uses: taiki-e/install-action@cargo-deny

- name: Cache cargo
uses: Swatinem/rust-cache@v2
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ This subproject is the Corgea developer CLI (Rust → npm + pip via maturin).

- After edits: `./harness check` — clippy fix, format, tests, suppression report
- Pre-commit: `./harness pre-commit` — staged Rust files only (auto via git hook)
- CI: `./harness ci` — strict clippy (`-D warnings`), format check, dep audit, tests + coverage gate (min 13%)
- Audit: `./harness audit` — `cargo audit` for known dep vulnerabilities
- CI: `./harness ci` — strict clippy (`-D warnings`), format check, dep policy (`cargo deny`: advisories + licenses + sources + bans), tests + coverage gate (min 13%)
- Deny: `./harness deny` — `cargo deny check` (vulns, licenses, sources, bans) per `deny.toml`
- Coverage: `./harness coverage [--min=N]` — cargo-llvm-cov; HTML report under `target/llvm-cov/`; fails if line coverage < N (default 13)
- Lint: `./harness lint` — clippy + format check, no fixes
- Test: `./harness test` — `cargo test`
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
name = "corgea"
version = "1.8.8"
edition = "2021"
# Distributed via maturin → npm + pip, never `cargo publish`ed to crates.io.
# Marks the crate private so `cargo deny` skips license checks on our own
# LGPL-2.1 source (see deny.toml `[licenses] private = { ignore = true }`).
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
41 changes: 41 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# cargo-deny policy for the corgea CLI.
# Run: ./harness deny (CI runs it strict via ./harness ci)

[advisories]
version = 2
# RustSec DB: fail on vulnerable/unmaintained/unsound/yanked crates.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidence: this comment says the advisory gate fails on yanked crates, but the new [advisories] config only sets version = 2 and does not set yanked. cargo-deny's current default for yanked crates is warn, so cargo deny check will not fail CI when a yanked crate is present. Impact: the replacement policy is weaker than the stated production gate and can ship a yanked dependency while reporting only a warning. Concrete fix: add yanked = "deny" under [advisories] (and keep ignores explicit/reasoned if a yanked crate must be tolerated), or change the stated policy if yanked crates are intentionally non-blocking.

# ignore = [] # add "RUSTSEC-YYYY-NNNN" with a justification comment if ever needed

[licenses]
version = 2
# SPDX ids allowed to ship in the distributed binary. All permissive,
# plus option-ext's file-level MPL-2.0 (transitive via `dirs`).
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-3-Clause",
"Unicode-3.0",
"Unlicense",
"0BSD",
"CC0-1.0",
"MIT-0",
"Zlib",
"BSL-1.0",
"MPL-2.0",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidence: lines 11-12 say MPL is being allowed only for option-ext, but putting "MPL-2.0" in the global licenses.allow list permits any current or future dependency with MPL-2.0. Impact: a future dependency/license drift to MPL-2.0 will pass the production license gate without reviewer visibility, which weakens the validation this PR is adding. Concrete fix: remove "MPL-2.0" from the global allowlist and add a crate-scoped exception instead, e.g. exceptions = [{ crate = "option-ext", allow = ["MPL-2.0"] }] under [licenses] (or the equivalent [[licenses.exceptions]] form supported by the chosen cargo-deny version).

]
# The `corgea` crate's own LICENSE file is LGPL-2.1; it ships only as a binary
# (never `cargo publish`ed) so it's marked `publish = false` in Cargo.toml,
# which makes it "private" and exempt from these dep-license rules.
private = { ignore = true }
confidence-threshold = 0.9

[bans]
# Duplicate versions are common & low-risk in a 310-crate tree → warn, don't fail.
multiple-versions = "warn"
wildcards = "warn"

[sources]
# Lock the supply chain to crates.io. Any git / alt-registry dep fails the gate.
unknown-registry = "deny"
unknown-git = "deny"
22 changes: 11 additions & 11 deletions harness
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Project development tasks. Bash + cargo + git only.
# Usage: ./harness <command> [--verbose] [--min=N]
#
# Commands: check, fix, lint, test, audit, coverage, pre-commit, ci,
# Commands: check, fix, lint, test, deny, coverage, pre-commit, ci,
# post-edit, setup-hooks, suppressions

set -u
Expand Down Expand Up @@ -160,21 +160,21 @@ cmd_test() {
run_with_summary "Tests" 0 -- cargo test
}

cmd_audit() {
_cmd_audit_inner 0
cmd_deny() {
_cmd_deny_inner 0
}

_cmd_audit_inner() {
_cmd_deny_inner() {
local strict="$1"
if cargo audit --version >/dev/null 2>&1; then
run "Dep audit" 0 -- cargo audit
if cargo deny --version >/dev/null 2>&1; then
run "Dep policy" 0 -- cargo deny check
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidence: the harness runs cargo deny check without --locked. Unlike the old cargo audit path, which audited the committed Cargo.lock directly, cargo-deny builds its graph through Cargo metadata and supports a global --locked flag specifically to assert the lockfile will not change. Impact: if Cargo.toml is changed without committing the lockfile update, the dep-policy gate can resolve/scan a transient graph in CI instead of failing fast on the stale committed lockfile, so the reviewed lockfile is not necessarily what the policy validated. Concrete fix: run cargo deny --locked check from the harness (and keep CI using that path) so dependency-policy validation is tied to the committed lockfile.

return
fi
if [ "$strict" = "1" ]; then
printf " %s✗%s Dep audit (cargo-audit not installed)\n" "$RED" "$RESET"
printf " %s✗%s Dep policy (cargo-deny not installed)\n" "$RED" "$RESET"
exit 1
fi
printf " %s⊘ Dep audit skipped (install: cargo install cargo-audit)%s\n" "$DIM" "$RESET"
printf " %s⊘ Dep policy skipped (install: cargo install cargo-deny)%s\n" "$DIM" "$RESET"
}

cmd_coverage() {
Expand Down Expand Up @@ -244,7 +244,7 @@ cmd_ci() {
printf "\n%s[ci]%s\n\n" "$BLUE" "$RESET"
run "Clippy (strict)" 0 -- cargo clippy -- -D warnings
run "Format check" 0 -- cargo fmt --check
_cmd_audit_inner 1
_cmd_deny_inner 1
if ! cargo llvm-cov --version >/dev/null 2>&1; then
printf " %s✗%s Coverage (cargo-llvm-cov not installed)\n" "$RED" "$RESET"
printf " %sInstall:%s cargo install cargo-llvm-cov\n" "$DIM" "$RESET"
Expand Down Expand Up @@ -274,7 +274,7 @@ case "$cmd" in
fix) cmd_fix ;;
lint) cmd_lint ;;
test) cmd_test ;;
audit) cmd_audit ;;
deny) cmd_deny ;;
coverage) cmd_coverage ;;
pre-commit) cmd_pre_commit ;;
ci) cmd_ci ;;
Expand All @@ -283,7 +283,7 @@ case "$cmd" in
suppressions) cmd_suppressions ;;
-h|--help|help)
printf "Usage: ./harness <command> [--verbose] [--min=N]\n\n"
printf "Commands: check, fix, lint, test, audit, coverage, pre-commit,\n"
printf "Commands: check, fix, lint, test, deny, coverage, pre-commit,\n"
printf " ci, post-edit, setup-hooks, suppressions\n"
;;
*)
Expand Down
Loading