---
name: kaizen-codebase
description: "Run one autonomous codebase-improvement pass on the current repo. Self-discover the single highest-leverage, low-risk improvement (architecture, tech debt, dead code, test gaps, simplification) and either ship it end-to-end as a non-draft PR for /process-prs to review and verdict, or, when it needs human judgment, file one needs-triage issue. Does exactly one thing then stops, so it composes with /loop for recurring improvement (e.g. `/loop /kaizen-codebase` or `/loop 1d /kaizen-codebase`). The self-directed sibling of /implement-issues: same shipping discipline, but it finds its own work instead of grabbing a ready-for-agent issue. Use when the user wants to continuously or periodically improve a repository, asks to \"improve the codebase\", set up a recurring code-quality agent, or run one improvement iteration."
---

# Kaizen codebase (one pass)

One bounded improvement per invocation, then stop. Compose with `/loop` for
recurrence (`/loop /kaizen-codebase`, `/loop 1d /kaizen-codebase`). Never
schedule yourself; `/loop` owns pacing.

The **self-directed sibling of `/implement-issues`**: same shipping discipline,
but it discovers its own candidate instead of grabbing a `ready-for-agent` issue.

```
self-discovery  ->  kaizen-codebase  ->  process-prs
                    (non-draft PR)       (review + recommend-* verdict, you merge)
                         \-> needs-triage issue -> maintainer / triage (uncertain path)
```

## Contract

- Exactly one outcome per pass: one non-draft PR, OR one `needs-triage` issue, OR
  a clean no-op.
- **Confident + surgical → non-draft PR. Uncertain / needs a human call →
  `needs-triage` issue. Nothing worthwhile → exit.** An empty pass is a success,
  not a failure; never manufacture churn to justify a run.
- Never merge, never force-push without `--force-with-lease`, never push to the
  base branch.

## Rails

- **Never merge.** The PR is opened for review; merging stays the maintainer's
  hand (and `/process-prs`'s verdict is a recommendation, not an action).
- **Never ship a guess.** If the candidate proves uncertain or cannot reach green
  mid-implementation, abort and escalate (§4), never open a speculative PR.
- **The finalize gates are mandatory, not optional.** `/review-fix` and
  `/recommit` run on **every** change before the PR opens, whatever its size, and
  `/verify` runs whenever the change is behavioral and a smoke is practical. "It's
  a one-line / test-only / obviously-correct change" is **not** grounds to skip
  `/review-fix` or `/recommit`, and a manual diff read is **not** a substitute for
  `/review-fix`. That rationalization is exactly how unreviewed AI-slop lands in a
  PR. Skipping a gate that applies is a process violation; if one genuinely cannot
  run, say so explicitly in the report rather than silently dropping it.
- **Never touch clean-room / relicensing work.** Self-discovery must skip any
  module under active clean-room or relicensing work, detected via whatever signal
  the repo uses (open relicensing issues/PRs, an ADR / `CONTEXT.md` marker, a path
  convention). Reading the prior implementation contaminates that work; this is a
  hard boundary, not a preference.
- **Every issue comment starts with a disclaimer:**
  `> *This was generated by AI during a kaizen pass.*`.

## 0. Preflight

- Abort if not a git repo.
- `git fetch`; identify the base branch (`main`/`master`); ensure the local base
  is current.
- Work happens in an isolated worktree, so a **dirty main checkout is fine**:
  don't abort on it and don't touch the user's WIP.
- Detect optional substrate, use what exists and skip what doesn't: `CONTEXT.md`,
  `docs/adr/`, triage labels, a GitHub remote. Repos like gdown/imgviz may have
  none of these, and that is fine.

## 1. Pick ONE candidate

- Read any ADRs + `CONTEXT.md` first so you don't re-litigate settled decisions.
- List open PRs and issues; skip anything already proposed or in flight.
- Skip any module under active clean-room / relicensing work (rail above).
- Explore broadly with subagents (architecture depth, tech debt, dead code, test
  gaps, simplification) to keep your context clean. Choose the single
  highest-leverage, lowest-risk candidate. Apply the deletion test and prefer
  surgical seams over sweeping rewrites.

## 2. Classify the candidate

File a **`needs-triage` issue** (do NOT write code) when ANY holds:

- needs a product or architecture decision with more than one reasonable answer
- large blast radius (public API, serialized/on-disk format, many call sites)
- contradicts or would amend an existing ADR
- cannot be proven correct by cheap or existing tests
- requirements are ambiguous or depend on intent only the maintainer knows
- the change is risky or hard to reverse

Otherwise ship a **non-draft PR**, but only when ALL hold: one cohesive surgical
change, low-risk, reversible, and verifiable green (tests + lint) before/after.

When in doubt, escalate to an issue. Shipping an uncertain change unattended is
the failure mode this skill exists to avoid.

## 3a. Ship it (confident path)

1. **Claim it:** create the conventional branch in an isolated worktree, branching
   from the fetched base so in-flight work never leaks into the diff:
   `git wt <type>/<slug> origin/<base>`, where `<type>` is the conventional-commit
   type for the change (`refactor`, `fix`, `chore`, `test`, `perf`, `docs`) and
   `<slug>` is derived from the change itself (there is no issue number). Work
   entirely in the worktree.
2. Apply the minimal change. Read the code before editing it; touch only what the
   change requires; respect any ADRs / `CONTEXT.md`.
3. Get the **full test suite and lint/typecheck green**.
4. `/review-fix` to a clean round (reviewers -> fixes -> re-verify; stop on a
   clean round or on oscillation). Invoke the skill; a hand review does not count.
5. `/recommit` into a clean, logical commit sequence.
6. `/verify` whenever the change is behavioral and a smoke is practical (the skill
   picks the method per project type). Skip it only when the change is
   non-behavioral (e.g. test-only or docs) or no smoke is practical, and note the
   reason in the report.
7. `/make-pr`: push and open a **non-draft** PR (the branch is already
   conventional, so no `/make-branch` rename is needed), assigned to yourself
   (`--assignee @me`), and **no verdict label** (`/process-prs` applies that
   during its independent review). `/make-pr` drafts PRs it opens autonomously by
   default, so pass an **explicit ready (non-draft) request** to override that;
   otherwise the PR lands as a draft and `/process-prs`'s non-draft queue never
   picks it up.
8. If a load-bearing decision was made or a candidate was rejected for a reason a
   future pass would need, record it as an ADR (or in `CONTEXT.md`) so the loop
   doesn't repeat itself.

## 3b. Escalate (uncertain path)

- Ensure the `needs-triage` label exists (`/setup-github-labels`, or
  `gh label create needs-triage` if missing).
- Dedup against open issues, then open ONE issue: the candidate, why it needs a
  human, the options/tradeoffs, and the affected files. Assign the repo owner
  (`--assignee @me`) and apply `needs-triage`. The maintainer (or the interactive
  `/triage` skill) then decides `ready-for-agent` vs `ready-for-human` vs
  `wontfix`; kaizen only parks the unevaluated belief. (`/process-issues` does not
  re-pick `needs-triage`, so the escalation waits on a human, not the agent loop.)
- If there is no GitHub remote, append the candidate to a local
  `docs/kaizen-codebase-backlog.md` instead, and say so.

## 4. Abort mid-flight

If a confident-path candidate proves uncertain mid-implementation, or the work
cannot reach green:

1. Remove the worktree and branch with `git wt -d <type>/<slug>` (leaves no cruft).
2. Fall back to §3b: file ONE `needs-triage` issue naming the **specific** blocker
   (the ambiguous requirement, the failing behavior, what a human must decide) and
   what the pass learned.

No PR. The aborted candidate re-enters the pipeline rather than dying silently.

## Report

End with one line for `/loop`: the PR url, the `needs-triage` issue url, or
"no high-leverage change this pass." If a finalize gate was skipped or could not
run, note which and why alongside that line.

## Composition

Shares the finalize discipline of `/implement-issues` (worktree, `/review-fix`,
`/recommit`, `/verify`, non-draft PR) but sources its own work. Confident work
becomes a non-draft PR that `/process-prs` reviews and verdicts; uncertain work
becomes a `needs-triage` issue the maintainer (or `/triage`) evaluates, since
`/process-issues` parks `needs-triage` and never re-picks it. Neither ever merges.
