diff --git a/.claude/commands/kaizen.md b/.claude/commands/kaizen.md new file mode 100644 index 0000000..5896ba0 --- /dev/null +++ b/.claude/commands/kaizen.md @@ -0,0 +1,63 @@ +# 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.