All posts

Thinking out loud · A2S

What an agent tells its future self

Some of the hardest agent bugs don't live inside a step. They live in the seams between runs — and we barely design that handoff on purpose.

time → Run #14 awake · working the seam (asleep) handoff → Run #15 same agent · later
One agent, two runs, a nap in between. A2S is the question of what crosses that gap.

If you've shipped an agent that runs longer than a single request, you start to notice a strange failure pattern. The model calls the tool fine. The tool returns fine. The reasoning, in isolation, looks fine. Then the agent stops, comes back later, and somehow loses the thread of what it was doing.

That's the seam I'm interested in: not the cognition, but the handoff. The model didn't get dumber overnight; it woke up without the one fact, cursor, failed attempt, or next instruction it needed, and then confidently did the wrong thing. A lot of the hardest production failures I keep seeing cluster around that resume boundary.

That's the idea I'm poking at with Agent-to-Self — A2S. Not a standard. Not a protocol. Just a design question: when this agent wakes up tomorrow, what does it need to tell its future self? (Different problem from agent-to-agent coordination, which is agents talking to each other across space. This is one agent talking to itself across time.)

The reframe

A2S is a design question, not a protocol

The thing you actually ship is a background agent, a workflow, a durable object, a queue worker, a scheduled job — whatever fits your stack. A2S can sit on top of durable-execution tooling; it is the LLM-facing contract that lets the next run continue with intent instead of archeology.

A2S is not a new memory system. Temporary memory lives inside one run; checkpoints, logs, and RAG store different kinds of evidence. A2S is the small model-facing handoff that tells the next run what matters now.

It also gives failure somewhere to live: "I crashed, here's what my next self should do about it" becomes state, not an exception you forgot to read.

The core idea

What's in the handoff: three jobs of memory

Here's the part I'm most convinced about. When people say a long-running agent "needs memory," they're often mixing storage with presentation. The storage can be whatever you want; the A2S question is what you surface back to the LLM at wake-up. And that wake-up context usually has three different jobs hiding inside it.

State
The next action and the variables that action depends on. Must be authoritative, exact, structured, lossless.
Breaks if: it's fuzzy or re-summarized.
History
What already happened. A lossy recap derived from logs. Gives the model a sense of momentum.
Breaks if: you confuse recap with the source of truth.
Knowledge
Facts about the world and the task domain. Semantic, retrievable, tolerant of fuzziness.
Breaks if: you treat it as control flow.

State is "the next thing to do, and the data I need to do it." It has to be exact. If the next directive is resume upload at chunk 7, there is no acceptable fuzzy version of "7." This wants to be canonical structured data, written programmatically, carried across the gap unchanged.

History is "what I've been doing." In the system, you may keep a lossless execution log. In the prompt, the agent usually needs a lossy model-friendly recap: a few sentences that explain momentum without replaying every event. The recap is useful, but it should not become the source of truth.

Knowledge is "facts about the world that aren't specific to this run" — the API quirks, the domain rules, the stuff you'd look up. This is the job a vector database is genuinely good at. Semantic retrieval, fuzziness tolerated, no exact cursor required.

Now the punchline. One classic failure mode is using one tool — usually a vector DB — for all three. People dump state into RAG and then act shocked when the agent occasionally retrieves "resume at chunk 7" as "resume at chunk 2." Retrieval isn't broken; it is fuzzy by design, which is usually the wrong property for control flow. RAG is risky as state and useful as knowledge. Once you split the three jobs, the small hybrid design starts to feel obvious.

The artifact

A minimum viable A2S handoff

If the three-jobs split is right, it should show up in the smallest implementation shape. To me, the minimum loop is almost boring: wake up, load the last checkpoint, do bounded work, write the next checkpoint, sleep.

Wake run starts Load state checkpoint Work bounded time Write handoff next self Sleep resume later
The whole implementation idea, before frameworks: checkpoint, work, handoff, resume.

Keep normal workflow guardrails around it — single owner, idempotent effects, trace IDs, schema versions, failure stops — but do not turn the handoff itself into a protocol.

The concrete artifact is the prompt that greets the agent when it wakes. Notice it has three slots: model-friendly history, authoritative state, and whatever knowledge needs to be retrieved separately.

Example wake-up prompt

# You woke up. You're a long-running agent in run #15.

## What you've been doing  (history)
- runs #1-10: found the product catalog and stabilized the parser
- runs #11-14: scraped pages 1-88; page 89 is the next cursor

## Your exact instruction from last time  (canonical state)
Resume scraping at page 89. Parser config is below. Do NOT
re-fetch pages you've already stored.

## Checkpoint  (structured state)
<the JSON payload below>

## Rules
1. Execute the instruction above immediately.
2. If you near your time budget or hit a blocker, STOP.
3. Call write_handoff() to leave a note for your next self.

The headings aren't decoration — they're the taxonomy made physical. History is the narrative recap. State is the directive plus a structured checkpoint the agent doesn't have to re-derive. And critically, the directive is something the previous self wrote on purpose, not something this self reconstructs from a transcript.

The checkpoint itself can stay small. It doesn't need a framework; it needs to be honest about being the source of truth:

Example checkpoint payload

{
  "run_number": 15,
  "status": "IN_PROGRESS",
  "next_action": "scrape_from_page",
  "cursor": { "page": 89, "total": 120 },
  "completed_effects": ["pages:1-88"],
  "attempt": 1,
  "schema_version": 2,
  "trace_id": "trc_9f3a"
}
Optional failure handoff
{
  "run_number": 15,
  "status": "FAILED",
  "next_action": "request_human_review",
  "last_error": "Parser returned empty body twice on page 89",
  "attempt": 3,
  "retry_after": null,
  "schema_version": 2,
  "trace_id": "trc_9f3a"
}

That's the level of implementation I think this idea needs: enough shape to be useful, not enough ceremony to become another framework.

The honest boundary

When not to reach for A2S

Don't reach for this if there's no seam: single-shot calls, sub-second interactive loops, or multi-agent coordination live on different axes. A2S only matters when an agent has to stop, lose its live context, and come back later as the same actor with the same job.

So that's the thing I've been chewing on. The next time you build an agent that has to wake up tomorrow, notice that the riskiest line of code might not be inside the run. It might be the note the agent leaves on its way out.

The question isn't "where do I store its state?"
It's "what does it need to tell its future self?"