boma/.claude/commands/kaizen.md
sjat 8d2f564382 feat(kaizen): /kaizen command — interactive friction curation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 21:26:21 +02:00

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 new scripts/repo-scan.py check, or a hook).
  • CHANGE — adjust an existing tool/convention/config rather than document it.
  • PARKout-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."
  • REMOVEobsolete: 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 → <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.