# ADR-0051: the gate is made as strong as its headline **Date**: 2026-08-12 **Status**: accepted (2026-08-13; ratification record below) ## Context The product prints and documents claims about the depth of its deterministic gate. Measured on the shipped 0.33.5 (`dist/cli.js`, every case executed 2026-08-12, none reasoned), each claim is stronger than the mechanism behind it. The reader this matters to is the one runward exists not to deceive: an auditor handed a green strict run. 1. **"The gate verifies the shape of the evidence" holds for 1 rule of 64.** `rules --json` lists 64 rules and exactly one `signature:` (`frontier-deterministic-boundary`). Reproduced on a fresh scaffold, one run, two rows side by side: `hexa-architecture | applied | file:src/guard.ts#guardFields`, pointing at a real file with no relation whatsoever to hexagonal architecture, raises **zero** violations, while the one signed rule on the same run raises "evidence does not match the rule's signature" with the hint "(cited, not applied?)". The credibility sentence [ADR-0020](ADR-0020-rule-evidence-signatures.md) made true is true exactly once. Everywhere else the pointer layer verifies existence, not shape, and nothing in the run says which regime a given row was judged under. 2. **The symbol check passes on any substring, while its message claims presence.** `src/lib/evidence.ts:413` tests `content.includes(p.symbol)`. Executed: a file containing only `guardFieldsLegacy`, pointer `#guardFields`, is green; the control `#guardRows` reds with "symbol not found in the file (moved or renamed? update the pointer)". So the exact case the message names, a renamed symbol, stays green whenever the old name is a prefix or fragment of the new one, and a seal can sit on a pointer naming an identifier that no longer exists. This is a declared depth, not a silence: [ADR-0019](ADR-0019-typed-evidence-pointers-verified-at-the-gate.md) declared the substring and [ADR-0045](ADR-0045-the-gate-cannot-be-satisfied-by-paperwork.md) preserved it by name ("the declared depth limits, unchanged"). Changing it amends a documented decision, and this ADR is that amendment, stated rather than slipped in. 3. **The run never says how thin the signed share is.** "What this gate verified" counts typed versus prose rows (`src/lib/evidence.ts:562-595`, rendered `src/commands/check.ts:150-167`) but not signed versus merely resolved. An operator reading "36 of 36 pointers the gate opened and checked (100%)" cannot tell that for 35 of them "checked" meant: the file exists, is non-empty, is not circular, and contains the substring. Never: has the rule's shape. The unfavorable case, plainly: today the gate's strongest printed sentence covers its weakest verification, in silence. A sibling decision from the same product review, [ADR-0053](ADR-0053-the-construction-gate-certifies-a-declared-horizon.md) (accepted), bounds a different overclaim (exit 0 read as "mission complete" during construction); the two are independent and neither depends on the other landing. ## Decision Three moves. Each either strengthens the mechanism to match the sentence, or narrows the sentence to match the mechanism. Nothing else moves: the 0/1/2 exit contract ([ADR-0030](ADR-0030-agent-operates-runward-neutral-baseline-best-effort-detection.md)), the six phases, `GATE_NON_SCOPE`, and the seal's semantics are untouched. **1. Symbols match at identifier boundaries.** For a pointer symbol of identifier form (`/^[A-Za-z_$][A-Za-z0-9_$]*$/`), the match requires an occurrence not embedded in a larger identifier: the escaped symbol wrapped in `(?