English · 简体中文
An append-only worklog so rotated coding agents don't lose the thread when one hits its usage limit and the next takes over. Kept in a store outside your project — your repo is never touched.
You run several coding agents against one repo — Codex, Claude, a local model — and rotate them as each hits its usage limit. An agent often gets cut off mid-edit, with no chance to explain itself. The next agent inherits an uncommitted diff with no context, commits that show what changed but not what was skipped or what came next, and — if it trusts a hand-written summary — a decent chance that summary is wrong.
Split the record in two, by what each medium is good at:
| Question | Answered by |
|---|---|
| What files changed, in which commits? | Git history |
| What was each change for? | worklog — intent.* |
| What's unfinished or uncommitted right now? | worklog — an intent.open with no intent.promote |
| Where are the hazards and shortcuts? | worklog — landmines |
| What should the next agent do? | worklog — next / plan |
handoff.start ── agent picks up: verified base commit + gate result + plan
intent.open ── before a small commit: what I intend
intent.promote ── after it lands green: what I did · landmines · next
intent.open
intent.promote
handoff.end ── best-effort on stop: end commit + gate + findings + open intents
handoff.start ── next agent: reconcile commits since the last base,
adopt any open intent, re-verify, continue
An intent.open with no matching intent.promote is the pointer the next agent
follows straight to the unfinished work in the dirty tree — even if the previous
agent vanished without writing handoff.end.
Pickup is identity-agnostic. It anchors to the last handoff, not to "your"
last commit — so when you resume after another agent (or your own limit reset)
has moved things, you reconcile their commits and carry on forward, rather than
resuming from a stale plan in your memory. ahp pickup says so when it spots a
prior turn of yours. The worklog is session continuity, not a per-agent journal:
a constraint that outlives a session belongs in the project's own docs, and
ahp log --worker <id> still shows any one agent's full trail.
The worklog is one JSON-Lines file per project, append-only, ordered by an
integer seq, living in a per-user store at
$XDG_DATA_HOME/agent-handoff/ — keyed by the project's Git identity, so it
works from any subdirectory and after a re-clone. Nothing is added to your repo.
(An in-repo .coworker/worklog.jsonl is also a valid layout — see SPEC §4.3.)
git clone https://github.com/Nonosword/agent-handoff-protocol ~/Repositories/agent-handoff-protocol
cd ~/Repositories/agent-handoff-protocol
./install.shThe installer walks through it with a step-by-step report — symlinks the
ahp / ahp-mcp CLIs onto your PATH and checks each runs, creates and probes
the store, deploys the workflow (the Claude Code skill + Codex AGENTS.md
snippet), then (arrow keys) asks whether agents should also get native ahp_*
tools:
- cli — agents run the
ahpCLI; the skill / snippet teach the sequence. - mcp (recommended) — the above, plus
ahp-mcpregistered as an MCP server with each detected host (claude mcp add/codex mcp add), so agents callahp_pickup,ahp_start, … directly. Structured arguments — no shell quoting of the free-text fields.
An agent with both prefers the MCP tools and falls back to the CLI. ./install.sh --mode cli|mcp skips the prompt · --dry-run · --no-color · --uninstall.
Requires Node ≥ 20 and Git.
From inside any Git repo:
ahp status # project, baton holder, open intents, tree/gate state
ahp pickup # guided pickup: last handoff, commits since, open intents
ahp start --plan "add rate limiting" --gate pass --evidence "188 tests pass"
ahp intent open --id i-0828-a --title "token bucket" --intended "per-IP, 429 on exhaustion"
ahp intent promote --id i-0828-a --commit 9f2e1df --gate pass \
--actual "middleware + 6 tests" --landmine "in-process only" --next "shared-cache state"
ahp end --reason limit --summary "1 of 3 commits landed" --gate pass --evidence "194 pass"The first ahp command in a repo auto-registers it. ahp fills in seq, the
timestamp, the base commit and tree state from Git — you supply the meaning.
From anywhere — every project at a glance:
ahp dashboard # baton holder + plan, worklog state, open intents, verify,
# git HEAD/tree, and a drift check (commits with no promote)
ahp dashboard -w # live view — refreshes on the alternate screen, ctrl-c to exit
ahp dashboard --jsonFour types. Full field tables in SPEC.md §5; machine contract in
schema/worklog.schema.json.
| type | when | carries |
|---|---|---|
handoff.start |
picking up the baton | base (verified commit + gate + tree), plan, continuesFrom |
intent.open |
before a commit | intentId, title, intended |
intent.promote |
after it lands green | commits, gate, actual, landmines, next |
handoff.end |
stopping (best-effort) | reason, end (commit + gate), summary, findings |
See examples/relay.jsonl for a full rotation with a
mid-session cutoff.
| Path | |
|---|---|
SPEC.md |
the normative protocol |
install.sh |
one-command deploy (--mode cli|mcp, --dry-run, --uninstall) |
bin/ahp, src/ |
the reference CLI |
bin/ahp-mcp |
the MCP server |
schema/worklog.schema.json |
JSON Schema for one record |
skills/claude-code/ |
Claude Code skill |
integrations/ |
Codex snippet, MCP config, generic prompt, git hook |
tools/verify-worklog.mjs |
standalone file validator |
examples/ |
relay-with-cutoff, solo, hard cutoff |
docs/ |
rationale & FAQ, adoption, networked server (planned) |
- …read the commit messages? They don't cover uncommitted work, deliberate non-choices, or catch an over-claimed "done". See rationale.
- …keep an editable
HANDOFF.md? No history, no blame, and two agents across a rotation clobber it. Append-only +seqfixes that. - …use timestamps for order? Three runtimes on two machines don't agree on
the clock.
seqis a monotone integer.
0.3.0 — first stable release. Record fields may still change before 1.0. Follows SemVer;
breaking changes are a major bump and land in CHANGELOG.md.
Extracted from a real project that rotates several coding agents under usage limits. The project's specifics aren't in here — what's left is the part that generalizes.
MIT © Nonosword