3.7 KiB
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 newscripts/repo-scan.pycheck, 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
/kaizenbeing run often enough (oldest consumed age)? Should the nudge thresholds inscripts/friction-scan.pychange? Note it. - Run
make lintif any code/docs changed; revert anything that breaks it. - Commit per
CLAUDE.mdgit conventions (one logical unit — straight tomainif 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 → <docs>.
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.