| name | rrr |
| description | Create session retrospective with AI diary and lessons learned. Use when user says "rrr", "retrospective", "wrap up session", "session summary", or at end of work session. |
| argument-hint | [--quick | --detail | --deep] |
/rrr
"Reflect to grow, document to remember."
/rrr # Retro + 1 background dig subagent (parallel, fast)
/rrr --quick # No dig, no subagent — memory only (fastest)
/rrr --detail # Full template + background dig
/rrr --deep # 5 parallel subagents
/rrr --deep --teammate # 3 coordinated team agents (requires AGENT_TEAMS)
Default mode: main agent starts writing the retro immediately from conversation memory.
One background subagent runs dig + .jsonl timestamp extraction in parallel.
When the subagent returns, main agent merges real timestamps into the Timeline section.
No speed penalty — dig runs while you write.
--quick skips dig entirely — memory only, zero subagents.
Subagent rules: default /rrr spawns exactly 1 background Agent (dig miner). --deep spawns 5. --quick spawns 0.
NEVER use the Task tool. Only --deep and --deep --teammate use TeamCreate.
Oracle Root Detection (REQUIRED — run before any ψ/ write)
Every skill that writes to ψ/ MUST detect the oracle root first. Do not assume pwd is the oracle repo.
ORACLE_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
if [ -n "$ORACLE_ROOT" ] && [ -f "$ORACLE_ROOT/CLAUDE.md" ] && { [ -d "$ORACLE_ROOT/ψ" ] || [ -L "$ORACLE_ROOT/ψ" ]; }; then
PSI="$ORACLE_ROOT/ψ"
elif [ -f "$(pwd)/CLAUDE.md" ] && { [ -d "$(pwd)/ψ" ] || [ -L "$(pwd)/ψ" ]; }; then
ORACLE_ROOT="$(pwd)"
PSI="$ORACLE_ROOT/ψ"
else
echo "⚠️ Not in oracle repo (no CLAUDE.md + ψ/ at git root). Writing to pwd."
ORACLE_ROOT="$(pwd)"
PSI="$ORACLE_ROOT/ψ"
fi
Why: prevents retros writing to ~/ψ/ (home) or incubated repo's ψ/ instead of the oracle's own vault.
All paths below use $PSI/ instead of bare ψ/.
/rrr (Default — background dig + parallel write)
1. Gather git context (main agent)
date "+%H:%M %Z (%A %d %B %Y)"
git log --oneline -10 && git diff --stat HEAD~5
Detect session ID:
ENCODED_PWD=$(echo "$ORACLE_ROOT" | sed 's|^/|-|; s|[/.]|-|g')
PROJECT_BASE=$(ls -d "$HOME/.claude/projects/${ENCODED_PWD}" 2>/dev/null | head -1)
LATEST_JSONL=$(ls -t "$PROJECT_BASE"/*.jsonl 2>/dev/null | head -1)
[ -n "$LATEST_JSONL" ] && SESSION_ID=$(basename "$LATEST_JSONL" .jsonl) && echo "SESSION: ${SESSION_ID:0:8}"
1.5. Spawn timestamp miner (background subagent)
Spawn ONE background Agent to extract real timestamps from the session .jsonl:
Agent({
name: "timestamp-miner",
description: "Extract session timestamps for /rrr",
run_in_background: true,
prompt: `Extract real user message timestamps from a Claude Code session file.
Read-only — do NOT write files.
Run this single command:
ENCODED_PWD=$(echo "[ORACLE_ROOT]" | sed 's|^/|-|; s|[/.]|-|g')
PROJECT_BASE=$(ls -d "$HOME/.claude/projects/${ENCODED_PWD}" 2>/dev/null | head -1)
LATEST_JSONL=$(ls -t "$PROJECT_BASE"/*.jsonl 2>/dev/null | head -1)
echo "SESSION_FILE: $LATEST_JSONL"
python3 -c "
import json, os
from datetime import datetime, timezone, timedelta
tz = timezone(timedelta(hours=7))
jsonl = '$LATEST_JSONL'
if not jsonl or not os.path.exists(jsonl): exit(0)
with open(jsonl) as f:
for line in f:
try:
m = json.loads(line)
if m.get('type') != 'user' or 'message' not in m: continue
content = m['message'].get('content', '')
if isinstance(content, list):
for c in content:
if isinstance(c, dict) and c.get('type') == 'text':
content = c.get('text', ''); break
if not isinstance(content, str): continue
ts = m.get('timestamp', '')
if not ts or '<command-name>' in content[:200]: continue
dt = datetime.fromisoformat(ts.replace('Z', '+00:00')).astimezone(tz)
snippet = content[:80].replace(chr(10), ' ')
print(f'{dt.strftime(\"%Y-%m-%d %H:%M\")} | {snippet}')
except: pass
"
Return ALL output lines. The main agent will use them for the Timeline.`
})
Why only .jsonl, not dig.py: the subagent has no conversation context — it can't interpret dig session summaries. The .jsonl timestamps are objective data (real ISO timestamps from every user message). That's all we need for the Timeline.
2. Write Retrospective (main agent — start immediately, don't wait for dig)
Path: $PSI/memory/retrospectives/YYYY-MM/DD/HH.MM_slug.md
mkdir -p "$PSI/memory/retrospectives/$(date +%Y-%m/%d)"
Start writing NOW from conversation memory. Draft all sections. When the dig-miner subagent returns (background notification), merge its timestamp data into the Timeline section.
Timeline format rules
-
Use dig-miner timestamps when available — real HH:MM from .jsonl extraction. If dig-miner hasn't returned yet or failed, write [timestamps pending from dig-miner] and fill in when it returns.
-
Date once in header, time-only in rows — same-day sessions:
## Timeline
**Date**: 2026-05-14 (GMT+7)
| Time | What |
|---|---|
| 20:14 | User: "..." |
| 20:21 | PR #379 merged |
-
Multi-day session — group by ### YYYY-MM-DD subheader, HH:MM rows under each.
-
Never invent timestamps. If dig-miner fails, say "timestamps unavailable" — don't guess.
Include in retrospective header:
📡 Session: 74c32f34 | repo-name | Xh XXm
Write immediately, no prompts. Include:
- Session Summary
- Timeline (real timestamps from .jsonl mining —
YYYY-MM-DD HH:MM | what)
- Files Modified
- AI Diary (150+ words, first-person; must contain one line labeled
[→ AGENT DECISION] naming a choice YOU made wrong — overconfidence, repeated wrong proposal, misread requirement; tool failures and env issues belong in friction, not here)
- Honest Feedback (100+ words, 3 friction points; session-specific only — what dragged in THIS session; if something generalizes beyond this session, it belongs in Lessons, not here)
- Lessons Learned (generalizable only — state each as a rule you'd tell another Oracle on a different project; if it only applies to this session's specific context, it's friction, not a lesson)
- Next Steps
3. Write Lesson Learned
Path: $PSI/memory/learnings/YYYY-MM-DD_slug.md
3.5. Append Session-Metrics Row (REQUIRED)
Path: $PSI/memory/learnings/session-metrics.md
If the file doesn't exist, create with this header:
# Oracle Session Metrics
Rule (parent CLAUDE.md §"Self-Evaluation Loop"): same friction 3 sessions → fix root cause, not another workaround.
| when | session | done | stuck | win | friction | error |
|---|---|---|---|---|---|---|
Then append ONE row:
| Column | Content |
|---|
when | YYYY-MM-DD HH:MM in GMT+7 |
session | first 8 chars of SESSION_ID (from Step 1.5). If detection failed, write unknown |
done | tasks/items completed this session (comma-separated, terse) |
stuck | items blocked, deferred, or dropped — or n/a |
win | biggest unlock or ship this session (one line) |
friction | operational drag: env issue, tool failure, process slowdown — session-specific (one line, or n/a) |
error | agent decision error: wrong call YOU made — overconfidence, premature action, misread scope (one line, or n/a) |
Rule: never skip. Trivial session? Still append with trivial in win/friction. Gaps break the pattern-detection value of the file.
4. Oracle Sync (two-layer pattern)
-
Write to $PSI/memory/learnings/YYYY-MM-DD_<slug>.md with frontmatter:
---
pattern: <lesson learned in one line>
date: <today>
source: rrr: REPO
concepts: [<tags>]
---
<body>
-
The Oracle's auto-memory layer picks up new files in $PSI/memory/learnings/ automatically — no separate API call needed.
4.5. Pattern Check (last 7 rows)
Read the last 7 rows (or all rows if fewer) of $PSI/memory/learnings/session-metrics.md.
Count keyword themes in the friction column (operational — escalation: file issue) and the error column (decision — escalation: raise in standup) independently. If any theme reaches ≥3 times in either column, append the recurring-pattern section, naming which column triggered and the appropriate escalation.
## 🔁 Recurring Pattern Detected
"<theme>" appeared in <N> of last 7 sessions (<session IDs>). Per parent CLAUDE.md §"Self-Evaluation Loop" — consider root-cause fix instead of another workaround.
Suggested: open issue `root-cause: <theme>` or raise with Boss during next standup.
If no theme reaches ≥3 → skip this section silently.
Rule: surface only. Do NOT auto-open issues or take action beyond flagging. Principle 3 (External Brain, Not Command) — Boss decides.
5. Save
Retro files are written to vault (wherever ψ symlink resolves).
Do NOT git add ψ/ — it may be a symlink to the vault. Vault files are shared state, not committed to repos.
6. Confirm (announce-mode — absolute paths required)
announce-mode → absolute path (no ψ/, no ~/, no $VAR, no ...).
Use: echo "marker: $RESOLVED_PATH" — bash substitutes. See CONVENTIONS.md.
RETRO_FILE="$PSI/memory/retrospectives/$(date +%Y-%m/%d)/$(date +%H.%M)_${SLUG}.md"
LESSON_FILE="$PSI/memory/learnings/$(date +%Y-%m-%d)_${SLUG}.md"
METRICS_FILE="$PSI/memory/learnings/session-metrics.md"
echo "📝 Retrospective: $RETRO_FILE"
echo "💡 Lesson learned: $LESSON_FILE"
echo "📊 Metrics row: $METRICS_FILE"
/rrr --detail
Same flow as default but use full template:
# Session Retrospective
**Session Date**: YYYY-MM-DD
**Start/End**: HH:MM - HH:MM GMT+7
**Duration**: ~X min
**Focus**: [description]
**Type**: [Feature | Bug Fix | Research | Refactoring]
## Session Summary
## Timeline
## Files Modified
## Key Code Changes
## Architecture Decisions
## AI Diary (150+ words, vulnerable, first-person)
## What Went Well
## What Could Improve
## Blockers & Resolutions
## Honest Feedback (100+ words, 3 friction points)
## Lessons Learned
## Next Steps
## Metrics (commits, files, lines)
Then steps 3-5 same as default.
/rrr --quick
Fast retro without dig — uses conversation memory only. Use when you want speed over timeline accuracy, or when dig.py is unavailable.
1. Gather
date "+%H:%M %Z (%A %d %B %Y)"
git log --oneline -10 && git diff --stat HEAD~5
1.5. Detect Session
ENCODED_PWD=$(echo "$ORACLE_ROOT" | sed 's|^/|-|; s|[/.]|-|g')
PROJECT_DIR="$HOME/.claude/projects/${ENCODED_PWD}"
LATEST_JSONL=$(ls -t "$PROJECT_DIR"/*.jsonl 2>/dev/null | head -1)
if [ -n "$LATEST_JSONL" ]; then
SESSION_ID=$(basename "$LATEST_JSONL" .jsonl)
echo "SESSION: ${SESSION_ID:0:8}"
fi
2. Write Retrospective
Same template as default but timeline is reconstructed from conversation memory (may be incomplete after compaction).
3-5. Same as default steps 3-5
Write lesson learned, oracle sync.
Do NOT git add ψ/ — vault files are shared state, not committed to repos.
/rrr --deep
Read DEEP.md in this skill directory. Only mode that uses subagents (5 parallel agents).
/rrr --deep --teammate
Read TEAMMATE.md in this skill directory. Coordinated team retro (3 agents + lead). Requires CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1.
Wizard v2 Context
If the Oracle was born via /awaken wizard v2, CLAUDE.md may contain:
- Memory consent: If
auto, /rrr runs are expected and welcomed. If manual, only run when explicitly asked.
- Experience level: Adjust diary depth (beginner = simpler language, senior = technical depth)
- Team context: If multi-Oracle team, note cross-Oracle learnings and handoff relevance
Check CLAUDE.md for these fields. If not present, use defaults (auto memory, standard depth).
Anti-Rationalization Guard
"You didn't come here to make the choice. You've already made it. You're here to try to understand why."
Before writing the final retrospective, scan your own draft for these excuse patterns:
Common Rationalizations
| Excuse | Reality |
|---|
| "This was too complex to finish" | Was it complex, or did you skip the hard part? Show the specific blocker. |
| "I ran out of context" | Context is a resource. Did you spend it well, or spiral on side quests? |
| "The API/tool didn't work" | Show the error. Show what you tried. "Didn't work" is not a diagnosis. |
| "I already tested it manually" | Manual testing doesn't persist. Where's the proof? |
| "I'll fix it next session" | Is there a concrete plan, or is this a polite way to abandon it? |
| "It's mostly done" | Define "mostly." What percentage? What's left? Be specific. |
| "The user changed direction" | Did they change, or did you misunderstand? Check the original request. |
| "This is a known issue" | Known by whom? Is there an issue filed? A workaround documented? |
Red Flags in Your Own Retro
Stop and re-examine if your retrospective contains:
- Vague success claims: "Made good progress" — on what? Show commits or it didn't happen.
- Blame-shifting: "The build was broken" — did you break it? Did you fix it?
- Missing friction: Zero "What Could Improve" items = you're not being honest.
- Inflated metrics: Counting config changes as "features shipped."
- Scope creep excuses: "I also refactored X" — was that in scope? Did you choose it over the actual task?
- Missing evidence: Claims without git hashes, file paths, or concrete output.
Verification Checklist + Required Audit Block
Before saving, run each check and append this block verbatim (filled in) as the final section of the retro file:
## 🔍 Self-Audit
- shipped: <N items — list commit hash or file path for each, or "none shipped">
- blocked: <N items — list specific error/reason for each, or "none blocked">
- uncomfortable truth: [→ AGENT DECISION] <one line — name the choice you made wrong>
- friction: <N points> (operational: <list> | strategic: <list>)
- next steps: <N — confirm each is actionable without a follow-up question>
- rationalizations caught: <N — name them, or "none">
Do not fill with "✓" or "done". Write the actual values. The eval scans this block.
If you catch yourself rationalizing: name it. Write "I noticed I was rationalizing about X because Y" in the AI Diary. Catching the pattern is more valuable than hiding it.
Rules
- NO SUBAGENTS: Never use Task tool or spawn subagents (only
--deep may)
- AI Diary: 150+ words, vulnerability, first-person
- Honest Feedback: 100+ words, 3 friction points
- Oracle Sync: REQUIRED after every lesson learned
- Time Zone: GMT+7 (Bangkok)
- Anti-rationalization: Scan draft against excuse table before saving