# Kaizen — curate the friction log into improvements Consume the **Open signals** in `docs/FRICTION.md`: decide a verdict for each, migrate durable knowledge into the right docs, and archive consumed signals into the decisions ledger. **Curate-only** — do not hunt for new signals; capture stays manual. This is an interactive, judgment-dense pass: propose, the operator decides, you apply on approval. Design: `docs/superpowers/specs/2026-06-14-kaizen-command-design.md`. ## Phase 0 — scan Run `python3 scripts/friction-scan.py > /tmp/kaizen.json`. It returns each Open signal as `{tag, first_seen, age_days, recurrence_count, referenced_paths, still_exists, text}`. Treat `still_exists: false` as a hint the signal may already be resolved. ## Phase 1 — triage Order signals by `recurrence_count` desc, then `age_days` desc, then tag. **Group signals that share a root cause** and curate them together. Present the agenda before editing anything: total open, how many recurring (≥3), how many look already-resolved. ## Phase 2 — per-signal curation (interactive) For each signal/group, present: a one-line restatement, the evidence (age, recurrence, still-real), and a proposed **verdict**. Verdicts: - **SYSTEMATIZE** — migrate the durable lesson into its right home (a runbook, an ADR, `CLAUDE.md`, a new `scripts/repo-scan.py` check, or a hook). - **CHANGE** — adjust an existing tool/convention/config rather than document it. - **PARK** — *out-of-phase but not obsolete*. Remove from the active tree, but write a ledger row recording **where it now lives (git SHA/branch/doc) and a resurrection trigger**. The default for "not touched lately but not wrong." - **REMOVE** — *obsolete*: superseded, wrong, never worked, duplicated. Ledger row states why. - **ALREADY-BUILT** — the systematization already exists / the fix landed; archive. - **ACCEPTED** — conscious no-op (revisit-if-recurs); archive. - **KEEP-OPEN** — still accruing, not ripe; leave it in *Open signals* (no ledger row). Rules: - **Knowledge is never removed** — SYSTEMATIZE/migrate it; only *active surface* (scripts, checks, conventions, plugins) is parked/removed. - Every reductive verdict must classify *why unused*: **obsolete → REMOVE**, **out-of-phase → PARK**. - The operator approves / modifies / rejects each verdict. On approval: do the mechanical edit (migrate text into the target doc; **move the signal from *Open signals* into the ledger table**; delete the parked/removed file) and show the diff. - PARK and REMOVE both delete from the active tree — the difference is the ledger row. Git history + the ledger row are the park mechanism; never create a `parked/` directory. ## Phase 3 — close-out - Add a new dated block under `## Kaizen reviews — decisions ledger` (newest first), same shape as the existing block: a table with columns **Signal (first seen) | Verdict | Resolution / where it lives now**. - **Bias-to-remove discipline check:** if every verdict this pass was SYSTEMATIZE/CHANGE (only accreting), say so explicitly. - **Self-eval (light):** is `/kaizen` being run often enough (oldest consumed age)? Should the nudge thresholds in `scripts/friction-scan.py` change? Note it. - Run `make lint` if any code/docs changed; revert anything that breaks it. - Commit per `CLAUDE.md` git conventions (one logical unit — straight to `main` if small/safe, a branch if sweeping; show the diff first for a branch). - Print a one-line summary: `consumed X · parked Y · removed Z · kept-open W · migrated → `. ## Headless / cron (future) Deferred until the notify + cron stack exists (`docs/TODO.md` 11.3). When run non-interactively, **report only**: print the proposed verdicts and the nudge, do not edit or commit.