Event-Sourced Agents: Why the Log Is the Agent

Every agent framework you have used stores two different things in two different places: what the agent did, and how the agent changed. The run lives in traces and transcripts. The changes — the edited prompt, the new tool, the rewritten instruction file — live in Git, or in a config table, or in somebody's head.
Nobody is running the same agent they were running a year ago. But almost nobody can reconstruct how theirs got here.
TL;DR — Event-sourced agents invert the usual arrangement: an append-only event log is the source of truth, the working state is a deterministic projection of that log, and behaviours react to state changes rather than calling each other. The payoff is replay, cheap forking, and lineage from a goal down to a single model call. What it does not give you is the human-readable conclusion — which ideas were tried, rejected, and why — and that is a document problem. MDflow is a markdown workspace where those conclusions live, readable by every agent over MCP and an HTTP API, versioned, and attributable to the token that wrote them.
What are event-sourced agents?
Event-sourced agents make an append-only log the source of truth and treat the agent's state as a projection of it. Nothing is edited in place. A prompt is not overwritten; a "prompt updated" event is appended, and the current prompt is whatever you get by folding the log forward. Rebuild the projection from event zero and you get the identical state, every time.
The clearest current statement of this is ActiveGraph, an open-source (Apache-2.0) runtime from Yohei Nakajima — creator of BabyAGI in March 2023, and by his own count nine iterations deep into the same question since. He presented it at AI Engineer in July 2026 and wrote it up as an arXiv paper with a title that does the whole argument in five words: The Log is the Agent.
The paper's framing of the status quo is worth quoting because it is uncomfortably accurate. Most frameworks are built around the language model: a conversation loop comes first, then tools, then rules, and finally a logging layer bolted on for observability, with state persisted as retrievable "memory". ActiveGraph inverts it. Three pieces:
- The event log — append-only, typed, immutable. Every change to the agent and every action it takes goes here, flattened into one stream rather than split between "runtime" and "config".
- The graph — a deterministic projection of the log. Objects, typed relationships, current values. This is the agent's state, and it is derived, never authoritative.
- Behaviours — functions, classes, LLM-backed routines, or logic attached to a typed edge. They subscribe to graph changes and emit new events, which change the graph, which may trigger other behaviours.
The structural rule is that no component instructs another. Behaviours do not call behaviours; LLMs do not message LLMs. Everything coordinates through the shared state. A planner behaviour fires on goal_created and emits two task objects plus a blocks relationship; a behaviour living on that edge fires when the first task completes and unblocks the second.
Two more concepts round it out. Views are context management expressed as graph queries — a behaviour sees the subset of the graph its query selects, which is a pleasantly declarative alternative to hand-assembling a prompt. Policies govern which changes the agent may make unsupervised: appending a source article it found during research is fine, editing its own master prompt requires a proposed patch and approval, and adding a claim that contradicts an existing claim triggers a contradiction check. Bundles of object types, behaviours and policies ship as packs, which is how you assemble a harness on top of the runtime.
Why event-sourced agents matter
The paper names three properties that fall out of the single design decision, and none of them are available in a retrieval-and-summarisation memory system.
Deterministic replay. Any run can be reconstructed exactly from its log. Not approximately, from a transcript — exactly, because the state was always a function of the events.
Cheap forking. You can branch a run at any event and explore an alternative continuation without re-executing the shared prefix. That converts "try a different approach" from a rerun into a diff.
End-to-end lineage. A fact in the graph traces back through the behaviour that emitted it, to the view that fed it, to the goal that started the chain, down to the individual model call. This is the thing that is genuinely hard to retrofit; see provenance for AI agent memory for why bolting it on afterwards mostly fails.
For developers
Debugging changes character. Nakajima's report is that his coding agent stopped reading session logs and started querying the ActiveGraph database directly, because everything was already there, typed and clean. You are no longer reconstructing a run from prose; you are querying it.
Long runs stop being fragile. During a LongMemEval evaluation his API key expired around question 350 of 500. The run resumed from 353 rather than restarting — a small anecdote that anyone who has lost a six-hour agent run to a transient failure will recognise as the entire value proposition.
And there is a counter-intuitive claim about authoring. Nakajima's hypothesis is that models are better at writing this architecture than at writing conventional agent loops, because shared-state micro-worker systems are not new. Blackboard architectures date to the 1970s and 80s; Kafka-style event streams have a decade of production literature. LLM agents have three years. The training data is lopsided, and it favours the older pattern. His own summary — that he would never write ActiveGraph code by hand but AI seems really good at it — is either a strong endorsement or a warning, depending on your priors.
For AI agents
An agent reading its own log gets something a vector store cannot give it: ordering and causality. In Nakajima's log-as-memory experiment there was no fact extraction, no entity extraction, no semantic ingestion pipeline — just embedding the query, finding relevant messages in the structured log, and grabbing a couple of messages either side to preserve context. It scored respectably on LongMemEval. The point is not that this beats a purpose-built memory system; it is that the log and the memory stopped being two datasets that drift apart.
The second thing it gives an agent is a safe way to change itself. This is where the Regimes experiment comes in — an improvement loop built on ActiveGraph that classifies a failure, routes it to the specific part of the pipeline allowed to change, has a model author a candidate repair, and then gates it: static analysis, sandbox execution, in-sample validation, and finally a held-out set. A candidate is promoted only if it does not regress held-out performance.
The funnel is the interesting number. 44 candidate repairs authored, 14 promoted — a 32% acceptance rate, with 27 of the rejections happening at in-sample evaluation before held-out data was consulted at all. Held-out gains ranged from +0.01 to +0.10 accuracy, two splits individually significant, and the pooled count was 43 improvements against 13 regressions. Modest, gated, and — crucially — recorded.
The part that usually gets thrown away
Nakajima's most quietly important observation came from an entirely unserious experiment: a Kaggle Pokémon trading card competition, where deck-building agents battle each other in an Elo ladder. Roughly 80 passes of "try this change", of which perhaps 20 to 30 were accepted, each producing a report of what was tried and what the verdict was.
His comparison to normal practice is exact. In a YOLO loop you keep trying things until something works, and then you know the thing that worked — but you have no idea what you already tried and discarded. With a policy that forces a gate before every acceptance, the agent knows both.
Negative results are the expensive half of the search, and they are the half nothing saves by default. A merged pull request records what was adopted. Nothing records that the obvious alternative was tested three weeks ago and made things worse, so the next run proposes it again and pays to re-learn it. Thirty rejected repairs are thirty pieces of knowledge; they exist only because something wrote down the verdict.
An event log records that a candidate was rejected. It does not, on its own, record why in terms a person or a future agent can act on — that the fix broke a customer integration, that the class of failure is really a race condition, that this whole approach is a dead end and here is the reasoning. That is prose, and prose belongs in documents.
Where the architecture is heading
Nakajima closed with a hypothesis he flagged as speculative, and it is worth taking seriously anyway. A predictive world model — the thing a frontier model gives you — behaves like a set of priors. What a long-running agent also needs is an experiential world model: the record of what actually happened to this agent, in this deployment, with these users. He points at the hippocampus as the loose analogy — an immutable event trace that projects a state and feeds back into the priors through replay.
The consequence contradicts a popular prediction. The common claim is that as models improve, the harness thins out and eventually disappears. If identity lives in the log rather than the weights, the harness does not disappear — it becomes the part that distinguishes your agent from everyone else's running the identical model. That is the same conclusion the harness era argument arrives at from a different direction, and it is why your data model is your moat.
Which applications benefit most
- Long-running and unattended agents — anything measured in hours or days, where a crash currently means starting over and a fork means a rerun.
- Self-improving systems — agents that modify their own prompts, tools or routing, where "prove it did not regress" has to be mechanical rather than vibes.
- Regulated and high-stakes deployments — finance, healthcare, insurance, where "reconstruct exactly what the system did on 14 March and why it was changed the week before" is a requirement, not a feature.
- Multi-agent systems — coordination through shared state removes the combinatorial mess of agents messaging agents, and gives you one place to look when the swarm misbehaves.
- Research and deep-research agents — evidence, contradictions between sources, and the reasoning chain are exactly what a typed graph over an event log is good at holding.
- Agentic coding platforms — where the artefacts are already versioned and the missing layer is the record of rejected approaches.
How MDflow fits
MDflow is not an agent runtime. It does not execute behaviours, project graphs, or store event streams. ActiveGraph, Temporal, Kafka, and your orchestration layer do that, and they should — an event log is high-volume machine data with a replay contract, and it belongs in a system designed for it.
What MDflow holds is the layer above: the conclusions the log cannot express. The rejected-approach ledger, the failure taxonomy, the design decision and its reasoning, the standing instruction that stops the next run from repeating a wrong turn. Those are documents, and they are the layer most teams leave in a Slack thread or a closed pull request.
What already lines up today
Markdown documents are the native unit. A write-up an agent produces is the same markdown you would commit to a repository — no block model, no conversion step. Every document is also served as a raw .md twin with YAML frontmatter, so a sandboxed behaviour can fetch one over plain HTTP with no client library, which matters when egress is allowlisted.
Version history is the document-level analogue of replay. Every saved change on every write path captures the previous version, with line-by-line diffs and non-destructive restore. When a runbook or a design note stops matching reality, you can see exactly when it stopped and revert the edit that broke it. It is deliberately Pro, private to the document owner, and not exposed over the API or MCP — an agent cannot quietly rewrite the record of its own writes. For the general case, see version control for documents.
The Document Log answers "which run wrote this?" A cross-document activity feed records created, edited, shared and deleted events with the actor on every row, shown as automated · <token name> for anything arriving through the API or MCP. Give each loop its own Personal Access Token and the feed tells you which scheduled run filed which conclusion, with a click-through side-panel diff.
Folder descriptions are declared intent, not inferred. Every folder carries a description of what belongs in it, and mdflow_get_context ranks those descriptions above folder names and document titles before returning matching bodies. A folder described as "Rejected approaches for the retrieval pipeline — one document per approach, with the gate that rejected it and the measurement" is a retrieval signal you wrote on purpose. That is why folder descriptions beat file names.
Every runtime reads and writes the same workspace. The same documents are reachable from Claude, ChatGPT, Cursor and Codex over the remote MCP server with OAuth or a Personal Access Token, and from a cron job, a CI workflow, an orchestration DAG or an n8n automation over the HTTP API with a bearer token — plus a local stdio server, a VS Code extension and an iOS app. The behaviour that files a verdict at 03:00 and the engineer reading it on a phone are looking at the same document.
Open questions become checkbox lines. /tasks aggregates ordinary - [ ] lines out of every markdown body, so "re-test the batching change once the eval set grows" written by an autonomous pass becomes something a human can re-order and tick off, with the document itself remaining the source of truth.
Sharing without granting runtime access. A post-mortem or a decision record can be shared as a read-only link or a .md endpoint so a partner team reads what happened without an account or access to your infrastructure. Collections group several documents into one shareable set, and client-side encryption keeps chosen documents opaque to any agent without the password.
Where we are headed
Direction, not a dated commitment. Two things about this use case interest us most. The first is richer structured retrieval over folder descriptions, so an agent asking "have we tried this?" reliably surfaces the two relevant rejected-approach notes out of four hundred documents rather than the two most lexically similar. The second is narrower agent credentials: a Personal Access Token today reads and writes everything its owner owns, which is enough for attribution but is not least privilege — and an unattended behaviour writing verdicts on a schedule is exactly the case that wants a token scoped to one folder. Neither turns MDflow into an agent runtime, and that is deliberate.
The bottom line
Event sourcing is not a new idea, and that is the point — it is a well-understood pattern being applied to a domain that badly needs it. Making the log the source of truth gives an agent deterministic replay, forks that cost a branch instead of a rerun, and lineage from a goal to a model call. It also relocates the agent's identity: not in the weights, not in the prompt, but in the accumulated record of what it has done and how it has changed.
The gap it leaves is the human-legible one. A log can tell you a candidate was rejected at the held-out gate. It cannot tell the next engineer, or the next agent, that the entire class of approach is a dead end and here is why. Write that down somewhere both of them can reach.
Start free · Connect an AI agent · Read the API docs
Frequently asked questions
What are event-sourced agents?
Event-sourced agents are agents whose source of truth is an append-only log of every change, rather than a conversation history plus a mutable memory store. The working state — usually a graph of objects and relationships — is a deterministic projection of that log, so it can always be rebuilt by replaying events from the beginning. Nothing in the state is edited in place; every change is a new event appended to the end.
What does "the log is the agent" mean?
It is the title of an arXiv paper by Yohei Nakajima, creator of BabyAGI, published in May 2026, describing the ActiveGraph runtime. The claim is that an agent's identity is not its model or its prompt but the accumulated record of everything it has done and every way it has been changed. Two agents on the same model with different logs are different agents, and rebuilding the log rebuilds the agent.
How is an event-sourced agent different from agent memory or RAG?
Retrieval memory stores summarised or embedded facts and answers similarity queries over them; it is lossy by construction and cannot tell you how a stored fact came to be. An event log stores the changes themselves in order, so state is derivable rather than remembered. The three things it adds that retrieval memory does not provide are deterministic replay of a run, forking a run at any point without re-executing the earlier steps, and end-to-end lineage from a goal down to the individual model call that produced a fact.
Why does forking matter for AI agents?
Because it makes experiments cheap. If the state is a projection of a log, you can branch at any event and run an alternative continuation without repeating the shared prefix, which is what turns self-improvement from a risky rewrite into a controlled A/B comparison. It also removes the failure mode where a long autonomous run has to restart from scratch after a crash or an expired API key: the log already knows where it stopped.
Why should an agent record what did not work?
Because negative results are the expensive part of the search and the part nothing saves by default. An agent that only records merged changes will happily propose the same rejected idea a month later and pay to re-test it. In the Regimes experiment on ActiveGraph, 44 candidate repairs were authored and only 14 promoted — the other 30 outcomes are the accumulated knowledge, and they exist only because the gates recorded them.
Further reading
- The Log is the Agent: Event-Sourced Reactive Graphs for Auditable, Forkable Agentic Systems — Yohei Nakajima, arXiv, May 2026
- Regimes: An Auditable, Held-Out-Gated Improvement Loop Demonstrated on LongMemEval with ActiveGraph — the self-improvement experiment and its funnel
- ActiveGraph on GitHub — Apache-2.0 implementation, with documentation
- LongMemEval — the long-term memory benchmark used in both experiments
- Agent observability: from production signal to PR — the same loop seen from the telemetry side
- Provenance for AI agent memory — why lineage is hard to retrofit
- The AI agent harness era — everything around the model that decides whether it works
- Version control for documents — history, diff and restore without Git
- MDflow MCP documentation and HTTP API documentation