Run a lightweight epic retrospective to capture learnings and update project conventions. Use when the user says "retrospective", "retro", or "retro for epic N".
Installs into .claude/skills of the current project.
Are you the author of Retrospective?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/rterakedis-retrospective)
---
name: retrospective
description: Run a lightweight epic retrospective to capture learnings and update project conventions. Use when the user says "retrospective", "retro", or "retro for epic N".
---
# Retrospective Skill
**Goal:** Extract learnings and update CLAUDE.md so next sprint starts smarter.
**Role:** Ask questions and record answers (don't draw conclusions).
## Activation
1. Detect epic: user specifies (e.g. "retro for epic 2") or infer from most recent `Status: done` stories in `docs/epics/`. Ask if ambiguous.
2. Read `docs/epics/{epic_num}-*.md` with `Status: done` or `review`. Summarize shipped.
3. Read CLAUDE.md and the previous epic's retro doc (avoid duplication; check prior conventions held).
4. Present summary, then ask seven questions.
## Seven Questions
**Always human-in-the-loop.** Ask the seven questions **one at a time and wait for each
answer** — including when invoked from the `/epic-flywheel` boundary. Auto-generating the
retro from git history (or any other artifact) is forbidden: the questions exist to capture
the *user's* perspective, not to restate what the code already shows.
1. **What did we ship?** → Final list of shipped stories with one-line outcomes.
2. **What went well?** → Approaches that paid off — patterns to keep, not change. Distinct from Q4 (codifying); this is reinforcement.
3. **What slowed us down?** → Blockers and root causes. For each blocker, ask "why didn't we catch this earlier?" at least twice (5-whys-lite).
4. **What patterns emerged?** → Approaches/structures/decisions worth codifying.
5. **Did last sprint's conventions hold?** → Read the previous retro's "CLAUDE.md Conventions Added" section. Audit one or two stories from this epic for each convention. Record violations as new blockers or pattern reinforcement. While auditing, also check each convention for a **half-rule**: does it establish a precondition without addressing its consequence? (e.g. "every attribute optional in the model" said nothing about the generated property it produces.) Tentative is fine — flag it as a question for Q6/Q7 rather than asserting a fix.
6. **What should change?** → Process changes for next sprint (story creation, architecture, Dev Notes, testing).
7. **What goes into CLAUDE.md?** → Standing rules for all future sessions.
**Direction decisions:** if any answer to Q2–Q6 sets or reverses a *direction* decision
("we chose X, it was wrong, now Y") and `docs/project/decisions.md` exists, append it via
**RECORD** from `skills/decision-log/SKILL.md` with `source: /retrospective`. Ordinary
convention learnings keep their existing home (CLAUDE.md, Q7) — the log records direction,
not habits.
## Harvest Test Findings (before the deferred sweep)
If `docs/epics/epic-{epic_num}-test-plan.md` exists and the manual test pass has run, invoke `/harvest-findings {epic_num}` (`skills/harvest-findings/SKILL.md`) first — it captures the tester's inline findings into `docs/epics.md`, opens a remediation story `{N}.{last+1}` for the in-scope ones, routes the rest through `deferred`, and resets the plan. Running it here means the deferred sweep below sees those findings already logged. Skip silently if there's no test plan or no findings to harvest.
Carry the harvest's `{p} plan-defects` count into the retro: each one is a human step the epic test plan asked for that automation had already proven. A non-zero count is a finding about the boundary's subtract pass (epic-flywheel → step 5), not about the product — note it under the process questions so the next plan is tighter.
## Deferred Item Status Check
### Pass 1 — Catch unlogged deferred items
Scan all story files for the epic just completed (`docs/epics/epic-{N}-*.md`) for any `[Defer]` checkbox entries (checked or unchecked). Compare against `docs/deferred-items.md`.
For each `[Defer]` item found in a story file that has **no matching D-ID** in `docs/deferred-items.md`: call **LOG-AND-SCHEDULE** from `skills/deferred/SKILL.md` immediately. Do not leave unlogged deferred items after the retro.
Also grep the codebase for deliberate in-code shortcut markers (`## Simplicity & Anti-Over-Engineering`'s `leanwheel:` convention), skipping vendored/build output:
```bash
grep -rnE '(#|//|--) ?leanwheel:' . --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=.build --exclude-dir=DerivedData --exclude-dir=dist
```
For each marker that names a **real ceiling** (e.g. `// leanwheel: O(n²) scan, index if list exceeds ~1k`) with no matching entry in `docs/deferred-items.md`, call **LOG-AND-SCHEDULE** the same way — so a deliberate corner-cut can't silently rot. Skip markers that are purely explanatory with no upgrade trigger.
### Pass 2 — Ensure all logged items are scheduled into open work
Read `docs/deferred-items.md`. For every row, check the `Scheduled As` story against `docs/epics.md`:
- **Scheduled into an open (not-started or in-progress) story:** OK — no action.
- **Scheduled into a `Status: done` story or completed epic:** INVALID — that story is locked dev-complete. Reassign via **SLOT-INTO-BACKLOG** from `skills/deferred/SKILL.md` (targeting only stories with `Status: not started`). If no slot found, call **SCHEDULE** Step 2 to create a new remediation story. Update `Scheduled As` in `docs/deferred-items.md`.
- **Scheduled story not found in epics.md (removed/renamed):** Treat as unscheduled — reassign same as above.
- **Completed/resolved:** Note as resolved in retro doc, no action needed.
**Hard rule:** Every unresolved deferred item must point to an open, not-started story when the retro ends. Narrating without editing `docs/deferred-items.md` is a failed retro.
Include a summary table in the retro doc:
```markdown
| D-ID | Title | Was Scheduled As | Action Taken |
|------|-------|-----------------|--------------|
| D-1 | ... | Story X.Y (done — reassigned to Z.W) | Slotted as AC |
| D-2 | ... | Story X.Y (open) | No change |
```
## Condense the Closed Epic
Call **CONDENSE** from `skills/epic-archive/SKILL.md` with `epic_num`. Runs here — after the deferred sweep (which must read the epic's full text) and before the retro stamp (which marks the epic closed). Idempotent; skips silently when nothing is collapsible.
## PRD / Architecture Sync Check
Before writing the retro, diff `docs/prd.md` and `docs/architecture.md` against stories shipped. List any required updates. Perform them in the same turn.
**Promote epic learnings into the canonical docs.** Call the Agent tool with `subagent_type: "lw-docs-sync"` (Haiku) and a prompt naming op `PROMOTE` and this epic (`epic_num`) — keeping this mechanical work off the session model (fallback: execute the docs-sync **PROMOTE** op inline if subagents are unavailable). It appends durable project-canonical learnings from `docs/epics/epic-{epic_num}-context.md` into `docs/architecture.md` (idempotent, so safe to run alongside `/epic-flywheel`'s boundary PROMOTE). It never edits `docs/setup/*`; if implementation revealed the guidance itself is stale, record an action item recommending `/refresh-swift` / `/refresh-web` rather than a direct edit.
## Metrics
Collect from `git log` and story files. Include in retro output:
```markdown
## Metrics
| Metric | Value | vs Last Epic |
|---|---|---|
| Stories shipped | N | +/- |
| Deferred items created | N | |
| Deferred items resolved | N | |
| Migrations added | N | |
| Test files added | N | |
| Story cycle time (median) | Nd | |
| Plan defects (already-automated steps in the test plan) | N | |
```
If `docs/metrics/flywheel-ledger.jsonl` exists, add a **by-model** row set for this epic only — read just this epic's lines, never the whole file (it rotates at CUT-RELEASE):
```bash
grep '"story":"{N}\.' docs/metrics/flywheel-ledger.jsonl | grep '"phase":"dev-story"' \
| sed -E 's/.*"model":"([^"]+)".*"bt_iterations":([0-9]+).*/\1 \2/' \
| awk '{n[$1]++; s[$1]+=$2} END {for (m in n) printf "%s: %d stories, %.1f avg build/test iterations\n", m, n[m], s[m]/n[m]}'
```
Report it as `| dev-story iterations by model | sonnet 1.2 · opus 1.0 | |`. This is the evidence for the model-routing decision (DD-20): rising iterations on one model is the signal to re-route, not prose.
## Security Sweep (mandatory — all epics)
Before writing the retro doc, run a scoped security review against all stories shipped in this epic. This is a blocking gate — no GO verdict until it completes.
**Scope determination:**
- Read story files for the epic. Collect all `Security Sensitivity:` values from Dev Notes.
- If any story touched auth, billing, payments, data-access, api, secrets, llm, or file-upload: run the matching categories from `skills/security-review/SKILL.md` checklists.
- If no `Security Sensitivity:` flags found: run Category: Secrets Management and Category: Data Exposure at minimum (always applicable).
**Steps:**
1. Run applicable checklist categories. Mark each item Pass / Fail (file:line) / N/A.
2. For any **critical or high** findings: call **LOG-AND-SCHEDULE** from `skills/deferred/SKILL.md` immediately. These must be scheduled before the GO verdict is issued.
3. For **medium/low** findings: include in retro doc under `## Security Findings` — user decides whether to schedule.
4. If zero findings across all applicable categories: write `Security sweep clean — no findings.`
Include in retro doc:
```markdown
## Security Findings
| Severity | Category | Finding | File:Line | Action |
|----------|----------|---------|-----------|--------|
| HIGH | Auth | ... | ... | Logged as D-N, Story X-Y |
| MEDIUM | Headers | ... | ... | Noted — user to schedule |
```
## CLAUDE.md Tier Audit
Tiers are defined in `claude-template.md` (T1 machine-enforced · T2 repo-wide prose ·
T3 nested). Run before writing Q7's additions, and perform the edits this turn:
1. For each **T2** rule in the project's CLAUDE.md, check whether a test, hook, linter, or
type has since been written that enforces it. If yes → **demote to T1 now**: collapse the
prose to the rule as one clause plus the enforcing artifact's name, and confirm that
artifact's doc comment carries the explanation being removed (add it there if not).
A rule machine-enforced for a full epic with zero violations is a demotion candidate
regardless of how it reads.
2. Run `wc -l CLAUDE.md` against the budget stated in `claude-template.md`. Over budget →
demote or move a T3 rule to a nested `CLAUDE.md` this turn. Never append past the budget.
## Action Items
Output an `## Action Items` section with explicit checkboxes. **Perform each edit in the same turn** — do not just list them.
Example:
```markdown
## Action Items
- [x] Updated `docs/deferred-items.md` D-1 → Story X-Y
- [x] Promoted footgun: `vi.hoisted` pattern → CLAUDE.md
- [ ] (anything requiring user action outside this turn)
```
## Next Epic Readiness
End the retro with a `## Next Epic Readiness` section:
- PRD section exists for next epic?
- Architecture pre-reqs met?
- Blocking unknowns next epic inherits?
- `epic-{epic_num}-context.md` existed and accumulated `## Story ... Learnings` across this epic? If it never existed, the flywheel's Step-1 epic-context gate failed — record that under Process Changes; do **not** backfill it now (the epic is closed; nothing will read it).
- `epic-{N+1}-context.md`: **not expected yet** — the first `/create-story` of Epic {N+1} generates it, and the flywheel verifies it exists before committing story 1. Never a HOLD item; note it only if you have epic-specific context worth pre-seeding.
- All critical/high security findings logged and scheduled?
- Explicit **GO / HOLD** verdict. HOLD if any critical/high security finding is unscheduled.
## Output
1. Write to `docs/epics/epic-{epic_num}-retro-{date}.md`: summary, metrics, what went well, blockers, patterns, conventions-held audit, process changes, CLAUDE.md additions, security findings (mandatory), deferred items status, action items (checked off), next epic readiness.
2. Update CLAUDE.md with new/revised conventions (Q7), placing each at its tier per `claude-template.md`. Keep it inside the line budget stated there — over budget means demote (T2→T1) or move (T3→nested `CLAUDE.md`), never append.
3. Edit `docs/deferred-items.md` for any reassignments or newly logged items from the Deferred Item Status Check (mandatory — same turn). Every unresolved item must point to an open, not-started story.
4. Stamp completion so `/next` can route deterministically: append `<!-- retro: epic {epic_num} — {date} -->` directly below the H1 of `docs/epics.md` (one line per epic; skip if already present).
5. Report: "Retrospective complete. CLAUDE.md updated. Next: `/epic-flywheel {N+1}` in a fresh session (or `/next` to confirm)."
6. **Release boundary (offer only).** If this retro closed the *last* epic — every epic in `docs/epics.md` carries a `retro:` stamp, no story is `ready-for-dev`/`in-progress`/`review`, and no story lacks a file — additionally offer `/epic-archive cut-release {version}` to archive the shipped release and seed the next phase. Requires an explicit user go-ahead; never run it automatically. If any epic remains open, say nothing — item 5 stands as-is.