* fix(#1906): require node-test clean-fixture causation control The node-test fail-first proof accepted a deceptive content-independent negative test — one that reds merely because GSD_PROHIB_SUBJECT is set, ignoring the subject's content — whenever no cleanFixture was supplied, because #1346's causation control was opt-in. The proof's observed signal (RED) thus diverged from its target (RED caused by content) by default. Make the causation control mandatory for the node-test kind: a descriptor that omits cleanFixture is un-provable (fail-closed), never accepted under the weaker violation-only proof. When a clean fixture is present, fail-first is proven exactly as before (RED on violation AND non-vacuous GREEN on clean). The lint-rule kind is unchanged (its subject IS the linted file; no GSD_PROHIB_SUBJECT indirection). Breaking (Hyrum): a previously-green node-test prohibition with no clean fixture now hard-gates — blast radius is zero in-tree (no node-test prohibition ships today; only the lint-rule local/no-source-grep dogfood). Supersedes ADR-1606 Decision 4 / ADR-550 #1346 addendum's opt-in. Closes #1906 Claude-Session: https://claude.ai/code/session_017vYn26e3nkDNxcpty1ciPJ * docs(#1906): supersede the #1346 opt-in causation control (mandatory for node-test) Record the node-test mandatory-causation-control supersede across the governing surfaces: - ADR-1606 (the enforcement decision-of-record): addendum + Decision 4 annotated + the "Mandatory causation control — REJECTED" alternative flipped to accepted (premise no longer holds: zero in-tree node-test consumers). - ADR-550: the 2026-06-21 #1346 "Why opt-in, not required" paragraph marked SUPERSEDED, pointing at ADR-1606. - spec-phase.md: check_clean_fixture is now REQUIRED for node-test (was "optional"). - CONTEXT.md: PROHIB.enforce.causation predicate updated. Regenerated the shipped-artifact cascade from the spec-phase.md edit (+149 B, well under the 40960 cap): 16 golden-install-parity fixtures and the workflow size baseline. Refs #1906 Claude-Session: https://claude.ai/code/session_017vYn26e3nkDNxcpty1ciPJ
This commit is contained in:
@@ -371,11 +371,13 @@ For each Requirement gathered so far, run the two-stage recall→precision pass:
|
||||
against to **machine-prove fail-first**; rides BOTH kinds. Capture it to let the item green
|
||||
end-to-end with zero hand-authoring at verify time; for `node-test` the negative test should
|
||||
read its subject from the `GSD_PROHIB_SUBJECT` env var so the prover can inject this fixture.
|
||||
- `check_clean_fixture` (#1346) — **optional** path to a KNOWN-CLEAN control subject. When
|
||||
captured, the `node-test` prover also runs the check against it and requires GREEN — proving
|
||||
the violation's RED is caused by the subject's *content*, not by `GSD_PROHIB_SUBJECT` merely
|
||||
being set. Capture it for a stronger guarantee; omit it and the check still proves fail-first
|
||||
on the violation alone (the content-causation residual stays documented for that case).
|
||||
- `check_clean_fixture` (#1346; **REQUIRED for `node-test` as of #1906**) — path to a
|
||||
KNOWN-CLEAN control subject. The `node-test` prover runs the check against it and requires
|
||||
GREEN — proving the violation's RED is caused by the subject's *content*, not by
|
||||
`GSD_PROHIB_SUBJECT` merely being set. For a `node-test` this is **mandatory**: omit it and
|
||||
the check is un-provable (fail-closed), never proven on the violation alone — so a deceptive
|
||||
content-independent test cannot pass. (`lint-rule` needs no clean fixture: its subject IS the
|
||||
linted file, no `GSD_PROHIB_SUBJECT` indirection.)
|
||||
This is a **SOFT capture (CHK-04): a `test`-tier prohibition WITHOUT a descriptor is still
|
||||
allowed** — if the author cannot yet name the wired check, leave the descriptor empty and
|
||||
proceed. It is NOT a hard authoring block; the item simply stays fail-closed/flagged
|
||||
|
||||
Reference in New Issue
Block a user