feat: brainstorm parse-every-block gate (issue #1 Fix 1)

Adds self-review check #6 to brainstorm Step 7: when the profile
declares `spec_validation.parsers`, every fenced spec block whose
fence label has an entry is written to a temp file (entry `ext`) and
run through the entry `cmd` ({file} substituted); non-zero exit is a
self-review failure that must be fixed before the spec proceeds. The
parse-trace goes into the brainstorm chat as the attestation the gate
fired. Labels with no entry are skipped-and-documented; a malformed
entry surfaces as a profile error; no `spec_validation` -> no-op.

Placed in Step 7 (not Step 4 as the issue's prose suggested) because
the spec file — and thus its code blocks — exists only after Step 6;
Step 7 also already re-runs on post-PASS edits, so a changed block
re-triggers the gate for free.

Also adds a Common Rationalisation ("it obviously parses") and a Red
Flag (configured parser, no trace in chat).

refs #1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 14:26:10 +02:00
parent 4a2c70baed
commit e1d33369f5
+22
View File
@@ -226,6 +226,24 @@ Inline checklist (not a subagent dispatch):
change (plus the worked user-facing example for a surface
cycle)? A load-bearing change described only in prose is
a self-review failure to fix, exactly like a placeholder.
6. **Parse-every-block gate.** If the project profile declares
`spec_validation.parsers`, extract every fenced code block
from the spec. For each block whose fence label has a
`parsers` entry: write the block to a temp file with the
entry's `ext`, run the entry's `cmd` with `{file}`
substituted, and require exit 0. A non-zero exit is a
self-review failure — the spec inlines code that does not
parse against the live tool — fix the spec before proceeding;
do not pass the unparsed bytes downstream. Paste the
parse-trace (the Run block and its output) into the
brainstorm chat: a visible trace is what attests the gate
fired, and its absence means the gate was skipped. A block
whose fence label has no `parsers` entry is skipped and the
skip is noted ("no parser for fence label X"); never a silent
pass. A malformed entry (`cmd` without `{file}`, or `ext` /
`cmd` missing) is a profile error to surface, not a skip. If
the profile declares no `spec_validation`, this check is a
documented no-op.
Fix issues inline. No need to re-review — fix and commit.
@@ -356,6 +374,7 @@ Hand off carries:
| "Approaches A, B, C are all bad — proceed with A" | This is exactly the moment to surface "the problem is mis-framed" rather than ratify a known-bad shape into the design ledger. Escalate to the user. |
| "Just polishing a wording after PASS, no need to re-dispatch" | The grounding-check report attests to specific bytes. A polish edit changes the bytes; the previous attestation no longer covers them. Re-dispatch is cheap; the alternative is a commit with an attestation that doesn't match the file. |
| "The shape is clear from the prose, I don't need to paste the code" | If it's clear, pasting it is free; if pasting it is hard, it wasn't clear. The feature-acceptance criterion is unjudgeable without the worked code; "a user reaches for it" with no shown code is the exact hand-wave the criterion exists to kill. |
| "The block obviously parses — I wrote it carefully" | Careful authoring is not a parse. A spec's code blocks are hypotheses until the live tool accepts them; treating them as truth is the compound-hallucination failure the parse-every-block gate exists to kill. If a parser is configured for the block's fence label, run it and paste the trace. |
## Red Flags — STOP
@@ -367,6 +386,9 @@ Hand off carries:
- A load-bearing change described in prose with no
before → after code block; a surface cycle with no worked
user-facing example
- A spec carrying a code block whose fence label has a
configured `spec_validation` parser, committed without a
parse-trace in the brainstorm chat
- Editing the spec file after a Step 7.5 PASS without
re-dispatching
- Jumping straight from spec to `implement` (must go via