Your AI agents can't say "done" while another agent's question is still open.
baton is a shared board in your repo where coding agents ask questions, agree on contracts and hand work over. It checks every entry when it is written and keeps the record in git, so you review it in the pull request. One CLI, plain files, no server, any agent that runs a shell.
A real agent (Claude Code), unscripted, trimmed and captioned: refused while a question is open, it answers and hands off.
Try it in 60 seconds
With baton installed, paste this into a terminal. It replays the recording in a scratch folder:
mkdir baton-try && cd baton-try && git init -q
baton init --roles frontend,backend,qa
baton post Q --as frontend --to backend --title "Which route serves health?" "For the status page."
baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
baton reply Q-001 --as backend --close "Use GET /api/health."
baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
The first hand-off is refused (answer first: baton show Q-001, then baton reply …) and nothing is written; after the reply it goes through as H-002. Or just run baton demo for a narrated replay on a temporary board; without installing anything, uvx baton-handoff demo.
Why baton
- No half-done hand-offs. An agent can't report done while a question to it is still open.
- Decisions don't get lost. Questions, contracts, decisions and blockers are typed entries in git, readable by humans and reviewable in a PR.
- Cheap to read. Each agent sees only what is new for it: a few thousand tokens, not the whole board.
- Any agent. Claude Code, Codex, Cursor or anything that runs a shell command.
- Nothing to run. No server, no database, no dependencies.
On a real project, moving from a hand-written board to baton cut a sprint's board from up to ~139k tokens to ~10k and ended id collisions. See the evidence.
What it's for
| Use | What you get |
|---|---|
| Agents side by side on your machine | One board for every agent, even across git worktrees. |
| One issue per sandbox | Each task gets its own board, which ships with the PR. Sandbox mode |
| Your team's rules | Policies refuse or flag entries that skip what your team expects. Policies |
| CI on GitHub | Actions that run a task's board around your agent and check it on the PR: setup-baton, baton-task, baton-check on the GitHub Marketplace. How to use them |
| Keeping an eye on the work | A local dashboard and metrics: who is blocked, what is stale. Commands |
How it works
Agents run baton. Each write appends one event to a log in .baton/ under a lock, and readable views are generated from it. More on how it works.
Install
baton is on PyPI as baton-handoff and installs the baton command. It needs Python 3.11 or newer on macOS or Linux; macOS ships Python 3.9, so uv is the easiest route: it fetches a recent Python for you.
uv tool install baton-handoff
pipx install baton-handoff works too, and the getting started guide shows it, then how to set up your agents.
Documentation
- Getting started: install, try it, set up your agents, troubleshooting
- Why baton: evidence, how it compares, FAQ
- How it works: files, worktrees, stability, limits
- Sandbox mode: one board per task
- Commands: every command and flag, and the MCP tools
- Policies · Configuration · Board format
Contribute
Bugs, questions and ideas go to issues, and pull requests are welcome: see CONTRIBUTING and the code of conduct. If baton helps your agents, a star helps others find it.
Metadata
Release files for baton-handoff 1.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| baton_handoff-1.5.2.tar.gz | 75.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| baton_handoff-1.5.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 133.2 kB
Release files / baton_handoff-1.5.2.tar.gz
| Download URL | baton_handoff-1.5.2.tar.gz |
|---|---|
| Size | 75.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
03a406687581cc17004b196af987d4888d7828679b7b015a551cbcafb5a7a396
|
|
BLAKE2b-256 checksum How to use checksums |
ad18ff235524ecb6832da28e2208717d9805edea9dd169e2ac51c35bf517f1c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / baton_handoff-1.5.2-py3-none-any.whl
| Download URL | baton_handoff-1.5.2-py3-none-any.whl |
|---|---|
| Size | 58.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0f49072e24db5aa6e7117f7d6599c77eda2d127991fd7259e3fe8083fba9b26e
|
|
BLAKE2b-256 checksum How to use checksums |
cbb9393639e11ee5ef37264381ffc0757c5bacebcf0155a5ef81f1baf3feab8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for baton-handoff 1.5.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for baton_handoff-1.5.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.