Stateful AI Agents: What State Actually Means Once Agents Work in Teams
Task, knowledge, and policy state fail in three different ways. The split, the collisions, and where enforcement leaks.
September 23, 2026 · Caura.AI
For one agent, state is its conversation history: one variable, one writer, one reader. For a fleet, state is a shared database with a concurrency model, and it splits into three things that fail in different ways. Skip that split and you get results like this one from a Purdue and University of Maryland benchmark: 256 concurrent agent operations against a budget permitting exactly 50 committed 79.4 to 80.8 of them, with 30 or more authorized against a state that had already moved.
Every policy check in that run was correct when it ran. That is the whole problem.
This blog covers the three kinds of state a fleet actually holds, why two agents collide when their writes never touch the same row, the fields a shared record has to carry that a chat log does not, and where enforcement leaks even in systems built for this.
What does “stateful” mean for a single agent, and where does it break?
A stateful single agent remembers across turns. It writes to a scratchpad, reloads it next session, and behaves as though the conversation continued. The state is a transcript with an index on it, and it has exactly one property that matters: it persists.
That definition survives because nothing contests it. One agent wrote every entry, so provenance is trivial. One agent reads them, so permissions are trivial. If two entries disagree, the same agent wrote both and can pick, so precedence is trivial.
Anthropic’s engineering team put the consequence plainly in their writeup of Claude’s Research system: “Agents are stateful and errors compound.” Their lead agent writes its plan to memory specifically because the context window truncates past 200,000 tokens, and their subagents write outputs to a filesystem rather than passing them back through the coordinator, to avoid what they call a game of telephone.
Add a second agent and all three trivial things stop being trivial at once. The transcript becomes a record other parties read, and a record other parties read needs to say who wrote it, who may see it, and whether it is still true.
What are the three kinds of state a fleet has?
Three, and they are usually conflated into one. The distinction is not academic hair-splitting: each one lives somewhere different, is owned by something different, and produces a different outage.
The split is visible in the literature once you look for it. A January 2026 survey of orchestrated multi-agent systems separates the orchestration layer’s state unit, which handles “checkpoints, workflow progress, agent states, and activity logs,” from its knowledge unit, which handles contextual and domain information. The authors argue this separation “preserves modularity, contextual consistency, and system coherence.” Peng and Wu at Purdue and UMD name a third, which they call policy state: “the logical state needed to decide all deployed stateful policies,” explicitly “not necessarily the entire application state.”
Task state: where is the work?
Checkpoints, step outcomes, retry counts, which subagent is still running. Owned by the orchestrator or graph runtime. Loses you a run when it breaks, which is expensive but visible: you notice a job that restarted.
Knowledge state: what does the fleet know?
Facts, decisions, episodes, preferences, learned rules. This is the one every agent memory product addresses, and it is the one people mean when they say “agent memory.” It breaks quietly: a stale fact gets recalled as current, two agents act on two different truths, and nothing throws.
Policy state: what is still allowed?
Budgets, quotas, holds, pending approvals, data residency rules, trust tiers. This is the layer almost nobody treats as state at all, because it usually lives in a system prompt. Peng and Wu are blunt about why that fails: “A prompt can ask an agent to respect a budget or wait for approval, but it does not create an enforcement boundary around the effect or the state that justifies it.”
Caura’s keystones primitive is the same idea shipped as a product decision. Keystones live in their own _keystones collection, are looked up deterministically by scope rather than by embedding similarity, and are merged across tenant, fleet, and agent before an agent’s first action. The docs are explicit that they are “intentionally not memories; they’re policies.” That distinction is a schema-level statement that policy state and knowledge state are different substances, and Caura’s earlier argument that probabilistic enforcement is not enforcement is the reasoning behind it.
If your fleet keeps all three in one pile, the pile inherits the worst properties of each.
Why do two agents conflict when their writes never touch?
Because they consume the same shared limit through different rows, and every conflict-detection mechanism you already own compares rows.
Peng and Wu’s minimal example: a team has spent 9 of 10 daily credits. Agent A debits Alice, agent B debits Bob, each for 1 credit. Both checks pass, because both read the same 9. Both commit. The team has now spent 11.
The application writes are genuinely disjoint. One touched Alice’s row, the other touched Bob’s. Ordinary transaction machinery sees no conflict and has no reason to serialize them. The authors name this failure stale authorization: acting on an allow decision after the state that justified it has changed. Its slower cousin is stale approval, where a human signs off on a purchase and other work consumes the capacity before the approved effect commits.
Their measured version is the number in the opening.
The second bar is the one worth sitting with. That run used Cedar, a real policy engine with reviewable rules, integrated the normal way: compute the current spend, hand it to the engine as request context, act on the verdict. It performed marginally worse than no coordination at all, because a value passed as context is a photograph of a number, and nothing binds the photograph to the effect that changes it.
Caura’s knowledge-state equivalent shows up in its own long-run fleet reference implementation. Three agents track a competitor’s pricing for 14 simulated days. The price reads $299 for days 1 through 8, reinforced by eight writes. On day 9 it changes to $349. In a plain vector store, the ninth memory joins the other eight and both are retrievable, with nothing marking which is current. The repo’s own framing: “Telling the agent to ‘ignore old data’ does not remove stale vectors from recall results.”
What does a fleet-grade state record carry that a chat log doesn’t?
Twelve extra fields per record, plus three things that live outside it entirely. Ten of the twelve are columns on the row; contains_pii is a flag inside the metadata JSON, and detection_status is computed by the contradictions API when you ask for it, so it is never stored. We counted these across Caura’s schema documentation and its four public reference implementations.
The grouping is not arbitrary. It follows the four governance dimensions Caura formalizes in its arXiv paper (2606.24535), which, in Section 3.1, defines a fleet-memory system as a five-tuple of agents, memory substrate, governance, provenance, and temporal supersession. Single-agent work optimizes the substrate alone.
| Dimension | Question it settles | Fields |
|---|---|---|
| Scope | Who may read this | tenant_id, fleet_id, visibility, contains_pii (metadata flag) |
| Time | Which version is current | status (8 values), supersedes_id, detection_status (API response field), validity bounds |
| Provenance | Where it came from | agent_id, memory_type (14 types), weight |
| Propagation | How it crosses a boundary | entity and relation links |
Three details in that table repay attention.
status carries eight values, not two: active, pending, confirmed, cancelled, outdated, conflicted, archived, deleted. A single agent needs “there” or “not there.” A fleet needs to distinguish a fact nobody has checked from one another agent confirmed, and a fact that was superseded from one that was contradicted. In the pricing scenario above, the eight $299 memories move to outdated and drop out of recall by status, not by prompt instruction.
Three of the 14 memory types are server-only: Per Caura’s memory pipeline docs, agents cannot write insight, outcome, or rule; caura_write rejects them. Those come from outcome reporting, crystallization, and reflection runs. An agent may not author the record of its own reliability, which is a governance decision expressed as a schema constraint.
Trust is not on the record at all: It sits on the agent row as agents.trust_level, a SmallInteger defaulting to 1, across four tiers: 0 restricted, 1 standard (read and write own fleet), 2 cross-fleet read, 3 admin. The same read returns different rows to different callers, by design.
None of these twelve fields improves retrieval quality. Every one exists to settle a dispute between two agents that a single agent never has. That is the cleanest available answer to what “state” means once agents work in teams: state is what you have to write down when someone else will read it.
Where does enforcement actually live, and where does it leak?
Wherever you put it, and it leaks wherever you put it somewhere weaker than you assumed.
The interesting evidence here is Caura’s own, because it published the failures rather than the architecture diagram.
The confused deputy: ArgusFleet, the open measurement rig accompanying the paper, probed the live caura.ai service with one experiment per governance dimension. Cross-fleet leak rate came back at 0.000 across 80 probes, and all 50 depth-four provenance chains reconstructed with the correct writer identity at every hop.
Then the scope probe found that POST /search enforced the full scope predicate while GET /memories/{id} evaluated only the tenant projection and skipped the sub-tenant check. A low-trust agent could fetch by identifier what the trust ladder denied by search. It was remediated mid-study, and a re-probe found zero leaks across 36 attempts.
The declared-scope gap. The cross-fleet governance repo documents its own weak point as a numbered test step. Step B′ asks the sales agent to recall with fleet_ids: ["fleet-legal"], a fleet it does not own, and states the expected result: the legal hold comes back. The storage layer filters to whatever is declared and does not validate the declaration against the caller’s identity. The repo’s words: “The boundary is a query-layer contract, not a cryptographic key.” Hard isolation requires separate tenants.
Both are path bugs rather than design bugs, and that is the generalizable lesson. A boundary that exists on the search path and not the fetch path is not a boundary; it is a boundary-shaped thing on one route. When you audit your own fleet, enumerate every path that returns state, not every rule you wrote.
There is a third disclosure worth naming because it inverts the usual story. Contradiction resolution scored 1.000 when both conflicting writes were admitted, but only 0.490 across all runs. The detector was fine. A synchronous near-duplicate gate was rejecting the second, contradictory write before the asynchronous detector ever saw it. An optimization built to suppress noise was suppressing the signal. Negative results like that only surface when you measure a running multi-tenant service, which is the paper’s actual argument.
If your fleet currently expresses its rules as instructions in an agent’s prompt file, that is the layer to move first. Caura’s keystones exist for exactly this: rules fetched deterministically at session start, merged across tenant, fleet, and agent scope, ordered by weight, and obeyed over conflicting instructions, with authoring gated at trust 2 and above.
Why does every serious design move the check to write time?
Because reads outnumber writes in a fleet, and a check at read time has to be right every time while a check at write time has to be right once.
We cataloged this across four independent 2025 and 2026 efforts working on unrelated problems, and it is the most useful pattern in the current literature because nobody involved was coordinating.
STORM attacks multiple agents editing one codebase. The standard answer is workspace isolation, one git worktree per agent, which the authors observe “defers conflict resolution to a post-hoc merge step where recovery is expensive.” STORM mediates access instead, so conflicting edits are detected and resolved at write time. It beats the worktree baseline by 18.7 points on Commit0-Lite, and the authors conclude explicitly that explicit state management is a better foundation than workspace isolation.
ALAS attacks job-shop scheduling under disruption, and names “lack of persistent state” as one of four fundamental LLM deficits alongside absence of self-verification, context erosion, and next-token myopia. Its framing is transaction-style planning demanding ACID-like guarantees, with history-aware local compensation instead of global replanning.
MasuGate holds the interval between the policy decision and the effect commit, and revalidates before committing. Zero stale allows where the baselines produced 30.
Caura’s paper lands in the same place from the memory side: in its ArgusFleet runs against the live service, under strong write mode, a freshly written fact became visible to authorized readers in 0.83 seconds at p50, effectively one search round-trip. The paper’s phrasing is that the consistency cost lives at write time, not read time, and that reads stay fast because the writer pays.
Four teams, four problem domains, one answer. Caura’s write path is the same bet: one LLM pass on every write classifies the type, generates title and summary and tags, scores importance, scans for PII, extracts entities, and stamps the visibility scope before the row is recallable. That is expensive per write and it is why recall stays at 23 ms (warm cache, single-tenant benchmark).
What does this cost, and when should you skip it?
Real money, and often.
Anthropic’s numbers are the best benchmark: agents use roughly 4 times the tokens of a chat interaction, and multi-agent systems about 15 times. Their conclusion is that these architectures need tasks valuable enough to justify it, and they name the cases where multi-agent is the wrong shape: domains “that require all agents to share the same context or involve many dependencies between agents.” Most coding tasks, in their assessment, have fewer genuinely parallelizable subtasks than research does.
Skip governed shared state when one agent does the work, when the fleet is three agents that never disagree, or when every memory is public inside the org and nothing is time-sensitive. A vector store is fine and cheaper. Caura’s own taxonomy piece names the cases where you should skip all of it, which is not the usual vendor posture.
Adopt it when any of these are true: two agents can write contradicting facts about the same entity; some memories must not cross a team boundary; you need to answer which agent recalled what, and when; or an agent’s action consumes a shared limit. That last one is the tell that you have policy state, whether or not you have modeled it. The token economics argument matters here too, since in a fleet the tokens that dominate the bill are spent on repetition rather than reasoning.
How do you wire it? Four reference implementations
Caura publishes four Apache-2.0 repositories that map cleanly onto the three kinds of state, which is a useful reading order rather than a marketing list.
| Repo | What it demonstrates | State type |
|---|---|---|
| caura | The engine: 12 MCP tools, write pipeline, audit trail, trust tiers. Four containers, roughly 30 seconds to a running stack | All three |
| caura-cross-fleet-gov | Sales, legal, and admin agents on one backend. Scoped writes, blocked recall, cross-fleet synthesis, and the declared-scope gap documented as a test | Scope |
| caura-long-run-fleet | 14 simulated days, the $299 to $349 price change, contradiction detection polled to completion before the synthesis agent reads | Time |
| caura-build-fleet | Five specialists with per-agent tool allowlists. The Performance agent writes “no external JS”; the SEO agent recalls it and picks inline JSON-LD | Propagation |
The fourth repo carries the sharpest design detail. Its Manager agent has no caura_write in its allowlist, so the tool definition never reaches the model. At the end of every run it reports zero writes, and that report is the data-isolation proof. The README’s own note: “Giving every agent every tool is a common mistake.”
Start with caura-long-run-fleet if you want to see the failure before the fix. Run days 1 through 8, look at the pool, then run day 9. The eight reinforced $299 memories transitioning to outdated is the clearest demonstration of what temporal supersession buys, and it takes an afternoon.
Start with the state you already have
You now have the split that makes the question answerable: task state in the runtime, knowledge state in the store, policy state at the gate. You also have the diagnostic. Take one rule your fleet is supposed to follow, find where it physically lives, and check whether anything evaluates it before an effect commits. If the answer is a line in a prompt file, you have found your weakest boundary in about five minutes.
Caura is governed shared memory for agent fleets: visibility scopes and trust tiers on every operation, keystone policies fetched deterministically at session start, contradiction detection and supersession on the write path, and an audit trail that answers which agent recalled what. It is Apache 2.0 if you want to run it yourself, and the free tier covers 10,000 memories with unlimited agents and fleets if you want to skip the infrastructure.
Frequently Asked Questions
Is a stateful AI agent the same as an agent with memory?
Not once there is more than one agent. For a single agent, the terms are interchangeable, since its memory is its state. In a fleet, memory usually means knowledge state only, while state also covers task state in the orchestrator and policy state in the enforcement boundary. A system that gives you excellent memory can still have no answer for what an agent is still permitted to do.
Does a bigger context window solve this?
No. A larger window holds more text; it does not give you scoped access, a rule for which of two conflicting facts is current, a trace back to the writer, or a boundary on how knowledge crosses teams. Caura’s paper defends exactly this point with measurements: the failures it found were governance and consistency failures, not retrieval failures.
What is stale authorization in plain terms?
A permission check that was correct when it ran and wrong by the time the action took effect, because something else changed the state the check depended on. It is the multi-agent version of a check-then-act race. Peng and Wu formalize it and show that request-local policy engines do not prevent it.
Can agents from different vendors share state?
Yes, if the store is the shared surface rather than the framework. Caura is MCP-native, so an Anthropic-based agent can recall what an OpenAI-based agent wrote, with visibility scopes and trust tiers deciding what crosses. The governance travels with the record, not with the client.
How do I tell whether my fleet has a policy-state problem?
Ask whether any agent action consumes something shared and finite: a budget, an API quota, seat inventory, a rate limit, a pending human approval. If yes, and if the rule governing it lives in a prompt rather than in something evaluated before the effect commits, you have the problem described here whether or not you have seen it fire.
Where should I start if I already run a vector store?
Add provenance and status first. Stamping agent_id on every write and giving records a lifecycle beyond present-or-absent buys the two things a shared store most needs: the ability to answer who wrote this, and the ability to retire a fact without deleting it. Scope and policy enforcement are the next layer, and they are harder to retrofit, which is an argument for choosing the schema early.
Related reading: Keystones: Deterministic Policy · What Is Agent Fleet Memory? · Governed Shared Memory (paper)