Skip to content
Merged
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
5 changes: 4 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,10 @@ reader can judge whether it still holds.
in CI — it is a recipe a human runs — and an overclaim phrased without those totality
words escapes it entirely. It raises the floor; it does not close the class. The
underlying rule is the check itself: for every sentence about a gate, name the exact
comparison the code performs, and delete any part of the sentence that outruns it.
comparison the code performs, and delete any part of the sentence that outruns it — and
where the sentence says what the mechanism does *not* cover, name the axes it was checked
against and state whether that list is exhaustive, because an enumeration read as complete
guarantees the axes it omits.
- **Never replace a decision procedure without accounting for its old conditions.** List
what the previous prose required, then mark each one kept, moved, or deliberately
dropped. A rewrite reliably preserves the condition that motivated it and silently loses
Expand Down
19 changes: 16 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,12 @@ not all of `.context/`, which would strip the committed `codex-gate.on` adoption
NO FINDINGS
```

Each pass: validate, revise, re-run. (Large/high-risk artifact: optional focused
Each pass: validate, revise, re-run. Before each read pass, settle mechanically what
the artifact asserts and a machine can decide without side effects — cited paths,
quoted passages, stated counts, the syntax of standalone fenced blocks — because a read
pass spends expensive judgement on what a parser settles in seconds and misses it
anyway, inspecting quoted commands rather than running them, since a command quoted in
a spec may be destructive or an intentional failure. (Large/high-risk artifact: optional focused
per-dimension passes on top.)
- **Gate B — Code.** Tests green, before `git commit`. Tool: `mcp__codex__review`
(args `instruction`, `whatWasImplemented`, `baseSha`; `reviewType: full` runs
Expand Down Expand Up @@ -251,7 +256,11 @@ not all of `.context/`, which would strip the committed `codex-gate.on` adoption
asks, nothing enforces the ask or validates the answer, and no comprehensive check
covers arbitrary semantic drift. Ask anyway — in one cycle it surfaced a shipped command
that would have let a one-line fix skip Gate B entirely, plus two user-facing docs
teaching a rule the same change had just narrowed.
teaching a rule the same change had just narrowed. **Name what this diff changes the
size, value or position of** — a list, a count, a version, an identifier, a cited
line — and grep for where each is described elsewhere, because asked as an open
question alone this lens missed three such statements in one cycle while being carried
with unusual force.

**What counts as prose (the only Gate-B exemption).** Every staged path is
explanatory documentation — `docs/**.md`, `README.md`, `MANIFEST.md` → N/A.
Expand Down Expand Up @@ -342,7 +351,11 @@ A check need not be an automated test — where none is possible, a **named veri
satisfies it and the entry says which route was taken and why. Either route owes the
**counterfactual**: the observation against the prior state. An **unobservable
counterfactual is a blocking evidence gap**, not a free pass — stop and surface; the human
may then lower the mode as a logged override. A fabricated test satisfies nothing.
may then lower the mode as a logged override. A fabricated test satisfies nothing. **Name
the observation that would exist if the claim were false, and confirm the wiring could
have produced it** — a check that supplies its own input, runs where the defect cannot
appear, or uses a fixture that never reaches the branch it covers reports success because
of how it was wired, not because the thing it checks succeeded.

**The evidence entry lives in the commit body** (see Mechanics), carries the **story path
and the named evidence but not the mode value**, and is **revalidated before every Gate-B
Expand Down
4 changes: 4 additions & 0 deletions docs/hardening-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ escape `\|`, one line), `source` (gate-a|gate-b|bot|manual),
| 2026-07-27 | unverified-enforcement-claim | FOURTH occurrence: a methodology paragraph describing the gate hook's path matcher was corrected in four consecutive Gate-B rounds — false rationale, then a categorical claim that agent definitions and hook messages always fire Gate B, then a partial-matcher claim ("a bare `agents/` matches nothing", while non-`.md` paths reach the reminder anyway), then an enforcement blur between an advisory hook and the policy — each correction a subtler version of the last, inside a paragraph being rewritten to fix that very class | gate-b | major | P std | docs/prompt-standards.md item 11, new sub-paragraph "Cite the source; do not paraphrase it" + "when a claim about a mechanism needs a fourth correction, delete the claim rather than refine it a fifth time". Sharpens item 11 rather than adding item 13, deliberately: a new numbered item ripples the checklist count through prompt-standards, the workflow-init template and AGENTS.md invariant 11, all pinned by check 4b. COUNT, stated because the escalation depends on it: the prior lineage is 2026-07-18 (first), 2026-07-19 (second), 2026-07-25 (third, `pending`) and 2026-07-26, which RESOLVES that pending row rather than recording a new defect — so this is the fourth occurrence, not the fifth. NOT ESCALATED to a mechanical rung despite the 2026-07-26 `2 lint` row being the latest: that check guards one spelling (`Target model:` lines) and this defect is outside it — exactly the over-escalation the 2026-07-26 row warns about by name. NO CURRENT DETERMINISTIC RUNG covers this paraphrase shape — the one candidate evaluated, a grep for the matcher's terms, fires on the matcher and the policy file themselves; that rules out the naive check, not every conceivable one, and the recurrence count here is a signal a human reads rather than anything that blocks a commit. The fix that finally held was DELETION — the enumeration was replaced by a pointer to the policy file; the same shape closed a second instance in the same cycle, where three successive `git status` recipes were replaced by naming the paths you edited |
| 2026-07-27 | rewrite-drops-prior-condition | NEW CLASS, minted this change: ten instances in one cycle where a multi-condition rule was rewritten, the new condition survived and an old one vanished with the prose it replaced — `process-pr-review` losing the no-story and all-stories branches, then losing fix-triviality so an eligible profile alone authorized a Gate-B skip (a gate-off path invented by the change that exists to close one); a spec surfaces sentence describing the skip as keyed "on the story profile, not on fix size"; story AC 6 dropping triviality in the very edit that added effective-level eligibility; and the §5 authority leaving triviality implicit inside the phrase "triviality skip", which is what every downstream summary copied and then lost | gate-b | major | 1 prose | AGENTS.md Don'ts, "Never replace a decision procedure without accounting for its old conditions" — list what the previous prose required and mark each kept, moved, or deliberately dropped; also check the paragraphs around any criterion you amend, since amending one does not touch the prose that motivated it. Class added to docs/hardening-taxonomy.md in this same change, with its boundary against `docs-drift` stated (drift is two artifacts disagreeing and is fixed by updating the stale one; this is one rewritten rule wrong on its own terms, fixed by restoring the condition). NO DETERMINISTIC RUNG: a dropped condition is textually indistinguishable from text that was never there, so no grep or checker decides it |
| 2026-07-27 | docs-drift | FOURTH occurrence, different mechanism from the first three: a change invalidated sentences in files it never touched — `plugins/dev-workflow/commands/process-pr-review.md` (a SHIPPED command still skipping Gate B on fix size alone, which would have let a one-line fix on a security-relevant story bypass the narrowed rule entirely), `docs/getting-started.md` twice, and `docs/coding-workflow.md`. Every one was correct before the change and false after it | gate-b | major | P std | CLAUDE.md §5 Gate B + the workflow-init inline template: a standing lens on every Gate-B call — "which existing statements does this diff falsify?". A TARGETED ASK found all four; the checks that ran — parity diffs, resyncs, greps of the edited paths — are scoped to files the change touched and do not look where these live, since those files were correct until the change landed elsewhere and nothing in the diff points at them. WHAT THIS RUNG DOES NOT DO, stated because the lens is the whole hardening: it is prompt text, nothing enforces that a reviewer asks it or checks the answer, and it guarantees no discovery. A narrow deterministic check could pin one stale spelling the way check 4b pins one count spelling; what does not exist is a comprehensive check for arbitrary semantic drift, which is why the rung is P and not 2. NOT ESCALATED past the 2026-07-26 `2 lint` row for the same reason as the sibling row above: that check guards prose count claims, and this defect is outside its spelling — the over-escalation the row warns about. Escalation from the 2026-07-18 `P std` row (spec-updated-with-fix) is real but narrow: that rule reaches the spec of the change being made, not arbitrary prose elsewhere in the repo |
| 2026-08-04 | docs-drift | fifth occurrence: three statements the 0.8.0 diff falsified — AGENTS.md's prerequisites list omitting `dash` while the battery invokes it twice, a plan's "four script runs" for a block holding five, and a spec citing a hook line the same rewrite had moved — all found by a PR bot, none by the standing Gate-B lens | bot | major | P std | CLAUDE.md §5 Gate-B lens + the same block in the workflow-init inline template: the lens now asks what the diff changes the size, value or position of, and to grep for where each is described elsewhere. PRIOR ROW: 2026-07-27 docs-drift (P std), guard "which existing statements does this diff falsify?" — this finding is INSIDE that guard, so it is a regression repaired at the same rung, not an escalation: the lens was carried on the 0.8.0 cycle (the execution notes record it under "Standing lens, with unusual force") and missed all three. WHAT CHANGED AND WHY THE OLD FORM MISSED IT: the open question asks for recall; all three cases are a fact recorded elsewhere that the diff changed — a list's membership, a count, a position — and enumerating those needs a search. STILL INSTRUCTION-BACKED: nothing runs the grep or validates the answer, so this raises the floor and does not close the class |
| 2026-08-04 | unverified-enforcement-claim | fifth occurrence: "It bounds the **scan**, not memory" named one uncovered axis and left the reader to infer the others were covered — the bound was a size bound, the work was quadratic in size, and the runtime it was read as bounding held only for the shapes that had been measured | gate-a | major | 1 prose | AGENTS.md Don't "Never describe what a gate proves without checking what it actually compares", closing rule extended: where a sentence says what a mechanism does NOT cover, name the axes it was checked against and state whether that list is exhaustive. PRIOR ROW: 2026-07-19 (1 prose), the same Don't, whose operative instruction covers "every sentence about a gate" — INSIDE it, so this is a regression, and the amendment closes a gap the comparison-focused wording left open. GUARD, exactly: the exhaustiveness statement. The motivating sentence names two axes and gives each a verdict, so a rule asking only for the axes checked would approve it; declaring the list exhaustive or not is what it never does. NOT LOGGED HERE: PR #21's C4 and C5 fall inside the same Don't but need nothing it does not already say, so no repair exists to name — they are parked in todos.md as a compliance recurrence with their own trigger. STILL INSTRUCTION-BACKED: no checker reads a coverage claim |
| 2026-08-04 | verification-masks-failure | second occurrence, four cases in one cycle: a dry run that defined `$EVIDENCE` itself, proving the git mechanics and never that the plan defines the variable; a regression test that only ever ran under macOS `sh` while the defect it guards appears under `dash`; timed rows whose single-record fixtures never reach the record accumulator's quadratic path; and release evidence claiming `dash` coverage from a run that executed the harness under `dash` and the hook under `/bin/sh` | gate-b | major | P std | CLAUDE.md §5 Profiles counterfactual + the same block in the workflow-init inline template: name the observation that would exist if the claim were false, and confirm the wiring could have produced it. GUARD, exactly: the second half — a check that supplies its own input, runs where the defect cannot appear, or uses a fixture that never reaches the branch it covers. Each of the four cases fails on it. PRIOR ROW: 2026-07-20 (1 prose), whose ref states its own scope — "nothing checks new plans for the same shape" — so all four are OUTSIDE it and this is the fitting rung rather than an escalation on the count. RUNG P NOT 1: the artifact is a prompt; the rung follows the artifact, not the count. SOURCE: two gate-a cases and two gate-b, so the tie-break applies — the triggering case is the `dash` release evidence, which is gate-b. STILL INSTRUCTION-BACKED: nothing tests whether a check could have failed |
| 2026-08-04 | mechanical-check-skipped-before-review | NEW CLASS, minted this change: eight read-only Gate-A passes over one plan missed eight defects that thirteen machine checks then found in a single sweep, including a rollback that would have byte-verified against the wrong hook | manual | major | P std | CLAUDE.md §5 Gate-A pass procedure + the same block in the workflow-init inline template: before each read pass, settle mechanically what the artifact asserts and a machine can decide without side effects — cited paths, quoted passages, stated counts, the syntax of standalone fenced blocks — because a read pass spends expensive judgement on what a parser settles in seconds and misses it anyway, inspecting quoted commands rather than running them, since a command quoted in a spec may be destructive or an intentional failure. Class added to docs/hardening-taxonomy.md in this same change, with its boundary against verification-masks-failure stated: there a check ran and could not fail; here the cheap check never ran at all. NO PRIOR ROW — this is the first occurrence. STILL INSTRUCTION-BACKED: nothing runs the sweep, records that it ran, or checks what it settled |
9 changes: 9 additions & 0 deletions docs/hardening-taxonomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ the synonyms a future reader might search for instead.
writing the thing down at all. Also not `truncated-tool-output-read-as-complete` —
nothing here is truncated or misread as complete; the content was simply never durable.

- `mechanical-check-skipped-before-review` — an artifact carrying machine-checkable assertions
goes to an expensive read pass before anything parses it, so attention is spent on what a
tool decides in seconds. Aliases: `sh -n` after the fact, the parser would have caught it,
read pass before the sweep, manual review of machine-decidable claims.

**Not `verification-masks-failure`.** There a check ran and could not fail; here the cheap
check never ran at all. Grep this one when the sentence is "a parser would have found it
immediately"; grep the other when it is "the check passed and proved nothing".

**Promotion candidate.** These classes are stack-neutral, not project vocabulary, so
they belong in the `harden-finding` base list rather than here. They live here because
the skill says to mint into this file (the plugin ships the base classes, the project
Expand Down
Loading