--- name: postmortem description: Use after a working session (or a `/boss` run) to grade how well the toolchain and the dispatched agents actually performed, and how many tokens the run spent. Reads the session's own Claude Code transcript + subagent logs + Workflow run logs, aggregates tokens/tool-health deterministically via a helper script, and writes a scored retrospective. Utility skill, user-invoked or orchestrator-invoked at run close; never a pipeline gate. --- # postmortem — grade the run > **Violating the letter of these rules is violating the spirit.** ## Overview Every session leaves a detailed flight recorder behind — the JSONL transcript under `~/.claude/projects//.jsonl`, one sidechain log per dispatched subagent under `/subagents/`, and for every Workflow run a per-agent summary in `/workflows/wf_*.json` with raw per-agent transcripts under `/subagents/workflows//`. Nobody reads it. So the same expensive habits repeat: a subagent fleet that bounces `BLOCKED`, a tool loop with a 30% error rate, a cache-cold run that re-sends the full input on every turn. This skill turns that recorder into a graded retrospective: **how well did the toolchain work, how effective were the agents, and how many tokens did it spend.** It is descriptive, not corrective. It produces a report and, where warranted, recommends filing tracker issues — it does not change code, baselines, or the pipeline. ## When to Use / Skipping Invoke: - After a substantial interactive session, when you want to know where the time and tokens went. - At the close of a `/boss` autonomous run, to grade the orchestrator's dispatch choices. - When a run *felt* token-heavy or thrashy and you want the numbers. Not a pipeline phase. Never a hard-gate. It reads logs; it never blocks a cycle. ## The Iron Law ``` NUMBERS COME FROM THE SCRIPT, NEVER FROM MEMORY OR EYEBALLING THE LOG REPORT TOKENS AS RAW COUNTS — NEVER CONVERT THEM TO A COST OR PRICE NEVER READ ~/.ionos_token, .credentials.json, OR ANY SECRET FILE INTO CONTEXT A GRADE WITHOUT A CITED METRIC IS AN OPINION — DROP IT DEDUP TOKEN USAGE BY requestId — THE SCRIPT DOES THIS; DO NOT RE-SUM THE RAW LOG BY HAND ``` ## What the data does and does not contain Read before interpreting, so the report never overclaims: - **Present:** per-request `usage` (input / output / cache-creation / cache-read / server-tool counts), `model`, `requestId`, timestamps, every `tool_use` with its input, every `tool_result` with the authoritative `is_error` flag, skill invocations, slash commands, and a full separate transcript + `agentType` / `description` for each subagent. Workflow runs additionally carry a per-agent summary (stage label, model, a live token counter) in `workflows/wf_*.json`; the counter under-tracks vs. the deduped raw transcripts (~11% in the corpus behind issue #28), so the script treats the raw transcripts as authoritative and reports the counter only as `reported_total_tokens` for cross-checking. - **Absent:** `costUSD` is always `null`; `durationMs` is always `null`. There is no metered cost in the log, so this skill does not compute one — it reports **raw token counts** (kept split by class: input / output / cache-creation / cache-read, plus a `total_tokens` sum). **Wall-clock is derived** from timestamp deltas and the report says so. The streamed transcript repeats the same `requestId` across several assistant lines with an identical `usage` object. The helper script dedups per `requestId`; never sum the raw lines. ## The Process ### Step 1 — Run the aggregator ``` python3 /scripts/postmortem.py [--session ] [--cwd ] ``` Defaults to the newest transcript in the current project's log dir — i.e. the session you are in (it will be flagged `active`, meaning totals are partial). To grade a finished run, pass its `--session `. The default log dir is derived from cwd (the path with `/` replaced by `-`), so a session run inside a git worktree resolves to a *different* slug than the primary clone, and after exiting a worktree the default again follows the current cwd. To grade a worktree run from the primary clone, pass `--project-dir ~/.claude/projects/` (or `--file ` to bypass slug derivation entirely). The script emits one JSON object on stdout. That JSON — not the raw log — is your evidence base. ### Step 2 — Read the JSON and grade three axes Grade each axis on the cited numbers. A grade with no number behind it is an opinion; drop it. 1. **Token spend & efficiency** — `totals.total_tokens`, the main-vs-subagent split, the token breakdown (output share is the write-heavy signal), `cache_hit_ratio` (the dominant efficiency lever: below ~0.7 on a long session means cache-cold turns re-sending the full input), `server_tools` (web_search / web_fetch counts). 2. **Toolchain health** — `tools.error_ratio` and `interrupted` (the authoritative `is_error` signal), the tool mix (a Read / Edit / Bash imbalance hints at thrashing or re-reading), `slash_commands` such as `/compact` (context pressure). 3. **Agent effectiveness** — per subagent: `terminal_status` (`DONE` / `DONE_WITH_CONCERNS` / `PARTIAL` / `BLOCKED` / `NEEDS_CONTEXT` / `unknown`), `total_tokens`, and `requests`. A fleet that burned real tokens to return `BLOCKED` is the headline finding. Compare each agent's token spend to what it delivered. For Workflow runs, grade per stage instead: `workflow_totals` and each run's `stages` table (label-prefix grouping, e.g. all `impl:N` under `impl`) show where the run's spend concentrated; `agents_untracked > 0` flags retried/dropped attempts. Schema-bound workflow stages carry no `terminal_status` — the workflow script's own aggregation already judged them. ### Step 3 — Write the report Write a Markdown report to the configured destination (see **Output destination**). Structure it as **Output format** below. Lead with the scorecard, support every grade with a number from the JSON, and keep the prose tight — this is a retrospective, not a transcript replay. ### Step 4 — Surface, don't fix Translate the sharpest findings into recommendations. Where a finding is a concrete, trackable defect (a subagent that reliably bounces `BLOCKED`, a tool loop with a runaway error rate), recommend filing it via the `issue` skill — name it, but do not file it yourself unless the user asks. This skill ends at the report. ## Output destination Resolve in this order: 1. `--out ` if the invoker passed one. 2. The project's post-mortem directory, if it has one (its CLAUDE.md project facts). 3. Default: `docs/postmortems/-.md` under the project root, creating the directory if needed. Also print a ≤200-word summary to the chat so the headline grade and token spend are visible without opening the file. ## Output format ``` # Post-mortem — () **Scorecard** | Axis | Grade | Headline metric | |------|-------|-----------------| | Token spend & efficiency | A–F | total, cache hit | | Toolchain health | A–F | , interrupts | | Agent effectiveness | A–F | / agents DONE, on subagents | **Token spend**
**Toolchain** **Agents** — one-clause verdict. Omit if no subagents were dispatched.> **Recommendations** <≤5 bullets. Each ties to a cited metric. Mark any that warrant an `issue`.> _Token counts are raw usage. Wall-clock is derived from timestamp deltas, not metered._ ``` If the session is flagged `active`, add one line at the top: "⚠️ Session still active — figures are partial." ## Common Rationalisations | Excuse | Reality | |--------|---------| | "I'll just skim the transcript and tally the tokens" | The transcript repeats usage per streamed line under a shared requestId. Hand-summing double-counts. Run the script. | | "Let me convert the tokens to a rough dollar figure" | Don't. There is no metered cost in the log and prices vary by plan; report raw token counts and let the reader price them if they want. | | "Cache hit ratio of 0.5 is fine" | On a long session it means half the input was re-sent uncached. That is the single biggest efficiency lever — grade it. | | "All agents returned, so effectiveness is an A" | "Returned" ≠ "succeeded". A `BLOCKED` agent that burned tens of thousands of tokens is a failure that still spent the budget. Read `terminal_status`. | | "Let me also peek at the IONOS token to check the endpoint" | Never. Secret files are out of bounds — see the Iron Law and the user's global rules. | | "I found a broken agent, I'll fix its prompt now" | Out of scope. This skill reports and recommends; the fix is a separate, tracked change. | ## Red Flags — STOP - Quoting any token number that did not come out of the script's JSON. - Converting token counts into a cost or dollar figure — report raw counts only. - Reading any file under `~/.claude` other than the session transcript and its subagent logs — and never any credential or token file. - Editing code, baselines, or pipeline config "while you're in there". Report only. - Grading an axis with adjectives instead of the cited metric. ## Cross-references - **Helper script:** `scripts/postmortem.py` — the deterministic aggregator. All numbers originate here. - **Hand-off target:** the `issue` skill, when a finding is a trackable defect worth filing. - **Report destination (optional):** the project's post-mortem directory, if its CLAUDE.md project facts name one. - **Data-source note:** this skill reads only the current session's own transcript and subagent logs. It does not crawl other projects or other sessions (single-session by design).