Stages
| Stage |
Path |
Description |
| Grooming |
.claude/kanban/grooming/ |
Draft tasks with open questions / unresolved scope |
| Todo |
.claude/kanban/todo/ |
Refined tasks ready to start |
| Progress |
.claude/kanban/progress/ |
Currently being worked on |
| Test |
.claude/kanban/test/ |
Implementation handed off; review/QA in progress |
| Ready |
.claude/kanban/ready/ |
Auto-review passed; awaiting authorized finalization |
| Done |
.claude/kanban/done/ |
Authorized completion |
Lifecycle: grooming → todo → progress → test → ready → done.
grooming/ and ready/ are agent-boundary stages: autonomous runs never enter grooming/
and never advance past ready/, except an EPIC with recorded EPIC-scoped upfront
autonomous authorization as defined in Done below.
IDs & Prefix
Every card carries <PREFIX>-<NUM> (epic subtasks: <PREFIX>-<NUM>-<NN>, see
Epics below). Counters live in <repo>/.claude/kanban.lock (git-committed,
flock-guarded, reconciled against cards actually on the board on every
allocation — a stale counter after a merge can't hand out a duplicate ID).
First use in a project (no prefix= yet) is a confirmation, never a
guess. kanban-id.sh next/prefix exits 2 with the board's candidate
prefixes (existing board cards win by count if any, else a dir-name-derived
one) — on that exit, ask the user which to use (AskUserQuestion,
candidates as options, recommended one first) and then run
kanban-id.sh set-prefix <PREFIX> to confirm it; don't auto-pick and don't
retry silently. Full mechanics, lock format, prefix registry →
scripts.md.
Scripts
Set ROOT="${AI_AGENTS_SKILLS_ROOT:-${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-}}}}" and
S="$ROOT/skills/kanban/scripts", then invoke every script below as "$S"/<name> — never by bare name
(optional leading --repo <path>, default git toplevel):
| Script |
Purpose |
Key flag |
"$S"/kanban-id.sh |
allocate/inspect IDs (next|epic|sub|peek|prefix) |
sub <EPIC-ID> |
"$S"/kanban-new.sh |
allocate ID + render template + stage card |
--epic|--sub <EPIC-ID> |
"$S"/kanban-move.sh |
validated stage transition (wraps git-move) |
--approved (required for →done) |
"$S"/kanban-status.sh |
board overview, subtasks grouped under their epic |
--epic ID |
"$S"/kanban-lint.sh |
card validation (shape, template, dupes, counter drift) |
— |
Full CLI, flags, exit codes, worked examples → scripts.md. Manual
fallback (hand-written card + git-move directly) still
works if a script is unavailable.
Task Lifecycle
1. Create
- Default:
"$S"/kanban-new.sh --title "…" --stage todo (or --stage grooming when scope isn't settled) — allocates the ID, renders task template, stages the card, prints its path.
- Manual fallback: allocate the next ID by hand against
.claude/kanban.lock, fill in task template, git add.
- Scope clear (AC, files, approach all settled) →
todo/.
- Open questions remain →
grooming/; list them in **Open questions:**.
Side-found / user-suggested fixes
When a bug/err is found OR the user suggests a fix:
- Dedupe first. Scan
grooming/ and todo/ for an existing card on the same topic. If found → do NOT create another; apply triage (step 2) against that card — if fix-now criteria hold → fix now and log/note on it; else leave work on that card (groom later).
- Triage — fix now vs file grooming:
- Fix now when ANY of: in-scope of the active task; OR cplx ≤ 3/10; OR standard-subagent-sized.
- Active task → log on the card (Execution Log /
**Decisions:**).
- No active task → mention in the commit msg.
- File a new
grooming/ card only when ALL hold: (oos of active task OR no active task) AND cplx > 3/10 AND not standard-subagent-sized.
- Append to the nits dump when the finding is oos of the active task AND is
NOT being taken into work now AND is too small to deserve its own card. This
is the catch-all: a finding is never dropped silently — it is fixed, carded,
or dumped.
- Wrap-up report. On task completion (hand-off / ready), surface to the user a short list of: (a) side-filed grooming cards created during the work, (b) en-route fixes that were done (no new card), (c) nits appended to the dump.
Nits dump — .claude/kanban/grooming/TODO.md
Running scratch list of small out-of-scope findings picked up in passing. Create
the file if absent.
- One line per finding:
<date> — <file>:<line> — what's wrong, grouped
under a dated heading ## <YYYY-MM-DD> — from <what you were doing>.
- Small findings only. Anything substantial gets its own
grooming/ card
instead. Mark a borderline entry CANDIDATE FOR ITS OWN CARD so the next
grooming pass promotes it rather than re-triaging it from scratch.
- Include the evidence, not just the symptom: how it was confirmed, and what
it was confirmed NOT to be (a ruled-out cause is the expensive part to redo).
- Promoted to a card → DELETE the line. Leave no back-pointer: the card is
the single source, and a pointer stub only clutters the dump and goes stale.
The file holds ONLY what has no card yet. Same when a nit gets fixed in
passing — delete it, don't annotate it as done.
- Project-local scratch. Projects commonly git-exclude this file — follow the
project's convention, and never slip it into a task branch or PR.
1a. Groom (grooming/ → todo/)
Grooming is a user consultation, not autonomous execution. Surface choices; don't resolve them silently.
- Read the card's
**Open questions:** and raise each with the user (options + trade-off + recommendation). Use AskUserQuestion for discrete choices (recommended first). Do not guess.
- If new ambiguities surface → append to
**Open questions:** and raise them too.
- Record every resolution in
**Decisions:** before moving to todo/. Remove **Open questions:** on transition.
- Only when nothing ambiguous remains (scope, acceptance, approach all settled) → move
grooming/ → todo/.
See reference.md for the full grooming protocol.
2. Start (todo → progress)
- Brief the user first (interactive starts). Before moving the card to
progress/, post a short, plain-language task briefing to the user in the
user's language: what the task does and why, the acceptance criteria, the
planned approach, and which files/areas it touches. It's a read-back so the
user can catch a wrong card or misread scope before work starts — keep it
concise and explained, don't dump the raw card. Skip only on autonomous/
unattended runs (no user present, e.g. schedule-tasks).
- From file: move
.claude/kanban/todo/<task>.md → progress/.
- From description: create from task template in
todo/, then move to progress/ (only if scope is clear).
3. Implement (progress/)
- Read task file. Plan via
TaskCreate (atomic subtasks, 1-5 iterations each); track with TaskUpdate.
- Add "Execution Log" section to the task file; update after each significant step.
4. Test (progress → test)
Move card to test/. Run QA checks (lint/tests per project CLAUDE.md).
5. Ready (test → ready)
Auto-review passed + AC met + tests green → move to ready/. If review finds issues → stay in test/.
6. Done (ready → done) — authorized finalization
Authorization is exactly one of: explicit user approval at hand-off; or, only
for one named EPIC and its approved child cards, recorded EPIC-scoped upfront autonomous authorization. The latter never authorizes push, a later EPIC, scope
expansion, or bypassing tests/review. Order matters — card first, merge last:
- Move the card
ready/ → done/ (kanban-move.sh <ID> done --approved or git-move manually).
- Verify the task branch is clean (
git status --short empty — everything
committed, nothing stray left uncommitted).
- Only then squash-merge the branch into the default branch (see Git Commits
below).
Outside an EPIC with recorded EPIC-scoped upfront autonomous authorization,
ready/ → done/ requires explicit user approval at hand-off. Never merge before
the card is in done/ and the branch has been verified clean.
Epics
An epic is a card whose body lists ordered subtask cards. Subtasks are normal
cards; the epic is their parent and their integration point.
- Naming — reserved shared ID. The epic always gets an
EPIC-<NUM> ID
(kanban-new.sh --epic), independently of the project's regular task prefix;
every subtask reuses that SAME ID plus a 2-digit suffix in execution order
(kanban-new.sh --sub <EPIC-ID>): e.g. EPIC-042-billing-epic.md,
EPIC-042-01-db-schema.md, EPIC-042-02-api-crud.md… Regular cards retain
their <PREFIX>-<NUM> IDs.
Epic and subtasks share the leading ^[A-Za-z][A-Za-z0-9]*-[0-9]+ ID token —
schedule-tasks groups them as one chain (related-card-first selection,
dependency blocking) and the byobu window name stays inside its 10-char cap.
- Start. Epic card →
progress/. Create ONE branch epic/<ID> for the whole
epic; every subtask is implemented in that branch, not in its own task/<ID>.
- Subtasks. Work them in the listed order. Each finished subtask card moves
progress/ → test/ → ready/ as usual. A subtask never reaches done/ on
its own — the epic gates that.
- Integration. When the last subtask reaches
ready/: restart the project,
refresh all data (re-run imports/migrations), and run the full test suite.
- Hand-off. Only then move the epic card to
ready/ and obtain explicit user
approval at hand-off or recorded EPIC-scoped upfront autonomous authorization.
Move the parent to done/, then its subtasks as the script permits; verify
epic/<ID> is clean; squash-merge once; then rename the archive to done/<ID>
(git branch -m epic/<ID> done/<ID>). Never delete that archive branch.
See reference.md for the full epic protocol.
Git Commits
Git mechanics follow the git-flow core. Kanban's delta:
a task is worked in its own branch (an epic's subtasks share the epic branch
— see Epics above).
- Branch. By default work the task in a NEW branch
task/<ID> (aligns with
schedule-tasks). Create it at start.
- Sub-agents commit. Each sub-agent commits its OWN zone's work into that
branch (git-flow format +
Agent: <zone> footer).
- Orchestrator finalizes. On task completion the orchestrator makes a
wrap-up commit on the branch (adding its own remaining bits).
- Merge on OK — card and clean-check before merge. Review OK → move the
card to
done/ and verify the branch is clean (git status --short empty)
before touching the default branch. Only then squash-merge the branch
into the default branch as ONE commit, then rename the branch to
done/<ID> — strip the task/ prefix (git branch -m task/<ID> done/<ID>);
the archive is done/<ID>, NOT done/task/<ID>. Kept as an archive for
optional later cleanup — do not delete immediately.
- Moving cards between stage dirs →
kanban-move.sh (wraps git-move, validates the transition); manual fallback → git-move directly.
See reference.md for the autonomous-run commit contract.
Stop Conditions
- Do NOT skip planning.
- Do NOT move to
done/ without explicit user approval at hand-off or recorded
EPIC-scoped upfront autonomous authorization.
- Do NOT start a card from
grooming/ — resolve open questions, move to todo/ first.
- Do NOT silently resolve
grooming/ questions — ask the user; record in **Decisions:**.
- Do NOT move to
ready/ while tests are red.
- Do NOT file a new card for an en-route/user-suggested fix until
grooming/+todo/ are scanned for a duplicate.
- Do NOT file when the fix is in-scope OR cplx ≤ 3/10 OR standard-subagent-sized — fix now; log on card or commit msg if no active task.
- Do NOT drop an oos finding silently — fix it, card it, or append it to
.claude/kanban/grooming/TODO.md.
- Do NOT commit the nits dump into a task branch/PR when the project git-excludes it.
- MUST surface wrap-up list (side-filed grooming + en-route fixes + dumped nits) on hand-off/ready.
Task Delegation Rules
- One agent — one zone. Cross-zone task: the main agent does its own zone;
the shared contract lives in a separate skill (e.g. a protocol/contract
skill); adjacent implementations are done by their own agents reading that
same skill.
security-auditor — read-only: emits a report, writes no code. Fixes are
done by an implementer agent.
test-engineer writes tests, not business logic. If a test needs a new
endpoint/hook in the code → file a subtask in kanban and delegate it to an
implementer agent.
- New agent — only when clearly needed. If the task fits an existing
agent — don't spawn extra agents.
1---2name: kanban3description: Use when managing tasks — creating, grooming/refining draft tasks, starting, completing, or reviewing task status.4---56## Stages78| Stage | Path | Description |9|----------|----------------------------|------------------------------------------------------------|10| Grooming | `.claude/kanban/grooming/` | Draft tasks with open questions / unresolved scope |11| Todo | `.claude/kanban/todo/` | Refined tasks ready to start |12| Progress | `.claude/kanban/progress/` | Currently being worked on |13| Test | `.claude/kanban/test/` | Implementation handed off; review/QA in progress |14| Ready | `.claude/kanban/ready/` | Auto-review passed; awaiting authorized finalization |15| Done | `.claude/kanban/done/` | Authorized completion |1617Lifecycle: `grooming → todo → progress → test → ready → done`.1819`grooming/` and `ready/` are agent-boundary stages: autonomous runs never enter `grooming/`20and never advance past `ready/`, except an EPIC with recorded EPIC-scoped upfront21autonomous authorization as defined in Done below.2223## IDs & Prefix2425Every card carries `<PREFIX>-<NUM>` (epic subtasks: `<PREFIX>-<NUM>-<NN>`, see26Epics below). Counters live in `<repo>/.claude/kanban.lock` (git-committed,27`flock`-guarded, reconciled against cards actually on the board on every28allocation — a stale counter after a merge can't hand out a duplicate ID).29**First use in a project (no `prefix=` yet) is a confirmation, never a30guess.** `kanban-id.sh next`/`prefix` exits 2 with the board's candidate31prefixes (existing board cards win by count if any, else a dir-name-derived32one) — on that exit, **ask the user** which to use (`AskUserQuestion`,33candidates as options, recommended one first) and then run34`kanban-id.sh set-prefix <PREFIX>` to confirm it; don't auto-pick and don't35retry silently. Full mechanics, lock format, prefix registry →36[scripts.md](scripts.md).3738## Scripts3940Set `ROOT="${AI_AGENTS_SKILLS_ROOT:-${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-}}}}"` and41`S="$ROOT/skills/kanban/scripts"`, then invoke every script below as `"$S"/<name>` — never by bare name42(optional leading `--repo <path>`, default git toplevel):4344| Script | Purpose | Key flag |45|---|---|---|46| `"$S"/kanban-id.sh` | allocate/inspect IDs (`next`\|`epic`\|`sub`\|`peek`\|`prefix`) | `sub <EPIC-ID>` |47| `"$S"/kanban-new.sh` | allocate ID + render template + stage card | `--epic`\|`--sub <EPIC-ID>` |48| `"$S"/kanban-move.sh` | validated stage transition (wraps [git-move](../git-move/SKILL.md)) | `--approved` (required for `→done`) |49| `"$S"/kanban-status.sh` | board overview, subtasks grouped under their epic | `--epic ID` |50| `"$S"/kanban-lint.sh` | card validation (shape, template, dupes, counter drift) | — |5152Full CLI, flags, exit codes, worked examples → [scripts.md](scripts.md). Manual53fallback (hand-written card + [git-move](../git-move/SKILL.md) directly) still54works if a script is unavailable.5556## Task Lifecycle5758### 1. Create5960- **Default:** `"$S"/kanban-new.sh --title "…" --stage todo` (or `--stage grooming` when scope isn't settled) — allocates the ID, renders [task template](task-template.md), stages the card, prints its path.61- **Manual fallback:** allocate the next ID by hand against `.claude/kanban.lock`, fill in [task template](task-template.md), `git add`.62- **Scope clear** (AC, files, approach all settled) → `todo/`.63- **Open questions remain** → `grooming/`; list them in `**Open questions:**`.6465#### Side-found / user-suggested fixes6667When a bug/err is found OR the user suggests a fix:68691. **Dedupe first.** Scan `grooming/` and `todo/` for an existing card on the same topic. If found → do NOT create another; apply triage (step 2) against that card — if fix-now criteria hold → fix now and log/note on it; else leave work on that card (groom later).702. **Triage — fix now vs file grooming:**71 - **Fix now** when ANY of: in-scope of the active task; OR cplx ≤ 3/10; OR standard-subagent-sized.72 - Active task → log on the card (Execution Log / `**Decisions:**`).73 - No active task → mention in the commit msg.74 - **File a new `grooming/` card** only when ALL hold: (oos of active task OR no active task) AND cplx > 3/10 AND not standard-subagent-sized.75 - **Append to the nits dump** when the finding is oos of the active task AND is76 NOT being taken into work now AND is too small to deserve its own card. This77 is the catch-all: a finding is never dropped silently — it is fixed, carded,78 or dumped.793. **Wrap-up report.** On task completion (hand-off / ready), surface to the user a short list of: (a) side-filed grooming cards created during the work, (b) en-route fixes that were done (no new card), (c) nits appended to the dump.8081#### Nits dump — `.claude/kanban/grooming/TODO.md`8283Running scratch list of small out-of-scope findings picked up in passing. Create84the file if absent.8586- **One line per finding:** `<date> — <file>:<line> — what's wrong`, grouped87 under a dated heading `## <YYYY-MM-DD> — from <what you were doing>`.88- **Small findings only.** Anything substantial gets its own `grooming/` card89 instead. Mark a borderline entry `CANDIDATE FOR ITS OWN CARD` so the next90 grooming pass promotes it rather than re-triaging it from scratch.91- **Include the evidence**, not just the symptom: how it was confirmed, and what92 it was confirmed NOT to be (a ruled-out cause is the expensive part to redo).93- **Promoted to a card → DELETE the line.** Leave no back-pointer: the card is94 the single source, and a pointer stub only clutters the dump and goes stale.95 The file holds ONLY what has no card yet. Same when a nit gets fixed in96 passing — delete it, don't annotate it as done.97- **Project-local scratch.** Projects commonly git-exclude this file — follow the98 project's convention, and never slip it into a task branch or PR.99100### 1a. Groom (grooming/ → todo/)101102Grooming is a **user consultation**, not autonomous execution. Surface choices; don't resolve them silently.103104- Read the card's `**Open questions:**` and raise each with the user (options + trade-off + recommendation). Use `AskUserQuestion` for discrete choices (recommended first). Do not guess.105- If new ambiguities surface → append to `**Open questions:**` and raise them too.106- Record every resolution in `**Decisions:**` before moving to `todo/`. Remove `**Open questions:**` on transition.107- Only when **nothing ambiguous remains** (scope, acceptance, approach all settled) → move `grooming/ → todo/`.108109See [reference.md](reference.md) for the full grooming protocol.110111### 2. Start (todo → progress)112113- **Brief the user first (interactive starts).** Before moving the card to114 `progress/`, post a short, plain-language task briefing to the user **in the115 user's language**: what the task does and why, the acceptance criteria, the116 planned approach, and which files/areas it touches. It's a read-back so the117 user can catch a wrong card or misread scope before work starts — keep it118 concise and explained, don't dump the raw card. Skip only on autonomous/119 unattended runs (no user present, e.g. schedule-tasks).120- **From file**: move `.claude/kanban/todo/<task>.md` → `progress/`.121- **From description**: create from [task template](task-template.md) in `todo/`, then move to `progress/` (only if scope is clear).122123### 3. Implement (progress/)124125- Read task file. Plan via `TaskCreate` (atomic subtasks, 1-5 iterations each); track with `TaskUpdate`.126- Add "Execution Log" section to the task file; update after each significant step.127128### 4. Test (progress → test)129130Move card to `test/`. Run QA checks (lint/tests per project `CLAUDE.md`).131132### 5. Ready (test → ready)133134Auto-review passed + AC met + tests green → move to `ready/`. If review finds issues → stay in `test/`.135136### 6. Done (ready → done) — authorized finalization137138Authorization is exactly one of: `explicit user approval at hand-off`; or, only139for one named EPIC and its approved child cards, `recorded EPIC-scoped upfront140autonomous authorization`. The latter never authorizes push, a later EPIC, scope141expansion, or bypassing tests/review. Order matters — card first, merge last:1421431. Move the card `ready/ → done/` (`kanban-move.sh <ID> done --approved` or git-move manually).1442. Verify the task branch is clean (`git status --short` empty — everything145 committed, nothing stray left uncommitted).1463. Only then squash-merge the branch into the default branch (see Git Commits147 below).148149Outside an EPIC with recorded EPIC-scoped upfront autonomous authorization,150`ready/ → done/` requires explicit user approval at hand-off. Never merge before151the card is in `done/` and the branch has been verified clean.152153## Epics154155An **epic** is a card whose body lists ordered subtask cards. Subtasks are normal156cards; the epic is their parent and their integration point.157158- **Naming — reserved shared ID.** The epic always gets an `EPIC-<NUM>` ID159 (`kanban-new.sh --epic`), independently of the project's regular task prefix;160 every subtask reuses that SAME ID plus a 2-digit suffix in execution order161 (`kanban-new.sh --sub <EPIC-ID>`): e.g. `EPIC-042-billing-epic.md`,162 `EPIC-042-01-db-schema.md`, `EPIC-042-02-api-crud.md`… Regular cards retain163 their `<PREFIX>-<NUM>` IDs.164 Epic and subtasks share the leading `^[A-Za-z][A-Za-z0-9]*-[0-9]+` ID token —165 `schedule-tasks` groups them as one chain (related-card-first selection,166 dependency blocking) and the byobu window name stays inside its 10-char cap.167- **Start.** Epic card → `progress/`. Create ONE branch `epic/<ID>` for the whole168 epic; every subtask is implemented in that branch, not in its own `task/<ID>`.169- **Subtasks.** Work them in the listed order. Each finished subtask card moves170 `progress/ → test/ → ready/` as usual. A subtask **never** reaches `done/` on171 its own — the epic gates that.172- **Integration.** When the last subtask reaches `ready/`: restart the project,173 refresh all data (re-run imports/migrations), and run the full test suite.174- **Hand-off.** Only then move the epic card to `ready/` and obtain explicit user175 approval at hand-off or recorded EPIC-scoped upfront autonomous authorization.176 Move the parent to `done/`, then its subtasks as the script permits; verify177 `epic/<ID>` is clean; squash-merge once; then rename the archive to `done/<ID>`178 (`git branch -m epic/<ID> done/<ID>`). Never delete that archive branch.179180See [reference.md](reference.md) for the full epic protocol.181182## Git Commits183184Git mechanics follow the [git-flow](../git-flow/SKILL.md) core. Kanban's delta:185a task is worked **in its own branch** (an epic's subtasks share the epic branch186— see Epics above).187188- **Branch.** By default work the task in a NEW branch `task/<ID>` (aligns with189 schedule-tasks). Create it at start.190- **Sub-agents commit.** Each sub-agent commits its OWN zone's work into that191 branch (git-flow format + `Agent: <zone>` footer).192- **Orchestrator finalizes.** On task completion the orchestrator makes a193 wrap-up commit on the branch (adding its own remaining bits).194- **Merge on OK — card and clean-check before merge.** Review OK → move the195 card to `done/` and verify the branch is clean (`git status --short` empty)196 *before* touching the default branch. Only then **squash-merge** the branch197 into the default branch as ONE commit, then **rename** the branch to198 `done/<ID>` — strip the `task/` prefix (`git branch -m task/<ID> done/<ID>`);199 the archive is `done/<ID>`, NOT `done/task/<ID>`. Kept as an archive for200 optional later cleanup — do not delete immediately.201- Moving cards between stage dirs → `kanban-move.sh` (wraps [git-move](../git-move/SKILL.md), validates the transition); manual fallback → `git-move` directly.202203See [reference.md](reference.md) for the autonomous-run commit contract.204205## Stop Conditions206207- Do NOT skip planning.208- Do NOT move to `done/` without explicit user approval at hand-off or recorded209 EPIC-scoped upfront autonomous authorization.210- Do NOT start a card from `grooming/` — resolve open questions, move to `todo/` first.211- Do NOT silently resolve `grooming/` questions — ask the user; record in `**Decisions:**`.212- Do NOT move to `ready/` while tests are red.213- Do NOT file a new card for an en-route/user-suggested fix until `grooming/`+`todo/` are scanned for a duplicate.214- Do NOT file when the fix is in-scope OR cplx ≤ 3/10 OR standard-subagent-sized — fix now; log on card or commit msg if no active task.215- Do NOT drop an oos finding silently — fix it, card it, or append it to `.claude/kanban/grooming/TODO.md`.216- Do NOT commit the nits dump into a task branch/PR when the project git-excludes it.217- MUST surface wrap-up list (side-filed grooming + en-route fixes + dumped nits) on hand-off/ready.218219## Task Delegation Rules2202211. **One agent — one zone.** Cross-zone task: the main agent does its own zone;222 the shared contract lives in a separate skill (e.g. a protocol/contract223 skill); adjacent implementations are done by their own agents reading that224 same skill.2252. **`security-auditor` — read-only**: emits a report, writes no code. Fixes are226 done by an implementer agent.2273. **`test-engineer` writes tests, not business logic.** If a test needs a new228 endpoint/hook in the code → file a subtask in kanban and delegate it to an229 implementer agent.2304. **New agent — only when clearly needed.** If the task fits an existing231 agent — don't spawn extra agents.