Skip to content
Back to skills

Postmortem

ASecurity

At the close of an epic (or a difficult issue), post a postmortem roundup comment β€” what went well, what was hard (backed by evidence), and 1–3 concrete proposals to improve the skills/flows β€” then offer to turn accepted proposals into their own `workflow`-labeled tasks, and end with a `πŸ”­ Next` handoff (a paste-ready next-session prompt + the next epic to start). Use at epic close, after the "verify the whole thing" rollup, or when asked to "do a retro", "postmortem this epic", "what did we ...

  • 10 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 12, 2026
toolsgobashgitapi

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add FriendlyInternet/nuxt-crouton --skill postmortem --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Postmortem?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Postmortem
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/friendlyinternet-postmortem/badge)](https://www.skillsdirectory.com/skills/friendlyinternet-postmortem)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: postmortem
layer: method
description: At the close of an epic (or a difficult issue), post a postmortem roundup comment β€” what went well, what was hard (backed by evidence), and 1–3 concrete proposals to improve the skills/flows β€” then offer to turn accepted proposals into their own `workflow`-labeled tasks, and end with a `πŸ”­ Next` handoff (a paste-ready next-session prompt + the next epic to start). Use at epic close, after the "verify the whole thing" rollup, or when asked to "do a retro", "postmortem this epic", "what did we learn", "how do we improve the workflow".
allowed-tools: mcp__github__issue_read, mcp__github__add_issue_comment, mcp__github__issue_write, mcp__github__sub_issue_write, mcp__github__list_issues, mcp__github__search_issues, mcp__github__list_commits, Read, Bash
---

# Postmortem β€” learn from the epic, tighten the loop

Turns a just-finished epic (or a difficult issue) into a short, honest **retro
comment on the epic**, plus an offer to spin the good ideas into tracked
`workflow` tasks. The point isn't ceremony β€” it's that **the loop only gets
tighter if we feed each run's friction back into the skills and flows**. See
epic #403.

This runs **after** the `github-tasks` "## πŸ§ͺ Verify the whole thing" rollup
(verify = *does it work?*) and **before** the epic is closed (postmortem =
*how did building it go, and how do we improve?*).

## When to use
- **Default:** at epic close, once all sub-issues have merged.
- A single **difficult issue** worth a retro on its own (lots of blocks, re-work).
- On ask: "do a retro / postmortem on #NN", "what did we learn".
- **Skip** for a trivial chore β€” not every issue needs a retro.

## What it produces
A single **comment on the epic** (`add_issue_comment`) with three sections, and
β€” on your go-ahead β€” one or more new issues labelled `workflow`.

## Step 1 β€” Resolve scope
- Input is an **epic number** (default) or a single issue number.
- Read it + its children: `issue_read` (`get`, `get_sub_issues`). Note which
  children merged cleanly vs. needed re-work.

## Step 2 β€” Mine the difficulty signals (evidence, not vibes)
For each child issue (and its PR), pull what the available tools can give. Each signal
below lists **how** to get it and how **precise** it is β€” be honest about the gaps, and
**never imply a measurement you didn't make**.

| Signal | How to get it (GitHub MCP) | Precision |
|---|---|---|
| **Time-in-progress** | `get_sub_issues` β†’ per child `created_at` β†’ `closed_at` | rough (proxy for build effort) |
| **Sign-off rounds** | `issue_read get_comments` on the child's PR β†’ count revisions on the `<!-- ui-proposal:* -->` / `<!-- schema-review:* -->` sticky thread + review replies | good (markers are explicit) |
| **Asked-for-help / blocks** | `get_comments` β†’ count `@`-mention + "blocked" comments; `get_labels` β†’ is `status:blocked` still on it | good for *count* |
| **Blocked duration** | not exposed directly (label add/remove timestamps aren't in these MCP methods) β†’ approximate from the gap between the blocking comment and the resuming comment | weak β€” **state it's an approximation** |
| **Re-work / commit churn** | `list_commits` on the PR branch β†’ many "fix"/"oops" rounds = friction | available now |
| **Fix-bot attempts** | the `claude/issue-*` retry count (from #336 watch-to-merge) | only when #336 is live β†’ say "n/a" otherwise |
| **Reopens** | `issue_read get` per child β†’ reopened-after-close | approx |

Aggregate into **3–5 "what was hard" lines**, each tied to a specific child + its signal.
Prefer a few true signals over a complete-looking guess; where a signal is unavailable,
write "n/a (not measurable with current tooling)" rather than inventing a number.

## Step 3 β€” Write the roundup comment
Keep it terse and human-first (the `github-tasks` two-audience convention). Three
sections:

- **βœ… What went well** β€” what was smooth / worth keeping. Name it concretely.
- **⚠️ What was hard** β€” the friction, each line tied to a signal or a specific
  issue (e.g. *"#NN sat blocked 3 days waiting on a sibling; the schema gate took
  2 revision rounds"*).
- **πŸ”§ Proposals (1–3)** β€” concrete, actionable changes to a **skill / agent /
  flow** that would remove that friction next time. Each proposal = a candidate
  `workflow` task with a one-line "why".
- **πŸ”­ Next** β€” the handoff (composed in Step 6): the next epic to start + a
  paste-ready next-session prompt. End the roundup with this so it's the first
  thing visible when the epic is reopened.

**Lead the comment with a machine-readable marker** so automation can detect that
this epic has had its postmortem without parsing the prose. Put it on the very
first line (it's an HTML comment β€” invisible in the rendered view, present in the
raw body via the API):

```
<!-- postmortem:done epic=#NN -->
```

The "ready to close vs needs postmortem" labeller (#763, `label-ready-epics.mjs`)
greps the epic's comments for `postmortem:done`: present β‡’ `status:ready-to-close`,
absent β‡’ `status:needs-postmortem`. Use the real epic number for `#NN`.

Post it with `add_issue_comment` on the epic.

**Flip the labels immediately (don't wait for the daily cron).** Right after posting,
add `status:ready-to-close` and remove `status:needs-postmortem` on the epic
(`issue_write` / label tools) so the review queue updates *now* β€” `label-ready-epics`
stays as the daily safety net. The epic is then closeable by the owner simply commenting
**`/close-epic`** on it (`close-epic-on-comment.yml` closes it, gated on the
`status:ready-to-close` label, #856) β€” surface that in the `πŸ”­ Next` handoff so they know
the one-gesture close is available.

## Step 4 β€” Dedup against existing follow-ups, then offer to turn proposals into work

**First, dedup β€” don't mint duplicates.** Before proposing anything new, search for an
existing home for each proposal: an open follow-up / "harden X" **epic** or issues that
already capture it. Use `search_issues` with the proposal's keywords (and `label:epic`),
and check the source epic's own linked follow-ups. If a proposal is already tracked,
**link to that issue/epic in the roundup instead of opening a new one**; add only a
*genuinely-new* proposal to that epic as a sub-issue (`sub_issue_write`). The roundup
should state, per proposal, **where it's tracked** (existing #NN, or "new").

> Why this matters: the #274 dogfood found its proposals already lived in epic #291 β€”
> the right move was to link #291, not open parallel `workflow` issues.

Then ask the human (plain): *"Open the remaining (untracked) proposals as `workflow`
tasks?"* On a yes, for each accepted, **not-already-tracked** proposal create an issue
with `issue_write`:
- Labels: **`workflow`** + **`meta:agents`** + one `type:*` (usually `type:chore` or `type:feat`).
- Body: the proposal as a small **hypothesis** (what we change, why, how we'll know it helped). Reference the source epic.
- If several relate, group them under a small tracking parent via `sub_issue_write`.

Don't open issues the human didn't accept; don't pad with filler β€” 1–3 real ones beat ten
generic ones; and **never open a `workflow` issue that duplicates an existing follow-up
epic** β€” link it instead.

## Step 5 β€” Propagate the change to neighbouring issues

The epic's decisions often land on *other* tickets β€” a sibling epic, a consumer, something it
supersedes. Tell them, so nobody works around a change they didn't know happened.

- **Find neighbours:** issues/PRs referenced by the epic, its sub-issues, and their PR bodies;
  plus a keyword `search_issues` on the change (reuse the Step-4 dedup search).
- **Open neighbour β†’ always comment:** one line of *what changed for you* + the link
  (e.g. "#515's release now wires to this App β€” see #NN"). This is how live work wires *into* the
  change instead of around it.
- **Closed neighbour β†’ comment ONLY if the change supersedes/contradicts what it decided** β€” a
  terse "superseded / updated by #NN" forward-pointer for later archaeology. **Never** for mere
  topical relevance (dead-ticket noise).
- Keep it to the genuinely-affected few β€” a couple of true cross-links beat ten tangential
  mentions (same spirit as the Step-4 dedup). Each comment carries the `πŸ€–` provenance header and
  is informational (won't trip agent-resume triggers).

## Step 6 β€” Hand off the next session (the `πŸ”­ Next` block)

A postmortem must not dead-end β€” it points at what to do next, so there's no "now what?" gap
between sessions (#615). Compose a **`πŸ”­ Next` block** and include it as the closing section of
the Step-3 roundup (so it's visible the moment the epic is reopened), **and echo the same block in
your chat reply** so it can be pasted straight into a new session.

1. **Pick the next epic.** From the initiative tree this epic belongs to (e.g. the `[Initiative]`
   parent) and the open `label:epic` list, choose the most sensible next one:
   - prefer an **unblocked sibling under the same initiative** (no open `Blocked-by:`), then the
     highest-priority open flow epic;
   - skip epics already in progress with an owner.
   State the choice + a one-line **why**. If there's **no obvious next epic**, say so and offer
   2–3 candidates rather than guessing.
2. **Emit a paste-ready prompt.** A fenced block a human can drop into a fresh session, containing:
   - **CONTEXT (done, don't redo):** 2–4 lines β€” what this epic delivered + any live state the next
     session needs (branch, preview URL, an open PR left as a testbed).
   - **NEXT:** the chosen issue `#NN` + its full URL, and "read it first, then propose a short plan".
   - **RULES:** ISSUE-FIRST Β· `/commit` skill, reference `(#NN)` Β· PRs not direct-to-`main` Β· never
     touch `packages/` without approval Β· deploy STAGING only.
3. **Post + echo.** The `πŸ”­ Next` block is the last section of the roundup comment (Step 3); repeat
   it verbatim in the chat reply.

Then **report:** the epic comment URL, the `workflow` issues opened (with URLs), the neighbour
issues cross-linked, and the chosen next epic. This closes the learning loop *and* opens the next β€”
the proposals are on the board, the change is wired to everything it touches, and the next session
has a runway.

## Conventions & gotchas
- **After verify, before close.** Don't close the epic until the postmortem is
  posted (the `github-tasks` epic-close walk-up sequences this).
- **Headless = no dialogs.** If running unattended, post the roundup + proposals
  and @mention the owner rather than blocking on a prompt; the owner converts
  proposals to issues by replying.
- **Bot-comment filter.** The roundup is informational; it should not itself
  trip the agent-resume triggers (`resume-on-comment.yml` ignores bot authors).
- **Signals are best-effort.** Prefer a smaller, true set of evidence over a
  complete-looking but guessed one.
- **Dedup first.** A proposal already owned by a follow-up/hardening epic gets a
  link in the roundup, not a fresh `workflow` issue (proven by the #274 dogfood,
  whose learnings already lived in #291).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…