Skip to main content

Kanban Mode NEW

UPDATED 2026-08-15 12 min read EDIT ON GITHUB ↗
NEW · v3.1

Kanban Mode

Info
Value affiliation: agentic loop engineering · multi-session orchestration

Kanban Mode replaces the old model — driving one SPEC at a time in a single session — with a multi-session board. One lead session conducts, companion sessions work simultaneously each in their own worktree, and completed cards flow across the board. The backbone of that board is the Origin-Trail Chain.

You start it by attaching the --kanban (short -k) switch to the session launcher. It is neither a new subcommand nor a new runtime — it is merely an entry contract on which a goal preset of the chain (kanban_chain, a bundle that predeclares a completion condition) rides. The four phases of the chain (plan → run → review → sync) and the human gates inherit the existing /moai goal engine and full-pipeline chaining rules as-is.

This page covers the entry conditions of Kanban Mode, the Origin-Trail Chain design, the chain phases, and “what is not automated.” For a short introduction from the workflow-command viewpoint, see /moai unified command first.

Why “kanban”

Info
Analogy: each card on a kanban board is one worktree session. As cards flow across the board, sessions flow along the chain.

In the old model, a single session owned one SPEC end to end — writing the plan, implementing in run, reviewing in review, and tidying docs in sync. As a SPEC grows large, one session struggles to handle it, and when it hits the context-window limit, the session must be split.

Kanban Mode reframes this structure from a board viewpoint:

  • One lead session writes the plan and coordinates progress.
  • Several run sessions implement in parallel, each in its own worktree.
  • Each session is a card on the board, and cards flow through phases.

For this multi-session board to work, “where did this session come from,” “is the parent session alive,” and “how far has it gotten” must not be lost. The Origin-Trail Chain takes on this role.

Origin-Trail Chain — design direction

The Origin-Trail Chain is an append-only tree that tracks the lineage of multi-session worktrees. Each worktree session is a node, and parent-child edges record “this session branched off that session.”

append-only JSONL event stream

The chain is stored in .moai/state/chain/events.jsonl. Every write appends one line via O_APPEND — there is no overwriting and no truncation. Because the kernel serializes concurrent appends, even when several sessions write simultaneously, one line never corrupts another.

flowchart TD
    Root["Root node
(primary checkout)"] Spawn1["Session A
(worktree 1 · depth 1)"] Spawn2["Session B
(worktree 2 · depth 1)"] Spawn3["Session C
(worktree 3 · depth 2)"] Root -->|"node-enter"| Spawn1 Root -->|"node-enter"| Spawn2 Spawn1 -->|"node-enter"| Spawn3 Spawn1 -->|"completion-edge"| Done1["Milestone complete"] Spawn2 -->|"completion-edge"| Done2["Milestone complete"]

Three event types are recorded in the stream:

EventWhen recordedContents
node-enterat worktree spawn timenode ID, parent node, depth, lineage chain, worktree path, SPEC ID, entry time
node-updateon child SessionStart or milestone completionsession ID backfill or milestone state update
completion-edgeon session end (SubagentStop hook)parent-child nodes, completed milestones, next resume target

The event stream is a flat file, but at read time BuildNodes() replays the events to derive the current node state. No mutable tree file exists.

WorktreeNode — 13 fields

Each node is reconstructed at read time as a state view with 13 fields:

FieldMeaning
node_idmonotonically sortable unique ID (millisecond timestamp + random)
parent_node_idthe parent node that spawned it. Empty for the root
depthnesting depth. Primary checkout is 0, first worktree is 1
origin_chainthe ID path from root to this node (O(1) lineage lookup without traversal)
worktree_pathabsolute worktree path
session_idthe Claude Code session ID assigned by the runtime (filled via two-phase backfill)
spec_idthe SPEC identifier this node works on
milestonecurrent milestone label
entered_atnode creation time (RFC 3339)
exited_atsession end time. Derived from heartbeat staleness (not an exit event)
last_completed_milestonethe most recently marked-complete milestone
resume_targetone-line description of what to do on resume
resume_commandthe single command to run on resume

CWD-collision resolution

Sessions that reuse the same worktree path can collide — if you delete a worktree and recreate it at the same path, two sessions share the same worktree_path. The chain distinguishes them by the (worktree_path, session_id) pair:

  1. Primary key: find the node whose (worktree_path, session_id) pair matches exactly.
  2. Fallback: if session_id is empty or no matching node exists, resolve to the most recently entered node at that path.

This mechanism accurately restores “what is the current node for this path” when resuming a session after /clear.

Two core problems and their solutions

The Origin-Trail Chain solves two problems:

Depth amnesia — when re-entering after /clear from a deeply nested worktree, “who are this session’s ancestors” is lost. You had to recover it through grep or scrollback archaeology. The chain denormalizes the full ID path from root to leaf in the origin_chain field, restoring lineage in O(1) without traversal.

Dead leader socket — the state where the lead session has died but the child session does not know it. The child sits frozen waiting for the dead leader. The chain records session termination with completion-edge events, so together with heartbeat staleness (the derived exited_at), a child can detect its parent’s state.

Depth ceiling

An infinitely deep session tree makes complexity uncontrollable. The chain caps complexity with a depth ceiling — beyond the ceiling it refuses deeper spawns and guides work to shallower layers.

Session ID two-phase backfill

At the moment of spawning a worktree, the session ID is not yet known — because the Claude Code runtime assigns the session ID only after starting the child process. So it is split into two phases:

  1. At spawn time: append a node-enter event with session_id left empty. The node ID is passed to the child process via the MOAI_CHAIN_NODE_ID environment variable.
  2. At child SessionStart: once the runtime assigns the session ID, backfill session_id with a node-update event.

This protocol bridges the gap between spawn time and session-ID assignment time.

Current implementation status

In v3.1 the entry path of Kanban Mode is wired end to end. Each surface differs in completeness, though, so it is worth separating what you can use from the command line today from what still lives only in the library layer.

Reachable from the command line today

  • -k / --kanban launcher switch — wired into both moai cc and moai glm. Passed bare (or with a SPEC identifier) it enters as the lead; passed as -k --name <role>-<run-id> it joins an already-open run as a companion session. The mixed-backend launcher moai cg refuses it with a sentinel.
  • Bootstrap notice — when the lead session opens, the SessionStart hook prints the run identifier and the four companion launch commands (moai cc -k --name plan-<run-id> and so on) in the user’s language. The notice a companion session receives identifies only the run it joined; the joined role is not in the notice — it is recorded separately in the session record.
  • Session record — the entered session’s role, backend, and target SPEC are recorded.
  • moai chain CLI — five subcommands work: status (current-node summary), lineage (root-to-leaf lineage), back (parent node’s resume target and command), list (all nodes with freshness), prune (folding terminated old nodes into an archive). The internal/chain/ storage layer below backs them.
  • Dispatch — the actor moving cards between columns is the lead session’s orchestrator. The protocol lives in .claude/rules/moai/workflow/kanban-dispatch.md, and companion sessions are launched by hand, one per terminal. There is no path by which a session launches another session.

Chain storage layer

  • internal/chain/store.go — append-only JSONL writer/reader. Appends one line at a time via O_APPEND, and skips corrupt lines with skip + warn.
  • internal/chain/node.goWorktreeNode (13 fields) + ChainEvent type definitions.
  • internal/chain/populate.goPopulator: node creation at spawn time, session ID backfill, milestone update, completion-edge recording, current-node interpretation.
  • GenerateNodeID — generates IDs with a monotonic timestamp + random, with no external dependencies.

Not yet called by anyone

The board state store in internal/kanban/ is complete as code — a closed six-column enumeration (backlog → plan → run → review → sync → done), a single-origin state file converging on one primary checkout, file locking, corruption recovery, and reconciliation with SPEC frontmatter status (it marks mismatches rather than fixing them). But no production caller reads or writes it yet. That means column position is held by the lead session’s memory and the SPEC status, not by a file, and no CLI verbs exist to view the board or move a card.

Warning
There is no moai kanban command. The CLI surface of Kanban Mode is the launcher switch -k and the lineage query command moai chain, nothing else.

Opening a session in Kanban Mode

Info
Not a slash command: Kanban Mode is not a / command in the Claude Code chat window; it is a switch that opens the session itself. You attach it in the terminal when starting the session.

Start in the terminal by attaching --kanban (short -k) to the MoAI launcher (moai cc or moai glm). If you also pass a SPEC identifier, that SPEC is the target; if you omit it, plan-phase begins from the first prompt.

bash
# Enter as the lead — start the kanban chain targeting a SPEC
$ moai cc --kanban SPEC-AUTH-001

# Short form
$ moai cc -k SPEC-AUTH-001

# Without a target SPEC — start plan from the first prompt
$ moai cc -k

# Same entry on the GLM backend
$ moai glm -k SPEC-AUTH-001

When the lead session opens, it prints the run identifier together with the four companion launch commands. A human runs each one in a separate terminal to populate the board.

bash
# Companion sessions — join with the run-id the lead reported
$ moai cc -k --name plan-<run-id>
$ moai cc -k --name run-<run-id>
$ moai cc -k --name review-<run-id>
$ moai cc -k --name sync-<run-id>

On successful entry the launcher arms the kanban_chain goal preset inside the session (after Implementation Kickoff Approval passes). The goal preset is a completion condition that the stop-goal Stop-hook evaluator evaluates at every turn end — it is not a new runtime or hook, but one condition laid on top of existing machinery.

Running one chain across five terminals

Opening the lead with moai cc -k prints one launch command per companion session alongside the run identifier. The operator opens each of them in its own terminal to complete the five-session run — the lead instructs, and plan · run · review · sync each work in their own worktree.

One Kanban Mode run: a lead and four companion sessions open in their own terminals

Cards flow like this: the lead instructs the plan session to author, the run session implements from that plan, the review session checks the implementation, and the sync session reconciles the code with the SPEC and commits. Each dispatch happens only after the lead has read the phase’s progress evidence.

Info
Why this shape — a backend per role. Design and leading run on Opus; implementation runs on GLM. When opening companions, moai glm -k --name ... instead of moai cc -k --name ... joins that session on the GLM backend. Keeping the expensive model where judgment is needed and routing the implementation load to the cheaper backend is what makes the token cost of a multi-session run sustainable. Sessions message each other, and cross-session messaging is auto-permitted through the injected --settings.

The model labels visible in the screenshot’s statuslines reflect one operator’s session at capture time, not the shipped default.

Watching the board in a browser

Rather than scanning five terminals by eye, moai web shows the same state on one screen. The Kanban screen carries the five-session chain board alongside the SPEC pipeline, with Overview, Specs, Monitor, and Settings screens beside it.

moai web console — Overview screen with SPEC counts, in-progress SPECs, and session registry

The console binds to loopback only. See moai web console for the full guide.

Chain phases

The kanban chain extends the full-pipeline contract (an agreement that auto-chains run → sync for one SPEC). Four phases proceed in order:

flowchart TD
    Entry["--kanban entry
(target SPEC or first prompt)"] --> Plan["plan
SPEC authoring + independent audit"] Plan --> Gate1{"Implementation Kickoff Approval
(human gate)"} Gate1 -->|"approved"| Run["run
implementation cycle → AC convergence"] Gate1 -->|"declined"| Stop1["Stop"] Run --> Review["review
security review"] Review --> Sync["sync
docs · changelog · closure"] Sync --> Done["Chain complete"]

The detailed procedure of each phase inherits the existing chaining rules:

  • plan — authors the SPEC document, and an independent audit (plan-auditor) verifies its contents. See /moai plan.
  • run — the implementation cycle (TDD or DDD) implements code until it converges on the Acceptance Criteria (AC). See /moai run.
  • review — produces a security review result with /moai review --security --deep --repo. By severity it returns to run or proceeds to sync.
  • sync — updates docs, writes the changelog, and closes the phase. See /moai sync.

What Kanban Mode adds on top is the multi-session board viewpoint — the lead session coordinates, run sessions work in parallel, and the Origin-Trail Chain tracks that lineage. For the detailed rules of the chain phases themselves, see the /moai unified command and /moai goal.

When to use it, when not to

Info
One lead, four companions. Entry and dispatch work in v3.1. The board state store that would pin column positions to a file has no callers yet, so the current position of a card is held by the lead session and the SPEC status.

When to use — when advancing one SPEC (or several SPECs) simultaneously across multiple worktree sessions. When you need to track session lineage with the Origin-Trail Chain. When you want to drive one SPEC all the way to closure in one go.

When not to use — when you want a human to judge and review intermediate artifacts between phases (in this case, run the ordinary plan → run → sync turn by turn). Short work that finishes in a turn or two. When you need the mixed backend (moai cg).

Scope boundaries

This page states explicitly what it does not do:

  • It is not a new subcommand--kanban is a launcher switch, not a chat command like /moai kanban.
  • It does not skip human gates — Implementation Kickoff Approval, the pre-implementation quality gate, and the documentation-scope gate all still fire. Even if the chain flows automatically, each gate requires human approval.
  • Unsupported backend — Kanban Mode is rejected by the mixed-backend launcher moai cg. moai cg runs the leader on one backend and teammates on another, which contradicts the chain’s precondition of “one session / one backend / one chain.” The session does not open, accompanied by a rejection sentinel.
  • /moai unified command — a short introduction from the workflow-command viewpoint
  • /moai todo — the backlog queue that admits cards onto the board
  • /moai goal — the goal engine that drives the kanban chain
  • Autonomous continuation loop — ownership and guardrail comparison of /moai goal, /moai loop, and the native /goal
  • /moai run — run-phase autonomy wiring, the rules the kanban chain’s run phase inherits
  • Harness engineering — how phase chaining and observation sit on top of the harness design
  • Statusline — how session lineage and worktree state are displayed in the statusline