Switch agents without losing the project
Most people now use more than one coding agent, and every switch costs you the context you built up in the last one. That cost is not inevitable. It comes from where the context is stored.

Nobody uses one agent any more
A year ago picking a coding agent was a decision you made once. Now it is a decision you make several times a day, usually without noticing:
- You plan in one tool because its reasoning is better, then build in another because it is faster and cheaper for mechanical work.
- You hit a usage limit at 3pm and finish the afternoon somewhere else.
- You use whatever is in the editor for small edits and whatever is in the terminal for anything that spans files.
- A teammate uses something different from you entirely, on the same repository.
Every one of those transitions is a context reset. You re-explain the architecture. You re-explain the constraint you discovered yesterday. You re-explain why the obvious approach does not work here. The second agent starts from the same blank slate the first one did, and quite often it proposes the thing you already ruled out, because from where it sits that idea has never been tried.
Why per-tool memory cannot fix this
Every major harness now has some form of memory, and each one is reasonable in isolation. The problem is structural rather than a quality issue with any of them.
A tool's memory is scoped to the tool. It is written in that tool's format, stored wherever that tool stores things, and read by that tool only. Which means the better each vendor's memory gets, the more you lose at every switch. The feature that helps you within a session is the same feature that punishes you for leaving.
Memory owned by the agent is memory you lose when you change agents. Memory owned by the project is memory you keep.
There is a second problem that shows up on teams. Per-tool memory is also per-person. Your agent learned something about the deploy process on Tuesday. Your colleague's agent, on the same repository, has no idea. Two people, two agents, two divergent pictures of one project, and no mechanism by which either would ever discover the other exists.
Put the record under the project instead
The alternative is not complicated to describe. Decisions, tasks, and lessons live in a record attached to the project rather than to any agent. Every agent reads from it and writes to it. Nothing about the record cares which one is connected at the moment.
What that buys is that the handoff stops being a handoff. There is no export step, no summary to paste, no context to rebuild, because the context was never in the agent in the first place.
That is a different agent, in a different terminal, possibly on a different machine, and it opens knowing what is happening. Including that something else is already holding the rate limiter work, which is the part that stops the two of them colliding.
Claiming is the part that makes it multi-agent
Shared notes are useful. Shared notes are not enough to run two agents at once, and the gap is small but absolute.
Two agents reading the same record will both see the same open work and both conclude it needs doing. Notes cannot prevent that, because a note cannot be held. What prevents it is that starting work means claiming it, the claim is atomic in the database, and the second agent to try is told no rather than told nothing:
claim TASK-418
→ refused: already claimed by "codex" 40m ago
worktree ~/code/acme-api · host mba-serkan
released automatically if that session ends without completing
open work nearby:
TASK-421 Backfill needs a dry-run flag
TASK-430 Token refresh drops the retry budgetThe refusal carries who, where, and since when, because an agent that only learns no will try again. An agent that learns another session on another machine has been on this for forty minutes will go and do something else, which is the behaviour you wanted.
The stale-claim case has to work too, or the mechanism becomes a liability the first time a session dies mid-task. A claim held by a session that ended is releasable, so a crashed agent does not leave work locked behind it forever.
Ten harnesses, three different extension models
The part of this that took the most work is the least glamorous. "Works with every agent" sounds like one integration. It is ten, and they do not share a shape.
Stele ships adaptors for Claude Code, Cline, Codex, Copilot, Cursor, Devin, Gemini, Grok, Kimi, and OpenCode. Underneath, they divide into roughly three capability tiers, and being straight about the differences matters more than claiming parity.
- Tool access. Every one of them speaks a tool protocol, so reading and writing the record works everywhere. This is the floor, and it is the same everywhere.
- Lifecycle hooks. Some harnesses let code run at defined moments: before a prompt reaches the model, when a session starts, when the context is about to be compacted. Where those exist, relevant context arrives automatically and nobody has to ask for it. Where they do not, the agent has to reach for the record itself, which works but depends on it choosing to.
- Enforcement. This is the sharpest difference. A read-only search helper, for instance, is genuinely read-only in some harnesses because the harness can restrict which tools it is allowed to touch. In others the same restriction is instruction-only: the helper is told not to write, and complies, but nothing physically stops it.
"Read-only" that is enforced and "read-only" that is requested are different guarantees, and a table with a tick in both columns would be lying about the second one. The behaviour is the same in normal use. The failure modes are not, and you should know which kind you have.
What the split day actually looks like
The abstract version of this is unconvincing, so here is the concrete one. A day where the work crosses three tools and nothing is re-explained.
Morning, planning agent. You talk through a change to how sessions are stored. The agent pulls up the original decision and the reason behind it, you argue with it, and you land somewhere new. What gets written is the new decision, the reason it replaced the old one, and three tasks with enough detail that someone who was not in the conversation could pick them up. The old decision is retired, not deleted, so the argument does not have to happen again in November.
Afternoon, terminal agent. Different tool, different model, no memory of the morning. It opens, sees three open tasks with written intent, claims the first, and starts. The decision from this morning arrives as context because the task links to it. Halfway through it discovers that the migration has to run before the deploy or live sessions drop. That becomes a risk bound to the deploy task, which means it retires itself when that task closes rather than haunting the record forever.
Evening, editor agent, different person. A colleague picks up the second task. They get the decision, the risk their teammate found four hours ago, and the fact that the first task is already claimed and in progress on someone else's machine. They do not ask anybody anything.
Nothing in that day required an export, a summary, or a handoff message. Three agents, two people, one record, and the only thing that moved between them was a project identifier.
Stable identifiers are what make it portable
A detail that seems cosmetic and turns out to be load-bearing: every node in the record has a short, human-readable identifier. TASK-418, KNOW-7, and so on. Not a UUID.
The reason is that these identifiers are the shared vocabulary across every surface. You can say TASK-418 to an agent in a terminal, paste it into a message to a colleague, type it into the web UI, or mention it to a planning tool that has never touched your code, and all of them resolve it to the same thing.
Agent-facing responses deliberately never contain raw UUIDs or internal identifiers. It is a hard boundary rather than a formatting preference: the moment an agent sees an internal identifier, it will helpfully repeat it back to you, and you have a string in your conversation that nothing else on any surface can resolve.
What does not carry over
Two limits, because the pitch above is cleaner than reality.
Your existing per-tool memory does not migrate itself. Whatever your current agent has accumulated in its own store stays there. Some vendors expose it, most do not, and we are not going to promise an import for formats we do not control. Practically, the record fills from the work you do after you set it up, plus a backfill pass over the repository and its history if you want a running start.
Continuity is not a transcript. What carries across a switch is the durable stuff: decisions, lessons, risks, what is in flight, what was tried. The texture of the conversation you had with the previous agent does not carry, and should not. If your workflow depends on the second agent knowing exactly how you phrased something an hour ago, this does not replace that.
What it does replace is re-explaining your architecture for the fourth time this week, and the specific irritation of watching a fresh agent confidently propose the thing you spent Tuesday ruling out.