Repository navigation
feat(rules): re-run rule 1's grep on every gate, not once by hand - #188
Conversation
Non-negotiable rule 1 — no consumer-specific identifier anywhere in crates/batten — was discharged once, as a manual grep when the crate landed (CLOUD-26). That leaves a standing property carried as prose, which non-negotiable rule 2 calls half a change: nothing re-checks it, so the first violation to land does so green. Two [[rule]] rows now re-run that grep under batten check, on every gate invocation. The glob is crates/** rather than crates/**/*.rs because rule 1 says *anywhere*: the crate manifest, the changelog and every fixture under tests/ are files a *.rs glob waves straight through. Only two of the four literals CLOUD-26's acceptance listed survive the membership test. forbid is a case-sensitive literal substring check, so a literal with an English reading is wrong in both directions at once — it fires on ordinary prose and misses the capitalised form. The vendor name and the predecessor repo's name both already occur in this repo's own text; what survives is the two shapes with no English reading. Neither rule id embeds the literal it bans, because a finding prints its rule id and the fixture's expected stdout lives inside the glob these rules scan. The fixture asserts full stdout equality rather than a substring, because that is the only form that discriminates. Measured: switching one rule to severity = "allow" fails the new test while the_committed_repo_config_gates_a_repository stays green. That older case seeds only a conflict marker, so its asserted bytes are identical whether these rules are present, absent, mis-globbed or switched off — its comment claimed to catch exactly that and is corrected here. Refs: CLOUD-7 Claude-Session: https://claude.ai/code/session_017fSX9B9EL7hzyEMqRYfTaE
CLOUD-7 Project scaffold and CLI-as-data spine
Foundational setup for the batten crate and the single-source-of-truth command surface. This group establishes the repo-agnostic crate, the usage-spec-driven CLI, and the derived read-only allowlist. Path correction: the crate landed at Refinement gateChildren of this epic are gated by the project-level Definition of Ready & Done, in the vocabulary of Batten CLI — the Button house style. Both are attached above. This parent does not restate the eight clauses, and it is not a merge of its children's blocks: each child carries its own per-clause specializations — CLOUD-26 the crate, CLOUD-27 the spec-as-data surface and its drift gate, CLOUD-28 the derived allowlist. What follows is only what is true of the parent and of nothing else.
|
121628a to
c95c69c
Compare
|
/fast-forward |
Non-negotiable rule 1 — no consumer-specific identifier anywhere in
crates/batten— was discharged once, as a manual grep when the crate landed (CLOUD-26). That leaves a standing property carried as prose, which non-negotiable rule 2 calls half a change: nothing re-checks it, so the first violation to land does so green.Two
[[rule]]rows now re-run that grep underbatten check, on every gate invocation.Why the glob is
crates/**and notcrates/**/*.rs— rule 1 says anywhere. The crate manifest, the changelog and every fixture undertests/are files a*.rsglob waves straight through.Why only two of the four literals CLOUD-26's acceptance listed —
forbidis a case-sensitive literal substring check, so a literal with an English reading is wrong in both directions at once: it fires on ordinary prose and misses the capitalised form. The vendor name and the predecessor repo's name both already occur in this repo's own text (git grep -Fn button -- crates/hitssrc/hook.rs;git grep -in complianhitsAGENTS.mdandLICENSE-APACHE). What survives is the two shapes with no English reading.Neither rule id embeds the literal it bans. A finding prints
<path>:<line> <rule-id>, so the id reaches the fixture's expected-stdout string — which lives undercrates/batten/tests/, inside the glob these rules scan. An id naming its own literal would make the gate fire on the test that proves it works.The discriminator
The fixture asserts full stdout equality, not a substring, because that is the only form that discriminates. Measured both ways:
the_committed_repo_config_gates_a_repositorydenyseverity = "allow"That second row is the gap this closes. The older case seeds only a conflict marker, so its asserted bytes are identical whether these rules are present, absent, mis-globbed or switched off — its comment claimed to catch exactly that, and is corrected here.
Refs: CLOUD-7
Generated by Claude Code