
Engineering Retrospective
Build a data-grounded engineering retrospective from git history: activity, hotspots, review patterns, and per-person growth notes for a given window.
Steps
Entry step: run. Each step names the specialist role it wants; the full working prompt is expandable.
- /retro — Weekly Engineering Retrospectiveentry
Show working prompt
Generates a comprehensive engineering retrospective analyzing commit history, work patterns, and code quality metrics. Team-aware: identifies the user running the command, then analyzes every contributor with per-person praise and growth opportunities. Designed for a senior IC/CTO-level builder using Claude Code as a force multiplier. ## User-invocable When the user types `/retro`, run this skill. ## Arguments - `/retro` — default: last 7 days - `/retro 24h` — last 24 hours - `/retro 14d` — last 14 days - `/retro 30d` — last 30 days - `/retro compare` — compare current window vs prior same-length window - `/retro compare 14d` — compare with explicit window - `/retro global` — cross-project retro across all AI coding tools (7d default) - `/retro global 14d` — cross-project retro with explicit window ## Instructions Parse the argument to determine the time window. Default to 7 days if no argument given. All times should be reported in the user's **local timezone** (use the system default — do NOT set `TZ`). **Midnight-aligned windows:** For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if today is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows. **Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare` (optionally followed by a window), or the word `global` (optionally followed by a window), show this usage and stop: ``` Usage: /retro [window | compare | global] /retro — last 7 days (default) /retro 24h — last 24 hours /retro 14d — last 14 days /retro 30d — last 30 days /retro compare — compare this period vs prior period /retro compare 14d — compare with explicit window /retro global — cross-project retro across all AI tools (7d default) /retro global 14d — cross-project retro with explicit window ``` **If the first argument is `global`:** Skip the normal repo-scoped retro (Steps 1-14). Instead, follow the **Global Retrospective** flow at the end of this document. The optional second argument is the time window (default 7d). This mode does NOT require being inside a git repo. ## Engineering Retro: [date range] ### Summary Table (from Step 2) ### Trends vs Last Retro (from Step 11, loaded before save — skip if first retro) ### Time & Session Patterns (from Steps 3-4) Narrative interpreting what the team-wide patterns mean: - When the most productive hours are and what drives them - Whether sessions are getting longer or shorter over time - Estimated hours per day of active coding (team aggregate) - Notable patterns: do team members code at the same time or in shifts? ### Shipping Velocity (from Steps 5-7) Narrative covering: - Commit type mix and what it reveals - PR size distribution and what it reveals about shipping cadence - Fix-chain detection (sequences of fix commits on the same subsystem) - Version bump discipline ### Code Quality Signals - Test LOC ratio trend - Hotspot analysis (are the same files churning?) - Greptile signal ratio and trend (if history exists): "Greptile: X% signal (Y valid catches, Z false positives)" ### Test Health - Total test files: N (from command 10) - Tests added this period: M (from command 12 — test files changed) - Regression test commits: list `test(qa):` and `test(design):` and `test: coverage` commits from command 11 - If prior retro exists and has `test_health`: show delta "Test count: {last} → {now} (+{delta})" - If test ratio < 20%: flag as growth area — "100% test coverage is the goal. Tests make vibe coding safe." ### Plan Completion Check review JSONL logs for plan completion data from /ship runs this period: If plan completion data exists within the retro time window: - Count branches shipped with plans (entries that have `plan_items_total` > 0) - Compute average completion: sum of `plan_items_done` / sum of `plan_items_total` - Identify most-skipped item category if data supports it Output: ``` Plan Completion This Period: {N} branches shipped with plans Average completion: {X}% ({done}/{total} items) ``` If no plan data exists, skip this section silently. ### Focus & Highlights (from Step 8) - Focus score with interpretation - Ship of the week callout ### Your Week (personal deep-dive) (from Step 9, for the current user only) This is the section the user cares most about. Include: - Their personal commit count, LOC, test ratio - Their session patterns and peak hours - Their focus areas - Their biggest ship - **What you did well** (2-3 specific things anchored in commits) - **Where to level up** (1-2 specific, actionable suggestions) ### Team Breakdown (from Step 9, for each teammate — skip if solo repo) For each teammate (sorted by commits descending), write a section: #### [Name] - **What they shipped**: 2-3 sentences on their contributions, areas of focus, and commit patterns - **Praise**: 1-2 specific things they did well, anchored in actual commits. Be genuine — what would you actually say in a 1:1? Examples: - "Cleaned up the entire auth module in 3 small, reviewable PRs — textbook decomposition" - "Added integration tests for every new endpoint, not just happy paths" - "Fixed the N+1 query that was causing 2s load times on the dashboard" - **Opportunity for growth**: 1 specific, constructive suggestion. Frame as investment, not criticism. Examples: - "Test coverage on the payment module is at 8% — worth investing in before the next feature lands on top of it" - "Most commits land in a single burst — spacing work across the day could reduce context-switching fatigue" - "All commits land between 1-4am — sustainable pace matters for code quality long-term" **AI collaboration note:** If many commits have `Co-Authored-By` AI trailers (e.g., Claude, Copilot), note the AI-assisted commit percentage as a team metric. Frame it neutrally — "N% of commits were AI-assisted" — without judgment. ### Top 3 Team Wins Identify the 3 highest-impact things shipped in the window across the whole team. For each: - What it was - Who shipped it - Why it matters (product/architecture impact) ### 3 Things to Improve Specific, actionable, anchored in actual commits. Mix personal and team-level suggestions. Phrase as "to get even better, the team could..." ### 3 Habits for Next Week Small, practical, realistic. Each must be something that takes <5 minutes to adopt. At least one should be team-oriented (e.g., "review each other's PRs same-day"). ### Week-over-Week Trends (if applicable, from Step 10) --- ## Global Retrospective Mode When the user runs `/retro global` (or `/retro global 14d`), follow this flow instead of the repo-scoped Steps 1-14. This mode works from any directory — it does NOT require being inside a git repo. ### Global Step 1: Compute time window Same midnight-aligned logic as the regular retro. Default 7d. The second argument after `global` is the window (e.g., `14d`, `30d`, `24h`). ### Global Step 2: Run discovery Locate and run the discovery script using this fallback chain: Run the discovery: If `total_sessions` is 0, say: "No AI coding sessions found in the last <window>. Try a longer window: `/retro global 30d`" and stop. ### Global Step 3: Run git log on each discovered repo For each repo in the discovery JSON's `repos` array, find the first valid path in `paths[]` (directory exists with `.git/`). If no valid path exists, skip the repo and note it. **For local-only repos** (where `remote` starts with `local:`): skip `git fetch` and use the local default branch. Use `git log HEAD` instead of `git log origin/$DEFAULT`. **For repos with remotes:** ```bash git -C <path> fetch origin --quiet 2>/dev/null ``` Detect the default branch for each repo: first try `git symbolic-ref refs/remotes/origin/HEAD`, then check common branch names (`main`, `master`), then fall back to `git rev-parse --abbrev-ref HEAD`. Use the detected branch as `<default>` in the commands below. ```bash # Commits with stats git -C <path> log origin/$DEFAULT --since="<start_date>T00:00:00" --format="%H|%aN|%ai|%s" --shortstat # Commit timestamps for session detection, streak, and context switching git -C <path> log origin/$DEFAULT --since="<start_date>T00:00:00" --format="%at|%aN|%ai|%s" | sort -n # Per-author commit counts git -C <path> shortlog origin/$DEFAULT --since="<start_date>T00:00:00" -sn --no-merges # PR/MR numbers from commit messages (GitHub #NNN, GitLab !NNN) git -C <path> log origin/$DEFAULT --since="<start_date>T00:00:00" --format="%s" | grep -oE '[#!][0-9]+' | sort -t'#' -k1 | uniq ``` For repos that fail (deleted paths, network errors): skip and note "N repos could not be reached." ### Global Step 4: Compute global shipping streak For each repo, get commit dates (capped at 365 days): ```bash git -C <path> log origin/$DEFAULT --since="365 days ago" --format="%ad" --date=format:"%Y-%m-%d" | sort -u ``` Union all dates across all repos. Count backward from today — how many consecutive days have at least one commit to ANY repo? If the streak hits 365 days, display as "365+ days". ### Global Step 5: Compute context switching metric From the commit timestamps gathered in Step 3, group by date. For each date, count how many distinct repos had commits that day. Report: - Average repos/day - Maximum repos/day - Which days were focused (1 repo) vs. fragmented (3+ repos) ### Global Step 6: Per-tool productivity patterns From the discovery JSON, analyze tool usage patterns: - Which AI tool is used for which repos (exclusive vs. shared) - Session count per tool - Behavioral patterns (e.g., "Codex used exclusively for myapp, Claude Code for everything else") ### Global Step 7: Aggregate and generate narrative Structure the output with the **shareable personal card first**, then the full team/project breakdown below. The personal card is designed to be screenshot-friendly — everything someone would want to share on X/Twitter in one clean block. --- **Tweetable summary** (first line, before everything else): ``` Week of Mar 14: 5 projects, 138 commits, 250k LOC across 5 repos | 48 AI sessions | Streak: 52d 🔥 ``` ## 🚀 Your Week: [user name] — [date range] This section is the **shareable personal card**. It contains ONLY the current user's stats — no team data, no project breakdowns. Designed to screenshot and post. Use the user identity from `git config user.name` to filter all per-repo git data. Aggregate across all repos to compute personal totals. Render as a single visually clean block. Left border only — no right border (LLMs can't align right borders reliably). Pad repo names to the longest name so columns align cleanly. Never truncate project names. ``` ╔═══════════════════════════════════════════════════════════════ ║ [USER NAME] — Week of [date] ╠═══════════════════════════════════════════════════════════════ ║ ║ [N] commits across [M] projects ║ +[X]k LOC added · [Y]k LOC deleted · [Z]k net ║ [N] AI coding sessions (CC: X, Codex: Y, Gemini: Z) ║ [N]-day shipping streak 🔥 ║ ║ PROJECTS ║ ───────────────────────────────────────────────────────── ║ [repo_name_full] [N] commits +[X]k LOC [solo/team] ║ [repo_name_full] [N] commits +[X]k LOC [solo/team] ║ [repo_name_full] [N] commits +[X]k LOC [solo/team] ║ ║ SHIP OF THE WEEK ║ [PR title] — [LOC] lines across [N] files ║ ║ TOP WORK ║ • [1-line description of biggest theme] ║ • [1-line description of second theme] ║ • [1-line description of third theme] ║ ╚═══════════════════════════════════════════════════════════════ ``` **Rules for the personal card:** - Only show repos where the user has commits. Skip repos with 0 commits. - Sort repos by user's commit count descending. - **Never truncate repo names.** Use the full repo name (e.g., `analyze_transcripts` not `analyze_trans`). Pad the name column to the longest repo name so all columns align. If names are long, widen the box — the box width adapts to content. - For LOC, use "k" formatting for thousands (e.g., "+64.0k" not "+64010"). - Role: "solo" if user is the only contributor, "team" if others contributed. - Ship of the Week: the user's single highest-LOC PR across ALL repos. - Top Work: 3 bullet points summarizing the user's major themes, inferred from commit messages. Not individual commits — synthesize into themes. E.g., "Built /retro global — cross-project retrospective with AI session discovery" - The card must be self-contained. Someone seeing ONLY this block should understand the user's week without any surrounding context. - Do NOT include team members, project totals, or context switching data here. **Personal streak:** Use the user's own commits across all repos (filtered by `--author`) to compute a personal streak, separate from the team streak. --- ## Global Engineering Retro: [date range] Everything below is the full analysis — team data, project breakdowns, patterns. This is the "deep dive" that follows the shareable card. ### All Projects Overview | Metric | Value | |--------|-------| | Projects active | N | | Total commits (all repos, all contributors) | N | | Total LOC | +N / -N | | AI coding sessions | N (CC: X, Codex: Y, Gemini: Z) | | Active days | N | | Global shipping streak (any contributor, any repo) | N consecutive days | | Context switches/day | N avg (max: M) | ### Per-Project Breakdown For each repo (sorted by commits descending): - Repo name (with % of total commits) - Commits, LOC, PRs merged, top contributor - Key work (inferred from commit messages) - AI sessions by tool **Your Contributions** (sub-section within each project): For each project, add a "Your contributions" block showing the current user's personal stats within that repo. Use the user identity from `git config user.name` to filter. Include: - Your commits / total commits (with %) - Your LOC (+insertions / -deletions) - Your key work (inferred from YOUR commit messages only) - Your commit type mix (feat/fix/refactor/chore/docs breakdown) - Your biggest ship in this repo (highest-LOC commit or PR) If the user is the only contributor, say "Solo project — all commits are yours." If the user has 0 commits in a repo (team project they didn't touch this period), say "No commits this period — [N] AI sessions only." and skip the breakdown. Format: ``` **Your contributions:** 47/244 commits (19%), +4.2k/-0.3k LOC Key work: Writer Chat, email blocking, security hardening Biggest ship: PR #605 — Writer Chat eats the admin bar (2,457 ins, 46 files) Mix: feat(3) fix(2) chore(1) ``` ### Cross-Project Patterns - Time allocation across projects (% breakdown, use YOUR commits not total) - Peak productivity hours aggregated across all repos - Focused vs. fragmented days - Context switching trends ### Tool Usage Analysis Per-tool breakdown with behavioral patterns: - Claude Code: N sessions across M repos — patterns observed - Codex: N sessions across M repos — patterns observed - Gemini: N sessions across M repos — patterns observed ### Ship of the Week (Global) Highest-impact PR across ALL projects. Identify by LOC and commit messages. ### 3 Cross-Project Insights What the global view reveals that no single-repo retro could show. ### 3 Habits for Next Week Considering the full cross-project picture. --- ### Global Step 8: Load history & compare **Only compare against a prior retro with the same `window` value** (e.g., 7d vs 7d). If the most recent prior retro has a different window, skip comparison and note: "Prior global retro used a different window — skipping comparison." If a matching prior retro exists, load it with the Read tool. Show a **Trends vs Last Global Retro** table with deltas for key metrics: total commits, LOC, sessions, streak, context switches/day. If no prior global retros exist, append: "First global retro recorded — run again next week to see trends." ### Global Step 9: Save snapshot Determine the next sequence number for today: ```json { "type": "global", "date": "2026-03-21", "window": "7d", "projects": [ { "remote": "<detected from git remote get-url origin, normalized to HTTPS>", "commits": 47, "insertions": 3200, "deletions": 800, "sessions": { "claude_code": 15, "codex": 3, "gemini": 0 } } ], "totals": { "commits": 182, "insertions": 15300, "deletions": 4200, "projects": 5, "active_days": 6, "sessions": { "claude_code": 48, "codex": 8, "gemini": 3 }, "global_streak_days": 52, "avg_context_switches_per_day": 2.1 }, } ``` --- ## Compare Mode When the user runs `/retro compare` (or `/retro compare 14d`): 1. Compute metrics for the current window (default 7d) using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`) 2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`) 3. Show a side-by-side comparison table with deltas and arrows 4. Write a brief narrative highlighting the biggest improvements and regressions 5. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics. ## Tone - Encouraging but candid, no coddling - Specific and concrete — always anchor in actual commits/code - Skip generic praise ("great job!") — say exactly what was good and why - Frame improvements as leveling up, not criticism - **Praise should feel like something you'd actually say in a 1:1** — specific, earned, genuine - **Growth suggestions should feel like investment advice** — "this is worth your time because..." not "you failed at..." - Never compare teammates against each other negatively. Each person's section stands on its own. - Keep total output around 3000-4500 words (slightly longer to accommodate team sections) - Use markdown tables and code blocks for data, prose for narrative - Output directly to the conversation — do NOT write to filesystem (except the `.context/retros/` JSON snapshot) ## Important Rules - ALL narrative output goes directly to the user in the conversation. The ONLY file written is the `.context/retros/` JSON snapshot. - Use `origin/<default>` for all git queries (not local main which may be stale) - Display all timestamps in the user's local timezone (do not override `TZ`) - If the window has zero commits, say so and suggest a different window - Round LOC/hour to nearest 50 - Treat merge commits as PR boundaries - Do not read CLAUDE.md or other docs — this skill is self-contained - On first run (no prior retros), skip comparison sections gracefully
Triggers
Phrases that suggest this craftbook to a crew.
- weekly retro
- what did we ship
- engineering retrospective
Source
View this craftbook on GitHub · MIT license