Skip to content

feat(p6-consistent-naming): recognize hierarchical noun-verb subcommand patterns - #73

Merged
brettdavies merged 1 commit into
devfrom
feat/consistent-naming-hierarchical
Jun 1, 2026
Merged

feat(p6-consistent-naming): recognize hierarchical noun-verb subcommand patterns#73
brettdavies merged 1 commit into
devfrom
feat/consistent-naming-hierarchical

Conversation

@brettdavies

@brettdavies brettdavies commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

Teaches the p6-should-consistent-naming behavioral audit to recognize the standard modern CLI shape that combines top-level verbs (anc audit, gh pull) with noun-grouped verb hierarchies (anc skill install, gh repo create). The previous heuristic flat-classified every top-level subcommand by name alone and Warned whenever the surface mixed verbs and nouns, which penalized every major CLI that uses this pattern (git, gh, kubectl, docker, npm, cargo, anc itself).

The audit now probes one level deeper for each top-level non-verb subcommand and classifies it into one of three
buckets:

  • TopLevelVerb: name is a known verb, OR a non-verb with no children (leaf action like anc emit), OR a non-verb whose children are all non-verbs themselves (verb-with-noun-objects shape like anc emit coverage-matrix).
  • HierarchicalNounVerb: non-verb name whose children are uniformly verbs (anc skill install / skill update). The noun groups its verbs; the action position stays predictable at the second level.
  • Mixed: non-verb name whose children include both verbs and non-verbs. The action position is unpredictable even within the group. This is the only case that warns.

Score impact on anc self-audit: 99 → 100. uv and cargo continue to warn because their second-level mixes are genuine (uv has tool, python, pip, self with mixed children; cargo has toolchain, override, self). The Warn evidence now names the offending subcommands so the operator can target the fix.

Changelog

Changed

  • p6-should-consistent-naming heuristic now recognizes hierarchical noun-verb subcommand patterns. Top-level verbs combined with noun-grouped verbs (the standard git, gh, kubectl, docker, npm, cargo, anc shape) Pass; only genuine inconsistency at the second level (a non-verb subcommand whose children include both verbs and non-verbs) Warns. The audit probes one level deeper per non-verb top-level subcommand via the existing cached BinaryRunner infrastructure.
  • emit added to the audit's COMMON_VERBS list so it is classified directly as a top-level verb action.
  • Warn evidence now names every offending subcommand by name so the operator can target the fix.

Type of Change

  • feat: New feature (non-breaking change which adds functionality)

Related Issues/Stories

  • Story: n/a
  • Issue: n/a
  • Architecture: Surfaced during the v0.5.0 self-audit pass; the prior heuristic incorrectly Warned on anc's own surface (1 verb audit, 1 verb-with-noun-objects emit, 1 noun-with-verb-children skill). The new heuristic matches the goal of "agents can predict where the action lives" rather than insisting on a single-convention surface.
  • Related PRs: cherry-picked to release/v0.5.0-audit-rename after this PR merges.

Testing

  • All tests passing

Test Summary:

  • cargo test: 800 passed, 2 ignored (was 793; +7 new red-team cases in consistent_naming).
  • cargo build --release: clean.
  • anc emit coverage-matrix --check: exit 0.
  • cargo deny check advisories: ok.
  • Score deltas across the six audit targets:
Target Before After Note
anc (self) 99 / warn 100 / pass The fix.
jq 77 / skip 77 / skip No subcommand surface.
gh 68 / skip 68 / skip Probe gating unchanged.
uv 73 / warn 73 / warn Genuine: tool / python / pip / self have mixed children.
cargo 69 / warn 69 / warn Genuine: toolchain / override / self have mixed children.
bc 74 / skip 74 / skip No subcommand surface.

Files Modified

Modified:

  • src/audits/behavioral/consistent_naming.rs (+273 / -41): new Classification enum, child-probing closure parameter, three-bucket classification logic, 10-case red-team test matrix covering anc / git / Mixed / leaf-noun / clap-builtin filtering / single-command skip / case-insensitivity / warn-message format.

Created:

  • None.

Renamed:

  • None.

Deleted:

  • None.

Breaking Changes

  • No breaking changes

The audit ID (p6-consistent-naming), the requirement ID it covers (p6-should-consistent-naming), the tier
(SHOULD), the principle group (P6), and the layer (behavioral) are unchanged. The scorecard JSON shape is unchanged. The behavior change is one audit's Pass/Warn boundary moving to the more accurate side; consumers feature-detect status values as before.

Deployment Notes

  • No special deployment steps required

…nd patterns

The p6-should-consistent-naming heuristic flat-classified every top-level
subcommand by name alone, then Warned whenever the surface mixed verbs and
nouns. That penalized the standard modern CLI shape where top-level verbs
(`anc audit`, `gh pull`) coexist with noun-grouped verb hierarchies (`anc
skill install`, `gh repo create`). Every major CLI uses this pattern: git,
gh, kubectl, docker, npm, cargo, anc itself.

The audit now probes one level deeper for each top-level non-verb
subcommand and classifies it into one of three buckets:

- TopLevelVerb: name is a known verb, OR name is a non-verb with no
  children (leaf action like `anc emit`), OR name is a non-verb whose
  children are all non-verbs themselves (verb-with-noun-objects shape
  like `anc emit coverage-matrix`).
- HierarchicalNounVerb: non-verb name whose children are uniformly verbs
  (`anc skill install` / `skill update`). The noun groups its verbs; the
  action position stays predictable at the second level.
- Mixed: non-verb name whose children include both verbs and non-verbs.
  The action position is unpredictable even within the group. This is the
  only case that warns.

The classifier reuses the same children-probing pattern as the existing
subcommand_help module (cached via the BinaryRunner), and filters clap
built-ins (help, completions) out of child counts so they do not skew the
all-verbs check.

Also folds `emit` into COMMON_VERBS so `anc emit` is classified directly
without falling through to the children-probing path (cheaper, and `emit`
is a reasonable canonical verb to recognize).

Self-audit score moves 99 -> 100. uv (4 noun groups with mixed children:
tool, python, pip, self) and cargo (toolchain, override, self) continue
to warn because their second-level mixes are genuine; the new evidence
string names the offending subcommands so the operator can target the
fix.

Test matrix (10 cases) covers all three classifications plus the anc
pattern, the git/gh pattern, clap-builtin filtering, the warn-message
format, and case-insensitive helpers. Closures (`children_of`) keep the
audit testable without spinning up a real BinaryRunner.
@brettdavies
brettdavies merged commit 91c5a79 into dev Jun 1, 2026
8 checks passed
@brettdavies
brettdavies deleted the feat/consistent-naming-hierarchical branch June 1, 2026 03:47
brettdavies added a commit that referenced this pull request Jun 1, 2026
…nd patterns (#73)

## Summary

Teaches the `p6-should-consistent-naming` behavioral audit to recognize
the standard modern CLI shape that combines top-level verbs (`anc
audit`, `gh pull`) with noun-grouped verb hierarchies (`anc skill
install`, `gh repo create`). The previous heuristic flat-classified
every top-level subcommand by name alone and Warned whenever the surface
mixed verbs and nouns, which penalized every major CLI that uses this
pattern (git, gh, kubectl, docker, npm, cargo, anc itself).

The audit now probes one level deeper for each top-level non-verb
subcommand and classifies it into one of three
buckets:

- **TopLevelVerb**: name is a known verb, OR a non-verb with no children
(leaf action like `anc emit`), OR a non-verb whose children are all
non-verbs themselves (verb-with-noun-objects shape like `anc emit
coverage-matrix`).
- **HierarchicalNounVerb**: non-verb name whose children are uniformly
verbs (`anc skill install` / `skill update`). The noun groups its verbs;
the action position stays predictable at the second level.
- **Mixed**: non-verb name whose children include both verbs and
non-verbs. The action position is unpredictable even within the group.
This is the only case that warns.

Score impact on `anc` self-audit: **99 → 100**. `uv` and `cargo`
continue to warn because their second-level mixes are genuine (`uv` has
`tool`, `python`, `pip`, `self` with mixed children; `cargo` has
`toolchain`, `override`, `self`). The Warn evidence now names the
offending subcommands so the operator can target the fix.

## Changelog

### Changed

- `p6-should-consistent-naming` heuristic now recognizes hierarchical
noun-verb subcommand patterns. Top-level verbs combined with
noun-grouped verbs (the standard `git`, `gh`, `kubectl`, `docker`,
`npm`, `cargo`, `anc` shape) Pass; only genuine inconsistency at the
second level (a non-verb subcommand whose children include both verbs
and non-verbs) Warns. The audit probes one level deeper per non-verb
top-level subcommand via the existing cached `BinaryRunner`
infrastructure.
- `emit` added to the audit's `COMMON_VERBS` list so it is classified
directly as a top-level verb action.
- Warn evidence now names every offending subcommand by name so the
operator can target the fix.

## Type of Change

- [x] `feat`: New feature (non-breaking change which adds functionality)

## Related Issues/Stories

- Story: n/a
- Issue: n/a
- Architecture: Surfaced during the v0.5.0 self-audit pass; the prior
heuristic incorrectly Warned on `anc`'s own surface (1 verb `audit`, 1
verb-with-noun-objects `emit`, 1 noun-with-verb-children `skill`). The
new heuristic matches the goal of "agents can predict where the action
lives" rather than insisting on a single-convention surface.
- Related PRs: cherry-picked to `release/v0.5.0-audit-rename` after this
PR merges.

## Testing

- [x] All tests passing

**Test Summary:**

- `cargo test`: 800 passed, 2 ignored (was 793; +7 new red-team cases in
`consistent_naming`).
- `cargo build --release`: clean.
- `anc emit coverage-matrix --check`: exit 0.
- `cargo deny check advisories`: ok.
- Score deltas across the six audit targets:

| Target | Before | After | Note |
|---|---|---|---|
| `anc` (self) | 99 / warn | **100 / pass** | The fix. |
| `jq` | 77 / skip | 77 / skip | No subcommand surface. |
| `gh` | 68 / skip | 68 / skip | Probe gating unchanged. |
| `uv` | 73 / warn | 73 / warn | Genuine: `tool` / `python` / `pip` /
`self` have mixed children. |
| `cargo` | 69 / warn | 69 / warn | Genuine: `toolchain` / `override` /
`self` have mixed children. |
| `bc` | 74 / skip | 74 / skip | No subcommand surface. |

## Files Modified

**Modified:**

- `src/audits/behavioral/consistent_naming.rs` (+273 / -41): new
`Classification` enum, child-probing closure parameter, three-bucket
classification logic, 10-case red-team test matrix covering anc / git /
Mixed / leaf-noun / clap-builtin filtering / single-command skip /
case-insensitivity / warn-message format.

**Created:**

- None.

**Renamed:**

- None.

**Deleted:**

- None.

## Breaking Changes

- [x] No breaking changes

The audit ID (`p6-consistent-naming`), the requirement ID it covers
(`p6-should-consistent-naming`), the tier
(SHOULD), the principle group (P6), and the layer (behavioral) are
unchanged. The scorecard JSON shape is unchanged. The behavior change is
one audit's Pass/Warn boundary moving to the more accurate side;
consumers feature-detect status values as before.

## Deployment Notes

- [x] No special deployment steps required
brettdavies added a commit that referenced this pull request Jun 1, 2026
The original v0.5.0 CHANGELOG section was generated before the
hierarchical noun-verb consistent-naming fix (PR #73) was cherry-picked
onto the release branch. Regenerated to include the new bullet plus a
couple of others (#68, #69, #71 cherry-picks) that landed between the
first generation and now.

Side-effect: the section header date moves 2026-05-31 -> 2026-06-01
since git-cliff uses the regeneration date. The tag will publish today;
the new date matches the actual release date.
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant