kaizen-agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Install the kaizen workflow itself, globally or per-project
3
+ ---
4
+
5
+ Invoke the `kaizen` skill with argument `install`.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Start a kaizen run and stop after the plan (plan-only)
3
+ argument-hint: "<request>"
4
+ ---
5
+
6
+ Invoke the `kaizen` skill with argument `plan $ARGUMENTS`.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Reject the kaizen approval the current run is waiting on — reason decides revise (back to planner) vs kill (abandon)
3
+ argument-hint: "<reason>"
4
+ ---
5
+
6
+ Invoke the `kaizen` skill with argument `reject $ARGUMENTS`.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Review-only kaizen run — audit existing code/work, no plan, no implementation
3
+ argument-hint: "[target]"
4
+ ---
5
+
6
+ Invoke the `kaizen` skill with argument `review $ARGUMENTS`.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Resume the current kaizen run and execute the approved plan
3
+ ---
4
+
5
+ Invoke the `kaizen` skill with argument `run`.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: List every kaizen run grouped waiting-on-you / in flight / done / abandoned, plus open backlog count
3
+ ---
4
+
5
+ Invoke the `kaizen` skill with argument `status`.
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "kaizen-agent",
3
+ "version": "0.1.0",
4
+ "description": "Staged AI development workflow: plan, human approval, implement, independent review, bounded fix loop.",
5
+ "type": "module",
6
+ "bin": {
7
+ "kaizen-agent": "./cli/install.ts"
8
+ },
9
+ "files": [
10
+ "cli",
11
+ "skills",
12
+ "agents",
13
+ "commands",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "install-links": "bun run cli/install.ts",
19
+ "check": "bun run cli/install.ts --check"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/hfadhlullah/kaizen.git"
24
+ },
25
+ "license": "MIT",
26
+ "keywords": [
27
+ "claude-code",
28
+ "agent",
29
+ "workflow",
30
+ "skill",
31
+ "codex",
32
+ "antigravity",
33
+ "code-review"
34
+ ]
35
+ }
@@ -0,0 +1,279 @@
1
+ # Kaizen
2
+
3
+ Kaizen is a staged workflow for work that is too big to hand an AI in one go. Instead
4
+ of one agent that plans, writes, and then congratulates itself, the work is split into
5
+ three agents that never share a context window, with human approval stops in between.
6
+ You approve a plan before anything is produced, and an independent reviewer that never
7
+ saw the work being made checks it afterwards.
8
+
9
+ ```
10
+ request -> PLAN -> [approval] -> IMPLEMENT -> REVIEW -> [fix loop] -> [approval] -> done
11
+ ```
12
+
13
+ Everything a run knows lives in plain files under `.kaizen/`, so a run can be paused,
14
+ resumed tomorrow, resumed by a different session, or picked up by a different tool.
15
+
16
+ ## Why the reviewer runs in a separate context
17
+
18
+ This is the one design decision worth understanding before you use it. An agent that
19
+ watched itself write the code will rationalize it — it remembers why every line seemed
20
+ reasonable, and that memory is exactly what stops it from finding the bug. The kaizen
21
+ reviewer starts fresh. It sees the plan, the diff, and the implementation notes, and
22
+ nothing else. It has no reason to defend anything.
23
+
24
+ The same split is why the planner does not implement: a plan written by the agent that
25
+ is about to do the work bends toward what is easy to write.
26
+
27
+ ## Install
28
+
29
+ First get the skill onto your machine: copy or clone this directory somewhere Claude
30
+ can read it. Then ask Claude to install kaizen from there, and it will ask where the
31
+ workflow should live:
32
+
33
+ - **Global** — `~/.claude/skills/kaizen/` and `~/.claude/agents/kaizen-*.md`.
34
+ Available in every project, not shared with your team.
35
+ - **Per-project** — `.claude/skills/kaizen/` and `.claude/agents/kaizen-*.md`,
36
+ committed so the team gets the same workflow.
37
+
38
+ Both can coexist; the project copy wins. Install also offers to write the adapter
39
+ files from [`adapters.md`](adapters.md) so Codex and Antigravity follow the same spec.
40
+
41
+ The workflow is `SKILL.md`, the split spec (`spec.md` core plus `spec-plan.md`,
42
+ `spec-build.md`, `spec-review.md`, `spec-main.md` — each reader takes core plus one),
43
+ `config.default.yml`,
44
+ `adapters.md`, and this README, plus the three agent definitions `kaizen-planner.md`,
45
+ `kaizen-builder.md`, and `kaizen-reviewer.md`.
46
+
47
+ To set a repository up for runs, ask for `kaizen init`. That creates `.kaizen/` with a
48
+ copy of the `spec*.md` files, a config, and the gitignore entry.
49
+
50
+ ## Your first run
51
+
52
+ Say what you want, and say the word kaizen:
53
+
54
+ > kaizen: add rate limiting to the public API
55
+
56
+ That is the whole invocation. The skill triggers on the word, so a plain sentence is
57
+ enough — no special syntax, no flags. `SKILL.md` also documents slash forms like
58
+ `/kaizen plan <request>`, `/kaizen status`, and `/kaizen approve`; those are shorthand
59
+ for the same requests, and they only work as literal slash commands if you have
60
+ installed a command file at `~/.claude/commands/kaizen.md`. Nothing here requires one.
61
+ Saying "kaizen status" or "approve the plan" works either way.
62
+
63
+ Then the run stops twice, and both stops want something specific from you.
64
+
65
+ **Stop one — the plan.** You get a written plan: what is wrong today, what would be
66
+ true instead, the approach chosen, what was rejected and why, and a plain-bullet
67
+ **Work list** of what will actually be done. If the request had genuine ambiguity, the
68
+ plan ends with open questions, and they reach you as a pick list of two to four
69
+ concrete options rather than an open prompt. You can always type something else.
70
+
71
+ Three things newcomers do not expect:
72
+
73
+ - **"Yes, but change X" is a normal answer.** You are not limited to approve or
74
+ reject. Approving with a modification — a different value, a dropped step — is
75
+ recorded in the approval file and binds the builder.
76
+ - **Rejecting is not a failure.** The reason is written down and handed back to the
77
+ stage that produced the artifact, which revises and re-presents.
78
+ - **The planner also lists out-of-scope suggestions** — things it noticed but did not
79
+ fold into the plan. Each is a separate yes or no. Saying nothing means no.
80
+
81
+ Nothing is produced until you clear this stop.
82
+
83
+ **Stop two — the review.** After the work is done, the reviewer reports findings with
84
+ severities, and the run stops before calling the work done. If a finding is below the
85
+ auto-fix threshold, or still open when the fix rounds run out, it is reported to you
86
+ rather than quietly patched.
87
+
88
+ ## What a run decided not to do
89
+
90
+ Both stops throw things away. The planner's out-of-scope suggestions you did not take,
91
+ the low findings nobody fixed, the "later" you said at an approval — all real work, all
92
+ previously surviving only in the conversation.
93
+
94
+ Kaizen writes them down instead, into `06-backlog.md` inside the run that produced
95
+ them, so an item sits next to the plan and the review that explain it. You do not
96
+ maintain this file; it is written at the two moments the run already writes to disk —
97
+ recording the plan approval, and marking the run done — so there is nothing to
98
+ remember.
99
+
100
+ Every item is `open`, `done`, or `rejected`. **Rejected is a real answer**: most
101
+ suggestions are not worth doing, and without a way to decline one it stays on the list
102
+ forever. Rejecting takes a reason, which is what stops the same idea coming back three
103
+ runs later. Closed items stay in their run's file as record and are never printed
104
+ again.
105
+
106
+ Two commands read across all of it:
107
+
108
+ - **`kaizen backlog`** — every open item, grouped by the run it came from, newest
109
+ first, with items rescued from pruned runs last under *Orphaned*. Nothing done,
110
+ nothing rejected.
111
+ - **`kaizen status`** — every run you have, in four groups: waiting on you, in flight,
112
+ done, and abandoned, with the open backlog count at the bottom.
113
+
114
+ A run you abort is abandoned, not outstanding: it sits in its own group and its backlog
115
+ items stop being printed and stop being counted.
116
+
117
+ Status is read live from each run's `state.json`, so nothing gets renamed or moved when
118
+ a run finishes and no path you have written down elsewhere ever breaks.
119
+
120
+ One thing to know about pruning: `state.keep_runs` eventually deletes old run
121
+ directories. Before a run goes, its still-open items are moved into
122
+ `.kaizen/backlog.md` — that file exists only as an orphanage. `kaizen backlog` reads it
123
+ too and prints those items last, under *Orphaned*, so nothing outstanding disappears
124
+ just because its run did. Items already done or rejected are deleted with their run,
125
+ which is the point.
126
+
127
+ ## A real run, start to finish
128
+
129
+ This one actually happened. The whole request was one line, said in passing:
130
+
131
+ > for this dropdown omarchy terminal can we make it much more to the bottom?
132
+
133
+ **Intake** wrote that down verbatim in `00-request.md`, along with what it could
134
+ establish on its own: the script is `~/.local/bin/omarchy-dropdown`, bound to
135
+ `SUPER + grave`, and its height comes from `OMARCHY_DROPDOWN_HEIGHT`, default `0.55`.
136
+
137
+ **The plan** noticed the request had two readings — the panel *extending* further down
138
+ versus the whole panel *sitting* lower — and, rather than asking which, argued for the
139
+ first and said so plainly:
140
+
141
+ > Reading (2) already has a knob — `GAP` (`omarchy-dropdown:13`) — and it does not do
142
+ > what the phrase wants. [...] Setting `GAP=200` moves the top down to y=230 but shrinks the height to 555,
143
+ > putting the bottom edge at 785 — *higher* than today.
144
+
145
+ It proposed `HEIGHT_FRACTION` `0.55 → 0.80`, and listed fixing the `GAP` asymmetry as
146
+ an out-of-scope suggestion rather than doing it.
147
+
148
+ **The approval** is the interesting part, because it was neither yes nor no:
149
+
150
+ > **Value changed: 0.80 → 0.70.** The user chose a smaller increase than proposed
151
+ > [...] Wherever the plan specifies `HEIGHT_FRACTION=0.80`, use **`0.70`** instead.
152
+ > Nothing else changes: same file, same three steps, same verification.
153
+
154
+ The out-of-scope `GAP` fix was explicitly not approved, which made it off-limits for
155
+ the rest of the run.
156
+
157
+ **The implementation** changed one token, verified the geometry arithmetic instead of
158
+ toggling the live window, and reported the thing it did not do:
159
+
160
+ > Live steps 3-6 of the plan's verification [...] were not run: this run was
161
+ > explicitly instructed not to toggle the live dropdown.
162
+
163
+ **The review** re-derived the numbers independently, confirmed the file said `0.70` and
164
+ not `0.80`, confirmed the `GAP` code was untouched — and found one thing nobody had
165
+ considered: a second monitor configured as portrait might report an untransformed
166
+ height, in which case the larger fraction could overflow where the old one did not.
167
+
168
+ > `FINDINGS: 0 critical, 0 high, 0 medium, 1 low`
169
+
170
+ Low is below the default fix threshold, so it was not auto-fixed. It was reported, with
171
+ the exact command to settle it when that monitor is next plugged in. The reviewer also
172
+ left a line in `memory.md`, which every later run in this directory reads:
173
+
174
+ > `GAP` cannot — `geometry()` subtracts `gap * 2` from the height but adds `gap` only
175
+ > once to `y`, so raising GAP moves the bottom edge *up*. Unfixed as of 2026-09-02.
176
+
177
+ One-line request, six files, one real finding, one lesson that outlives the run.
178
+
179
+ ## Kaizen is not only for code
180
+
181
+ Every stage adapts to the **track** — the kind of work a run is doing, which is what
182
+ decides what *deliverable*, *verification*, and *finding* mean. A chapter, a landing
183
+ page, a migration runbook, and a research memo each get a reviewer that checks the
184
+ right things; a reviewer hunting race conditions in a manuscript is worse than none.
185
+
186
+ The track is inferred from your request and stated back to you in the plan, so you
187
+ correct a reading instead of categorizing your own work. You are never asked "is this
188
+ software or writing?"
189
+
190
+ ## Configuration
191
+
192
+ Defaults live in [`config.default.yml`](config.default.yml). Copy it to
193
+ `.kaizen/config.yml` in a repository and override only the keys you care about;
194
+ anything absent falls back to the defaults.
195
+
196
+ | Key | Default | Change it when |
197
+ |---|---|---|
198
+ | `mode` | `approve` | You want `plan-only` to think without building, `auto` to run unattended, or `review-only` to audit existing work |
199
+ | `approvals.plan` | `true` | Rarely. This is the stop that makes the workflow worth running |
200
+ | `approvals.review` | `false` | Set `true` to add a second human stop after the review; with `auto_fix` on it mostly re-approves a report you are already reading |
201
+ | `approvals.each_file` | `false` | You want to confirm every single file edit. Maximum control, slowest |
202
+ | `auto_fix.enabled` | `true` | Set `false` and every finding becomes your decision instead |
203
+ | `auto_fix.min_severity` | `high` | Lower to `medium` or `low` to have more auto-fixed; raise findings you see instead of auto-fixing |
204
+ | `auto_fix.max_iterations` | `2` | Fix/recheck rounds before whatever is left is escalated to you |
205
+ | `review.memory_max_lines` | `100` | The cap on `memory.md`, which every stage of every run reads. Raise only if the lessons are genuinely all load-bearing |
206
+ | `git.auto_commit` | `false` | Leave it. Kaizen does not commit or push unless you ask |
207
+ | `track.default` | `""` (inferred) | A repo that is always one kind of work, e.g. a docs repo |
208
+ | `backlog.enabled` | `true` | Set `false` to skip both backlog capture points; the run still executes, just without a `06-backlog.md` |
209
+ | `backlog.file` | `06-backlog.md` | The per-run file name. Rarely. |
210
+ | `backlog.statuses` | `[open, done, rejected]` | Rarely. Only `open` items are printed |
211
+ | `backlog.orphan_file` | `backlog.md` | Where open items go when their run is pruned |
212
+ | `state.keep_runs` | `20` | You want a longer or shorter run history |
213
+
214
+ Mode never overrides a refusal: destructive or irreversible actions still get confirmed
215
+ even in `auto`.
216
+
217
+ ## Where your files live
218
+
219
+ ```
220
+ .kaizen/
221
+ spec.md # core contract, copied in by init
222
+ spec-plan.md # per-stage contracts; each reader takes core + one
223
+ spec-build.md
224
+ spec-review.md
225
+ spec-main.md
226
+ config.yml
227
+ memory.md # cross-run lessons, appended by the reviewer
228
+ backlog.md # orphanage only: open items rescued before pruning
229
+ runs/
230
+ 2026-09-02-add-oauth/
231
+ 00-request.md # the original request, verbatim
232
+ 01-plan.md
233
+ 02-approval.md # decisions, with reasons and timestamps
234
+ 03-impl.md # what changed, which files, what was skipped
235
+ 04-review.md # findings, severity-tagged
236
+ 05-iterations/
237
+ 01-fix.md
238
+ 01-recheck.md
239
+ 06-backlog.md # what this run deliberately did not do
240
+ state.json
241
+ ```
242
+
243
+ `state.json` is the resume point — stage, mode, and what the run is waiting on:
244
+
245
+ ```json
246
+ {
247
+ "id": "2026-09-02-add-oauth",
248
+ "mode": "approve",
249
+ "stage": "review",
250
+ "awaiting": "approvals.review",
251
+ "iteration": 1,
252
+ "updated": "2026-09-02T14:31:00+07:00"
253
+ }
254
+ ```
255
+
256
+ If a repository has no `.kaizen/`, state goes to `~/.kaizen/` keyed by working
257
+ directory instead.
258
+
259
+ Run state is per-person and not worth committing; the workflow itself is. `init` writes
260
+ this gitignore stanza:
261
+
262
+ ```gitignore
263
+ .kaizen/*
264
+ !.kaizen/spec*.md
265
+ !.kaizen/config.yml
266
+ ```
267
+
268
+ ## Where to go next
269
+
270
+ - [`spec.md`](spec.md) + [`spec-plan.md`](spec-plan.md), [`spec-build.md`](spec-build.md),
271
+ [`spec-review.md`](spec-review.md), [`spec-main.md`](spec-main.md) — the tool-neutral
272
+ stage contract, split so each reader loads only core plus its own stage: exactly what
273
+ that stage reads, writes, and must not do. If anything here and the spec disagree, the spec
274
+ wins.
275
+ - [`config.default.yml`](config.default.yml) — every key with its default and a comment.
276
+ - [`adapters.md`](adapters.md) — running kaizen from Codex or Antigravity, and handing a
277
+ half-finished run between tools.
278
+ - [`SKILL.md`](SKILL.md) — the instructions the agent itself follows. Read it if you want
279
+ to know what Claude is doing between your two approval stops.
@@ -0,0 +1,281 @@
1
+ ---
2
+ name: kaizen
3
+ description: >
4
+ Staged AI development workflow: plan, human approval, implementation, then
5
+ independent bug/security review with a bounded fix loop. Each stage runs as its own
6
+ subagent with clean context, and all state lives in a portable `.kaizen/` directory so
7
+ a run can be resumed later, by another session, or by another AI tool (Codex,
8
+ Antigravity). Use when the user says "kaizen", "/kaizen", asks to plan-then-build-then-review
9
+ a change, wants approval steps before code is written, or wants to resume or check an
10
+ existing kaizen run. Also use to install the workflow into a repository.
11
+ ---
12
+
13
+ # Kaizen
14
+
15
+ A staged workflow for non-trivial development work:
16
+
17
+ ```
18
+ request -> PLAN -> [approval] -> IMPLEMENT -> REVIEW -> [fix loop] -> [approval] -> done
19
+ ```
20
+
21
+ Three separate subagents do the work. They never share a context window, which is
22
+ the point: a reviewer that watched the code being written will rationalize it, a
23
+ reviewer that sees only the diff and the plan will not.
24
+
25
+ The stage contract is split so no reader loads a stage it is not running:
26
+ [`spec.md`](spec.md) is the core (track, intake, resume) and every reader takes it,
27
+ plus exactly one of [`spec-plan.md`](spec-plan.md), [`spec-build.md`](spec-build.md),
28
+ [`spec-review.md`](spec-review.md), or [`spec-main.md`](spec-main.md) — the main
29
+ thread's own file. Read core plus your stage before running it; do not read the
30
+ others. Configuration defaults are in [`config.default.yml`](config.default.yml).
31
+ Porting the workflow to Codex or Antigravity is covered in [`adapters.md`](adapters.md).
32
+
33
+ ## Commands
34
+
35
+ | Invocation | Action |
36
+ |---|---|
37
+ | `/kaizen <request>` | Start a new run in the configured mode (default: `approve`) |
38
+ | `/kaizen plan <request>` | Start a run and stop after the plan (`plan-only`) |
39
+ | `/kaizen auto <request>` | Start a run in `auto` mode: every stage back to back, no approval stops |
40
+ | `/kaizen run` | Resume the current run and execute the approved plan |
41
+ | `/kaizen review [target]` | Review-only: audit existing code, no plan, no implementation (`review-only`) |
42
+ | `/kaizen status` | List every run grouped waiting-on-you / in flight / done / abandoned, plus the open backlog count |
43
+ | `/kaizen backlog` | Print the open backlog items across all runs, grouped by source run, with rescued items last under `Orphaned` |
44
+ | `/kaizen approve` | Approve whatever the current run is waiting on |
45
+ | `/kaizen reject <reason>` | Reject it; the reason is fed back to the stage that produced it |
46
+ | `/kaizen abort` | Mark the current run abandoned |
47
+ | `/kaizen init` | Install `.kaizen/` with the `spec*.md` files, config, and the gitignore entry into the current repository |
48
+ | `/kaizen install` | Install the workflow itself globally or per-project (see below) |
49
+
50
+ If the user typed `/kaizen` with no argument and a run is in progress, treat it as
51
+ `/kaizen status`. If no run is in progress, ask what they want to build.
52
+
53
+ ## Before doing anything
54
+
55
+ 1. Locate the state directory: `.kaizen/` in the repository root, else `~/.kaizen/`
56
+ keyed by working directory. If neither exists and the user is starting work, run
57
+ `/kaizen init` first: it creates `.kaizen/` with a copy of the `spec*.md` files, a config, and
58
+ the gitignore entry (see [`adapters.md`](adapters.md)).
59
+ 2. Read `.kaizen/config.yml`, falling back to `config.default.yml` in this skill for
60
+ any key it does not set.
61
+ 3. Read `.kaizen/runs/<current>/state.json` if a run is active. Never assume the
62
+ stage from conversation memory — the run may have been advanced by another tool
63
+ or another session.
64
+ 4. Read `.kaizen/memory.md` if present. It holds cross-run lessons and carries real
65
+ weight: it is what previous reviewers learned about this codebase.
66
+
67
+ ## Modes
68
+
69
+ Set by `mode` in config, overridable per invocation.
70
+
71
+ - **`plan-only`** — produce the plan, write it, stop. No code is touched.
72
+ - **`approve`** (default) — stop at every approval enabled in config and wait for an
73
+ explicit human decision.
74
+ - **`auto`** — run every stage back to back with no approval, report at the end. The fix
75
+ loop still respects `max_iterations`.
76
+ - **`review-only`** — skip plan and implementation, run the reviewer against existing
77
+ code or a diff.
78
+
79
+ Mode never overrides a refusal: destructive or irreversible actions still get
80
+ confirmed even in `auto`.
81
+
82
+ ## Approvals
83
+
84
+ Approvals are configured, not hardcoded. Each enabled approval halts the run, writes what it
85
+ is waiting for into `state.json`, and reports to the user. The run only advances on
86
+ an explicit `/kaizen approve` or a clear approval in conversation.
87
+
88
+ - `approvals.plan` — after the plan, before any code is written. On by default.
89
+ - `approvals.review` — after the review passes, before the work is called done. Off by
90
+ default: with `auto_fix` on, it mostly asks for approval of a report being read anyway.
91
+ - `approvals.each_file` — confirm each file edit individually. Off by default; slow.
92
+
93
+ A rejected approval is not a failure, and it is not always the same action. Two shapes:
94
+ **revise** ("do it differently") sends the plan back to the planner, which produces a
95
+ new version and returns to this same approval. **Kill** ("not doing this") means the
96
+ request itself was wrong, not the approach — set `stage: "abandoned"` and stop, no
97
+ revision to make. The reason says which; state the reading taken in `02-approval.md`
98
+ when it is not obvious. See *Plan approval* in [`spec-plan.md`](spec-plan.md) for the full rule.
99
+
100
+ **Asking the user anything:** use AskUserQuestion with 2–4 concrete options, taken
101
+ from the options the planner wrote into the plan. Subagents cannot prompt the user,
102
+ so every question reaches them through you. Do not add an "other" option — free text
103
+ is always available. Reserve plain prose questions for things that genuinely have no
104
+ discrete answers.
105
+
106
+ **Before the builder runs:** show the plan's **Work list** — plain bullets of what
107
+ will actually be done. It is the last thing the user sees before anything is
108
+ produced, so show it even when they have already approved the plan in conversation.
109
+
110
+ ## The fix loop
111
+
112
+ When the reviewer reports findings, behavior depends on config:
113
+
114
+ - `auto_fix.enabled: false` — always stop and hand every finding to the user as a
115
+ decision, listed by the reviewer's number so the user can name a subset. Nothing is
116
+ fixed automatically.
117
+ - `auto_fix.enabled: true` — the builder fixes findings at or above
118
+ `auto_fix.min_severity` (default `high`), the reviewer re-checks, repeating up to
119
+ `auto_fix.max_iterations` (default 2). Findings below the threshold, and anything
120
+ still open when iterations run out, are reported to the user rather than silently
121
+ dropped.
122
+
123
+ Every iteration is written to `runs/<id>/05-iterations/` so the loop is auditable.
124
+
125
+ ## Backlog and status
126
+
127
+ Each run keeps its own backlog at `runs/<id>/06-backlog.md`. You write it, in the main
128
+ thread, at two writes that already happen: `02-approval.md` at the plan approval
129
+ (out-of-scope suggestions not folded into the approved scope, and anything cut at the
130
+ approval) and `stage: "done"` at the final approval (findings still open, findings
131
+ below the fix threshold, and the builder's out-of-scope notes). No subagent writes it.
132
+ The full rules are in [`spec-main.md`](spec-main.md).
133
+
134
+ Items are one line each, `- <status>: <item text>`, with `<status>` one of `open`,
135
+ `done`, or `rejected`. Findings keep the reviewer's line verbatim. `rejected` always
136
+ carries a reason after a `|`. Closing an item edits its status in place; the line
137
+ stays in the run's file as record.
138
+
139
+ `/kaizen backlog` reads every `runs/*/06-backlog.md` at read time and prints the `open`
140
+ items only, grouped by source run, newest run first. There is no central backlog file
141
+ to keep in sync. `<state.dir>/backlog.md` is an orphanage and nothing more: before
142
+ `state.keep_runs` prunes a run, move that run's still-open items into it. `/kaizen
143
+ backlog` reads that file too and prints its open items last, under an **Orphaned**
144
+ group, so a rescued item stays visible after its run is gone.
145
+
146
+ **`/kaizen backlog` and `/kaizen status` are read-only.** They print; they never edit
147
+ a `06-backlog.md` or `state.json`, even when reading one turns up an inconsistency
148
+ (a stale `open` item already closed elsewhere, a duplicate, a bad reference). Report
149
+ what looks wrong as part of the output and ask before touching anything — fixing it
150
+ unasked is exactly the scope creep the rest of this spec exists to prevent, applied to
151
+ kaizen's own bookkeeping instead of a user's code.
152
+
153
+ `/kaizen status` reads each `runs/*/state.json` live and prints every run in four
154
+ groups:
155
+
156
+ ```
157
+ Waiting on you — awaiting is non-null and stage is not "abandoned"
158
+ In flight — awaiting is null and stage is neither "done" nor "abandoned"
159
+ Done — stage is "done"
160
+ Abandoned — stage is "abandoned" (set by /kaizen abort)
161
+
162
+ Backlog: <n> open
163
+ ```
164
+
165
+ The count is every open item across all runs plus the orphanage. An abandoned run's
166
+ backlog items are not open work: leave them in place, and do not print or count them.
167
+
168
+ Each line is the run id, its stage, and what it is awaiting. Grouping is derived from
169
+ `state.json` at read time, never from the directory name — run directories are flat and
170
+ are never renamed or moved, so a path written into another file cannot break.
171
+
172
+ ## Running a stage
173
+
174
+ Each stage runs as a subagent via the Agent tool, with the agent type named below.
175
+ Pass it the run directory path and let it read its own inputs from there — do not
176
+ paste plans or diffs into the prompt, since the file is the shared source of truth
177
+ across tools. Name its spec files in the prompt: core `spec.md` plus its own stage
178
+ file, never the whole set.
179
+
180
+ | Stage | Agent type | Writes |
181
+ |---|---|---|
182
+ | Plan | `kaizen-planner` | `01-plan.md` |
183
+ | Implement | `kaizen-builder` | `03-impl.md` + the actual code changes |
184
+ | Review | `kaizen-reviewer` | `04-review.md` |
185
+
186
+ After a subagent returns, update `state.json` yourself in the main thread. Subagents
187
+ report; the main thread owns the state machine.
188
+
189
+ **Scope precisely, don't scope narrow.** Each subagent starts cold — no context from
190
+ you carries over except what the prompt names. List exactly the files this stage's
191
+ task actually touches; don't default to "read everything" for safety. But cutting a
192
+ file the task genuinely needs is worse than the tokens it would have cost: a
193
+ under-scoped subagent produces a wrong plan or misses a real defect, which costs a fix
194
+ iteration — more tokens than the read would have. Precise beats narrow.
195
+
196
+ Relay what matters from each subagent's report to the user — their output is not
197
+ shown automatically.
198
+
199
+ ## State layout
200
+
201
+ ```
202
+ .kaizen/
203
+ spec.md # core contract, copied in by init
204
+ spec-plan.md # per-stage contracts; each reader takes core + one
205
+ spec-build.md
206
+ spec-review.md
207
+ spec-main.md
208
+ config.yml
209
+ memory.md # cross-run lessons, appended by the reviewer
210
+ backlog.md # orphanage only: open items rescued before pruning
211
+ runs/
212
+ 2026-09-02-add-oauth/
213
+ 00-request.md # the original request, verbatim
214
+ 01-plan.md
215
+ 02-approval.md # decisions, with reasons and timestamps
216
+ 03-impl.md # what changed, which files, what was skipped
217
+ 04-review.md # findings, numbered and severity-tagged
218
+ 05-iterations/
219
+ 01-fix.md
220
+ 01-recheck.md
221
+ 06-backlog.md # what this run deliberately did not do
222
+ state.json
223
+ ```
224
+
225
+ `state.json` is the resume point:
226
+
227
+ ```json
228
+ {
229
+ "id": "2026-09-02-add-oauth",
230
+ "mode": "approve",
231
+ "stage": "review",
232
+ "awaiting": "approvals.review",
233
+ "iteration": 1,
234
+ "updated": "2026-09-02T14:31:00+07:00"
235
+ }
236
+ ```
237
+
238
+ `init` adds a gitignore entry that ignores run state but keeps the workflow: it
239
+ ignores `.kaizen/*` and un-ignores `.kaizen/spec*.md` and `.kaizen/config.yml`, which
240
+ are meant to be committed (see [`adapters.md`](adapters.md)).
241
+
242
+ ## Install
243
+
244
+ `/kaizen install` asks where the workflow should live: **global** (this machine, every
245
+ project) or **per-project** (this repo, committed, shared with the team). Both can
246
+ coexist; the project copy wins when present.
247
+
248
+ **Global.** Kaizen's source of truth is the repo at `~/kaizen` (symlinked in on this
249
+ machine). Installing or updating global kaizen means that repo is current and linked:
250
+
251
+ ```bash
252
+ [ -d ~/kaizen ] && (cd ~/kaizen && git pull) || git clone <kaizen repo url> ~/kaizen
253
+ mkdir -p ~/.claude/skills ~/.claude/agents
254
+ ln -sfn ~/kaizen/skills/kaizen ~/.claude/skills/kaizen
255
+ for f in kaizen-planner kaizen-builder kaizen-reviewer; do
256
+ ln -sfn ~/kaizen/agents/$f.md ~/.claude/agents/$f.md
257
+ done
258
+ ```
259
+
260
+ Symlinks, not copies — future `git pull` in `~/kaizen` updates every project on this
261
+ machine at once. This only works because `~/kaizen` is a repo the installing user
262
+ controls; it is not something to hand a teammate.
263
+
264
+ **Per-project.** A teammate cloning this repo does not have access to `~/kaizen` (it
265
+ can be private, or simply not theirs), so the project copy must be self-contained —
266
+ real files, not symlinks, committed into the project:
267
+
268
+ ```bash
269
+ mkdir -p .claude/skills/kaizen .claude/agents
270
+ cp ~/kaizen/skills/kaizen/*.md ~/kaizen/skills/kaizen/*.yml .claude/skills/kaizen/
271
+ cp ~/kaizen/agents/kaizen-*.md .claude/agents/
272
+ git add .claude/skills/kaizen .claude/agents/kaizen-*.md
273
+ ```
274
+
275
+ Then commit. Updating a per-project copy later means re-running the `cp` lines against
276
+ a current `~/kaizen` and committing the diff — there is no live link to keep it in
277
+ sync automatically, by design.
278
+
279
+ `install` also offers to write the adapter files from [`adapters.md`](adapters.md) so
280
+ Codex and Antigravity follow the same spec, per-project only (a global adapter file has
281
+ nowhere sensible to live).