Skip to main content

baton: hand-offs for AI agents that build software together

tests PyPI license Python 3.11+ dependencies: none

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.

Try it in one command: uvx baton-handoff demo

Two real coding agents from different vendors share one baton board. Codex, as frontend, asks backend which route serves the health check (Q-001). Claude Code, as backend, runs baton handoff and is refused because Q-001 is unanswered; it reads the question, answers and closes it, and the hand-off goes through as H-002 without --force. A live board along the bottom shows each entry as it is written. Captioned; the agents' output is unchanged
Two real agents, unscripted: Codex asks, Claude Code is refused until it answers, and the live board records it all.

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

How baton works, as a conversation where every message is a typed entry in an append-only log: frontend asks backend which route serves the health check (Q-001); backend's hand-off to qa is refused and nothing is appended, because Q-001 is unanswered; backend answers, and the hand-off goes through as H-002, so qa takes over

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

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.

CHANGELOG · SECURITY · LICENSE (MIT)

Metadata

Release files for baton-handoff 1.5.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for baton-handoff 1.5.4
File Size Uploaded Provenance
baton_handoff-1.5.4.tar.gz 75.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for baton-handoff 1.5.4
File Interpreter ABI Platform
baton_handoff-1.5.4-py3-none-any.whl Python 3 none any Details

Total release size: 133.4 kB

Release files / baton_handoff-1.5.4.tar.gz

Download URL baton_handoff-1.5.4.tar.gz
Size 75.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0880f5a1dff3a31f1078f0ede5c07cedc720774cdea8dbf9011a706040f7df2e
BLAKE2b-256 checksum
How to use checksums
7141138ddf61cd37d488021de31ce603811770d97803bd350048c22808e6e487
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 log

Release files / baton_handoff-1.5.4-py3-none-any.whl

Download URL baton_handoff-1.5.4-py3-none-any.whl
Size 58.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c46660fdf885dd7f09bc3e07f013fae3fa7903c4de0a0a1124e8220021872b23
BLAKE2b-256 checksum
How to use checksums
979e7d50393329051bd3e19813e432cba83aa3677c548c00df14019b51e26c98
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 log

Security for baton-handoff 1.5.4

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.

Select from 2 files

Attestation for baton_handoff-1.5.4.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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page