Session roaming
Session roaming is the part of 0dai you feel first. You start a task in one coding agent, stop, and continue it in a different agent — a different CLI, possibly on a different machine — and the second agent already knows the goal, the plan, what files were touched, and the decisions that were made. No copy-paste, no re-explaining. This page covers what a session captures, how the next agent finds it, the file architecture underneath, and how to drive the whole thing from the command line.
Why roaming exists
A coding agent's memory ends with its context window. Close the session and the working memory is gone — the plan you agreed on, the dead end you ruled out, the reason you picked one library over another. The next session starts blank. That is bearable when one person uses one tool for one sitting. It stops being bearable the moment work crosses a boundary: a different tool that is better at the next step, a teammate picking up where you left off, or simply tomorrow.
Roaming treats the handoff as a first-class object instead of a chat transcript you scroll back through. The state that matters is written to a small, structured file. Any agent that opens the project reads that file and continues. Because the file is plain data in the repository, the handoff is portable across tools, machines, and reboots. The broader case for keeping memory in the repo is in Why 0dai; this page is the mechanism.
What a session captures
A session is deliberately small. It records the things a competent successor needs and nothing it can rederive from the code itself.
- Goal — what you are working on, in one line.
- Plan — the steps and which ones are done.
- Files touched — what has been modified so far.
- Key decisions — the architecture choices made and why.
- Handoff notes — free text for the next agent: what is left, what to watch for.
What it does not store is as important as what it does. It is not a transcript. It does not duplicate file contents — the files are in the repo. It carries no secrets. The discipline is to record the reasoning, not the raw material, so the file stays short enough that the next agent actually reads all of it.
How the next agent detects it
Detection is automatic, not a command you have to remember. When an agent starts in a project that has an active session, a startup step injects a short banner into the agent's context before it does anything else:
[ai-layer] ACTIVE SESSION DETECTED — pick up where the last agent left off:
Goal: implement auth
Status: in_progress
Roaming: claude -> codex (session handed off to you)
Handoff: designed API, need implementation
Use get_session MCP tool for full contextThe Roaming: claude -> codex line is the system noticing that the session was last saved by one agent type and is now being read by another — the literal moment of a roam. When the same agent type continues its own session, that line instead reads Agent: claude (continuing your session). The banner also lists the files touched, key decisions, and remaining plan steps when the session records them, then ends by pointing at the get_session MCP tool for the full context. The agent reads the banner, loads the full session if it needs detail, and continues from the handoff. Nothing is re-derived that was already written down.
Architecture
The whole system is files. There is no session server, no socket, no background daemon holding state. The diagram below is the entire moving part.
Agent A (claude) Agent B (codex / gemini / aider)
| |
| 0dai session save |
v |
ai/sessions/active.json <-------- startup read on launch
| { goal, plan, files, | -> inject "ACTIVE SESSION DETECTED"
| decisions, handoff, | -> continue from handoff
| last_agent, roam } |
| |
| 0dai session complete |
v |
ai/sessions/archive/<id>.json (history; active.json cleared)The pieces:
- Active session.
ai/sessions/active.jsonis the single live handoff. There is one active session per project at a time. Saving updates it in place; the file is the source of truth. - Archive. Completing a session moves it to
ai/sessions/archive/and clears the active slot. Past sessions stay queryable as history without cluttering the live state. - Startup injection.Each agent's generated config includes a session-start step. On launch it reads
active.json, computes whether this is a roam (the reading agent type differs from the saving one), and prepends the banner so the context is present before the first user turn. - Retrieval interface.Beyond the banner, the handoff context is reachable through the project's MCP tools, so an agent can pull the full session on demand rather than relying only on the startup summary.
Two properties fall out of this design. First, it is offline by default — no network call is required to save or read a session, so it works on a plane and inside a locked-down CI box. Second, it is auditable — the session and its archive are tracked in git, so the handoff history is a diff you can read, not a vendor's opaque log.
Commands
| Command | What it does |
|---|---|
session save --goal "..." | Create or update the active session |
session status | Show the current active session |
session complete | Archive the active session to history |
session history | List past sessions |
A typical roam, end to end:
# In Claude Code — save before switching tools
0dai session save --goal "implement auth" \
--summary "designed API, need implementation"
# Launch Codex in the same repo — it auto-detects:
# [ai-layer] ACTIVE SESSION DETECTED — pick up where the last agent left off:
# Goal: implement auth
# Status: in_progress
# Roaming: claude -> codex (session handed off to you)
# Handoff: designed API, need implementation
# When the work is done — archive it
0dai session completeGuarantees and limits
Roaming is intentionally simple, and being clear about its edges keeps it trustworthy.
- One active session per project. The model is a single live handoff, not a multiplexed set of parallel sessions. Parallel work is the job of swarm delegation, where each task is its own queue record.
- The save is manual. The handoff is only as good as what you write into it. An agent that finishes a slice without
session saveleaves the next agent the transcript and nothing else. The convention in the multi-agent workflow is to save before stopping and read before starting. - It carries context, not capability.Roaming moves what the next agent should know. It does not grant it tools or permissions it would not otherwise have; that is the picking CLI's responsibility.
Common patterns
A few ways roaming earns its keep in day-to-day work, drawn from how the agents are actually routed in the delegation policy:
- Design in one tool, build in another. Use a reasoning agent to settle the architecture and write the decisions down, save the session, then continue in a fast-edit agent that implements against the plan. The implementer does not re-argue the design; it reads the handoff and writes code.
- Hand a stuck task to a fresh agent. When an agent has circled the same bug twice, the cheapest next move is often a different agent with the same context. Save the session — including what was already ruled out — and let the next agent start from the dead ends rather than rediscovering them.
- Pause across days. A session saved on Friday is the same handoff on Monday. The plan, the files touched, and the open question are exactly where you left them, in a file you can read in a diff.
- Move between machines. Because the session is a committed file, the handoff travels with the repo. Pull on a second machine and the active session is there.
Questions people ask
Does roaming need a server or an account? No. Saving and reading a session are local file operations. The retrieval interface that can surface a session through MCP is optional convenience on top, not a requirement for the core handoff.
What if I forget to save? Then the next agent gets only the repository and the transcript, which is the pre-0dai default. The habit the workflow encodes is to save before stopping; that habit is the whole value.
Can two people roam the same session? There is one active session per project, so two people editing the same active handoff would be editing the same file — fine in sequence, a merge in parallel. Genuine parallel work belongs in the swarm, where each task is its own record.
Is anything sent to a model provider that would not be sent anyway?The session injects a short summary into the agent's context at startup — the same kind of context the agent would read from the repo regardless. It is reasoning and pointers, not file contents and not secrets.
How is this different from just writing notes in a file? It is a more disciplined version of exactly that. You could keep a free-form scratchpad, and many people do — but a scratchpad is not detected on startup, has no agreed shape, and tends to drift into a wall of text nobody reads. Roaming gives the handoff a small fixed structure, a known location, and automatic surfacing, so the next agent is shown the context instead of having to go looking for it. The discipline is the feature.
What happens to old sessions? They archive to ai/sessions/archive/ when you run session complete, and stay queryable through session history. Nothing is deleted on your behalf; the archive is a record of how the work actually moved, which is occasionally worth reading back when a decision needs its context reconstructed.
Next up
- Multi-agent workflow — how the handoff fits into roles, swarm delegation, and conflict resolution.
- Why 0dai — the broader case for project memory in the repository.
Related reading: Why AI agents need shared context and Config files compared across Claude, Codex, and Gemini. See what shipped on the changelog, or run a guided play such as adding OIDC auth to a Next.js app.