Skip to main content

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

tests latest release 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.

A real coding agent, acting as backend, runs baton handoff and is refused because frontend's question Q-001 (which route serves the health check?) is unanswered; it reads the refusal, answers and closes Q-001, and the hand-off goes through as H-002 without --force. Trimmed and captioned; the agent's output is unchanged
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

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

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.2
File Size Uploaded Provenance
baton_handoff-1.5.2.tar.gz 75.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for baton-handoff 1.5.2
File Interpreter ABI Platform
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 log

Release 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 log

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

Select from 2 files

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