/gaia-sprint-review

user-facing
Category:
Sprint Management
Lifecycle phase:
4 -- Implementation (end-of-sprint ceremony)
Arguments:
<sprint-id>

What it does

/gaia-sprint-review runs the end-of-sprint review ceremony. It composes two parallel tracks into a single composite verdict:

  • Track A -- Val text-validation. A Val sub-agent reads sprint-status.yaml, the sprint's story files, and the rubric at rubrics/base/sprint-review.json, then emits a per-goal verdict (PASSED / FAILED / PARTIAL) across three rubric dimensions: story-to-goal traceability, velocity-vs-capacity fit, and PRD priority coverage.
  • Track B -- per-stack execution review. Re-runs the configured per-stack test matrix in the foreground and reports a per-stack PASSED / FAILED / UNVERIFIED verdict. Track B is a stub on the current build; the real runner ships in a later release.

The two tracks reduce through compose-verdict.sh into a single composite verdict that routes the sprint:

  • PASSED -- handoff to /gaia-sprint-close to finalize.
  • FAILED -- transition the sprint to correction, emit per-failed-goal action items via the sprint-correction resolver, hand off to /gaia-correct-course story_injection.
  • UNVERIFIED -- the bypass path: collect mechanical signals (infra-only, docs-only, or deferred-implementation), request a PM explanation, then dispatch a second Val pass that validates the bypass justification. If that pass PASSES, the sprint may still close with an UNVERIFIED-bypass marker.

When to use it

  • All stories in the sprint are status: done and you are ready to close out the iteration.
  • The sprint's goals: field has been populated (via /gaia-sprint-plan or sprint-state.sh set-goals) -- the review rubric is evaluated per-goal, so an empty goals[] array is a hard refuse.
  • The sprint is currently status: active. The skill transitions it to review as Step 2 and routes onward from there.

Prerequisites

  • Sprint must be active. The Step 1 pre-condition gate verifies the current sprint status before firing the active → review transition.
  • All stories must be done. Any story with a non-done status REFUSES the run with the canonical stderr listing the offending keys. Complete the remaining work or roll it over via /gaia-correct-course before re-invoking.
  • goals[] must be non-empty. The rubric is per-goal; a sprint with no goals cannot be reviewed. Use sprint-state.sh set-goals --sprint <id> --file goals.yaml to populate it.

Arguments

NameTypeRequiredDefaultDescription
sprint-id Positional Yes -- The sprint identifier (e.g., sprint-12) whose review is being run. Must match a sprint in .gaia/state/sprint-status.yaml.

Orchestration mode

/gaia-sprint-review declares orchestration_class: heavy-procedural and runs as a main-turn Mode A ceremony. It is not YOLO-able by design: yolo_steps: []. Three AskUserQuestion boundaries require human judgment that cannot be safely auto-answered:

  1. Step 3 pre-Val dispatch confirmation -- the stakeholder reviews the sprint goals and rubric path before Val fires.
  2. Step 4 per-goal Track B stakeholder confirmation -- the stakeholder records, for each goal, one of works-as-expected, fails-goal, needs-rework, or delegate-to-val.
  3. Step 8 UNVERIFIED bypass PM explanation -- the PM provides a 200--1000 character justification for the bypass.

CI or unattended pipelines that need sprint-review automation should script the boundary writes directly via sprint-state.sh transition --sprint <id> --to review and emit the sprint-review artifact + Val sentinel manually, matching the documented YARA-2 manual workaround pattern.

How to invoke

/gaia-sprint-review sprint-12

Replace sprint-12 with the active sprint identifier.

What it does step by step

  1. Pre-condition gate Reads sprint-status.yaml for the given sprint id. REFUSES if any story is non-done (canonical stderr lists the offending keys); REFUSES if goals: is empty or missing. Exits non-zero on either condition.
  2. Transition active → review Invokes sprint-state.sh transition --sprint <id> --to review. Atomically updates sprint-status.yaml (mktemp + mv). Exports SPRINT_ID so the finalize hook can locate the dispatch sentinel later.
  3. Track A Val dispatch (dual-sentinel) Emits an AskUserQuestion presenting sprint goals + rubric path (the substrate halt is the auto-mode bypass mitigation). On user acknowledgement, dispatches Val via the main-turn Agent tool with the rubrics/base/sprint-review.json rubric, the sprint yaml, and the story files. The orchestrator writes the envelope sentinel via lib/write-val-envelope.sh, asserts it via assert-agent-envelope.sh, and writes the dispatch sentinel via write-val-sentinel.sh. CRITICAL findings HALT before Track B fires.
  4. Track B execution dispatch Invokes track-b-dispatch.sh --sprint <id>. The stub reads sprint_review: from .gaia/config/project-config.yaml, iterates the per-stack matrix, and emits a JSON array. On the current build every entry is verdict: SKIPPED; a later runner replaces this stub with a real foreground per-stack execution review.
  5. Per-goal stakeholder confirmation For each sprint goal, fires AskUserQuestion with the 4-option set: works-as-expected / fails-goal / needs-rework / delegate-to-val. The delegate-to-val option records delegate-to-val:<val-verdict> so the audit trail preserves the delegation chain.
  6. Compose composite verdict Invokes compose-verdict.sh --track-a <a> --track-b <b>. PASSED iff both tracks PASSED (SKIPPED on Track B counts as PASSED-equivalent on the current stub; PARTIAL on Track A does not block). FAILED if either track FAILED. UNVERIFIED if either track UNVERIFIED and neither FAILED.
  7. Route to PASSED / FAILED / UNVERIFIED Writes the sprint-review artifact under .gaia/artifacts/implementation-artifacts/sprint-review/sprint-review-<sprint_id>-<date>.md. On PASSED, emits the handoff message pointing the user at /gaia-sprint-close. On FAILED, transitions to correction via sprint-state.sh transition and emits one action item per failed goal through the sprint-correction resolver in type-target-resolver.sh.
  8. UNVERIFIED bypass (when applicable) Collects mechanical signals (primary criterion, qualifying ratio ≥ 0.80, qualifying stories), fires AskUserQuestion to PM (Derek) for the explanation, persists the review_justification: block via sprint-state.sh set-review-justification, then dispatches a second Val pass that validates the justification against ground truth. On Val PASSED, emits the handoff to /gaia-sprint-close with the UNVERIFIED-bypass marker; on Val FAILED, reverts to the FAILED path.

Inputs

Input Source Description
Sprint tracking file .gaia/state/sprint-status.yaml The sprint under review. status: must be active; all stories[].status must be done; goals: must be non-empty.
Story files .gaia/artifacts/implementation-artifacts/epic-{slug}/{key}-{slug}/story.md The completed stories that the per-goal rubric evaluates against.
Sprint-review rubric ${CLAUDE_PLUGIN_ROOT}/rubrics/base/sprint-review.json The rubric Val reads to produce per-goal verdicts across the three rubric dimensions.
Sprint-review config .gaia/config/project-config.yaml (key sprint_review:) Per-stack matrix consumed by Track B's track-b-dispatch.sh.

Outputs

Output Location Description
Sprint-review artifact .gaia/artifacts/implementation-artifacts/sprint-review/sprint-review-<sprint_id>-<date>.md Charter + goals + Track A Val verdict + Track B per-stack output + per-goal stakeholder confirmations + composite verdict + routing decision.
Val dispatch sentinel .gaia/memory/checkpoints/sprint-review-<sprint_id>-val-dispatched.json The dispatch sentinel /gaia-sprint-close verifies before accepting the review → closed edge.
Val envelope sentinel .gaia/memory/checkpoints/val-envelope-<sha256(sprint_id):0:16>.json The envelope sentinel (forgery-resistant) for the Val verdict.
Sprint state transition .gaia/state/sprint-status.yaml On PASSED: stays at review awaiting /gaia-sprint-close. On FAILED: transitions to correction.
Action items (FAILED only) .gaia/state/action-items.yaml One sprint-correction entry per failed goal, routed to /gaia-correct-course via the 11-type resolver.

Examples

1. PASSED path

> /gaia-sprint-review sprint-12

Pre-condition gate:
  6 stories, all status: done.
  goals[]: 3 entries.
  Proceeding.

Transition: active -> review (atomic write via sprint-state.sh).

Track A -- Val dispatch:
  AskUserQuestion: confirm sprint goals + rubric path? [yes]
  Val (claude-opus-4-7) reading sprint-status.yaml + 6 story files + rubric.
  Verdict: PASSED
    Goal G1 (auth-flow):    PASSED
    Goal G2 (audit-log):    PASSED
    Goal G3 (rate-limit):   PASSED

Track B -- execution review:
  track-b-dispatch.sh: 2 stacks configured (python, node).
    python: SKIPPED (real runner not yet shipped)
    node:   SKIPPED (real runner not yet shipped)

Per-goal stakeholder confirmation:
  Goal G1: works-as-expected
  Goal G2: works-as-expected
  Goal G3: works-as-expected

Compose verdict: PASSED (Track A=PASSED, Track B=SKIPPED).

Artifact written: .gaia/artifacts/implementation-artifacts/sprint-review/sprint-review-sprint-12-2026-05-29.md

/gaia-sprint-review: composite verdict PASSED -- sprint sprint-12 ready to close;
  invoke /gaia-sprint-close to finalize.

2. FAILED path with composite reasoning

> /gaia-sprint-review sprint-13

Track A -- Val verdict: FAILED
  Goal G1 (payment-flow):  PASSED
  Goal G2 (refund-flow):   FAILED -- 2 stories missing acceptance evidence

Track B: SKIPPED (stub).

Per-goal stakeholder confirmation:
  Goal G1: works-as-expected
  Goal G2: fails-goal

Compose verdict: FAILED (Track A=FAILED).

Transition: review -> correction (sprint-state.sh).

Action items emitted via sprint-correction resolver:
  AI-101 "Refund-flow goal G2 missing acceptance evidence" -> /gaia-correct-course

Artifact written: sprint-review-sprint-13-2026-05-29.md (composite verdict FAILED).

/gaia-sprint-review: composite verdict FAILED -- sprint sprint-13 transitioned to correction;
  invoke /gaia-correct-course story_injection to inject rework stories,
  then re-run /gaia-sprint-review after the injected stories reach done.

What to run next

Troubleshooting

"refuse -- N sprint stories are non-done"

The Step 1 pre-condition gate enforces that every story in the sprint is status: done before the active → review transition fires. Either drive the listed stories to done (run /gaia-dev-story + /gaia-review-all on each) or roll them over via /gaia-correct-course.

"refuse -- no sprint goals defined"

The rubric is per-goal; an empty goals[] array makes the review meaningless. Populate goals via sprint-state.sh set-goals --sprint <id> --file goals.yaml (or supply goals during /gaia-sprint-plan) and re-invoke.

"HALT: Val agent envelope assertion failed"

The orchestrator could not verify the envelope sentinel (sentinel absent, malformed, or forged). Inspect .gaia/memory/checkpoints/val-envelope-*.json and the Val sub-agent return. Re-running the skill from Step 3 re-dispatches Val with a fresh envelope.

Track B reports SKIPPED for every stack

The current build ships a stub for Track B (delivered: false). The composite reducer treats SKIPPED as PASSED-equivalent so the composite verdict still composes cleanly. The real per-stack runner ships in a later release -- until then, the per-goal stakeholder confirmation in Step 5 is the only Track B signal that influences the composite.