{
  "markdown": "# 🏃 BATON\n\n**Hand off AI work — with a receipt.**\n\nAn AI did the work. How does the next person — or the next AI — know it actually *works*, not just that the build passed? BATON seals a unit of AI work into a portable capsule, and an **independent verifier** replays it and issues a **server-signed Verification Receipt**. The receiver trusts observed evidence, not a claim.\n\n> **Never trust an agent handoff without a receipt.**\n\nBATON is a standard MCP (Model Context Protocol) server — any MCP-capable tool (Claude Code, Codex CLI, Gemini CLI, Cursor …) connects with one URL. The producer and the verifier can be **different models, machines, and people**.\n\n## Why this, and not the dozen orchestration tools?\n\nRunning Claude + Codex + Gemini together (swarms, rooms, agent messaging) is a crowded space. BATON isn't that. The one thing almost nobody does: **bind the handoff artifact to independent execution evidence as a single, forgeable-proof trust unit.** That's the receipt.\n\n```\nClaude did the work\n   ↓  baton_pass  → sealed capsule (BTN-H-…)\nCodex / a teammate receives it\n   ↓  baton_verify → replay in a clean env, observe the real flow\n   ↓\n🕸️ VERIFIED — signed receipt: who verified · what was observed · in what env · with what artifacts\n   ↓\ntrust  (or reject)\n```\n\nThe real buyer isn't \"me switching Claude→Codex\" (just re-read the repo). It's **outsourcer→in-house, leaver→joiner, KO team→US team** — where \"an AI made this, does it *really* work?\" is a question worth paying to answer.\n\n## The receipt (the differentiator)\n\n`baton_verify` doesn't return a `✅` sticker. It returns a signed record:\n\n```json\n{\n  \"kind\": \"baton.verification-receipt/v1\",\n  \"capsule\": \"BTN-H-…\",              // the handoff this verifies\n  \"verifier\": \"receiver-spider\",    // WHO verified — independent of the producer\n  \"environment\": { \"os\": \"ubuntu-24.04\", \"node\": \"24.2\" },\n  \"observed\": [{ \"claim\": \"payment succeeds\", \"observed\": true,\n                 \"detail\": \"POST /pay 200 + order row +1\" }],\n  \"artifacts\": [\"playwright.trace.zip\", \"network.har\"],\n  \"verdict\": \"verified\",\n  \"signature\": \"…hmac-sha256…\"       // server-signed → tamper the verdict, break the sig\n}\n```\n\nFlip `verdict` to `\"verified\"` without re-signing and the badge is refused. A passing build never earns `verified` on its own — only **observed** E2E does (this is what catches a silent upsert that returns 200 but writes nothing).\n\n## Tools\n\n| Group | Tools | What it does |\n|---|---|---|\n| **Handoff** | `baton_pass` `baton_receive` `baton_diff` `baton_revoke` | Seal a work capsule into a code (`BTN-H-…`), hand it over, diff versions. Body encrypted with a code-derived key — the server never sees plaintext |\n| **Verify** | `baton_verify` `baton_verify_plan` `baton_consolidate` + `spider_*` ×6 | Independent verifier replays and issues the signed receipt (no observation, no 🕸️); `consolidate` gathers many handoffs into one result board by trust tier |\n| **Team rooms** *(supporting)* | `baton_create_room` `baton_new_invite` `baton_join` `baton_send` `baton_inbox` `baton_who` `baton_leave` `baton_kick` `baton_approve` `baton_close_room` | A persistent room the owner manages; people enter via rotating **invite codes** (`BTN-R-…`, 72h, re-issuable). Owner can kick, approve (optional gate), close. After join, activity is keyed by `member_id` |\n| **Operations** | `baton_task_*` `baton_git_*` `baton_cost_*` | Cycle-safe private task DAG, Git commit/diff/test evidence binding, and idempotent provider/model/task cost ledger |\n\nOperations dashboard: `/ops.html`. It stores only task metadata, Git evidence, and cost facts; BATON never asks for repository credentials.\n\nNetwork dashboard: `/network.html`. Shared Memory encrypts bodies under the account key and searches metadata only. MCP Hub rejects credential-bearing URLs. Marketplace reputation accepts only independent, server-signed VERIFIED receipts.\n\n모든 공개 화면은 한국어를 기본으로 제공하며 `/dash.html`(협업방), `/board.html`(검증 결과), `/ops.html`(작업·Git·비용), `/network.html`(기억·MCP·에이전트)을 상호 연결한다.\n\n## Design principles (from the security review)\n\n- **Code-derived encryption.** The server stores only `ciphertext + code_hash`. Without the code, even the operator can't read the plaintext — the proof of \"we can't lock you in.\"\n- **Signed receipts.** Verdicts are HMAC-signed server-side (`BATON_RECEIPT_SECRET`); no client can forge `verified`.\n- **Prompt-injection containment.** Inbound capsules/messages are returned fenced as *untrusted data*; secrets are auto-masked before storage.\n- **Codes are ≥128-bit secrets**, one-time codes redeem atomically, alias-spoofing blocked.\n- **A passing build ≠ working behavior.** `verified` requires observed side effects, never static analysis alone.\n\n## Run\n\n```bash\nnpm install\nnpm test                                      # 15/15 E2E groups pass\nnode src/server.js                            # stdio (local / any CLI)\nBATON_HTTP=1 PORT=8080 node src/server.js      # remote Streamable HTTP\n```\n\n### Register (remote)\n```bash\nclaude mcp add --transport http baton https://baton-mcp-production.up.railway.app/mcp\n```\n\nBilling/gating is **off by default** (dogfooding phase). Set `BATON_BILLING=on` to re-enable quotas. See **[USAGE.md](USAGE.md)** for the full guide.\n\n## Storage\nMVP uses SQLite (`better-sqlite3`) — self-host single binary. The hosted service drops a Postgres adapter into the narrow interface in `src/store.js`.\n\n## License\nMIT\n",
  "bytes": 5431,
  "sha": "128a115e438ce4aaf1c9877adfaa7c2aabfea6bd797b066c3fe796f5311b7953",
  "repo_slug": "vinsenzo83/baton",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_vinsenzo83_baton_5a078300/readme"
}