Which agent for which job, and the handoff you still do by hand
One session id resumed in the tool that made it and was a stranger in the other five. How to route work between agents, and what you still carry across by hand.
One session id, six tools, five strangers
We created a Claude Code session with a decision and its rationale, picking staging-7 because staging-3 is pinned to an old runtime, and ran it with a UUID on Haiku using --session-id.
claude -p "We picked staging-7 as the deploy target for this repo, because staging-3 is pinned to \
an old runtime. Acknowledge in one short sentence." \
--session-id 7c9e6a1b-4f2d-4a3e-9b81-0d5c2f8e1a70 --model haikuIf we were to go back to Claude Code and resume that UUID, it'd still say it's set to staging-7 for that reason.
$ claude --resume 7c9e6a1b-4f2d-4a3e-9b81-0d5c2f8e1a70 \
-p "Which deploy target did we pick, and why? One sentence." --model haiku
Staging-7 is the deploy target because staging-3 is pinned to an old runtime.We gave the same UUID to all of the other agents:
| Harness | Command | Exit | What came back |
|---|---|---|---|
| Codex 0.146.0 | codex exec resume <id> | 1 | no rollout for this thread ID (code -32600) |
| Copilot CLI 1.0.78 | copilot --resume=<id> | 1 | no names, sessions or tasks found |
| cursor-agent 2026.07.23 | agent --resume <id> | 1 | asking for workspace trust, it never even inspected the id |
| Antigravity 1.1.10 | agy --conversation <id> | 0 | an empty conversation, with a message that no deployment target is set yet |
| Kimi Code 0.31.1 | kimi -S <id> | 1 | session not found |
So, four of them exited with 1, three saying they don't know about it (in different ways) and one prompting to set up workspace trust before the id was even seen, and one exited with 0 but started a new conversation. We also tried a zero UUID — the most well-formed UUID there is — in Claude Code and it exited with 1, saying it can't find a session, so Antigravity seems to be the only one here that creates a new conversation for an id it doesn't know. But ofc, this is not a bug, as every agent has its own store of conversations and nobody has agreed on a format for reading somebody else's.
Six private databases
| Harness | Where the session lives |
|---|---|
| Claude Code | ~/.claude/projects, with per-project JSONL files keyed by session UUID |
| Codex | per-day folders under ~/.codex/sessions, plus an SQLite state file |
| Copilot CLI | a single SQLite file, ~/.copilot/session-store.db |
| cursor-agent | hashed directories under ~/.cursor/chats |
| Antigravity | one SQLite file per conversation under ~/.gemini/antigravity-cli/conversations |
| Kimi Code | per-workspace hashed directories under ~/.kimi-code/sessions, plus a session_index.jsonl |
So, 3 technologies behind the scenes and 6 different ways of organising things, no common schema. The only thing that two of them actually export is a transcript: Copilot with --share (to Markdown) and Kimi with its export command (to ZIP), both for humans to read rather than for another agent to ingest. So it seems that we can't get the session to move but can make a lot of other things portable.
What crosses the gap, ranked
There are a few layers of this:
The most trivial one is the instructions file, which is the cheapest thing to align —
AGENTS.mdis where the field converged; agents.md calls it "a README for agents", says it's "used by over 60k open-source projects" and that it's "now stewarded by the Agentic AI Foundation under the Linux Foundation"The adoption part: Codex, Copilot and Cursor say (in docs or help output) that they use AGENTS.md. During the later experiment Kimi even mentioned the filename on its own
There's a little exception with Claude Code; we can make it also read AGENTS.md by creating a
CLAUDE.mdsymlink in the root, pointing to it:BASHln -s AGENTS.md CLAUDE.mdthis is what the Claude Code docs say: "Claude Code reads
CLAUDE.md, notAGENTS.md. If your repository already usesAGENTS.mdfor other coding agents, create aCLAUDE.mdthat imports it so both tools read the same instructions without duplicating them." The import is@AGENTS.mdas the first line, so it can be easily extended with Claude-specific things laterThe only caveat here is that Windows needs either Administrator or Developer Mode for symlinks, so if you're on Windows consider importing it instead of symlinking
The second layer are skills — these are fairly portable, and there's more to them than the reference table suggests; we created three skills (one per directory convention) in one repo and asked Copilot what it sees:
TEXT$ copilot skill list Project skills: from-github-dir - Marker skill placed in .github/skills to see who discovers it. from-agents-dir - Marker skill placed in .agents/skills to see who discovers it. from-claude-dir - Marker skill placed in .claude/skills to see who discovers it.It showed us all of them. Their help says that Copilot looks for project skills in .github/skills, .agents/skills or .claude/skills, and personal ones in
~/.copilot/skillsor~/.agents/skills, so it's very likely that a SKILL.md you created for another tool is already in use by yours, so before creating a new one checkThe third layer is MCP — this is what standardises the workflow the most; as per the reference table, all 6 support it
But when it comes to registration there are two groups: four of them have an
mcpsubcommand on the CLI (Claude Code, Codex, Copilot and cursor-agent), while we couldn't find one in Kimi's or Antigravity's help (at least for the versions we were using) so we assume they require configuration filesThere's a partial convergence in terms of location: .mcp.json is mentioned in Claude Code's and Copilot's help, Copilot also supports .github/mcp.json and Cursor expects .cursor/mcp.json — same servers, different locations
The last layer are hooks; they're not portable at all, as all 6 have an entry but describe completely different mechanisms. Only two of them even mention hooks in their --help, and each in its own terms rather than a shared format, so either you create hooks for each of them or don't use them, and if your team uses multiple agents then enforcing things by hook is an individual thing, never a repo-wide one
The protocol that got standardised isn't this one
A standardised protocol is needed for something else — there's the Agent Client Protocol (ACP), created by Zed, and their docs compare it to LSP standardising language server integration. It standardises the editor-to-agent part of the connection, and for 2 of the 6 agents we were using there's an ACP server on the CLI (Copilot with a flag and Kimi with a subcommand). There are dozens of ACP agents listed on Zed's website, including Claude Agent, Codex CLI, Cursor, Gemini CLI, GitHub Copilot and Kimi CLI. But as we said, ACP standardises the IDE-to-agent connection, MCP standardises the agent-to-tool connection, neither of them connects agents to each other. So using a standardised protocol doesn't mean that you can open your colleague's morning Codex session in Claude Code, they both just have a standardised way of talking to their tools.
Route by the surface, not by the model
Given that, it'd make more sense to choose based on UI. For example, you can't decide which tool to use by looking at benchmarks; all 6 of them take --model (Claude Code, Codex, Copilot, cursor-agent, Antigravity, Kimi Code), and two of them even list the available models — it's about the flag, not the tool. Differences are on the surface, and that's where they should be addressed:
| The job | What decides it |
|---|---|
| Unattended CI runs | probably the most common scenario; in that department the default posture is different between codex and cursor-agent — codex tells you in its startup banner that it's a read-only sandbox and never asks for approval, while in cursor-agent's print-mode help there's info about being able to access everything (including write permissions and shell) |
| GitHub-related stuff | using some tools is probably already authorised for your organisation, as Copilot comes with an embedded GitHub MCP server, so if you're on GitHub it's very likely that the company already has a seat for it |
| Creating PRs | some of them can create pull requests asynchronously for you, others require your presence |
| Long runs | you might want to run things in the background and get the terminal back; for that there's claude --bg which you can pair with claude agents, or some cloud runner |
| Multiple agents working on the same file | here, what matters is worktree isolation, both claude and cursor-agent support it as a flag |
| Using the output in a script | if you need to consume the output of an agent in a downstream script, it's good to control its shape; for that both claude and agy have --json-schema to enforce a certain structure on their output |
| Sharing the outcome with someone who wasn't there | here, you need an export — Copilot creates a Markdown file with --share or a secret gist with --share-gist, Kimi creates a ZIP |
Every tool change is also a new session, so you'll need to explain things again and again. Whenever you feel like splitting a task between 2 agents, stop for a moment and think — you can get a little bit better output, but you'll need to rethink everything, so it's best to pick one tool and do the entire thing there.
The handoff you still do by hand
But even then, the handoff is still manual; you can't give your session to a colleague, so they need three things:
Your reasoning, not just the decision — what was wrong with the two options you rejected
The very options that you decided were bad, as they could have seemed like good ideas
And your previous attempts — the half an hour nobody should spend
Experiment A: We created a Claude Code session with the above decision, and committed the decision — the fact, not the reason — to AGENTS.md. Then, we started a new session in Kimi Code and asked it where to deploy:
$ kimi -p "What is the deploy target for this repo, and why was that one chosen? \
Answer in two short sentences."
The deploy target is **staging-7**, as declared in `AGENTS.md`. That's the only mention in the
repo — no reason for the choice is documented anywhere, so I can't say why it was chosen.It responded with staging-7 (because of AGENTS.md), saying that it was the only occurrence of this information.
Experiment B: We created a note in the repo, and linked to it from AGENTS.md with a single line. Then, we asked another agent (same tool and same question) — and got this:
The deploy target is `staging-7`. It was chosen because `staging-3` is pinned to an old runtime
(and can't be bumped, since its image is shared with other teams) while `staging-9` has no
database attached.So, same tool, same question — and no session resume, but the only thing that changed was a note with 4 headings and a couple of sentences each. That's cheap, and again, no tool does it automatically, and even if the standardisation goes further it won't.
So, keep this note in the repo (as it's the common read surface for all of them, the only thing changing is the filename they auto-import). And commit it with the work (rather than afterwards), as a note from tomorrow will become a summary, and summaries omit what didn't work.
Claude Code: the handoff surfaces are the PR and the background agent
There are two flags in Claude Code which are actually more like ways of passing work between people (or machines), rather than features you use during a session.
The first one is --from-pr — this allows you to either pass a number or URL of a PR and resume a session connected with it (so the session has an address that points to the PR, not some random UUID), or launch the interactive mode and choose the PR from a list (with an option of searching for a PR by typing a search term). This is useful because you can point to a PR (that's something your colleague probably knows about) rather than some UUID (which they don't).
The second one is --bg (or --background), which allows you to run a session as a background process and immediately get back control. Behind the scenes, it creates an agent in claude agents which is how you can manage it. This is useful for running long-running processes without giving up your terminal (and without using a cloud runner).
Another thing that's useful to know if you plan to use multiple agents within a single repository is the --worktree flag (or -w). It tells git to create a worktree for the session, so you can have two sessions using Claude Code in a single repository and they won't collide.
The memory file trap. Last but not least, if you're a part of a team that uses multiple tools, you should be aware of the "memory file trap". This is the worst kind of a trap. Basically, it's because Claude Code reads CLAUDE.md (not AGENTS.md), and the Claude Code docs say it plainly: "Claude Code reads CLAUDE.md, not AGENTS.md. If your repository already uses AGENTS.md for other coding agents, create a CLAUDE.md that imports it so both tools read the same instructions without duplicating them." So you can either create a symbolic link from CLAUDE.md to AGENTS.md:
ln -s AGENTS.md CLAUDE.mdor you can prepend the following line to CLAUDE.md:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.We'd recommend the import one on a team, as it leaves you a place in CLAUDE.md for the Claude-specific instructions (like "use plan mode for changes under src/billing/") which shouldn't land in everyone else's context. If you're on Windows, you'll need to be an admin or enable developer mode to create symlinks so in that case you should go with import.
The last thing we'd like to mention is that /init has already been "stealing" some best practices from other tools to include them in CLAUDE.md by default — for example:
cursor rules (from .cursor/rules or .cursorrules)
copilot rules (from .github/copilot-instructions.md)
And actually, if you set the env var CLAUDE_CODE_NEW_INIT=1 and run /init, it will also read:
AGENTS.md
.devin/rules/
.windsurf/rules or .windsurfrules
.clinerules
So if you join a repo that has been set up for another tool, instead of creating an empty CLAUDE.md from scratch, you get a more sensible starting point.
What we ran. We've also tested:
Claude Code 2.1.221 on macOS
Made a session using
--session-idand resumed it using--resumeResuming with
--resumeand a UUID of00000000-0000-4000-8000-000000000000results in exit code 1 and message "No conversation found with session ID"The flags' descriptions are from
claude --help, the memory-file thing is from the Claude Code docs (checked today, 2026-08-05)
Codex: the handoff is a diff, not a session
It's important to understand that the unit of transfer in Codex is a patch, not a chat log. Thanks to that, it's possible to move work itself in Codex, not only a record of a conversation about work.
Using the codex apply <TASK_ID> command you can pull the most recent changes from a Codex agent into your local working tree using git apply. In other words, when you use this command, the remote task lands as a regular diff in your working tree so you can review it with any tool you're used to, and so can a colleague who's never seen Codex.
codex apply <TASK_ID>If you want to explore the tasks in the Codex Cloud, you can use the experimental codex cloud command. It allows you to apply changes from the tasks in the cloud locally.
Thanks to these two commands, working with Codex feels like sending work files between each other rather than a chat log.
Another useful command for teams using multiple tools is codex mcp-server, which starts Codex as an MCP server listening on stdio. This way, you can make Codex a tool that another agent can call. It's not a session handover, so sometimes it might even make sense to combine these two approaches and create a session in which there's another session.
Sessions.
Resuming a session is possible with the
codex resumecommand, which accepts either a session UUID or its name, but by default falls back to an interactive picker. If you want to see all sessions, not only those connected with the current working directory, you can add the--allflag (in this mode, the CWD filter is disabled and an additional column called "CWD" appears in the picker)To split a branch from an existing session, you can use
codex fork. Just like with resuming, this command falls back to the interactive picker by defaultThere are more commands connected with the session's lifecycle, like
codex archive,codex deleteorcodex unarchive
The session ID doesn't need to be hunted down, as a headless invocation prints a startup banner (with the ID in it) before actually doing anything:
$ codex exec "Reply with the single word ok."
OpenAI Codex v0.146.0
--------
workdir: /private/tmp/waw-check
model: gpt-5.6-terra
provider: openai
approval: never
sandbox: read-only
reasoning effort: none
reasoning summaries: none
session id: 019fd0c8-2ef8-7912-be1e-cd06db8121ab
--------As you can see, it contains the session's ID as well as a description of the context in which the run was started (version, working directory, model, provider, approval mode, sandbox state, reasoning effort and summaries state).
The session's ID is especially valuable, as thanks to it, you can resume the session at any point. At the same time, the context is a piece of information that's always useful to have in a CI log.
The gotcha. Resuming a session is a TUI feature though, so if you try to run codex resume without a tty on stdin, it will throw an error:
$ codex resume <id>
Error: stdin is not a terminalThe headless equivalent of this command lives under the exec namespace and can be called as codex exec resume <session-id> "<prompt>":
codex exec resume <session-id> "carry on with the migration"If you decide to use the session ID from another tool, it won't work either — you'll get Error: thread/resume: thread/resume failed: no rollout found for thread id … (code -32600), which means that there's no session with such an ID in Codex's own store, and its exit status is 1, which is the proper behaviour when it comes to scripts.
What we ran. These are the commands we've actually used, except for apply and cloud as they want an existing task in the cloud:
codex resume(from a non-tty)codex exec "Reply with the single word ok."(to get the banner)codex exec resume <a session id from another tool>(to try and resume somebody else's)--helpfor: codex, exec, resume, apply, fork
Copilot: the one that exports, and the one you already pay for
Copilot is great for route decisions more often than you might think; two reasons for that:
It exports sessions as a human-readable markdown. Compared to other tools, only Kimi Code also supports it, but what's important, it exports everything as ZIP files, while Copilot allows you to copy the result and share it as a single command with a PR comment for example.
copilot -p "…" --shareFor instance, using --share-gist, it can post the session to a secret GitHub gist, or using --remote-export to GitHub web or mobile in a read-only mode (no remote control), but still, nothing of these is a file another agent can eat; but dropping that markdown into a PR comment is a handoff, done with a single command.
It has the GitHub MCP server pre-installed. It's called github-mcp-server if you check --disable-builtin-mcps. What's more, in most of the teams there's already a seat booked, so naturally, it can route any GitHub-related work.
It utilises skills defined for other tools; if your team is mixed, it's probably the most important takeaway. You can drop a marker skill into each directory convention and list it like this:
$ copilot skill list
Project skills:
from-github-dir - Marker skill placed in .github/skills to see who discovers it.
from-agents-dir - Marker skill placed in .agents/skills to see who discovers it.
from-claude-dir - Marker skill placed in .claude/skills to see who discovers it.If you have a look at the help, it says the project skills are from these 3 directories, and for your personal ones, there's either ~/.copilot/skills/ or ~/.agents/skills/ directory, so if you're using Claude Code, one of your teammate's Claude Code skill might already work in Copilot. Before creating a new skill, make sure to list them first.
It also consumes AGENTS.md and related files (see --no-custom-instructions) and workspace-level MCP config from .mcp.json or .github/mcp.json files (the former is actually in Claude Code's help as well).
Finally, it can resume sessions using session ids, task ids, id prefixes or names — the most flexible way to address a session compared to other tools. What's more, if you set your own name using --name, it's much easier to communicate than UUID; if you use an unknown id, it will exit with code 1 and list all ways you can address sessions.
What we ran. Using GitHub Copilot CLI v1.0.78 on macOS. Skill listing run in a throwaway repository with all three skill conventions. Resume with an id from another tool (exited with code 1). --share, --share-gist and --remote-export are quoted from copilot --help, we didn't exercise them.
Cursor: chat ids you can mint in advance, and a trust gate to plan around
The most distinctive feature of Cursor's CLI is that it can pre-allocate a session container before you actually run anything and enforces a certain routing thanks to a permission gate. One of the capabilities it has is a subcommand that creates an empty chat and returns its ID.
agent create-chat # "Create a new empty chat and return its ID"Thanks to this, you can easily share the ID with your teammates or include it in a ticket or a script before doing any work. The ID is also a thing that other Cursor CLI commands consume. For example, --resume accepts a chat ID, agent ls and agent resume are documented as resuming a chat session, and ls allows you to pick one while resume takes the most recent one. In terms of the competition, both Claude Code and Copilot provide ways to pin a session UUID in advance via --session-id parameter but it's the user who is responsible for generating the value there. Cursor is the only one here that pre-generates an ID and provides it out of the box without actually needing to run anything.
Another capability is the worker subcommand which starts a private cloud worker connected with Cursor that runs agents within your environment. Perfect for cases when you need to run things on your machine, not on a third party's cloud.
The last one is -w/--worktree [name] which runs a session in an isolated worktree under ~/.cursor/worktrees/<reponame>/<name>, and the --worktree-base <branch> parameter allows you to select a fork point.
The gotcha, and it's the one that decides routing. Now let's think about the problem that we're facing here. Before anything, Cursor runs a per-directory trust check — before model selection, before session ID handling etc. During this check, the following prompt is being displayed:
⚠ Workspace Trust Required
Cursor Agent can execute code and access files in this directory.
Do you trust the contents of this directory?As you can see, it says that Cursor Agent will be able to run code and access files in this directory and asks if you're sure if you trust files in this directory. When we tried to run agent --resume with an ID from another tool in a fresh temp repo, we've seen it and the process has been terminated with code 1. It was obvious that the ID wasn't examined in this scenario. That means that when you run a CI job, the directory is always new so you need to somehow get rid of this check if you want to make your pipeline automated. The prompt offers three solutions: --trust which is bound only to the directory, and -f/--force (also aliased as --yolo) which is described as allowing every command unless explicitly denied. The latter seems like a good option but it also allows everything so generally speaking you might want to go for --trust.
Also, if you look at the help, you'll notice that -p/--print is described as having every tool available, including write and shell. We assume it means that in print mode, Cursor gives you access to write and shell without asking for a permission (that's opposite to Codex which by default operates in read-only mode and displays it in its banner). That'd be very important to know if we were to choose between these tools for an automated pipeline.
This is actually not something we've observed. What we've seen is that when you run the agent with an ID inside an untrusted directory, it asks about the trust first. And as it didn't examine the ID, it must be that the trust check happens before any of the other steps.
The last thing is that MCP configuration is read from .cursor/mcp.json (or ~/.cursor/mcp.json) as part of agent mcp login.
What we ran. We've been testing this using: cursor-agent version 2026.07.23-e383d2b, macOS. Tried to pass a chat ID from another tool to --resume inside an untrusted temp repo and hit the trust gate with exit code 1. Due to that, we couldn't check if the ID was processed at all. As the directory wasn't trusted, the rest of the process wasn't run either. Print-mode tool-access part is a piece of information from the help rather than our observations. Other details from agent --help and subcommands' help.
Antigravity: check that it knows which conversation it's in
Only one of the harnesses from the comparison group silently accepts a session id from somewhere else and doesn't throw an error; for example:
$ agy --conversation 7c9e6a1b-4f2d-4a3e-9b81-0d5c2f8e1a70 \
-p "Which deploy target did we pick, and why? One sentence."The command above returns:
We have not selected a deployment target yet in our session, so please let me know which target
options or project you are referring to.We passed a session id of a Claude Code session and therefore it doesn't exist here, but instead of throwing, Antigravity started a new conversation and responded that there's no context.
Let's try it again:
$ agy --conversation 7c9e6a1b-4f2d-4a3e-9b81-0d5c2f8e1a70 \
-p "Which deploy target did we pick, and why? One sentence."And it returns a different shape of nothing (a read_file auto-denial). The exit code is 0 in both cases too; for the rest of the harnesses from the comparison group it's 1 if an id is unknown.
So it doesn't make sense to check the exit code of --conversation in scripts — if previous context matters you should assert on the output anyway.
Its own handles. Antigravity-specific flags that are connected with sessions and resuming:
--conversation— resumes a specific conversation id-c/--continue— continues the last one--project— sets "Project ID for the current CLI session"--new-project— creates a new project; which is an additional layer above conversations, not available as a session flag in any of the other tools
There's a separate SQLite file per conversation stored under ~/.gemini/antigravity-cli/conversations and there's also a conversation_summaries.db file in this directory.
Worth mentioning that it has a --json-schema flag too — "Optional JSON schema string or path to a schema file to enforce structured output (for stream-json, only applicable to the final result)". Whenever you use some tool to power another program rather than a human, it's better to standardise the output's structure there instead of parsing texts later on.
What we ran. Antigravity CLI 1.1.10, macOS, a disposable git repo under /tmp, no permission flags:
agy --conversation <an id from another tool> -p "…"Twice, exit code 0 both times. The flag descriptions are from agy --help.
Kimi Code: the export is a ZIP, and the resume flag it prints isn't the one in the help
The latest version of Kimi Code exports the current session to ZIP when using the export subcommand, if you don't provide a session ID it falls back to the latest one, also by default it includes the global diagnostic log from ~/.kimi-code/logs/kimi-code.log which is worth knowing when you attach the output to a ticket. You can exclude it with the --no-include-global-log flag. There's also a browser-based visualiser for sessions (kimi vis [session ID]) and a local web UI (kimi web).
kimi export [sessionId] -o handoff.zipThere's also kimi acp, which exposes it as an Agent Client Protocol server on stdio so ACP editors can connect to it and control the agent — that way they can drive the agent from the editor, but they don't import another person's session.
The gotcha. Looking at the resume command, we can see there's a resume instruction printed in the end-of-run message using -r and the session ID.
To resume this session: kimi -r session_ac2c5d8d-f45e-4d3e-92d0-c85025aaf3d0On the other hand, as per the help on 0.31.1 version, the tool supports only -S/--session [id] and -c/--continue
We checked that -r is indeed a valid flag (it shows an error about the session when we pass it an invalid ID, instead of saying that it doesn't know such flag) so it's best to use -S in scripts as it appears there
Sessions are stored per workspace under ~/.kimi-code/sessions/wd_<workspace>_<hash>/ and the index file is under ~/.kimi-code/session_index.jsonl. If you provide a session ID from another tool you'll get code 1 with a message saying that the session wasn't found
It reads AGENTS.md. In terms of the AGENTS.md thing, we have seen the tool refer to it without us naming the file in the prompt during our handoff test. We've noticed it mentions the deploy target but doesn't say why. And then it refers to this note:
The deploy target is `staging-7`. It was chosen because `staging-3` is pinned to an old runtime
(and can't be bumped, since its image is shared with other teams) while `staging-9` has no
database attached.This tool hasn't been involved in the original session so the entire process of using the file for handoff worked end-to-end in this tool.
What we ran. We were testing Kimi Code CLI 0.31.1 (the rewritten native binary from ~/.kimi-code/bin, with its own config directory and a migrate subcommand to migrate an older Python-based kimi-cli, which is a separate package) in two runs of kimi -p in a throwaway git repo under /tmp and in one run of kimi -S with an ID from another tool and one of kimi -r with an invalid ID. The flag descriptions were taken from kimi --help and kimi export --help
For a team where everyone drives something different
If you have a mixed team:
One instructions file — symlink or import AGENTS.md to the root and create CLAUDE.md in it pointing to it (or whatever the outlier needs), as 2 copies of the same content diverge after 2 weeks
Check before rewriting a skill — a SKILL.md you created under .claude/skills might be already used by more tools than you think
Don't standardise on a tool — standardising flags, permission models, hook schemas and people's habits is all about closing a gap that a committed file can close for free
Do standardise the seam — it's about the handoff points (branch, PR, note), these are what deserves a team agreement, as they're the only thing that will survive the next quarter's tool switch
But at the end of the day, session stores won't ever merge — there are 6 vendors, and 6 stores; and the 2 existing export formats are for humans to read, so as long as you treat the handoff as a file, not as an automated thing, it works.
docs/HANDOFF.md# Handoff — <what this is about>
<!--
The note that carries what a session can't. Commit it with the work, not the morning after.
Point at it from your instructions file with one line — AGENTS.md, and CLAUDE.md too if you
have one, since Claude Code doesn't read AGENTS.md:
See `docs/HANDOFF.md` for open decisions and what was already tried.
-->
**Where it stands.** <One or two sentences. What is true right now, not the history.>
**Why, and what we rejected.** <The reasoning. Name the options that looked right and say what
killed each one — that's the part a fresh session cannot reconstruct.>
**Already tried, don't repeat.** <The dead ends. Every hour here is an hour the next person or
the next agent doesn't spend.>
**Next.** <The concrete next step, small enough to start on.>