feat(audits): expand standard verb list and add .anc.toml domain_verbs - #76
Merged
Conversation
… from .anc.toml Teach `p6-may-standard-names` two things: (a) Recognize the common social/notification platform verbs that previously penalized any CLI shipping the X, Slack, GitHub, etc. native vocabulary. Eighteen verbs land in a new alphabetized subgroup of `STANDARD_VERBS`: archive, block, bookmark, dm, follow, like, mute, post, quote, reply, repost, subscribe, unarchive, unblock, unfollow, unlike, unmute, unsubscribe. Scope kept conservative — verbs that are unambiguous across platforms and don't read as domain jargon. Vocabulary that's genuinely X-specific (mentions, timeline, whoami) stays out of the built-in list and lands in `.anc.toml` instead. (b) Load `.anc.toml` at the audit target's repo root and honor `[p6] domain_verbs = [...]` as per-CLI vocabulary extensions. Recognition becomes `builtin OR domain` — additive, never subtractive. The new `crate::anc_toml` module owns the loader contract: missing file -> Absent, parse error -> Invalid(msg) surfaced as the audit's primary signal, non-directory target -> Absent. Also drops a duplicated `"audit"` entry from `STANDARD_VERBS` — a pre-existing typo from when the action-style subgroup was hand-merged. HashSet semantics masked the duplication; no behavior change beyond cleaning the source list. Verification: `anc audit /home/brett/dev/xurl-rs --output json` now reports `p6-may-standard-names` as `pass` (was `warn` with 7/35 standard verbs). xurl-rs ships `.anc.toml` declaring its X-platform vocab; the loader picks it up and the verb-set membership check carries the audit past threshold. Tests: - 9 unit tests in `src/anc_toml.rs` covering absent, loaded, empty, missing section, wrong-type, syntactically broken, file-target, fallback accessor. - 5 new unit tests in `standard_names.rs` covering the expanded built-in list, mentions-without-vs-with domain_verbs, empty-slice regression, and the duplicate-with-builtin harmlessness. - 3 integration tests in `tests/standard_names_integration.rs` exercising the full pipeline through the `anc` binary: pass via domain_verbs, warn on malformed `.anc.toml`, regression-warn when absent.
brettdavies
added a commit
that referenced
this pull request
Jun 3, 2026
…llow-up plans Adds five plans surfaced by the post-merge adversarial review of PRs #73, #76, #77, and #79: - 2026-06-03-001 (umbrella, P1): structure-over-vocabulary audit philosophy. Spec is canonical; closed-vocabulary lookups (COMMON_VERBS, STANDARD_VERBS, DISCRIMINANT_FIELD_NAMES, SUCCESS_VALUE_STRINGS) are failed quality proxies; per-PR redesigns of p6-consistent-naming and p2-must-json-errors land under this plan. - 2026-06-03-002 (P1): PR #73 follow-up. Probe-failure now Warns instead of silent Pass, leaf non-verb requires a successful probe, drop emit from COMMON_VERBS, add 4 negative-case tests. - 2026-06-03-003 (P1): PR #76 follow-up. Scorecard transparency for .anc.toml domain_verbs (using_domain_verbs flag + domain_match_count + evidence string showing built-in vs domain ratio), trim 7 platform-specific verbs out of built-in STANDARD_VERBS, document the social-CLI .anc.toml pattern. - 2026-06-03-004 (P0): PR #77 follow-up. cfg(not(test)) is treated identically to cfg(test) in the new cfg-args parser, silently exempting production-only code from code-unwrap. Thread polarity through the recursive call site, add 8 negative-case tests, correct an inner-attribute comment. - 2026-06-03-005 (P1): PR #79 follow-up. Close three role-based-validator bypasses: numeric discriminant on info-coded values, success synonyms outside the 8-string closed set, and nested-recursion harvesting roles from a success-coded outer envelope. Add 6 adversarial tests. Plans 002, 003, and 005 are tactical stopgaps that stop active misclassification while plan 001 owns the long-term redesign. Plan 004 is a correctness bug fix and ships independently.
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
The
p6-may-standard-namesaudit penalized every CLI shipping its native platform vocabulary. An X CLI'spost/like/repost, a Slack CLI'sdm, a GitHub CLI'sblock/mute— none were in the built-in verb list, so the ratio fell below 70 percent and the audit warned. Renaming those verbs toposts create/likes addwould worsen agent ergonomics; the right fix is to teach anc the vocabulary.Two changes:
STANDARD_VERBSwith 18 widely-understood social/notification verbs..anc.tomlat the audit target root and honor[p6] domain_verbs = [...]as per-CLI extensions. Recognition becomesbuiltin OR domain; the existing pass/warn semantics stay intact.Changelog
Added
p6-may-standard-names(archive,block,bookmark,dm,follow,like,mute,post,quote,reply,repost,subscribe,unarchive,unblock,unfollow,unlike,unmute,unsubscribe)..anc.tomlat the audit target root. Honor[p6] domain_verbs = [...]as per-CLI vocabulary extensions to the built-in standard-verb list.Fixed
"audit"entry fromSTANDARD_VERBS(HashSet semantics masked the dup; no behavior change).Type of Change
feat: New feature (non-breaking change which adds functionality)Related Issues/Stories
/home/brett/dev/xurl-rs/docs/plans/2026-06-02-001-feat-anc-100-percent-compliance-plan.md(U2)Testing
src/anc_toml.rscovering: absent path, loaded withdomain_verbs, empty list, missing[p6]section, wrong-typedomain_verbs, syntactically broken TOML, file-as-target, fallback behavior, evidence accessor.src/audits/behavioral/standard_names.rscovering: the expanded built-in list, mentions-without-vs-withdomain_verbs, empty-slice regression, duplicate-with-builtin harmlessness.tests/standard_names_integration.rsexercising the full pipeline through theancbinary: pass viadomain_verbs, warn on malformed.anc.toml, regression-warn when absent.Test Summary:
cargo test: 817 passed, 2 ignored (8 suites)cargo clippy --all-targets -- -D warnings: cleancargo fmt: cleanFiles Modified
Modified:
src/main.rs— registermod anc_toml;.src/audits/behavioral/standard_names.rs— expanded built-in verb list (alphabetized new subgroup); refactoredaudit_standard_names(help, domain_verbs);StandardNamesAudit::runloads.anc.tomland surfaces parse errors asWarn(msg); existing tests adapted to pass&[]as the new arg; dropped duplicated"audit"entry.Created:
src/anc_toml.rs— loader for.anc.toml.ANC_TOML_FILENAME,AncConfig { p6: P6Config },P6Config { domain_verbs: Vec<String> },AncConfigLoad::{Absent, Loaded, Invalid},pub fn load(repo_root: &Path) -> AncConfigLoad.tests/standard_names_integration.rs— end-to-end coverage through theancbinary.Schema
.anc.tomlat the audit target's repo root, optional:Loader contract:
Absent(additive, never required).Invalid(msg)surfaced as the audit's primary signal (Warnwith"could not parse .anc.toml: <reason>").Absent.Before / After on xurl-rs
Before this PR:
"status": "warn"(7/35 subcommands matched the standard list).After this PR (with xurl-rs's committed
.anc.tomldeclaring its X-platform vocabulary):"status": "pass".Benefits
.anc.tomlas the per-CLI extension point — additive, opt-in, audit-side parse errors surfaced rather than swallowed.Breaking Changes
The audit's
id, evidence string format, and pass/warn thresholds are unchanged. CLIs without.anc.tomland without vocab in the new social subgroup get identical verdicts.Deployment Notes
Checklist