{"slug": "a-json-receipt-for-ai-handoffs-and-a-small-check-for-done", "title": "A JSON receipt for AI handoffs, and a small check for \"done\"", "summary": "A developer running a personal website in nine languages with ChatGPT/Codex and Claude built an open-source \"Multi-AI Handoff & Approval Card,\" an eight-field JSON receipt that travels with work between AI agents, plus a Python checker that returns DONE only when every field is filled, all evidence passed with a named non-same-run checker, rollback specifies both how and who, and no open items remain. The card assigns each task a risk tier — auto, auto-then-verify, or human-approval — so routine steps like drafting translations run automatically while publishing, deleting, spending, or touching credentials stops for a human.", "body_md": "An AI saying \"done\" is a claim. Work is complete only when something outside that AI has checked it.\n\nI run my personal website, [akiohirayama.com](https://akiohirayama.com/), in nine languages with ChatGPT/Codex and Claude. Several AIs touch the same work: one drafts, another reviews, a third checks how pages actually render. The weak point is the handoff. The next AI usually receives a summary it has to believe.\n\nThis post shows the fix I use: a small, structured receipt that travels with the work, and a check that reads it.\n\nThe [Multi-AI Handoff & Approval Card](https://github.com/akiohirayama/multi-ai-handoff-card) has eight fields. If any of them is empty, the work has only been reported. It is not done yet.\n\n```\n{\n  \"task\": \"what was asked, in one sentence\",\n  \"claimed_result\": \"what the AI says it did\",\n  \"risk_tier\": \"auto | auto-then-verify | human-approval\",\n  \"risk_reason\": \"why this tier\",\n  \"evidence\": [\n    { \"check\": \"what was checked\", \"checked_by\": \"script / fresh-context run / human (not the same AI run)\", \"result\": \"pass | fail | unclear\" }\n  ],\n  \"changed\": [\"pages, files or systems touched\"],\n  \"rollback\": { \"how\": \"how to undo it\", \"who\": \"who can undo it\" },\n  \"open_items\": [\"anything unverified, ambiguous or skipped\"],\n  \"approved_by\": \"a human, or the rule that allowed auto-approval\"\n}\n```\n\nThree fields do most of the work:\n\nNot every step needs a human. Approving everything trains people to click \"yes\" without reading.\n\n| Tier | Examples | Default | \n|---|---|---|\n| auto | Draft a translation, generate a design option | Run automatically, log it | \n| auto-then-verify | Change a live page, update shared text | Run, then verify before it counts as done | \n| human-approval | Publish, delete, spend, touch credentials, message anyone | Stop and ask a human, with a one-screen summary | \n\nA receipt is only useful if something reads it. This script returns `DONE` only when every field is filled, every piece of evidence passed and has a named checker, the rollback says both how and who, and no open items remain.\n\n``` python\nimport json\nimport sys\n\nREQUIRED = [\"task\", \"claimed_result\", \"risk_tier\", \"risk_reason\", \"evidence\",\n            \"changed\", \"rollback\", \"open_items\", \"approved_by\"]\nTIERS = {\"auto\", \"auto-then-verify\", \"human-approval\"}\n\ndef check(card):\n    problems = []\n    for key in REQUIRED:\n        if key not in card:\n            problems.append(f\"missing field: {key}\")\n    for key in [\"task\", \"claimed_result\", \"risk_reason\", \"approved_by\"]:\n        if key in card and not str(card[key]).strip():\n            problems.append(f\"empty field: {key}\")\n    if card.get(\"risk_tier\") not in TIERS:\n        problems.append(\"risk_tier must be auto, auto-then-verify or human-approval\")\n    evidence = card.get(\"evidence\") or []\n    if not evidence:\n        problems.append(\"no evidence: the work is reported, not done\")\n    for item in evidence:\n        if item.get(\"result\") != \"pass\":\n            problems.append(f\"evidence not passing: {item.get('check', '?')}\")\n        if not str(item.get(\"checked_by\", \"\")).strip():\n            problems.append(f\"evidence without a checker: {item.get('check', '?')}\")\n    rollback = card.get(\"rollback\") or {}\n    if not rollback.get(\"how\") or not rollback.get(\"who\"):\n        problems.append(\"rollback needs both how and who\")\n    if card.get(\"open_items\"):\n        problems.append(f\"{len(card['open_items'])} open item(s) still listed\")\n    return problems\n\nif __name__ == \"__main__\":\n    with open(sys.argv[1], encoding=\"utf-8\") as f:\n        card = json.load(f)\n    found = check(card)\n    for p in found:\n        print(\"-\", p)\n    print(\"DONE\" if not found else \"NOT DONE\")\n    sys.exit(0 if not found else 1)\n```\n\nHere is a card that fails:\n\n```\n{\"task\":\"Publish the article\",\"claimed_result\":\"Published\",\"risk_tier\":\"human-approval\",\"risk_reason\":\"public\",\"evidence\":[{\"check\":\"links work\",\"checked_by\":\"\",\"result\":\"unclear\"}],\"changed\":[\"note.com\"],\"rollback\":{\"how\":\"unpublish\"},\"open_items\":[\"image credits\"],\"approved_by\":\"\"}\n- empty field: approved_by\n- evidence not passing: links work\n- evidence without a checker: links work\n- rollback needs both how and who\n- 1 open item(s) still listed\nNOT DONE\n```\n\nThe exit code is non-zero, so the same check can gate a pipeline step or a handoff to the next agent.\n\nThe card, `card.json` and a longer field guide are free under CC BY 4.0:\n\nI am also hiring an AI Engineer, at a monthly salary of USD 30,000, to build this kind of control layer across multiple AIs: [role details](https://akiohirayamaaiengineer.wordpress.com/).\n\n— AKIO HIRAYAMA ([akiohirayama.com](https://akiohirayama.com/))", "url": "https://wpnews.pro/news/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done", "canonical_source": "https://dev.to/akiohirayama/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done-2fp2", "published_at": "2026-10-29 16:13:46+00:00", "updated_at": "2026-10-29 16:19:37.785955+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-safety"], "entities": ["ChatGPT", "Codex", "Claude", "Multi-AI Handoff & Approval Card", "akiohirayama.com"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done", "markdown": "https://wpnews.pro/news/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done.md", "text": "https://wpnews.pro/news/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done.txt", "jsonld": "https://wpnews.pro/news/a-json-receipt-for-ai-handoffs-and-a-small-check-for-done.jsonld"}}