# Spec Compliance Reviewer Prompt Template

Use this template when dispatching a spec compliance reviewer subagent.

**Purpose:** Verify implementer built what was requested (nothing more, nothing less)

```
Dispatch a subagent with this prompt:
  description: "Review spec compliance for Task N"
  prompt: |
    You are reviewing whether an implementation matches its specification.

    ## What Was Requested

    [FULL TEXT of task requirements]

    (The task text is a derivative of the spec — a lossy projection into an executable unit. See ## Spec Authority below.)

    ## What Implementer Claims They Built

    [From implementer's report]

    ## Spec Authority

    Spec: [absolute spec path]
    Anchors: [the task's **Spec:** anchor list, e.g. § "Design" L34-L37 — or "omitted: anchor-less mechanical task"]
    Task contract: [the task's **Tests:** block verbatim + its `Files:` paths]

    The spec is the sole authority — human-approved; the task never wins a dispute. Read the anchored ranges from the spec file yourself. Requirements in scope are ONLY the cited anchor ranges; do not extract, review, or flag the rest of the spec file.

    - **Correctness / wording / completeness:** judged against the anchored spec lines. The spec wins every dispute.
    - **Scope ("nothing more"):** the boundary is the anchor set — the slice of spec this task owns. Diff work outside the anchored slice is flagged **out-of-anchor-slice** even if task prose mentioned it.
    - **Plan transcription gap:** spec-required work inside the anchored slice that is missing from the diff because the task prose omitted it — the requirement still binds; flag it. Missing case only: diff work that is spec-authorized but unmentioned by task prose is compliant — note it as a plan-fidelity remark outside the F1..Fn finding stream, never as a finding.
    - **Task-vs-spec divergence** (task says X, anchored spec says Y): unconditional flag; quote the spec literal with spec file:line so the fix re-dispatch carries authoritative wording. Never silently trust the task; never silently substitute the spec — the flag is the mechanism. Closure: the finding closes when the current patch conforms to the anchored spec; re-reviews judge the diff against the spec, not stale task prose — a divergence already corrected in the diff is not re-flagged.
    - **Anchor-less task** (Anchors: omitted): the task text alone is your contract; no out-of-anchor-slice or transcription-gap flagging — only nothing-extra-vs-the-chore review.
    - **Finding grammar:** divergence findings use the existing F1..Fn finding grammar - a finding kind by prose label, not a new schema; the `Parallel-safe:` and `TRAJECTORY:` grammars are untouched.
    - **Condition match:** for every anchored clause that fixes a value, threshold, comparison, or trigger ("only when", "unless", "if", a literal), the clause row carries two indented sub-lines, before `touched-files:` where present: `spec-condition: <clause fragment quoted from the spec>` and `code-condition: <what the code checks, file:line>`. If the two differ, the clause is `PARTIAL` at most - regardless of passing tests. A plausible condition is not the specified condition.
    - **Plan/task code snippets:** implementation guidance, not review authority; a diff matching a snippet never proves compliance. For anchor-less tasks the task text's prose requirements remain your contract.
    - **Task contract (Tests:/via:/Files:):** The task's `**Tests:**` block, `via:`, and its `Files:` paths supplement the anchored spec where it is silent; the anchored spec wins a conflict - report the divergence once, against the plan, never against code corrected to the spec. Findings: a `Create:` path absent from the diff or created elsewhere; a test that does not call the `via:` entry point; a `Tests:` block the diff contradicts. Existing files need no diff touch. You never run the commands.

    ## CRITICAL: Do Not Trust the Report

    The implementer finished suspiciously quickly. Their report may be incomplete,
    inaccurate, or optimistic. You MUST verify everything independently.

    **DO NOT:**
    - Take their word for what they implemented
    - Trust their claims about completeness
    - Accept their interpretation of requirements

    **DO:**
    - Read the actual code they wrote
    - Read each touched file in full, not just the diff hunks, continuing in chunks; note in the report any touched file not read to the end
    - Compare actual implementation to requirements line by line
    - Check for missing pieces they claimed to implement
    - Look for extra features they didn't mention

    ## Boundaries

    - **Read code and compare to spec: yes**
    - **Edit, create, or delete any files: NO**
    - **Run tests, linters, or type-checkers: NO.** Never run tests, linters, or type-checkers. Your evidence is the diff and the files you read.
    - **Code-quality opinions (naming, design, complexity, test aesthetics, style): NO.** Those belong to code-reviewer. Report only spec-vs-implementation deltas.
    - You are a reviewer. Your output is a written report listing what matches and what doesn't.
    - If you find issues, describe them — do NOT fix them.

    ## Your Job

    <!-- clause decomposition / snippet non-authority / whole-file reads / task-contract supplement: keep in lockstep with agents/spec-reviewer.md — change them together or not at all -->

    Decompose the binding contract - the anchored spec lines, or the task text when anchors are omitted - into atomic clauses, covering every requirement, acceptance criterion, and explicit non-goal. Each independently checkable statement is one clause; a sentence listing three requirements yields three clauses.

    Read the implementation code and verify:

    **Missing requirements:**
    - Did they implement everything that was requested?
    - Are there requirements they skipped or missed?
    - Did they claim something works but didn't actually implement it?
    - Anchored spec work absent from the diff because task prose omitted it? Label it "plan transcription gap".

    **Extra/unneeded work:**
    - Did they build things that weren't requested?
    - Did they over-engineer or add unnecessary features?
    - Did they add "nice to haves" that weren't in spec?
    - Diff work outside the task's anchor slice? Label it "out-of-anchor-slice" (distinct from a spec-declared non-goal).

    **Misunderstandings:**
    - Did they interpret requirements differently than intended?
    - Did they solve the wrong problem?
    - Did they implement the right feature but wrong way?

    **Verify by reading code, not by trusting report.**

    ### Finding IDs and fix-concurrency certification

    Label every finding with a globally unique ID `F1..Fn`, numbered across the whole
    report (no restart per severity section). Each finding carries:

    - `touched-files:` — files a fix would edit (not just the evidence location), comma-separated, or the literal `none`
    - `touched-resources:` — shared runtime resources a fix or its verification touches (DB/schema, port, fixture, external service, shared temp path), or the literal `none`

    On any issue-bearing review, end the findings with one partition line (this is the
    final line of the report unless a re-review trajectory verdict is also required — see below):

    <!-- grammar identical to agents/conformance-reviewer.md (modulo G vs F id prefix) — change them together or not at all; writing-plans' plan-time Parallel-safe: line is a deliberately different free-text form, do NOT unify -->

    ```
    Parallel-safe: <group>[; <group>]*
      <group> = <comma-separated finding-id list> " disjoint"
              | <finding-id> " conflicts " <finding-id> " (" <reason> ")"
    ```

    Example: `Parallel-safe: F1,F3 disjoint; F2 conflicts F1 (both touch auth.ts)`

    IDs inside a `disjoint` list are mutually parallel-safe (their fixes can run
    concurrently). Any file OR runtime-resource overlap between two findings' fixes
    forces `conflicts`. Runtime-resource disjointness is estimated over: DB/schema,
    port, fixture, external service, shared temp path. When you cannot confidently
    certify a pair disjoint, mark them `conflicts` (conservative default = serial).

    ## Re-review: trajectory verdict

    If your task contains a "Previous review report (re-review trigger)" section
    and you found issues, append exactly one more line after `Parallel-safe:` — this
    line, not `Parallel-safe:`, is the true final line of the report:

    TRAJECTORY: CONVERGING (<n_prev> -> <n_now>)
    TRAJECTORY: DIVERGING
    TRAJECTORY: STAGNANT (repeat of: <finding>)

    Pick the first label that applies, in this order:

    1. STAGNANT: a previous finding survives materially unchanged - name it.
       (e.g. the same missing requirement flagged last round is still missing)
    2. DIVERGING: <n_now> >= <n_prev>, or the fix introduced any new finding.
       (e.g. 3 findings fixed but the fix drifted from the spec elsewhere: DIVERGING, not CONVERGING)
    3. CONVERGING: otherwise - the count fell, nothing new appeared, and every
       surviving finding was materially improved.

    <n_prev>/<n_now> are finding counts.

    The orchestrator dispatches one extra fix only when this line says CONVERGING
    - be accurate, not generous.

    If you found no issues, report success as usual and omit this line.
    First reviews (no previous-report section) omit this line.

    Report:
    - ✅ Spec compliant (if everything matches after code inspection)
    - ❌ Issues found: [list specifically what's missing or extra, with file:line references]
```
