---
name: fp-extract-learnings
description: After a feature ships, extract the surprises, corrections, and reversals into fastpace/context/learnings.md as `status: unreviewed` entries. Downstream skills (fp-ask, fp-review-pr) ignore unreviewed entries until a human confirms in the dashboard. Never blocks the feature flow — emit zero if nothing was surprising.
---

# fp-extract-learnings

Run this at the end of a feature lifecycle (typically right after `/fp-new-feature` completes the `push` phase, or after a PR merges).

Capture **hard-won knowledge that a future session wouldn't derive from the code alone** — and write it *directly* into `fastpace/context/learnings.md` with `status: unreviewed`. A human triages from the dashboard when they have a minute; nothing is blocked in the meantime.

## Inputs

One of these:
- A watch card: `fastpace/watch-cards/<slug>.json`
- A merged PR: git ref or PR number (you have git via Bash, gh via Bash)
- Nothing — infer from the most recently completed watch card

## What counts as a learning (signal)

Include only things where a future reader would say "huh, I wouldn't have guessed that":
- **Reversals** — we tried X, it didn't work, we switched to Y.
- **Surprises** — assumption was A, reality was B.
- **Corrections** — reviewer caught a pattern violation; the reviewer was right; the rule is now codified.
- **Workarounds** — tool/library constraint that forced a non-obvious approach.
- **Retired knowledge** — we removed X; mentioning why, so nobody re-adds it.

## What to skip (noise)

- Anything already captured in `decisions.md`, `patterns.md`, `glossary.md`, or the ERD.
- Routine bug fixes with obvious causes.
- Style/lint corrections.
- "Added tests" / "updated docs" — not learnings.
- Anything that reads like a changelog entry.

## Process

1. **Gather context** — read:
   - The watch card (`phase history`, `review_findings` if present)
   - Recent `fastpace/audit.log` entries tagged to this feature
   - `git log --oneline base..head`
   - `gh pr view` if available
   - The ERD/PRD that seeded the feature
2. **Filter for signal**. Aim for 0-3 learnings per feature. **Zero is the right answer if nothing surprised anyone.**
3. **Append each learning** directly into `fastpace/context/learnings.md` using the format below. Each entry is preceded by an HTML comment carrying metadata (including `status: unreviewed`). Downstream skills filter on this status — so your entry is captured but won't affect PR reviews or `/fp-ask` citations until a human approves it.
4. **Do not modify reviewed entries.** Append only.
5. **Report** to the user: "Captured N learning(s) as unreviewed in `fastpace/context/learnings.md` — triage in `fastpace ui` → Recent learnings when convenient."

## Exact format to append

```markdown
<!-- fp-entry · id: <YYYY-MM-DD>-<random6> · status: unreviewed · captured_at: <YYYY-MM-DD> · source_feature: <slug> · source_branch: <branch> -->
## <YYYY-MM-DD> — <short title>

**What happened:** <one sentence>

**Why it matters:** <one or two sentences — the non-obvious insight>

**Evidence:** <link/ref to PR, commit sha, or review comment>
```

Rules for the HTML comment:
- **Do not omit it.** Downstream skills rely on it to filter unreviewed.
- Generate a short random id (6 chars, lowercase alphanumeric). It doesn't need to be cryptographically random — just unique within this file.
- `captured_at` is today's ISO date (absolute, not "today").
- `source_feature` is the watch-card slug; `source_branch` is the git branch name.

## Failure modes to avoid

- **Don't paraphrase the feature description.** That's a changelog, not a learning.
- **Don't invent surprises.** If the review went cleanly, say so and emit zero entries.
- **Don't duplicate.** Grep `learnings.md` for near-matches before writing.
- **Don't omit the `status: unreviewed` marker.** Without it, the entry becomes citable immediately and could cause a downstream review to block on something that isn't verified.
- **Don't include sensitive data.** Redact secrets, customer data, internal hostnames.
- **Don't rewrite existing entries.** Append only. If something needs correcting, flag it in the report and let the user supersede it from the dashboard.

## Integration

- The dashboard's **Recent learnings** view surfaces every `unreviewed` entry with one-click **Approve · Edit · Remove** actions. Edits/removals are only allowed while status is `unreviewed`; once reviewed, the entry becomes append-only and can only be superseded.
- `/fp-ask` and `/fp-review-pr` read only `status: reviewed` entries by default. Users can pass `--include-unreviewed` to either skill if they want the full picture.

## Exit criteria

- Zero or more entries appended to `fastpace/context/learnings.md`, each with a complete `<!-- fp-entry ... -->` comment and `status: unreviewed`.
- Report back: count of entries + pointer to `fastpace ui` → Recent learnings.
- No reviewed entries touched.
