--- name: capture-knowledge description: Capture durable, project-specific learnings from the work just done into the knowledge/ base — gotchas, implementation quirks, things looked up or web-searched, live-API behaviours, and design decisions (as ADRs). Use before opening a PR (it runs automatically in /deliver), or any time you've learned something worth remembering. Records only non-obvious, reusable facts; skips anything already in the repo, CLAUDE.md, or git history. --- # Capture Knowledge Fold what you just learned into the committed knowledge base at `knowledge/`, so a future session (or contributor) doesn't have to re-learn or re-discover it. Run this **before a PR** — in `/deliver` it runs automatically pre-PR, so the notes land in the same PR as the change. ## What to capture (be selective) Record only **durable, project-specific, non-obvious** facts — the test is "would a future me waste time without this?": - **Gotchas / quirks** → `knowledge/gotchas.md` — a trap you hit, a tooling surprise, anything that needed a **web search or doc lookup** to resolve. - **Live-API behaviours** → `knowledge/tmdb-api-notes.md` — a nullable/absent field, an undocumented response shape, an enum value the docs omit. - **Design decisions** → a new **ADR** in `knowledge/decisions/` (next number — take it from [`decisions/README.md`](../../../knowledge/decisions/README.md)'s index, not a directory listing), using `decisions/0000-template.md`. Any non-obvious choice and its rationale — why this approach over the alternatives. Add the new row to that index. - **Deferred breaking changes** → `knowledge/next-major.md` — any fix rejected or deferred *because* it is breaking. The skill-improvement log remembers the "no"; this file is what makes the deferred "yes" resurface at the next major. **Reconcile its status line whenever you add an entry:** it states which major window is open, and an entry filed against a window that already shipped is invisible at exactly the moment it should fire. A window is open until the version is **tagged** — an unreleased `CHANGELOG` section is not a release (`git tag --list | sort -V | tail -1`). ## What NOT to capture Mirror the discipline of a good memory — don't record: - Anything already in the code, `CLAUDE.md`, the topic docs under `.claude/docs/`, the DocC docs, or git history. - Facts that only mattered to this one task and won't recur. - Restatements of the obvious. If asked to record something obvious, capture the *non-obvious* part (what surprised you) or skip it. Quality over volume: a few high-signal entries beat a long dump. **A learning that implies work is not a knowledge entry.** `knowledge/` records what is *true*; an issue records what should *change*. "The decoder drops `tv` rows" is not a gotcha to remember, it is a defect to file — writing it here instead buries it in a file nobody greps until they hit the same wall. When a candidate is really a task, file it per [`.github/ISSUE_FILING.md`](../../../.github/ISSUE_FILING.md) and record only the durable half here, if any survives. The two are not exclusive: a live-API quirk often earns a `tmdb-api-notes.md` line *and* an issue for the code that mishandles it — cite the issue number from the entry so they stay tied. ## When an entry records a count, ask what enforces it If a candidate entry states a **known-remaining defect count** — "54 sites still do X", "3 models still decode Y unsafely" — stop and ask the follow-up: **"what fails if that number changes?"** A number in a markdown file is a promise with nothing behind it; it silently goes stale as sites are fixed *or* regressed, and the two cancel out. Prefer a committed check with an **explicit set**, not a count (so a fix and a regression can't cancel, and an empty scan can't pass), wired into **both** `make lint` and CI — no workflow runs `make`, so one alone is invisible. `Scripts/check-defaulted-witnesses.py` is the worked example, and its history is the lesson: it began as an allowlist of sites still to fix, which checked only that the count went *down*. Once those sites were rewritten it had to also assert that each one's replacements were actually written, because every other gate is deletion-side — a missing replacement is a silent source break that passes lint, build, test and CI. **Ask which direction your check runs in**, and whether its green would look any different if the scan had matched nothing at all. If a guard isn't worth building, say so in the entry, so the number reads as an observation rather than an invariant. ## Steps 1. **Start from the candidates list, if one exists.** If the caller passed a **knowledge-candidates** list as the argument (`$ARGUMENTS` below — `/deliver` pastes its ledger list here), use that as your input — that's the reliable source, jotted while the learnings were fresh, and it reaches you intact even if the caller's context was compacted. Otherwise, reconstruct candidates by reviewing the work just done — the diff, the dead-ends, the things you looked up, the decisions you made. 2. **Filter** against "What NOT to capture". Drop the rest. 3. **Check for duplicates** — skim the relevant `knowledge/` file; **update** an existing entry rather than adding a near-duplicate. 4. **Write each entry** in the right file: - Gotchas / API notes: a short dated subsection (`###