Inspiration
Every agent protocol today assumes both ends are alive. A2A moves tasks over HTTP between running agents; MCP connects an agent to tools. Neither answers the question that actually stops work:
The agent that was doing this is gone. The machine is different. The person is different. What has to travel with the task so the next agent can pick it up — without being lied to?
When a long-running agent crashes, a laptop is closed, or the model is switched, the default answer is "restart from zero" — because the state lived in a chat transcript that was never meant to be state. Task Passport makes "agents shouldn't restart from zero" a property of the file format, not a promise in a README.
What it does
Task Passport keeps the durable state of a long-running task — versioned, locked, stored outside any single harness. A TaskPack is that state sealed into a single portable file that travels through whatever channels people actually use for handoffs: chat, email, a USB stick, a git commit.
- Agent A works on a task. The laptop shuts down / the agent crashes / the model switches.
- A TaskPack is packed: goals, current state, verified facts, decision rationale, next steps, open asks, luggage.
- Agent B — Gemini, Claude, Codex, any harness — lands the pack and continues the task. Not from zero. From the verified state.
It ships as one npm package with an MCP server, so Claude Code, Codex and DeepSeek Harness all read and write the same passport through the same seven tools: list / open / new / checkpoint / pack / land / conformance.
How we built it
Pure Node.js, zero runtime dependencies, one npm package, 78 tests (every regression mutation-verified). One model, two encodings: .taskpack (BagIt 1.0 + ZIP with sha256 manifests) and .taskpack.json (flat, zero-install, opens in any editor) — both MUST round-trip byte-for-byte (conformance check C9). A conformance command judges any file against 10 checks with exit code 0/2. The local store uses cross-process file locks, atomic same-directory replacement and expected_version conflict detection, so two terminals can't silently overwrite each other's checkpoint.
Challenges we ran into
The one non-obvious rule: a verified fact does not stay verified when it crosses a machine. "The build passes", "the port is free" — true on the sender's machine, shipped as verified: true they make the receiving model act confidently on something false. So machine-scoped facts are sealed as unproven at pack time — pack time, not landing time, because a safety property that depends on the receiver running the right code is not a property of the format. The degradation happens on the sender's side, in the file itself.
A real first handoff taught us the second rule: the receiving AI refused to execute the handoff instructions inside the file. That was correct behavior — the protocol must live in a world where every byte in a package is data, not commands.
Accomplishments that we're proud of
- Tested across two macOS machines and one Windows Server: conformance 10/10, attachments byte-identical, sealing rules enforced in both directions.
- Published via npm Trusted Publishing (OIDC) with SLSA provenance — the artifact you install carries GitHub's signed attestation.
- A sending-end ledger (
outbox): every pack appends a JSONL record plus a snapshot stub of the passport as it actually shipped — because a shipped package can't be un-shipped, the record lives at the sending end. - Receipts merge back into the original passport (
land --into): the answer lands on the passport that asked, not a new one.
What we learned
- CI green ≠ published. The only authority for "what can users install" is the registry itself.
- State belongs in a file, not in a chat transcript. A passport outlives the harness that wrote it.
- Handoffs fail at the trust boundary, not the transport boundary.
What's next
Cross-machine scope persistence (facts remember which machine verified them), signatures for adversarial handoff (tender/bounty scenarios where a bidder could rewrite acceptance criteria), and a Project Passport that pins a repo revision alongside task state.
Built With
- a2a
- bagit
- claude-code
- cli
- codex
- deepseek-harness
- github-actions
- javascript
- mcp
- node.js
- npm
- zip
Log in or sign up for Devpost to join the conversation.