/gaia-sprint-review
user-facingWhat 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 atrubrics/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-closeto finalize. -
FAILED -- transition the sprint to
correction, emit per-failed-goal action items via thesprint-correctionresolver, 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: doneand you are ready to close out the iteration. -
The sprint's
goals:field has been populated (via/gaia-sprint-planorsprint-state.sh set-goals) -- the review rubric is evaluated per-goal, so an emptygoals[]array is a hard refuse. -
The sprint is currently
status: active. The skill transitions it toreviewas 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 theactive → reviewtransition. -
All stories must be
done. Any story with a non-donestatus REFUSES the run with the canonical stderr listing the offending keys. Complete the remaining work or roll it over via/gaia-correct-coursebefore re-invoking. -
goals[]must be non-empty. The rubric is per-goal; a sprint with no goals cannot be reviewed. Usesprint-state.sh set-goals --sprint <id> --file goals.yamlto populate it.
Arguments
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
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:
- Step 3 pre-Val dispatch confirmation -- the stakeholder reviews the sprint goals and rubric path before Val fires.
-
Step 4 per-goal Track B stakeholder confirmation
-- the stakeholder records, for each goal, one of
works-as-expected,fails-goal,needs-rework, ordelegate-to-val. - 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
-
Pre-condition gate
Reads
sprint-status.yamlfor the given sprint id. REFUSES if any story is non-done(canonical stderr lists the offending keys); REFUSES ifgoals:is empty or missing. Exits non-zero on either condition. -
Transition active → review
Invokes
sprint-state.sh transition --sprint <id> --to review. Atomically updatessprint-status.yaml(mktemp + mv). ExportsSPRINT_IDso the finalize hook can locate the dispatch sentinel later. -
Track A Val dispatch (dual-sentinel)
Emits an
AskUserQuestionpresenting 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 therubrics/base/sprint-review.jsonrubric, the sprint yaml, and the story files. The orchestrator writes the envelope sentinel vialib/write-val-envelope.sh, asserts it viaassert-agent-envelope.sh, and writes the dispatch sentinel viawrite-val-sentinel.sh. CRITICAL findings HALT before Track B fires. -
Track B execution dispatch
Invokes
track-b-dispatch.sh --sprint <id>. The stub readssprint_review:from.gaia/config/project-config.yaml, iterates the per-stack matrix, and emits a JSON array. On the current build every entry isverdict: SKIPPED; a later runner replaces this stub with a real foreground per-stack execution review. -
Per-goal stakeholder confirmation
For each sprint goal, fires
AskUserQuestionwith the 4-option set:works-as-expected/fails-goal/needs-rework/delegate-to-val. Thedelegate-to-valoption recordsdelegate-to-val:<val-verdict>so the audit trail preserves the delegation chain. -
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. -
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 tocorrectionviasprint-state.sh transitionand emits one action item per failed goal through thesprint-correctionresolver intype-target-resolver.sh. -
UNVERIFIED bypass (when applicable)
Collects mechanical signals
(primary criterion, qualifying ratio ≥ 0.80, qualifying
stories), fires
AskUserQuestionto PM (Derek) for the explanation, persists thereview_justification:block viasprint-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-closewith 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
-
/gaia-sprint-close-- on a PASSED (or UNVERIFIED-bypass) verdict, finalizes the sprint. -
/gaia-correct-course story_injection-- on a FAILED verdict, injects rework stories before re-running/gaia-sprint-review. -
/gaia-retro-- typically run before/gaia-sprint-closeto capture went-well, didn't-go-well, and action items.
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.