lead-session-orchestrator · open source
Several sessions.
One lead.
You decide.
One lead session keeps the overview above your AI coding sessions, so you don’t have to.
Claude Code in one terminal, Codex in another, three repositories, maybe a headless run in the background. It works, until it doesn’t. Two sessions edit the same checkout. Each one asks you the same question. One merges while the pipeline is still red. And your evening goes to babysitting terminals instead of deciding the things only you can decide.
How it works
You, one lead,
and the sessions.
The lead decides which session runs next and what it may do. Inside each session, session-orchestrator does the actual work. They talk only through files in a shared directory, never by waiting on each other’s messages.
What carries the lead.
Version 0.x, GitLab only for now- 01
Lead
One lead above, session-orchestrator inside.
The lead decides which session runs next and what it may do. Inside each session the session-orchestrator plugin plans, runs waves, checks and closes. A lease makes sure only one lead acts at a time.
LeaseConstraints per sessionCheck-in at session startNever waiting: A session never blocks on the lead. Without constraints it falls back to conservative defaults after 10 minutes.
- 02
Rules
Your rules, signed and committed.
One YAML file per repository, the authority artifact, says which actions are free, which need your approval each time, and which never happen. It counts only when it is committed and SSH-signed by a key you trust.
freifreeeinzelnask each timenieneverWithout a signature: Every action asks. The trust anchor starts empty, so nothing is free until you add a signer.
- 03
Gates
Measured before a run, and before a merge.
Before a run starts, and before a merge, the lead checks what it can measure.
Repository busy?Remote on a blocked host?Disk and memoryStop set?Pipeline green on this exact commitIf it cannot measure, it refuses: Anything that cannot be measured ends with exit 6, never with 0.
- 04
Ledger
A record that shows when it was changed.
Decisions and merges go into an append-only, hash-chained log per host.
Edited later?
ledger verifynames the first broken line.
From check-in to merge
- Check inAt start, a session writes what it plans: repository, mode, issues, write scope. It never waits for a reply.
- ConstraintsThe lead answers with constraints for that session, such as a merge protocol and a pipeline budget. No constraint is an approval.
- GatesBefore a run starts, the lead checks busy signals, blocked hosts, disk, memory and the stop.
- Your roundQuestions only you can answer collect in one queue. You answer them together, not one terminal at a time.
- RecordA merge waits for a green pipeline on its exact commit. Decisions and merges land in the ledger.
What you get
Fewer terminals to watch.
More decisions you make.
Each part takes one job off your evening. First what it does for you, then how it works. State lives in plain files on your machine.
- Decide in one round
You decide, it prepares.
Open questions from all sessions end up in one queue. You answer them in one round, not in five terminals.
owner-queue addcollects decisions only you can make, andowner-queue rendershows them as one round of structured questions. Headless sessions ask throughask: it answers from the authority file or parks the question for you. - Signed, not assumed
Nothing ships without your yes.
What a session may do on its own is written in a file you signed and committed. Anything else needs your yes, every time.
Each action is
frei(free),einzeln(ask each time) ornie(never).authority checkchecks the schema, the signature by a trusted key and that the file is unchanged against HEAD.authority queryanswerseinzelnas long as no valid file exists. - No collisions
Sessions stay out of each other’s way.
A new run does not start in a checkout another session is already working in.
slot checklooks for a fresh session-orchestrator lock, a fresh Codex session in that repository and a remote on a blocked host. The starters for Claude Code and Codex add disk, memory, the stop and a claim. Given a worktree path, each run works in its own worktree. - Proof before merge
Merges wait for green.
Nothing merges on a red or missing pipeline, and nothing merges because a message said so.
merge-windowchecks the pipeline on the exact head commit, with all required jobs. Without--executeit only reports. It merges only if the signed file saysfreiformerge_auf_main. GitLab only for now. - Hard stop
One command stops everything.
When something looks wrong, no new run starts until you say so.
navigator stop set --reason "maintenance"and every starter refuses with exit 8.navigator stop clear --reason "<why>" --source <you>lifts it. The stop keeps a history log. - Clean handover
The next lead picks up.
A lead session can end without the fleet losing its thread.
The lease runs for 30 minutes at a time and passes only to the successor it names.
handoverdrafts the state for the next lead.resume-draftdrafts the next phase of a headless run that hit its time limit.
Also included: situation shows the current picture on one screen, status and watch list all Claude sessions on this host with open questions first, and costs keeps cost pots for what the lead itself triggered. The CLI is called lead-session-orchestrator, with the short alias navigator.
Better together
Each works alone.
Together they cover the fleet.
session-orchestrator runs one session well. lead-session-orchestrator coordinates several of them. Neither calls the other. On the same host they coordinate through files, so a session never waits for a message from the lead.
session-orchestrator
Plan, waves, quality gates, close. It holds a session lock in its repository and writes a check-in at session start. Available today for Claude Code, Codex, Cursor and Pi.
Visit session-orchestratorlead-session-orchestrator
Lease, gates, ledger and the owner queue. It writes constraints for each session, decides which one runs next and hands over between lead sessions.
Without session-orchestrator, authority, ledger, stop, owner queue, GitLab gates and handover still work. Busy detection is weaker then: an interactive Claude Code session leaves no lock, so slot check cannot see it.
| Which issues a session works on, in which waves | session-orchestrator |
|---|---|
| Whether a session starts now, and where | the lead: gates, lease, stop |
| Whether an action is allowed without asking | your signed authority file, read by the lead |
| Whether a merge request may merge now | the lead, through merge-window; the merge itself only if the authority file allows it |
Where it comes from
Every rule exists
because something broke.
This tool grew out of a real setup: one person, many repositories, several AI sessions working in parallel, day and night.
- An approval through the back doorA coordinator tried to hand out an approval through a peer message. The sessions had to refuse it on their own. Now a message carries an instruction, never an approval.
- Zero that meant “could not look”A counter showed zero because it could not read its source, and everyone read it as “nothing there”. Now anything that cannot be measured ends with exit 6.
- Two sessions, one checkoutTwo sessions shared a working tree and staged each other’s files. Now the lead checks whether a repository is busy, and every headless run gets its own worktree.
The goal is not more automation. The goal is that you can step away from the terminals and still know that nothing ships without your yes.
Principles
It prepares.
It never approves.
Five rules shape every command. When in doubt, it asks or refuses.
- Never grants approvalsIt reads your signed authority file or refuses. A message from another session carries an instruction, never an approval.
- Fail-closedWhat is not explicitly allowed is not allowed. An action missing from the authority file needs your yes. It is never treated as free.
- Not found is not absentAn empty counter, a silent job or a green gate can all mean “could not look”. Anything that cannot be measured ends with exit 6.
- Numbers carry their populationEvery number says what was counted and when.
- Reads, never typesNo daemon, no listening port, no keystrokes into other sessions. Watching commands only read.
Limits
What it does not do.
Yet, or by design.
Version 0.x. Read this before you plan around it.
- GitLab only. There are no GitHub gates yet.
- Tested on macOS. Linux works in parts; the second stage of the boundary gate runs on macOS only.
- One host. Merging ledgers across hosts is planned.
- It does not start sessions on its own, by design.
- The trust anchor starts empty. Until you add a signer, every action asks for approval.
- Commands, file formats and exit codes may still change. Some JSON keys and protocol fields are German for now.
- Without session-orchestrator, an interactive Claude Code session leaves no lock. Exit 0 from
slot checkthen means “no foreign signal found”, which is weaker than “nobody works here”.
Exit codes most commands share
| 0 | done, or nothing found; never an approval |
|---|---|
| 1 | check failed (fail-closed) or write error |
| 2 | usage error |
| 4 | refused |
| 5 | busy |
| 6 | not measurable |
| 7 | boundary hit: remote on a blocked host |
| 8 | stop is set (starters) |
Each command’s --help lists its own set.
Get started
Install
from npm.
Requires Node.js 24 or newer and git. It requires Node.js 24 or newer and git.
npm i -g lead-session-orchestrator
navigator situation # the current picture on one screen navigator status # all Claude sessions on this host, open questions first navigator authority query acme-api merge_auf_main # frei | einzeln | nie; without a trusted signer: einzeln navigator slot check acme-api # busy gate: 0 no foreign signal, 5 busy, 6 not measurable navigator stop set --reason "maintenance" # nothing new starts until navigator stop clear --reason ... --source ...
Source code: github.com/Kanevry/lead-session-orchestrator
Start small
Start with
one good session.
The lead works best with session-orchestrator. Start with one good session, then add the lead when you run several.