Horizontal recipe · works in any domain
Agent work context: checkpoint and resume
An agent working through something long-running loses its context: the process dies, the window fills, compaction drops a constraint that mattered, or the work moves to a different model entirely. A handoff by prose summary loses whatever the summary's author didn't think to keep.
This recipe makes work state a typed record instead. The agent checkpoints what it is doing, what is done, what is next, and what it decided and why, as immutable records under one root that represents the piece of work. A fresh process finds the current state in one query, reads the head checkpoint's resume instructions, does the next pending item, and writes its own checkpoint superseding the old head. The schema refuses a checkpoint that doesn't declare what it replaces, so a confused resumer gets a hard 400 instead of silently forking the history.
It is a tested reference scaffold, not a turnkey product: one contract type, a convention set, and a walkthrough proven against a live server. The work content, field depth, and key policy you wire around it are yours.
The shape
One root record represents the work. Every checkpoint is a child of that root via parentRecordId: siblings, never chained checkpoint-to-checkpoint. The head is simply the newest checkpoint, one call:
GET /v1/records/search?parentRecordId=<root>&type=work-context-v1 # newest first; data[0] is the head
The root carries a navigation hint in its criteria telling any reader where the state lives and how to find the head, so a cold-start agent that reads the root first (most do) is steered to the current state before it touches anything else.
Writing a checkpoint is one record create. The first one declares itself initial; every later one names the checkpoint it supersedes:
POST /v1/records
{
"type": "work-context-v1",
"parentRecordId": "<root>",
"criteria": {
"objective": "Consolidate the Q3 vendor data into the reporting store",
"summary": "Schema mapped and validated; two source feeds loaded.",
"checkpointReason": "context-limit",
"supersedesRecordId": "<previous head>",
"completedWork": [
"Loaded feeds A and B; row counts notarized in record <record id>"
],
"pendingWork": ["Load feed C", "Run the reconciliation report"],
"resumeInstructions": "Read decisions before loading feed C; it needs the datetime cast agreed there."
}
}A checkpoint is typed, not a summary
The contract type gives the state a shape a resuming agent can rely on: objective and summary for the zero-context reader, completedWork and pendingWork (ordered, first entry is what to do next), decisions with rationale and who rendered them, assumptions, constraints, openQuestions, and resumeInstructions. What a prose handoff keeps is up to whoever wrote it; what a typed checkpoint keeps is declared.
Two guards live in the schema itself. A non-initial checkpoint without supersedesRecordId is refused with a 400, so a resumer that misidentified the head cannot silently fork the chain with a stale write. And a final checkpoint must have empty pendingWork: the work cannot be declared done while items remain.
Checkpoints are snapshots, not appended logs. Superseded checkpoints stay on the ledger forever, so the head keeps only the recent working set and the supersedes chain is the archive of how the work actually progressed. A useful working checkpoint is 2 to 4KB; an instructed model compacts an oversized head into a small successor naturally.
Seats and occupants
A registered agent is a persistent seat. The processes that occupy it, across models, harnesses, and runs, are ephemeral occupants. Resume means a new occupant presents the seat's existing key. For a handoff you want on the record, mint an additional key bound to the same seat for the successor process: attribution in each record carries both the seat and the specific key, so the succession is visible in the chain and each successor's key is independently revocable. Under live probes, a key bound to a different seat could neither read nor continue the work.
What the cold runs showed
The recipe was exercised with fresh model contexts across four model families (Gemini, GPT, Claude, and their small variants), each given nothing but a base URL, a seat key, a root id, and a type name, against a live server. The run counts are small, so read this as trace evidence rather than rates: the strongest performer completed the full resume protocol in every run, including reading an oversized head and writing a compacted successor around a tenth its size.
The finding that holds across every failed run: the schema guard kept the lineage clean. No model ever forked the chain or landed a successor on a stale head, because the write that would have done so was refused.
One failure mode survives the guard, and it shaped a convention. A small model wrote a checkpoint that correctly superseded the head while claiming work that never happened; its own request trace shows no such call. A signed checkpoint is attributed, not fact-checked. The convention: when a pending item creates a record, the successor checkpoint carries the created record id, which turns “I did it” into a claim checkable against the chain.
Scale, as far as it was exercised: at 150 checkpoints under one root, the head is still one call and the full lineage check walks every page in tens of milliseconds against a local server. Months-long work items with thousands of checkpoints remain unexercised.
Forks, and the check that finds them
Two occupants resuming the same seat concurrently can both read the same head and both write successors that supersede it. Both land, both are genuinely signed, and the head query silently returns whichever got the later timestamp: a fork, not tamper. The server notarizes what it is told; lineage coherence is the client's job by design.
The recipe ships the tool for that job: a lineage checker that, given a root, proves exactly one initial checkpoint, every supersedes reference resolving under the root, no checkpoint superseded twice, a single chain covering everything, and a terminus that matches the head query. Run it at every resume if concurrent occupancy is possible in your deployment. Recover from a fork by writing a checkpoint that supersedes the branch you keep and records the merge; never try to un-write the other branch.
Working with A2A
The checkpoint spine is REST today. The pattern that works for an A2A fleet is hybrid: agents coordinate over A2A, and whichever occupant holds the seat reads and writes checkpoints over REST with the seat's key. Carry the work-context root id in A2A task metadata so the fleet can find the ledger tree, and record A2A task ids in checkpoint references so the A2A side of a handoff is checkable from the chain. The schema guards are dialect-independent: a stale write sent over A2A is refused the same way.
What you get without asking
Every checkpoint is an ordinary AGLedger record, so it is signed, attributed, hash-chained, and verifiable offline like everything else on the ledger. You adopt the recipe for resume and handoff; what accumulates is a tamper-evident archive of how the work progressed, with a succession between two processes provable from the exported bytes alone. Nothing to migrate when an operator wants oversight or an auditor wants proof: it is the same record.
Limits
- Same-seat resume and succession only. Continuation across seats is deliberately refused: the seat boundary is the point.
- Checkpoint claims are checkable, not checked. The ledger proves who wrote what and when; whether a claim is true is established against the records it cites.
- Lineage coherence is client-side by design, and the lineage checker needs the server for the head query; a fully offline auditor walks the exported checkpoint contents themselves.
- Nothing steers an agent that ignores both the root hint and the schema description; the cold-run traces include such runs.
The files
The recipe is plain files: the contract type, a registration script, the lineage checker, and a ten-step walkthrough that proves the spine end to end against your own server, offline verification included. It is distributed through the recipes catalogue alongside the industry recipes; the install guide covers registering one against your Server in one command.
For the measured background, the blog post Durable Intent, Measured wiped four agents mid-task and asked them to finish their own work.