| name | retrospective |
| description | Analyze accumulated mistakes, identify recurring patterns, and generate action items for systemic fixes |
| allowed-tools | Read, Edit, Bash, Grep, Glob |
Retrospective Skill
Analyzes accumulated mistakes, identifies recurring patterns, checks action item effectiveness, and generates new action items for systemic fixes.
When This Skill Activates
- Automatically triggered by SessionStart hook (
check-retrospective-due.sh) when:trigger_interval_days(default 14) have passed since last retrospective, ORmistake_count_threshold(default 10) mistakes accumulated since last retrospective
- Can be manually invoked anytime
Data Files
| File | Purpose |
|---|---|
.claude/retrospectives/mistakes.json |
All logged mistakes with pattern linkage |
.claude/retrospectives/retrospectives.json |
Retrospective history, patterns, action items |
Workflow
Phase 1: Data Collection
- Read all mistakes from
.claude/retrospectives/mistakes.json - Read retrospective history from
.claude/retrospectives/retrospectives.json - Filter to mistakes since last retrospective date
- Identify mistakes not yet processed (
processed_in_retrospectiveis null)
# Get last retrospective date
LAST_RETRO=$(jq -r '.last_retrospective // "1970-01-01"' .claude/retrospectives/retrospectives.json)
# Count unprocessed mistakes
jq --arg date "$LAST_RETRO" '[.mistakes[] | select(.timestamp > $date)] | length' \
.claude/retrospectives/mistakes.json
Phase 2: Pattern Analysis
For each mistake since last retrospective:
Categorize by type (from schema):
tdd_violation- Skipped test phasesdetection_gap- Validation missed issuebash_error- Shell command failureedit_failure- String not foundarchitecture_issue- Design-level problemsprotocol_violation- Skipped required stepsgit_operation_failure- Git command issuesbuild_failure- Compilation/style errorsworktree_violation- Wrong working directorygiving_up- Abandoned optimal solutiondocumentation_violation- Created prohibited docslogical_error- Incorrect logic/thresholdsother- Uncategorized
Extract patterns:
- Group by category
- Identify common keywords in
pattern_keywords - Find same root cause patterns
# Group mistakes by category
jq '.mistakes | group_by(.category) | map({category: .[0].category, count: length})' \
.claude/retrospectives/mistakes.json
Phase 3: Effectiveness Analysis (CRITICAL)
For each COMPLETED action item, check if the fix was effective:
- Query mistakes with matching pattern_id WHERE timestamp > completed_date
# Check effectiveness of action item A001
jq --arg pattern "PATTERN-003" --arg completed "2025-11-28" '
[.mistakes[] | select(.pattern_id == $pattern and .timestamp > $completed)] | length
' .claude/retrospectives/mistakes.json
- Determine effectiveness status:
| Post-Fix Mistakes | Status | Action |
|---|---|---|
| 0 | effective |
None - fix is working |
| 1 | partially_effective |
Monitor closely |
| 2+ | ineffective |
ESCALATE - needs deeper fix |
Update action item effectiveness in retrospectives.json
Generate escalation for ineffective fixes:
- Create new action item with higher priority
- Reference the ineffective action item
- Propose deeper architectural change
Phase 3b: Escalation Protocol (for INEFFECTIVE fixes)
When an action item is marked ineffective (2+ post-fix mistakes), escalation is MANDATORY.
Escalation Entry Format:
{
"id": "ESCALATE-YYYY-MM-DD-NNN",
"original_action_id": "A00X",
"original_fix_description": "What was tried",
"failure_analysis": {
"expected_result": "What the fix should have done",
"actual_result": "What actually happened",
"root_cause": "Why the fix didn't work",
"gap_identified": "What the fix missed"
},
"proposed_solution": {
"approach": "defense-in-depth | architectural-change | tool-improvement",
"description": "Detailed solution proposal",
"prevention_type": "code_fix | hook | validation (NOT config)",
"layers": ["Layer 1 description", "Layer 2 description"]
},
"priority": "critical",
"status": "open"
}
Escalation Decision Tree:
Ineffective Fix Detected (2+ post-fix mistakes)
↓
1. WHY did the original fix fail?
- Incomplete detection? → Strengthen detection logic
- Wrong validation timing? → Add earlier checkpoint
- Coverage gap? → Expand scope
- Agent workaround? → Add multi-layer defense
↓
2. What PREVENTION TYPE is needed?
- If original was `config` → MUST escalate to `hook` or `code_fix`
- If original was `hook` → Consider `code_fix` or multi-layer hooks
- If original was `code_fix` → Deeper architectural analysis needed
↓
3. Propose DEFENSE-IN-DEPTH (if single fix keeps failing):
- Layer 1: PreToolUse validation (block before execution)
- Layer 2: PostToolUse detection (catch after execution)
- Layer 3: SessionStart reminder (proactive guidance)
- Layer 4: Build/test integration (final safety net)
Key Principle:
"Prevention requires active enforcement, not passive reporting."
When fixes prove ineffective, the solution is NEVER "add more documentation". The solution is:
- Analyze why detection/prevention failed
- Implement stronger enforcement mechanism
- Add multiple layers of defense
Phase 4: Cross-Retrospective Analysis
Compare current patterns with ALL previous retrospectives:
Load
recurring_patternsfrom retrospectives.jsonFor each current pattern:
- Check if it matches any previous pattern (by category + keywords)
- If match: increment
occurrences_total - If occurrences >=
recurrence_threshold(default 2): mark as RECURRING
For RECURRING patterns:
- Check
occurrences_after_fix(mistakes after last action date) - If
occurrences_after_fix>=recurrence_after_fix_threshold: escalate
- Check
Phase 4.7: Action Item Coverage Validation (MANDATORY)
⚠️ CRITICAL: Every recurring pattern with new occurrences MUST have an action item.
Before generating the report, validate action item coverage:
Identify patterns with new occurrences in this period:
patternsWithNewOccurrences = currentMistakes .filter(m => m.pattern_id != null) .groupBy(m => m.pattern_id) .map(group => { pattern_id, count: group.length })Check each pattern has an action item:
for each pattern in patternsWithNewOccurrences: if pattern.count >= 1: // Pattern recurred - MUST have action item existingAction = actionItems.find(a => a.pattern_id == pattern.pattern_id AND a.status == "pending" ) if NOT existingAction: // ⚠️ VIOLATION: Missing action item for recurring pattern createActionItem(pattern)Mandatory action item triggers:
Condition Action Required Pattern has 3+ new occurrences MUST create action item Pattern is most frequent in period MUST create action item Previous action item marked INEFFECTIVE MUST create escalation Pattern has escalated status MUST create action item Self-check before Phase 5:
□ Every pattern with 3+ new occurrences has a pending action item? □ The most frequent pattern has an action item? □ Every INEFFECTIVE action item has an escalation? □ Every ESCALATED pattern with new mistakes has an action item?If validation fails:
- DO NOT proceed to Phase 5
- Generate missing action items
- Re-validate
- Only proceed when all patterns are covered
Background (Session 2c58ba44): RETRO-2025-12-01-001 missed creating action items for PATTERN-002 (Detection Gaps) despite:
- 6 new occurrences (55% of all mistakes)
- Previous escalation (ESCALATE-2025-11-29-001) marked INEFFECTIVE
- Being the most frequent pattern
This validation phase prevents that oversight.
Phase 5: Action Item Generation
For each RECURRING pattern (occurs 2+ times):
Analyze root cause type:
- Knowledge gap? → Add to CLAUDE.md
- Missing check? → Create new hook
- Design flaw? → Propose architecture change
- Tooling issue? → Propose tool improvement
Generate action item:
{
"id": "A00X",
"priority": "high|medium|low",
"description": "What needs to be done",
"category": "mistake category",
"pattern_id": "PATTERN-XXX",
"status": "open",
"created_date": "ISO timestamp",
"completed_date": null,
"related_mistakes": ["M001", "M002"],
"effectiveness_check": {
"mistakes_before": N,
"mistakes_after": null,
"post_fix_mistakes": [],
"verdict": "pending"
}
}
Phase 6: Report & Update
- Display summary:
================================================================================
📊 RETROSPECTIVE REPORT: YYYY-MM-DD
================================================================================
Period: [last_retrospective] to [now]
Mistakes analyzed: N
New patterns: N
Recurring patterns: N
## Action Item Effectiveness
| ID | Pattern | Status | Post-Fix Mistakes |
|----|---------|--------|-------------------|
| A001 | build_failure | effective | 0 |
| A002 | detection_gap | partially_effective | 1 |
## Mistake Breakdown by Category
| Category | Count | % |
|----------|-------|---|
| detection_gap | 7 | 33% |
| git_operation_failure | 4 | 19% |
...
## Recurring Patterns (REQUIRES ACTION)
### PATTERN-003: build_failure
- Occurrences: 3
- Last action: A001 (2025-11-28)
- Status: addressed
## New Action Items
- [ ] A00X: [description] (priority: high)
================================================================================
- Update data files:
# Update retrospectives.json
jq '.last_retrospective = "TIMESTAMP" | .mistake_count_since_last = 0' \
.claude/retrospectives/retrospectives.json > tmp && mv tmp .claude/retrospectives/retrospectives.json
# Mark mistakes as processed
jq '.mistakes |= map(if .processed_in_retrospective == null then .processed_in_retrospective = "R00X" else . end)' \
.claude/retrospectives/mistakes.json > tmp && mv tmp .claude/retrospectives/mistakes.json
Effectiveness Tracking Algorithm
function checkActionItemEffectiveness(actionItem, mistakes):
if actionItem.status != "implemented":
return // Only check completed items
completedDate = parseDate(actionItem.completed_date)
patternId = actionItem.pattern_id
// Find mistakes matching this pattern AFTER fix was implemented
postFixMistakes = mistakes.filter(m =>
m.pattern_id == patternId AND
parseDate(m.timestamp) > completedDate
)
// Determine effectiveness
if postFixMistakes.length == 0:
verdict = "effective"
else if postFixMistakes.length == 1:
verdict = "partially_effective"
else:
verdict = "ineffective"
// Generate escalation action item
createEscalation(actionItem, postFixMistakes)
// Update action item
actionItem.effectiveness_check.post_fix_mistakes = postFixMistakes.map(m => m.id)
actionItem.effectiveness_check.verdict = verdict
Integration with learn-from-mistakes
When learn-from-mistakes logs a new mistake:
- Check if mistake matches any existing pattern (by category + keywords)
- If match found, set
pattern_idon the mistake - Increment
mistake_count_since_lastin retrospectives.json - If pattern has a completed action item:
- Add mistake ID to action item's
post_fix_mistakes - If
post_fix_mistakes.length >= 2, flag for escalation
- Add mistake ID to action item's
This creates a feedback loop:
Mistake → Pattern Match → Action Item Check → Effectiveness Update → Escalation if needed
Example Invocation
User: Run a retrospective
Claude: I'll run a retrospective analysis.
[Phase 1: Reading mistake and retrospective files...]
[Phase 2: Analyzing 5 new mistakes...]
[Phase 3: Checking effectiveness of 4 action items...]
[Phase 4: Cross-referencing with 3 known patterns...]
[Phase 5: Generating action items for recurring patterns...]
================================================================================
📊 RETROSPECTIVE REPORT: 2025-11-28
================================================================================
Period: 2025-11-14 to 2025-11-28
Mistakes analyzed: 5
Recurring patterns requiring action: 1
## Action Item Effectiveness
| ID | Description | Status |
|----|-------------|--------|
| A001 | Pre-commit checkstyle/PMD | pending_verification (just implemented) |
| A002 | TDD enforcement | effective (0 violations since) |
## New Action Items
None - all patterns have active preventions.
================================================================================
The retrospective is complete. All patterns have active prevention mechanisms.
Related Skills
- learn-from-mistakes: Logs individual mistakes with root cause analysis
- get-history: Access conversation logs for mistake investigation
- get-session-id: Provides session ID for log correlation
Notes
- NEVER delete mistakes - Full history required for trend analysis
- Only reset
mistake_count_since_lastafter retrospective (trigger counter) - Pattern recurrence is checked using timestamps, not counts
- Retrospective reports are NOT saved as files (per CLAUDE.md policy) - data is in JSON