feat: complete v0.1 — 30 checks, 3 layers, test fixtures, README - #2
Merged
Conversation
4 tasks
- Add group() and layer() as required Check trait methods; update all 11 existing checks. Error fallback in orchestration now uses correct values instead of hardcoded P1/Behavioral. - Cap stdout/stderr capture at 1MB via Read::take(N+1) idiom with boolean truncation flag. - Add MAX_DEPTH (20) and MAX_FILES (10,000) limits to directory walk with actionable warning messages. - Wire --include-tests CLI flag through to Project.include_tests and walk_source_files; tests/ excluded by default, target/ always excluded. - Fix matches_principle() to always include CodeQuality and ProjectStructure checks in --principle filtered views. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace every .unwrap() with .expect("descriptive message") across all
production and test code (97 occurrences in 14 files).
- Add Project::runner_ref() helper to centralize the expect message for
behavioral checks (replaces 8 repeated .unwrap() patterns).
- Add short = 'q' alias for --quiet flag in CLI.
- Dogfood gate: code-unwrap check now passes on self.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tests (Units 3-5, 7, 10) Source checks (12 new): - P1: headless-auth (conditional: auth code → --no-browser flag) - P2: structured-output (OutputFormat enum detection) - P4: error-types, exit-codes, process-exit, try-parse - P6: no-pager, timeout-flag, tty-detection, env-flags - P7: naked-println, output-clamping Behavioral: - JsonOutputCheck upgraded from skip-only to actual JSON validation with safe probing (--help/--version + --output/--format json) - Error-path tests added for all 8 behavioral checks (crash scenarios) Total: 23 checks (8 behavioral + 15 source), 178 tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New project check layer (src/checks/project/): - P1: non-interactive-source (prompt library dep detection) - P2: output-module (centralized output formatting) - P4: error-module (dedicated error types module) - P5: dry-run (--dry-run flag for write commands) - P6: agents-md, completions, dependencies Orchestration: project checks collected when path is a directory and --binary flag is not set. Total: 30 checks across 3 layers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixtures (tests/fixtures/): - perfect-rust: exemplary CLI passing all checks - broken-rust: intentionally bad practices for failure detection - binary-only: shell script exercising behavioral checks - source-only: Rust project with no compiled binary Integration tests (tests/integration.rs): - CLI flags: --version, --help, --output json, -q, --principle N - Error cases: nonexistent path, bogus flag - Fixture validation: binary-only, source-only, broken, perfect - Shell completions generation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full README with installation, quick start, 7 principles table, example scorecard output, three check layers, CLI reference, JSON output example, shell completions, and contributing section. Add AGENTS.md for agent-readiness (fixes p6-agents-md dogfood check). Dogfood: 30 checks — 21 pass, 7 warn, 0 fail, 2 skip, 0 error. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add #[expect(dead_code)] to stdout_truncated/stderr_truncated fields in RunResult — these are public API for downstream consumers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- headless_auth: use ast-grep function name matching instead of substring search to avoid false positives from comments, strings, and the check's own keyword constants - structured_output: match `pub enum OutputFormat` in addition to bare `enum OutputFormat` - error_types: match enums with visibility modifiers (pub, pub(crate)) - output_module: add scorecard.rs and render.rs as valid output module names Dogfood improvement: 21 → 24 pass, 7 → 3 warn. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
try_parse: Only flag .parse().unwrap() — .parse().expect() shows the developer already considered the error case. Removes false positive on internal TOML manifest parsing. output_module: Replace hardcoded filename list with content-based detection. Any non-main source file containing format/render/display functions, Display implementations, or Write trait usage qualifies as a centralized output module. Avoids an ever-growing accepted-names list. Dogfood: 25 pass, 2 warn, 0 fail, 3 skip. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip unsupported languages instead of false-warning on non-Rust projects. Content patterns (fn format_, impl Display, etc.) are Rust-specific — Python/Go patterns will be added with their respective source check layers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The check scans parsed source files for Rust-specific content patterns (fn format_, impl Display, std::fmt::Write). That's source analysis, not project structure inspection — it belongs in source/rust/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
brettdavies
force-pushed
the
feat/v01-completion
branch
from
April 1, 2026 21:44
8890010 to
54c56a5
Compare
14 tasks
brettdavies
added a commit
that referenced
this pull request
Apr 16, 2026
…#13) ## Summary Resolves the seven recommended fixes from the post-merge `/ce-review` of PR #12 (commit `4afef67`). All actionable findings closed; main.rs trimmed back under the 200-line trigger. ## Changelog ### Added - `value_hint = ValueHint::CommandName` on `--command` so zsh, fish, and elvish completions suggest PATH commands instead of file paths. Bash is patched post-generation in `scripts/generate-completions.sh`. - `after_help` text on `Cli` documenting the implicit default subcommand and the bare-invocation contract directly in `anc --help` output. - Mutual exclusion: `--command` and `--source` now error at parse time instead of silently producing an empty result. ### Changed - `anc -q` / `anc --quiet` (top-level flag without subcommand) now prints help and exits 2 instead of panicking via `unreachable!()` (pre-existing bug). - `anc help` and `anc help check` now work — clap's auto-generated `help` subcommand was missing from our known-subcommand set and got misclassified as a path. - `anc --command <NAME>` where NAME collides with a subcommand name (e.g. `anc --command check`) now resolves NAME as a binary on PATH instead of producing a confusing clap error. - `anc --command rg` and `anc --output json --source` (no positional argument) now work — the pre-parser detects subcommand-scoped flags and injects `check` accordingly. - `anc -- .` (POSIX double-dash separator) now runs check against `.` instead of producing undefined behavior. ### Documentation - README and AGENTS.md exit-code tables clarify that exit 2 is overloaded (failures, errors, and usage errors all share it). Suggest parsing stderr (`Usage:` text) to distinguish. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Original feature: PR #12 (Plan 003 merge, commit `4afef67`) - Review run artifact: `.context/compound-engineering/ce-review/20260415-173344-efaaf5ff/` - Plan: `docs/plans/2026-04-02-003-feat-cli-default-subcommand-and-command-flag-plan.md` ## Findings Resolved | # | Severity | Title | Resolution | |---|----------|-------|------------| | 1 | P2 | clap `help` subcommand missing from known set | Append `\"help\"` to `known` after `get_subcommands()` | | 2 | P2 | `--command <NAME>` value collides with subcommand | Pair value-taking flags with their values via clap introspection | | 3 | P2 | Flag-value tokens silently fragile | Same fix as #2; also tracks subcommand-scoped flags to inject `check` when no positional follows | | 4 | P2 | `anc -q` panics via `unreachable!()` (pre-existing) | `None` arm now renders help to stderr and exits 2 | | 5 | P2 | `--command` + `--source` silent empty result | `conflicts_with = \"source\"` on `command` arg | | 6 | P2 | Bare `anc` exit 2 conflates user-error vs check-failure | Documented in README/AGENTS exit-code tables | | 7 | P2 | Default-subcommand magic not in `--help` | `after_help` block on `Cli` documents it | | 8 | P2 | `anc -- .` POSIX double-dash undefined | New branch in inject_default_subcommand | | 10 | P2 | main.rs over 200-line refactor trigger | Extract `inject_default_subcommand` + tests to new `src/argv.rs` module (538 → 203 lines) | | 14 | P3 | Bash `--command` completion uses `compgen -f` | `ValueHint::CommandName` fixes zsh/fish/elvish; bash post-patched in gen script | | 22 | P3 | `anc .` succeeds where it previously errored | Documented in PR Changelog above | Findings not addressed (intentional): #11/#12/#17/#18 (subsumed by #10 refactor), #15/#16/#19/#20/#21/#23/#24 (low-priority test/style nits or pre-public-schema concerns). ## Testing - [x] Unit tests added/updated (244 → 253, +9 covering all 5 fixed edge cases) - [x] Integration tests added/updated (26 → 34, +8 covering same) - [x] All tests passing - [x] Pre-push hook clean (fmt + clippy `-Dwarnings` + test + Windows compat) - [x] Manual probes: every previously-broken invocation now does the right thing, bare `anc` still exits 2 (fork-bomb guard intact), explicit subcommands still work **Test Summary:** - Unit tests: 253 passing (was 244) - Integration tests: 34 passing, 3 ignored (was 26 / 3) - Coverage: every fix has both a unit test (where applicable) and an integration test ## Files Modified **Modified:** - `src/cli.rs` — `after_help` text, `value_hint` on `--command`, `conflicts_with = \"source\"` - `src/main.rs` — `None` arm prints help instead of panicking; refactor extracts injection to `argv` module - `tests/integration.rs` — 8 new tests covering the fixed edge cases - `scripts/generate-completions.sh` — post-process bash to substitute `compgen -c` for `--command` (clap_complete bash backend ignores `ValueHint::CommandName`) - `completions/anc.{bash,zsh,fish}` — regenerated to expose new behavior - `README.md`, `AGENTS.md` — exit-code clarification **Created:** - `src/argv.rs` — new module hosting `inject_default_subcommand` and 19 unit tests ## Breaking Changes - [x] No breaking changes Every previous valid invocation continues to produce identical output. Previously-broken invocations (`anc help`, `anc -q`, `anc --command check`, `anc --command rg`, `anc --output json --source`, `anc -- .`) now behave correctly. ## Deployment Notes - [x] No special deployment steps required Ships with Plan 003 in the v0.1.0 `release/*` batch when Plan 002 (release infra) runs. No standalone release branch. ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible
brettdavies
added a commit
that referenced
this pull request
Apr 16, 2026
11 tasks
brettdavies
added a commit
that referenced
this pull request
Jun 4, 2026
…tests (#80) ## Summary Closes a P0 correctness regression in `code-unwrap` surfaced by the adversarial review of merged PR #77. PR #77 (commit 817d6fa) introduced a tree-sitter walk that exempts `.unwrap()` calls inside `#[cfg(test)]`-gated items. The cfg-args parser, however, treats `not(...)` identically to `any(...)` and `all(...)`: it descends into the inner argument list without polarity tracking and returns `true` whenever the bare identifier `test` appears at any depth. The effect was that `#[cfg(not(test))]` on production-only code silently exempted that code from the audit, a regression confirmed both by reading the parser and by an injected adversarial test that panicked under the buggy logic. This PR threads a `negated: bool` parameter through `cfg_args_contain_test`. The bare-test branch returns `true` only at even parity (`!negated`); at odd parity (under a `not(...)`) the predicate means production code and the walker keeps scanning siblings in case another predicate resolves to test-gated. The recursive call for `not(...)` flips polarity; `any(...)` and `all(...)` preserve it. Double-negation (`not(not(test))`) correctly restores even parity. Also corrects the inner-attribute comment block (which claimed sticky propagation across all siblings while the code actually does one-shot reset) and pins the intentional asymmetry with a named test. Per plan #4, the diff is surgical: only the parser function, the inner-attribute comment, and the test module are touched. ## Changelog ### Fixed - `code-unwrap`: `#[cfg(not(test))]` no longer silently exempts production-only code from the audit. The cfg-args parser now tracks polarity through `not(...)` wrappers; `not(test)`, `any(not(test), unix)`, and `all(not(test), feature = "x")` correctly classify as production. Polarity-pinning tests cover the double-negation case (`not(not(test))`), the `not(any(test))` shape, `cfg_attr(test, …)` non-gating, and the inner-attribute one-shot reset asymmetry. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Plan: `docs/plans/2026-06-03-004-fix-pr77-code-unwrap-cfg-not-test-polarity-plan.md` - Origin: adversarial review of merged PR #77 (commit 817d6fa) - Umbrella plan (audit philosophy, supersedes plans #2 and #5): `docs/plans/2026-06-03-001-refactor-audit-philosophy-structure-over-vocabulary-plan.md` ## Testing - [x] Unit tests added/updated - [x] All tests passing **Test Summary:** - `cargo test`: 846 passed, 2 ignored (8 suites). 9 new unit tests in `src/audits/source/rust/unwrap.rs`: `cfg_not_test_does_not_exempt_production_unwrap`, `cfg_any_not_test_unix_does_not_exempt`, `cfg_all_not_test_feature_does_not_exempt`, `cfg_any_test_or_not_feature_still_exempts`, `cfg_attr_test_does_not_exempt`, `inner_attribute_one_shot_consumes_on_use_not_fn`, `mod_tests_without_gate_does_not_exempt`, `cfg_not_not_test_does_exempt`, `cfg_not_any_test_does_not_exempt`. - `cargo clippy --all-targets -- -Dwarnings`: clean. - Dogfood (`anc audit .`): `code-unwrap` flags one production unwrap at `src/audits/behavioral/json_errors.rs:192` (`trimmed.chars().next().unwrap()`). The unwrap has no cfg gate; it surfaces because PR #79 added it and the audit wasn't re-dogfooded after that merge. Verified identical behavior on pre-fix `dev` via `git stash` + rebuild, ruling out a regression from this PR. Owned by plan #5 (PR #79 follow-up) or addressable as a one-line fix in a separate PR. - Dogfood (`anc audit ~/dev/xurl-rs`): `code-unwrap` continues to `pass`. xurl-rs has zero `#[cfg(not(test))]` items, so the polarity fix is a no-op against that target. ## Files Modified **Modified:** - `src/audits/source/rust/unwrap.rs`: thread `negated: bool` through `cfg_args_contain_test`; flip polarity on `not(...)` recursion (preserve on `any`/`all`); rewrite the inner-attribute comment block to match one-shot reset semantics and name the pinning test; add 9 negative-case unit tests. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Breaking Changes - [x] No breaking changes The audit becomes strictly more accurate. Callers that previously relied on `#[cfg(not(test))]` exempting production code from `code-unwrap` were doing so accidentally, since that path was an unintended consequence of PR #77's missing polarity tracking. ## Deployment Notes - [x] No special deployment steps required ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible
12 tasks
brettdavies
added a commit
that referenced
this pull request
Jun 4, 2026
… platform verbs (#83) ## Summary Follow-up to merged PR #76 addressing two coupled gaps surfaced during the post-merge adversarial review. `.anc.toml [p6] domain_verbs` lets any CLI declare its own subcommand vocabulary as "standard," but the scorecard row gave no signal whether the Pass was assisted. A domain-verb-assisted Pass was byte-identical in JSON to a built-ins-only Pass. Separately, of the 18 verbs PR #76 added to `STANDARD_VERBS`, 7 are X/Mastodon-specific (`post`, `repost`, `unrepost`, `quote`, `like`, `unlike`, `dm`). Their inclusion encoded one platform's vocabulary as universal, and let any social CLI Pass without exercising the `.anc.toml` opt-in PR #76 introduced. This PR adds scorecard transparency for domain-verb-assisted Passes and trims the platform-specific verbs out of the built-in list. Schema bumps `0.7 → 0.8` (additive). ## Changelog ### Added - Schema `0.8`: `using_domain_verbs: Option<bool>` and `domain_match_count: Option<usize>` on each `AuditResultView` row. Populated when `p6-standard-names` Passes via `.anc.toml [p6] domain_verbs` recognition; absent (not `null`) for rows that did not consult `domain_verbs`. - `MitigationInfo` carrier on `AuditResult` (typed, audit-agnostic) tracking built-in vs domain match counts and the first 5 matched domain-verb names in encounter order. - Pass row's `evidence` field is populated with the built-in vs domain ratio when assisted by `domain_verbs`, e.g. `"7/8 subcommands standard (3 via .anc.toml [p6].domain_verbs: [post, like, repost])"`. Rows without mitigation keep the historical `evidence: null` on Pass. ### Changed - `STANDARD_VERBS` no longer recognizes `post`, `repost`, `unrepost`, `quote`, `like`, `unlike`, `dm`. Social and platform-specific CLIs that previously Passed via built-ins must now declare these in `.anc.toml [p6] domain_verbs` (documented). - `audit_standard_names` returns a `StandardNamesResult` struct (status + optional `MitigationInfo`) instead of bare `AuditStatus`. - Warn evidence on `p6-standard-names` includes a pointer to `docs/solutions/architecture-patterns/anc-toml-domain-verbs-pattern-2026-06-03.md` so authors discover the opt-in. - `CLAUDE.md` schema history block updated to document the `0.6`, `0.7`, and `0.8` additions (the inline history had drifted at `0.5`). ### Fixed - Audit-identity collapse from PR #76: a `.anc.toml`-assisted Pass is now distinguishable in the scorecard JSON from an unassisted one. - Verb-list dilution from PR #76: platform-specific vocabulary no longer inflates the cross-CLI built-in list. ## Type of Change - [x] `fix`: Bug fix (non-breaking change which fixes an issue) ## Related Issues/Stories - Plan: `docs/plans/2026-06-03-003-fix-pr76-domain-verbs-scorecard-transparency-plan.md` - Origin: adversarial review of merged PR #76 (commit 9263c5c). - Umbrella plan (audit philosophy, supersedes plans #2 and #5 at the design level): `docs/plans/2026-06-03-001-refactor-audit-philosophy-structure-over-vocabulary-plan.md` - Pattern documentation: `docs/solutions/architecture-patterns/anc-toml-domain-verbs-pattern-2026-06-03.md` (already committed and pushed to the symlinked `solutions-docs` repo, commit `402354b`). ## Testing - [x] Unit tests added/updated - [x] Integration tests updated - [x] All tests passing **Test Summary:** - `cargo test`: 855 passed, 2 ignored (8 suites). Net +7 from baseline: 5 new R5 adversarial tests in `audit_standard_names`, 2 new format-evidence tests pinning the 5-example truncation contract. - `cargo clippy --all-targets -- -Dwarnings`: clean. - `cargo fmt --check`: clean. - `anc emit coverage-matrix --check`: clean. - Dogfood: `anc audit . --output json | jq '.results[] | select(.id == "p6-may-standard-names")'` returns `status: "pass"` with `using_domain_verbs` and `domain_match_count` absent from the row keys (`anc` itself has no `.anc.toml`). ## Files Modified **Modified:** - `src/types.rs`: new `MitigationInfo` struct; new optional `mitigation: Option<MitigationInfo>` field on `AuditResult`. - `src/audits/behavioral/standard_names.rs`: refactored `audit_standard_names` to return `StandardNamesResult`; bifurcated built-in vs domain match counting; populates `MitigationInfo` on domain-assisted Pass; trimmed 7 platform-specific verbs from `STANDARD_VERBS`; appends docs URL to Warn evidence; 13 unit tests (8 updated to the new return shape + 5 new adversarial + 2 format-evidence pinning tests). - `src/audits/behavioral/mod.rs`: made `standard_names` `pub(crate)` so the scorecard view layer can call `format_pass_evidence`. - `src/scorecard/mod.rs`: `SCHEMA_VERSION` bumped to `"0.8"`; `AuditResultView` gains `using_domain_verbs` and `domain_match_count`; `from_row` reads `r.mitigation`, populates the fields, and synthesizes Pass evidence prose via `format_pass_evidence`. - `schema/scorecard.schema.json`: `$id` pinned to `scorecard-v0.8`. - `tests/standard_names_integration.rs`: fixture retuned to `archive` + `follow` + `mentions` so the `.anc.toml` loader is genuinely exercised after the platform-verb trim. - `tests/integration.rs`, `tests/scorecard_metadata_security.rs`, `tests/scorecard_schema_v05.rs`: schema-version assertions bumped to `"0.8"`; the v0.7 → v0.8 schema `$id` rename pinned by `schema_v05_target_path_carries_no_separators` regression test. - `CLAUDE.md`: schema history block updated (was stuck at `0.5`); new `MitigationInfo` semantics block mirrors the existing per-version addition pattern. - ~77 audit and test files: mechanical `mitigation: None` insert in every `AuditResult { ... }` constructor. This is the unavoidable churn of adding a typed transparency field to the canonical result carrier. `cargo check` verified the sed hit only valid sites. **Created:** - None. (`docs/solutions/architecture-patterns/anc-toml-domain-verbs-pattern-2026-06-03.md` lives in the symlinked `solutions-docs` repo and was committed there separately.) **Renamed:** - None. **Deleted:** - None. ## Breaking Changes - [x] No breaking changes (schema `0.8` is additive) The 7 platform verbs removed from `STANDARD_VERBS` are a behavior tightening, not a contract break. CLIs that relied on them being built-ins were exploiting PR #76's overly broad vocabulary; the remediation path is `.anc.toml [p6] domain_verbs` (documented). ## Deployment Notes - [x] No special deployment steps required ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Grow the check suite from 11 to 30 checks across all three layers: behavioral, source/Rust, and project. Adds 13 new Rust source checks and 6 project checks, 4 test fixtures (perfect-rust, broken-rust, binary-only, source-only), 15 integration tests, a complete README with examples and CLI reference, and AGENTS.md for agent context.
Changelog
Added
Type of Change
feat: New feature (non-breaking change which adds functionality)Files Modified
Created:
tests/fixtures/perfect-rust/,tests/fixtures/broken-rust/,tests/fixtures/binary-only/,tests/fixtures/source-only/,AGENTS.md,README.md, new check modules insrc/checks/source/andsrc/checks/project/Modified:
Cargo.toml,src/checks/mod.rs, integration test filesChecklist