Documentation menu
tutorial experimental~10 min

Stand up a pod
in ten minutes.

Four sessions work one repository at once, and none of them sees another's half-finished edits, because every peer gets a git worktree of its own. This run is hands-on: you will open a lead and a peer pod, dispatch one small feature across lanes, and watch a question travel peer to lead to human.

you need
git · 2+ terminals
pod size
up to 4, incl. lead
runs on
one machine, one repo
isolation
a worktree per peer
Experimental, and opt-in.

Org mode is off by default and needs git. The channel the sessions talk over is a file-locked directory under .claude/state/sprint/<channel_id>/, so every session in the pod has to sit on the same machine and in the same repository. The channel finds that directory through git rev-parse --git-common-dir, which answers the same from every worktree in a repository (a linked worktree included). Peers therefore share one store while org-dispatch gives each of them a working tree of its own. The baseline server ships already registered in .mcp.json, and a peer is just an ordinary Claude Code session with no launcher and no special flags.

Prerequisites

01

A git repository with the baseline installed, checked out on a branch.

02

The claude CLI on your PATH, and the repo opened in it.

03

Two or more terminals: one lead, one or more peers.

The run

Six steps. You finish with a lead and a peer pod working one feature together, having watched a question travel from peer to lead to you and the answer come back down the same chain.

  1. Turn org mode on

    In .claude/project.json, set the flag. It is false by default:

    .claude/project.json
    "velocity": { "org_mode": { "enabled": true } }

    Once the flag is on you can pick the org track at triage, and org-dispatch will run rather than refuse.

  2. Open the lead session

    In your first terminal, from the repository root. The lead is an ordinary session that runs triage and settles whatever the peers escalate. It can also take the hat explicitly with acquire_lead, which one session holds at a time. Ask for a channel someone already leads and the refusal names the holder, so you know who to escalate to.

    terminal 1 · lead
    $ claude
    $ claude mcp list   # baseline ... Connected

    If baseline is missing, the session started before the server registered, so restart it.

  3. Register a peer

    Use a second terminal, or a third for a larger pod of up to four including the lead. Open an ordinary session in the same repository, then register it on the channel from inside that session.

    terminal 2 · peer p2
    $ claude
    > /companion on lobby p2
      { ok: true, registered: true }

    The channel id is yours to pick, and lobby is only a name both sessions agree on. If you leave the peer id off it defaults to companion-1. The peer now sits in the pod as an equal, polling sprint_status for lanes it is eligible to claim.

  4. Dispatch a feature from the lead

    Put a small change through triage, one that genuinely does split into two lanes, and pick the org track when it is offered. Drive it as far as phase 6, where org-dispatch splits the approved spec into lane-tagged tasks and writes them to the channel.

    Before any lane can be claimed, each peer is given its own git worktree and branch. Two peers sharing one working tree would each read the other's half-finished edits as their own, and whichever committed first would carry both. Where isolation fails, the dispatch stops and names the reason (your own tree is left exactly as it was).

    terminal 1 · lead
    > /triage "your small two-lane change"
    
    # or hand a lane directly to a named peer:
    enqueue_task { task_id: "lane-b", brief: "...", assignee: "p3" }
    undirected lane

    Claim-any: the first free peer whose dependencies are met wins the race.

    directed lane

    Only the named peer can take it. This is the lead's lever for spreading work.

  5. Exercise the escalation chain

    From a peer, ask an open question with ask_lead. The lead decides in its own main context and replies with answer_peer, and the peer reads that answer back off sprint_status. If instead the peer hits a choice it cannot settle inside its own task, it calls yield_fork and stops that lane there.

    The org-mode escalation chain Peers p2, p3 and p4 sit on the broker and decide inside their own lanes. A fork a peer cannot settle travels up to the lead, which relays. A fork needing human judgment travels up from the lead to the human, who decides. human decides fork needing judgment lead relays p2 p3 p4 decide in-lane · claim from the broker The org-mode escalation chain Peers p2, p3 and p4 sit on the broker and decide inside their own lanes. A fork a peer cannot settle travels up to the lead, which relays. A fork needing human judgment travels up from the lead to the human, who decides. human decides fork needing judgment lead relays fork it cannot settle p2 p3 p4 decide in-lane broker .claude/state/sprint/<channel>/
  6. Verify every lane finished

    Pull the authoritative state from the lead. Because the shipped peer path polls sprint_status rather than trusting pushed events, a notification that gets lost cannot hide an unfinished lane.

    terminal 1 · lead
    > sprint_status
      { all_done: true, lanes: [ done, done ], asks: [ answered ] }

    The all_done flag turns true only once every lane is empty, so a missed notification cannot leave you stuck part-way.

What just happened

You ran one feature across a flat pod, with each peer deciding things inside its own lane. A choice a peer could not settle went up to the lead, and the one which needed human judgement came to you. Article X governs that chain.

Teardown and limits

Set org_mode.enabled back to false and you get the default solo and swarm behaviour again. Triage stops offering the org track.

/companion off

Takes this session off the channel with leave_peer and marks its local marker inactive.

release_task

Returns a claimed or yielded lane to the pool so another peer can take it.

the worktrees

A peer's tree is removed once its diff has been audited against the lane's declared write_set and applied to the main tree. A lane that strayed outside that write_set keeps its worktree and lands nothing, so you can still read what it did.

release_lead

Hands the lead hat back, so another session can take it. The holder is the one session with standing to release it.

If something stalls

Three causes cover most stalls.

Either org mode is off, or the tree is not a git repository. Check the flag first, then git rev-parse --is-inside-work-tree.

The session started before the server registered. Restart it; claude mcp list should show baseline connected.

Either the lane's dependencies are not all done, another peer won the race for it, or the lane is directed at a different peer. Pull sprint_status and take another pending lane instead.

last updated 2026-08-23 edit on GitHub →