Agent state needs migration semantics before it needs faster checkpoints
Agent state needs migration semantics before it needs faster checkpoints. A checkpoint that writes in ten milliseconds is useless if next week’s code reads the same bytes with a different meaning. Durable execution preserves work across process death; migration discipline preserves it across software change. Production agents need both, because a long-running task will eventually outlive the version that started it.
“State” is not one blob. It includes goals, tool results, pending effects, approvals, memory references, retry counters, policy decisions, and the control position in a workflow. Those fields evolve at different rates and carry different risks. Renaming a display label is not the same as changing the meaning of an approval token. Adding an optional observation is not the same as splitting one tool into two effects. Treating every change as a serializer concern misses the behavioural contract encoded in the checkpoint.
API evolution offers the right vocabulary. A state schema needs explicit versions, additive changes where possible, breaking-change detection, deprecation windows, and consumers that declare what they can read. But agent state has an extra consumer: future control flow. The schema may validate while semantics break silently. A renamed enum can route to a different tool; a defaulted field can grant broader authority; a “completed” step interpreted under a new workflow can skip a newly required check. Structural compatibility is necessary, not sufficient.
I therefore want migrations to be executable and directional. Every stored record carries a schema version and the code version or workflow definition that produced it. Restore first identifies the reader and writer versions, then applies a tested sequence of transformations or refuses recovery. Destructive transforms preserve the original record or an event history so rollback does not depend on reversing lost information. Canary workers restore representative old states before a release receives live resumptions. Golden checkpoint fixtures belong in CI next to API contract tests.
Per-consumer version pinning is especially useful during rolling deployments. Old workers can continue reading the representation they understand while new workers opt into a migrated view. This resembles date-based API versions or consumer-driven contracts more than a one-time database migration. The unit of compatibility is not the table; it is the agent release: behaviour, policy, tools, and state interpretation moving together. Cold-start readiness should fail if that compatibility cannot be established.
Migration policy also clarifies ownership. Session state, durable workflow history, long-term memory, and distributed coordination state should not share one version number merely because one framework serializes them together. Session state and memory have different lifecycles; a replay log may require append-only preservation while a derived memory index can be rebuilt. Separating these schemas lets teams spend strict compatibility guarantees where lost meaning would create effects.
There is one precise concession: ephemeral agents whose entire task is cheap, idempotent, and safe to restart can discard old state instead of migrating it. That is a legitimate lifecycle policy when explicitly bounded. It stops being legitimate when an agent has accepted an approval, charged for substantial work, or produced an effect that cannot be repeated safely. At that point, “start over” is an unacknowledged breaking change.
Checkpoint throughput is visible on a benchmark, so it attracts attention. Migration semantics are noticed only during a deploy, rollback, or incident — exactly when improvisation is most expensive. I would rather restore a versioned checkpoint slowly and correctly than resume an ambiguous one instantly. Faster persistence improves efficiency. Compatible meaning is what makes persistence durable.