Purpose
Stage: Spec — the last skill before the human Spec sign-off. The run downstream is autonomous, and
the one oracle it cannot out-vote is a person's act: acceptance.md, signed for this feature's
behavior. A human reviewing a spec littered with stray file paths, dangling ADR refs, placeholder TODOs, and
coverage gaps burns scarce attention on mechanical defects instead of the judgment calls only a human can
make. spec-review is a fresh, code-cold agent
(maker≠checker) — never the agent that authored the spec — that fixes the spec before the human sees
it: decidable facts are silently corrected; contestable judgment is corrected and flagged inline.
The human then reviews a clean spec and spends attention where it counts. The silent-re-authoring risk is
resolved by making judgment changes visible, not by withholding the fix.
When to use / when to skip
Use: runs last in Spec, after spec-grilling (ADRs/CONTEXT.md), to-prd (prd.md), acceptance-criteria
(acceptance.md), environment-manifest (environment.md), architecture-design (architecture.md + its page,
on a structure pass), and — when the feature has UI — frontend-design (the design contract) have all
landed; immediately before the human Spec sign-off. architecture-design runs against a draft
acceptance.md; the two are signed together at the Spec gate — so nothing in the bundle is signed when
you run, every artifact is still editable, and a fix you apply costs nobody a re-signature.
Skip / boundaries (depth: lite escape hatch):
- It is not a third gate. It signs nothing and blocks nothing; the human still reviews and signs.
- For a one-artifact trivial fix with no cross-artifact relation, a single inline pass without the full
bundle is acceptable — but the default is the full relational grade anchored on
intent.md.
Inputs
Read the full Spec bundle in this order — intent.md first (everything is graded relationally
against what the user actually asked for):
intent.md (interview-me / idea-refine) — Outcome · User · Why · Success · Constraints · Out-of-scope.
Read first; it is the oracle of intent.
- ADRs (
docs/adr/ADR-<NNN>-*.md) + CONTEXT.md (spec-grilling) — referenced design substrate.
prd.md (to-prd) — Problem · Solution · User Stories · Implementation Decisions · Testing Decisions ·
Out of Scope.
acceptance.md (acceptance-criteria) — Given/When/Then scenarios, behavioral-only, feature-namespaced ids
(e.g. PWR-A1) back-referencing a story id.
environment.md (environment-manifest) — typed rows, closed kind enum {env-var|mcp|service|runtime-dep|fixture|
account}; no value column, no command column.
- design contract (frontend-design) — only if the feature has UI. Read
docs/design.md alongside it
when the repo has one: the contract records only what differs from that file, so an axis marked
inherits: or departs: is complete as written. The three axes that file decides nothing on are the
exception, and the split table below says what to do about them.
architecture.md + architecture.html (architecture-design) — only if the feature ran a structure
pass. The page carries the markdown's
source block verbatim, so the two are one artifact in two forms. status: reads unsigned here and
stays that way — a person flips it at the gate after reading the page, and nothing an agent does flips it.
Refuse to run if the minimum bundle (intent.md + prd.md + acceptance.md) cannot be resolved —
without intent.md there is no oracle to grade against. Missing optional items (ADRs, or the design
contract on a non-UI feature) are soft warnings; proceed. Run as a fresh, code-cold subagent: the agent
that authored these artifacts must NOT be the one reviewing them (maker≠checker; cr-evaluator §"Why
this stage exists").
Process
- Dispatch a fresh, code-cold subagent. No author memory, no conversation history from spec-grilling/
to-prd. Read the bundle in the order above —
intent.md first.
- Grade relationally. For each downstream artifact ask: does it deliver what
intent.md asked for?
Walk the four classic axes (placeholders · internal consistency · scope · ambiguity) PLUS the
artifact-boundary rules and the coverage ledger.
- Classify every issue as Decidable (fact) or Contestable (judgment) — see the split table. A
few rows there are marked outside your grant, and those you leave exactly as written; the row says
why. Two buckets would otherwise force a third kind of item into one of them, and both of those end in an
edit.
- Decidable facts → auto-fix in place, then re-run the deterministic re-check (grep) until it
converges. Greppable, so it converges cheaply. No inline flag — it was simply wrong.
- Contestable judgment → apply your best correction in place too, but mark each change inline:
<!-- spec-review: changed X → Y because Z — revert if you disagree -->. No loop — one pass; the
human is the convergence point.
- Hand back the cleaned spec + write
spec-review.md (auto-fixes, flagged judgment changes, coverage
ledger, "open the referenced ADRs" list). That handback and architecture.html are what the person
opens at the gate, so anything they have to see before signing has to be in one of the two. Tell the
human: review the fixed spec, judgment changes are flagged inline, you keep final authority — revert any.
The fact / opinion split
| Issue |
Class |
Action |
File path / signature / driver-or-library internal appears in prd.md (prd MUST NOT contain these) |
Decidable |
Strip it; re-home to an ADR reference. Re-check: grep prd.md for paths/extensions/signatures. |
Dangling see ADR-NNN — referenced ADR file does not exist |
Decidable |
Fix the ref or create the missing ADR pointer. Re-check: cross every ADR-\d+ in prd.md against docs/adr/. |
CONTEXT.md ## Glossary term used non-verbatim in prd.md |
Decidable |
Normalize to the exact ## Glossary term (prd uses CONTEXT terms verbatim). |
Placeholder / TODO / TBD / incomplete section |
Decidable |
Fill from context or remove. A design-contract axis reading inherits: docs/design.md or departs: docs/design.md is not incomplete — never fill either in. The first points at the decided look, the second at that axis's own ## Departure block; restating what either already says is the second copy the format exists to prevent. Nor is architecture.md's §6 (Open questions for the human) — see its own row below. |
Value or command embedded in environment.md (no value column, no command column — structurally illegal) |
Decidable |
Remove. If it is a real secret → also a security STOP (see Red flags). |
acceptance.md scenario contains a file path / signature / table (behavioral-only) |
Decidable |
Rewrite as an observable outcome. |
architecture.html's embedded source block differs from architecture.md |
Decidable |
Re-splice the block from the markdown — never retype it. Compare the two byte for byte; a copy that was typed rather than spliced is already drifting while looking exactly like one that is not. This is the last stop before a person signs the page, and they read the page rather than the markdown. |
An acceptance.md scenario traces through no module or seam in architecture.md |
Contestable (spotting it is mechanical; which structure absorbs it is not) |
A backstop: architecture-design traces the draft first, so a scenario reaching here got past that. Say which of the two you believe is wrong. Where the structure is missing a part, draft the trace into architecture.md and flag it inline with the scenario id. Where you believe the scenario is the thing that does not belong, flag it for the person and change nothing — that judgement is contestable, and your grant on acceptance.md covers a decidable fact, not a call about which side is right. Deleting a scenario is the one correction that cannot be flagged inline, because a removed scenario leaves no line to carry the flag; it would leave no RED test, nothing for quality-verification to grade, and the story-coverage checks pass either way. Name it by id in spec-review.md instead. Calling it a structural gap when it is a scenario gap is how a structure gets bent around a scenario nobody wanted — and quietly cutting the scenario is how a behaviour ships unguarded. |
architecture.md's §6 (Open questions for the human) reads like unfinished work — every row states a question and a recommended answer |
Neither — outside your grant |
Leave every row exactly as written, recommended answer included. That section opens with a line saying its rows are unanswered by design and that the person answers them at the gate; the recommended answer is what its format requires of each row, not an invitation to apply it. This overrides both standing rules: §6 is not a placeholder to fill, and not a contestable item to correct-and-flag. Resolve one and you hand the person a section that looks settled, which removes the only question they were being asked — and the rows raised by the code-cold sweeps are precisely the ones nobody has put to them yet. |
Acceptance coverage gap: a prd.md user story or intent.md success-criterion with no scenario (every story must map to ≥1 reachable scenario) |
Contestable |
Draft the missing scenario; flag it inline. |
| ADR-worthiness: a hard-to-reverse ∧ surprising decision buried in prd prose instead of an ADR |
Contestable |
Propose extracting an ADR; flag. |
One feature or two: intent.md describes two independent subsystems crammed into one spec |
Contestable |
Propose the split; flag. |
Internal contradiction between prd.md and an ADR or acceptance.md |
Contestable |
Reconcile to one side; flag the chosen side. |
A design-contract Quality floor, Restraint, or Copy-as-design-material axis reads inherits: docs/design.md or departs: docs/design.md |
Contestable (spotting it is mechanical; what the delta: says is not) |
docs/design.md decides the other four axes and holds nothing on these three, so the line points at nothing and Verify would grade the axis against a file with no decision in it. Draft the delta: from what this surface decided; flag it inline. |
ADR-open check (risk mitigation / handoff)
Design now lives in referenced ADRs that the single Spec gate does not name — so the gate could
rubber-stamp design it never opened. spec-review closes that gap: verify every see ADR-NNN in prd.md
(a) resolves to a real ADR file (decidable) and (b) was surfaced inline by to-prd; then put the full list
of referenced ADR ids into spec-review.md under ## Open the referenced ADRs so the human opens each at
the gate. ADR cross-refs are immutable once written — rename/supersede → update referrers in the same commit.
Rationalizations
- "The spec looks clean, I'll skip the relational pass." → The whole value is a fresh code-cold read;
the author can't see their own gaps. Do the full grade against
intent.md.
- "I'll just list the issues for the human." → No. Hand back a cleaned spec, not a punch-list.
Apply the fix.
- "This judgment call is too risky to change." → Apply your best correction and flag it inline; the
human reverts if they disagree. Withholding the fix IS the failure mode.
- "I'll loop on the judgment fixes until they're perfect." → No loop on contestable items — the human
is the convergence point. Only decidable facts get the deterministic re-check loop.
- "I wrote this spec, I can review it." → maker≠checker. A fresh code-cold agent reviews, never the author.
Red flags
- You are the agent that authored the spec → STOP; dispatch a fresh code-cold subagent.
- You are producing a list of complaints instead of edits → STOP; fix in place.
- You are looping on a judgment call → STOP; one pass, flag, move on.
- You silently re-authored a contestable section with no inline flag → STOP; every judgment change
must be visible.
intent.md is absent → refuse to run; there is no oracle to grade against.
- An embedded value in
environment.md looks like a real, committed secret → remove it from the manifest
AND treat the exposure as a security STOP per safety rail 2 (references/safety-rails.md) — hard halt, surface to the human.
Verification (ending criteria)
Done when ALL hold:
- Every decidable check greps clean: no file paths/signatures in
prd.md; no dangling ADR-NNN; no
non-verbatim ## Glossary terms; no placeholders/TODO/TBD; no value/command in environment.md; no
behavioral-only violations in acceptance.md.
- Every contestable change is applied and carries an inline
<!-- spec-review: … --> flag.
- Every
acceptance.md scenario id back-references a story id, and every story / intent.md
success-criterion maps to ≥1 scenario (coverage ledger has no orphan story).
spec-review.md written with the four stable sections, including ## Open the referenced ADRs.
- The bundle is handed back cleaned (not a punch-list); the human is told judgment changes are flagged
and they keep final authority.
Outputs & handoff contract
- Emits — fixed spec: the bundle artifacts (
prd.md, acceptance.md, environment.md, CONTEXT.md,
ADRs) edited in place; decidable facts silently corrected, contestable judgments corrected + inline-flagged.
- Emits —
spec-review.md: ephemeral, OUT of the resume-spine (not a chain link). Stable
sections: ## Auto-fixed (facts) · ## Flagged (judgment — revert if you disagree) · ## Coverage ledger (scenario↔story map + any not-reachable classification) · ## Open the referenced ADRs.
- Not a gate:
spec-review does not flip STATE.md feature state. The human Spec sign-off does that
(feature spec → plan); spec-review runs immediately before it.
- Stable-section discipline: it reads consumer artifacts' stable sections (per the registry) and edits
those sections in place — it never invents a new artifact or a new stable section.
1---2name: spec-review3description: Use this LAST in the Spec stage, before the human signs off — a fresh code-cold agent that FIXES the spec instead of listing complaints. You MUST run it after spec-grilling/to-prd/acceptance-criteria/environment-manifest (plus frontend-design for UI and architecture-design for a structure pass) land and before the Spec gate, while the whole bundle is still draft. It auto-fixes decidable facts (stray file paths/signatures in prd.md, dangling `see ADR-NNN`, non-verbatim CONTEXT terms, placeholders, embedded secrets/commands in environment.md) and applies-then-inline-flags contestable judgment fixes (coverage gaps, ADR-worthiness, one-feature-or-two), handing back a cleaned spec, not a punch-list.4---56## Purpose78**Stage: Spec — the last skill before the human Spec sign-off.** The run downstream is autonomous, and9the **one oracle** it cannot out-vote is a person's act: `acceptance.md`, signed for this feature's10behavior. A human reviewing a spec littered with stray file paths, dangling ADR refs, placeholder TODOs, and11coverage gaps burns scarce attention on mechanical defects instead of the judgment calls only a human can12make. `spec-review` is a **fresh, code-cold agent13(maker≠checker)** — never the agent that authored the spec — that **fixes the spec before the human sees14it**: decidable facts are silently corrected; contestable judgment is corrected **and flagged inline**.15The human then reviews a clean spec and spends attention where it counts. The silent-re-authoring risk is16resolved by making judgment changes **visible**, not by withholding the fix.1718## When to use / when to skip1920**Use:** runs **last in Spec**, after `spec-grilling` (ADRs/CONTEXT.md), `to-prd` (prd.md), `acceptance-criteria`21(acceptance.md), `environment-manifest` (environment.md), `architecture-design` (architecture.md + its page,22on a structure pass), and — when the feature has UI — `frontend-design` (the design contract) have all23landed; immediately before the human Spec sign-off. `architecture-design` runs against a draft24`acceptance.md`; the two are signed together at the Spec gate — so nothing in the bundle is signed when25you run, every artifact is still editable, and a fix you apply costs nobody a re-signature.2627**Skip / boundaries (depth: lite escape hatch):**28- It is **not a third gate.** It signs nothing and blocks nothing; the human still reviews and signs.29- For a one-artifact trivial fix with no cross-artifact relation, a single inline pass without the full30 bundle is acceptable — but the **default is the full relational grade** anchored on `intent.md`.3132## Inputs3334Read the full Spec bundle **in this order — `intent.md` first** (everything is graded *relationally*35against what the user actually asked for):36371. `intent.md` (interview-me / idea-refine) — Outcome · User · Why · Success · Constraints · Out-of-scope.38 **Read first; it is the oracle of intent.**392. ADRs (`docs/adr/ADR-<NNN>-*.md`) + `CONTEXT.md` (spec-grilling) — referenced design substrate.403. `prd.md` (to-prd) — Problem · Solution · User Stories · Implementation Decisions · Testing Decisions ·41 Out of Scope.424. `acceptance.md` (acceptance-criteria) — Given/When/Then scenarios, **behavioral-only**, feature-namespaced ids43 (e.g. `PWR-A1`) back-referencing a story id.445. `environment.md` (environment-manifest) — typed rows, closed kind enum {env-var|mcp|service|runtime-dep|fixture|45 account}; no value column, no command column.466. design contract (frontend-design) — **only if the feature has UI**. Read `docs/design.md` alongside it47 when the repo has one: the contract records only what differs from that file, so an axis marked48 `inherits:` or `departs:` is complete as written. The three axes that file decides nothing on are the49 exception, and the split table below says what to do about them.507. `architecture.md` + `architecture.html` (architecture-design) — **only if the feature ran a structure51 pass**. The page carries the markdown's52 source block verbatim, so the two are one artifact in two forms. `status:` reads `unsigned` here and53 stays that way — a person flips it at the gate after reading the page, and nothing an agent does flips it.5455**Refuse to run** if the minimum bundle (`intent.md` + `prd.md` + `acceptance.md`) cannot be resolved —56without `intent.md` there is no oracle to grade against. Missing optional items (ADRs, or the design57contract on a non-UI feature) are soft warnings; proceed. **Run as a fresh, code-cold subagent: the agent58that authored these artifacts must NOT be the one reviewing them** (maker≠checker; cr-evaluator §"Why59this stage exists").6061## Process62631. **Dispatch a fresh, code-cold subagent.** No author memory, no conversation history from spec-grilling/64 to-prd. Read the bundle in the order above — `intent.md` first.652. **Grade relationally.** For each downstream artifact ask: does it deliver what `intent.md` asked for?66 Walk the four classic axes (placeholders · internal consistency · scope · ambiguity) PLUS the67 artifact-boundary rules and the coverage ledger.683. **Classify every issue** as **Decidable (fact)** or **Contestable (judgment)** — see the split table. A69 few rows there are marked **outside your grant**, and those you leave exactly as written; the row says70 why. Two buckets would otherwise force a third kind of item into one of them, and both of those end in an71 edit.724. **Decidable facts → auto-fix in place**, then re-run the **deterministic re-check** (grep) until it73 converges. Greppable, so it converges cheaply. No inline flag — it was simply wrong.745. **Contestable judgment → apply your best correction in place too**, but **mark each change inline**:75 `<!-- spec-review: changed X → Y because Z — revert if you disagree -->`. **No loop** — one pass; the76 human is the convergence point.776. **Hand back the cleaned spec** + write `spec-review.md` (auto-fixes, flagged judgment changes, coverage78 ledger, "open the referenced ADRs" list). That handback and `architecture.html` are what the person79 opens at the gate, so anything they have to see before signing has to be in one of the two. Tell the80 human: review the fixed spec, judgment changes are flagged inline, you keep final authority — revert any.8182## The fact / opinion split8384| Issue | Class | Action |85|---|---|---|86| File path / signature / driver-or-library internal appears in `prd.md` (prd MUST NOT contain these) | **Decidable** | Strip it; re-home to an ADR reference. Re-check: grep `prd.md` for paths/extensions/signatures. |87| Dangling `see ADR-NNN` — referenced ADR file does not exist | **Decidable** | Fix the ref or create the missing ADR pointer. Re-check: cross every `ADR-\d+` in prd.md against `docs/adr/`. |88| `CONTEXT.md` `## Glossary` term used non-verbatim in `prd.md` | **Decidable** | Normalize to the exact `## Glossary` term (prd uses CONTEXT terms verbatim). |89| Placeholder / `TODO` / `TBD` / incomplete section | **Decidable** | Fill from context or remove. A design-contract axis reading `inherits: docs/design.md` or `departs: docs/design.md` is **not** incomplete — never fill either in. The first points at the decided look, the second at that axis's own `## Departure` block; restating what either already says is the second copy the format exists to prevent. Nor is `architecture.md`'s §6 (Open questions for the human) — see its own row below. |90| Value or command embedded in `environment.md` (no value column, no command column — structurally illegal) | **Decidable** | Remove. If it is a real secret → also a security STOP (see Red flags). |91| `acceptance.md` scenario contains a file path / signature / table (behavioral-only) | **Decidable** | Rewrite as an observable outcome. |92| `architecture.html`'s embedded source block differs from `architecture.md` | **Decidable** | Re-splice the block from the markdown — never retype it. Compare the two byte for byte; a copy that was typed rather than spliced is already drifting while looking exactly like one that is not. This is the last stop before a person signs the page, and they read the page rather than the markdown. |93| An `acceptance.md` scenario traces through no module or seam in `architecture.md` | **Contestable** (spotting it is mechanical; which structure absorbs it is not) | A backstop: `architecture-design` traces the draft first, so a scenario reaching here got past that. Say which of the two you believe is wrong. Where the **structure** is missing a part, draft the trace into `architecture.md` and **flag it inline** with the scenario id. Where you believe the **scenario** is the thing that does not belong, **flag it for the person and change nothing** — that judgement is contestable, and your grant on `acceptance.md` covers a decidable fact, not a call about which side is right. Deleting a scenario is the one correction that cannot be flagged inline, because a removed scenario leaves no line to carry the flag; it would leave no RED test, nothing for `quality-verification` to grade, and the story-coverage checks pass either way. Name it by id in `spec-review.md` instead. Calling it a structural gap when it is a scenario gap is how a structure gets bent around a scenario nobody wanted — and quietly cutting the scenario is how a behaviour ships unguarded. |94| `architecture.md`'s §6 (Open questions for the human) reads like unfinished work — every row states a question **and a recommended answer** | **Neither — outside your grant** | Leave every row exactly as written, recommended answer included. That section opens with a line saying its rows are unanswered by design and that the person answers them at the gate; the recommended answer is what its format requires of each row, not an invitation to apply it. This overrides both standing rules: §6 is not a placeholder to fill, and not a contestable item to correct-and-flag. Resolve one and you hand the person a section that looks settled, which removes the only question they were being asked — and the rows raised by the code-cold sweeps are precisely the ones nobody has put to them yet. |95| Acceptance **coverage gap**: a `prd.md` user story or `intent.md` success-criterion with no scenario (every story must map to ≥1 reachable scenario) | **Contestable** | Draft the missing scenario; **flag it inline**. |96| **ADR-worthiness**: a hard-to-reverse ∧ surprising decision buried in prd prose instead of an ADR | **Contestable** | Propose extracting an ADR; **flag**. |97| **One feature or two**: `intent.md` describes two independent subsystems crammed into one spec | **Contestable** | Propose the split; **flag**. |98| Internal contradiction between `prd.md` and an ADR or `acceptance.md` | **Contestable** | Reconcile to one side; **flag the chosen side**. |99| A design-contract `Quality floor`, `Restraint`, or `Copy-as-design-material` axis reads `inherits: docs/design.md` or `departs: docs/design.md` | **Contestable** (spotting it is mechanical; what the `delta:` says is not) | `docs/design.md` decides the other four axes and holds nothing on these three, so the line points at nothing and Verify would grade the axis against a file with no decision in it. Draft the `delta:` from what this surface decided; **flag it inline**. |100101## ADR-open check (risk mitigation / handoff)102103Design now lives in **referenced** ADRs that the single Spec gate does not name — so the gate could104rubber-stamp design it never opened. `spec-review` closes that gap: verify every `see ADR-NNN` in `prd.md`105(a) resolves to a real ADR file (decidable) and (b) was surfaced inline by `to-prd`; then put the full list106of referenced ADR ids into `spec-review.md` under `## Open the referenced ADRs` so the human opens each at107the gate. ADR cross-refs are immutable once written — rename/supersede → update referrers in the same commit.108109## Rationalizations110111- *"The spec looks clean, I'll skip the relational pass."* → The whole value is a fresh code-cold read;112 the author can't see their own gaps. Do the full grade against `intent.md`.113- *"I'll just list the issues for the human."* → No. Hand back a **cleaned spec, not a punch-list**.114 Apply the fix.115- *"This judgment call is too risky to change."* → Apply your best correction **and** flag it inline; the116 human reverts if they disagree. Withholding the fix IS the failure mode.117- *"I'll loop on the judgment fixes until they're perfect."* → No loop on contestable items — the **human**118 is the convergence point. Only decidable facts get the deterministic re-check loop.119- *"I wrote this spec, I can review it."* → maker≠checker. A fresh code-cold agent reviews, never the author.120121## Red flags122123- You are the agent that authored the spec → **STOP**; dispatch a fresh code-cold subagent.124- You are producing a list of complaints instead of edits → **STOP**; fix in place.125- You are looping on a judgment call → **STOP**; one pass, flag, move on.126- You silently re-authored a contestable section with no inline flag → **STOP**; every judgment change127 must be visible.128- `intent.md` is absent → **refuse to run**; there is no oracle to grade against.129- An embedded value in `environment.md` looks like a real, committed secret → remove it from the manifest130 AND treat the exposure as a security STOP per safety rail 2 (`references/safety-rails.md`) — hard halt, surface to the human.131132## Verification (ending criteria)133134Done when ALL hold:135- Every **decidable** check greps clean: no file paths/signatures in `prd.md`; no dangling `ADR-NNN`; no136 non-verbatim `## Glossary` terms; no placeholders/TODO/TBD; no value/command in `environment.md`; no137 behavioral-only violations in `acceptance.md`.138- Every **contestable** change is applied **and** carries an inline `<!-- spec-review: … -->` flag.139- Every `acceptance.md` scenario id back-references a story id, and every story / `intent.md`140 success-criterion maps to ≥1 scenario (coverage ledger has no orphan story).141- `spec-review.md` written with the four stable sections, including `## Open the referenced ADRs`.142- The bundle is handed back **cleaned** (not a punch-list); the human is told judgment changes are flagged143 and they keep final authority.144145## Outputs & handoff contract146147- **Emits — fixed spec:** the bundle artifacts (`prd.md`, `acceptance.md`, `environment.md`, `CONTEXT.md`,148 ADRs) edited in place; decidable facts silently corrected, contestable judgments corrected + inline-flagged.149- **Emits — `spec-review.md`:** ephemeral, **OUT of the resume-spine** (not a chain link). Stable150 sections: `## Auto-fixed (facts)` · `## Flagged (judgment — revert if you disagree)` · `## Coverage151 ledger` (scenario↔story map + any not-reachable classification) · `## Open the referenced ADRs`.152- **Not a gate:** `spec-review` does **not** flip STATE.md feature state. The human Spec sign-off does that153 (feature `spec → plan`); `spec-review` runs immediately before it.154- **Stable-section discipline:** it reads consumer artifacts' stable sections (per the registry) and edits155 those sections in place — it never invents a new artifact or a new stable section.