/retrospect — Release retrospective with validation enforcement
Run a structured retrospective on a shipped commit range (or single commit, or current session). Produces a 10-section markdown report with per-fix verdicts, validation status, action recommendations, and re-diagnosis when fixes failed. Writes findings to knowledge/logs/retrospect/ and runs aria's standard intake. Source spec: docs/specs/2026-05-03-retrospect-skill-design.md.
When to use
- After a release ships and the bug is partially or fully unresolved
- When the user reports a regression and a recent change set could be the cause
- Before proposing another fix to a bug that's already been "fixed" once
- As a soft-suggested response to user pushback ("review what you did," "are these changes necessary")
Step 0: Inputs & Mode Detection
Parse the invocation arguments. The first positional argument is the scope keyword; subsequent positional arguments are scope-specific. Seven scopes plus a no-args default:
| Scope | Trigger | Backward-compat flag (still accepted) | Bundle source |
|---|---|---|---|
| (no args) | /retrospect | — | Auto-range: last push on current branch — git log @{push}..HEAD if upstream is set, else git log -10 and ask user to confirm range |
| commit | /retrospect commit <hash> | --commit <hash> | Single commit |
| range | /retrospect range <ref1>..<ref2> | --range <ref1>..<ref2> | git log <ref1>..<ref2> |
| pr | /retrospect pr <num> | --pr <num> | gh pr view <num> --json commits then resolve to commit SHAs |
| session | /retrospect session | --session | Files Claude has touched in the current conversation (read from session state, not git). No deploy yet — all fixes auto-tag 🚫 unvalidatable. |
| release (NEW) | /retrospect release | (none) | Commits since the most recent semver tag. git describe --tags --abbrev=0 to find the tag, then git log <tag>..HEAD. If no tags exist on the repo, fall back to auto-range and warn the user. |
| deployment (NEW) | /retrospect deployment | (none) | Commits since the last deployment marker — see "Deployment detection cascade" below. |
Argument parsing rules:
- If the first positional arg matches a scope keyword (case-insensitive), use it. Otherwise treat it as auto-range and try to parse the args under the legacy flag form.
- Backward-compat flag forms (
--range,--pr,--session,--commit) remain accepted indefinitely. Both/retrospect range a..band/retrospect --range a..bresolve identically. - Modifier flags (apply to any scope):
--linear-post(post the retrospective verdict to detected Linear tickets at end),--no-source(skip Step 3.5's Evidence-Sourcing Pass),--lens=overbuild(run the over-build review pass — see "Over-build lens" section; opt-in, off by default).
Deployment detection cascade (Q2.1=3)
When invoked as /retrospect deployment, attempt to resolve the deployment marker by trying these signals in order. First success wins; on no-success, fall through to the prompt.
- GitHub Releases —
gh release view --json publishedAt,tagName 2>/dev/null(most recent release). If returned, treat the release tag as the marker; bundle =git log <tag>..HEAD. - Semver tags —
git tag --sort=-creatordate | head -1. If a tag matchesv?\d+\.\d+\.\d+(and step 1 returned nothing), use it as the marker. - Last commit on
main(ormaster) —git log -1 --format=%H origin/main(ororigin/masterifmaindoesn't exist). Treat as the marker; bundle =git log <sha>..HEAD. This catches projects without releases or tags. - Prompt user — if none of the above resolved (e.g., no remote, no tags, no
ghauth), ask: "I couldn't auto-detect the last deployment for/retrospect deployment. Provide a marker (commit hash, tag, or ISO timestamp), or typeauto-rangeto fall back to last-push behavior."
Print the resolved marker source ("Detected via gh release: v1.4.2 (2026-05-01)") in the Anchor block (§4.1) so the user can verify what the skill thought "deployment" meant.
After mode detection, gather:
- Goal — Ask the user: "What was this release/range supposed to fix? (One sentence is fine.)" If they don't reply, fall back to commit message subjects + PR description.
- Tickets — Scan commit messages with regex
\b([A-Z]{2,}-\d+)\bfor Linear-style ticket IDs. If any are found AND Linear MCP is available, fetch each ticket's Product/Technical Intake + recent comments. If Linear MCP is unavailable, note "ticket context unavailable" but continue. - Post-deploy outcome — Ask the user: "For each fix, what's the post-ship evidence? (✅ closed / ⚠ partial / ❌ failed / ❓ untested)" Show the per-commit list and accept inline replies. If user can't supply evidence for any fix, mark those ❓ and note that §10 will recommend instrumentation.
If scope is session (or invoked via --session), skip post-deploy outcome (no production yet) and tag all fixes 🚫 unvalidatable; their actions will resolve to HOLD-PENDING-DEPLOY.
Step 0.5: Active Knowledge Surfacing
If the user's config (~/.gemini/antigravity/aria-knowledge.local.md) has active_knowledge_surfacing: true (default as of v2.15.0), surface relevant tagged knowledge BEFORE Steps 1-3 so loaded files inform pattern selection and evidence sourcing. If the field is false, skip this step entirely (note Active surfacing: disabled in the Anchor block).
Algorithm:
-
Build query. Combine, separated by spaces: the Goal sentence from Step 0; the first 3 commit subjects in the bundle range; PR title if scope is
pr; any detected Linear ticket IDs (e.g.,LINEAR-123); the resolved deployment marker label if scope isdeployment; the range descriptor (e.g.,v0.4.2..HEAD). -
Read the index.
Read<knowledge_folder>/index.md(resolve<knowledge_folder>from the config'sknowledge_folderfield). Parse the## Tag Indexsection for### tagnameheaders — that's the matching vocabulary (~77 known tags as of v2.15.0). Ignore the## Other Tagssection (freeform tier, intentionally excluded from auto-surfacing). -
Tokenize. Lowercase the query, strip punctuation to spaces, dedupe to a word set.
-
Match. Exact word-vs-tag equality only — no substring, no fuzzy. Collect the set of matched tags.
-
Threshold gate. If fewer than 2 tags matched, note
Active surfacing: 0 matches (below threshold)in the Anchor block and skip to Step 1. -
Collect files. Under each matched tag's
### tagsection, gather the- path — descriptionlines. Dedupe by path. Cap at top-5 by first-appearance order. -
Ledger filter (best-effort). Run
ls -t /tmp/aria-active-* 2>/dev/null | head -1via Bash to find the current session's ledger. If found, read it and drop any matched paths already listed there. If no ledger exists, proceed unfiltered. -
Read matched files. For each remaining path (up to 5),
Readthe full file into context. Prefer files underlogs/retrospect/if any matched — they're prior retros on overlapping tags, which is the loop-closure case (past retros inform new retros on the same topic). If both a retro and a non-retro file match, prioritize the retro within the top-5 cap. -
Summarize. Before Step 1's Anchor Block, emit a 3-line surfacing block:
Active Knowledge Surfacing: Tags matched: <tag1> <tag2> ... Files loaded: <N> (<file1>, <file2>, ...) Relevance: <one sentence per file: why this informs the retrospective> -
Carry-forward. These loaded files become input to Step 2 (Load Pattern Libraries — past retros may already have catalogued the relevant failure-mode patterns) and Step 3.5 (Evidence-Sourcing Pass — they may already provide validation or falsification for fixes in this range).
-
Tracked artifacts surfacing (added v2.16.1). After Step 10's carry-forward, ALSO surface CODEMAP + STITCH for the analyzed range's p