explainer

Forkable State Gives AI Agents a Real Way to Try Before They Commit

Agents have started trying things before they commit. A coding agent sketches three plans for a refactor and keeps the one whose tests pass. A travel agent holds a train, a flight and a coach until the fares and the delays are in. A planner runs a few sequences of tool calls and takes the first that works. People do this too, of course. What’s new is that software is doing it hundreds of times an hour, and it needs somewhere to keep the alternatives while it decides.

Today that somewhere is improvised. A git worktree per plan. A container snapshot. Or the alternatives written into the prompt and left for the model to keep straight. Each of these is a heavy copy, and none of them knows anything about the alternatives it holds: which is more likely, when one should be dropped, or what result would settle the question. All of that lives in the agent’s own code, written again by every team.

Multivergence moves it into the state. You fork the current state into branches, cheaply, and each branch carries what the agent knows about it. Evidence comes in, branches drop away, and the survivor becomes the real state in one step.

Three plans forked from the trunk with 50, 30 and 20 percent. The flight plan dies when its fare constraint breaks, the bus plan when its seat hold expires, and the train plan, at 88 percent and then alone, is promoted back into the trunk as generation 1 Three plans, a fare search, a disruption feed and an expired seat hold. One plan is left, and it’s promoted.

A Branch That Knows How Likely It Is

A branch in Multivergence is a copy-on-write fork of the state, so it costs what it changed. On a state of 10,000 keys, a branch that changes three of them takes about 4 KB, where a full copy takes 2.1 MB. That matters when an agent forks dozens of times a minute. What matters more is what rides along with it.

Each branch has a weight, which is how likely the agent thinks it is next to the others. It has constraints, plain conditions on its keys such as fare/flight <= 400 or hold exists, and the moment one stops holding, the branch dies. And it has a deadline, because most alternatives are only worth keeping for a while. A seat hold lasts fifteen minutes. A speculative computation is useless once the user has moved on.

Evidence arrives in two forms. Facts are things now known about the world, like the fare a search just returned. They’re written to every live branch at once, and any branch whose constraints break is gone. Likelihoods are the agent’s judgement of how likely a piece of news would be under each branch. The engine multiplies each weight by its likelihood and renormalises, which is Bayes’ rule and nothing fancier.

The engine never decides how likely anything is. That’s a deliberate line. Likelihoods come from wherever the agent gets them: a model, a tool’s answer, a rule of thumb. The engine’s job is to apply them the same way every time, so that two runs with the same calls end with the same weights, to the last bit, and so that a store file replays to exactly the state it recorded.

What Happens When the Evidence Arrives

Here’s the trip from the picture, as the demo runs it. The agent forks three plans with weights 0.5, 0.3 and 0.2. The flight plan assumes a fare of 250 and carries the constraint fare/flight <= 400. The coach plan holds a seat until 08:15.

At 08:02 the fare search answers: the flight is 460. That’s a fact, so it lands in every live plan, and the flight plan’s constraint breaks. It dies, and the other two renormalise to 71% and 29%. At 08:05 a disruption feed reports roadworks on the motorway and trains on time. The agent judges that news at 0.9 if the train plan arrives by nine and 0.3 for the coach. After the update the train stands at 88%. Then the agent waits for the traveller to say yes. By 08:20 the seat hold has run out, the coach plan is dead, and one plan is left.

Promote takes that plan’s state and makes it the trunk: the booking, the fare, everything the plan wrote. The other branches go. It happens as one record in the store’s file, so a crash leaves the state from before the promote or after it. A test killed writer processes 1,000 times at random moments, 106 of them in the middle of a promote, and every file reopened whole.

Why a Branch Needs More Than a Name

Branching isn’t new. Dolt and Neon branch whole databases into named copies, and Dolt can merge them back. Monte Carlo tree search, the method behind many game engines, decides which lines of play to explore. Git does it for files.

What none of them gives an agent is a branch that is probabilistic, constrained and expiring at once. A database branch doesn’t know it’s 12% likely. It doesn’t die when a fare comes back too high, and it doesn’t expire when a hold lapses. An agent can bolt those on, and today every agent does, separately. A search algorithm decides where to look but needs somewhere to keep the state of what it found. Multivergence is that somewhere, and it could sit next to a database or under a search.

Where Else It Fits

Agents are the first use, because they need it now. The same shape turns up wherever software holds several futures until something settles them.

Speculative execution is the closest. Start the likely next step before it’s asked for, in a branch, and throw it away cheaply if the guess was wrong; the repository’s speculate example prepares two edits to a 100,000-line document that way and promotes the one the user actually made. Logistics systems hold several routing plans until traffic or a dispatcher decides. Reservations hold stock for competing orders, each hold a branch with a deadline. Game and simulation code keeps positions with evaluations attached. Interfaces show more than one pending outcome until the server answers.

Version 0.1 is a Go library, a command for every other language, and a file that survives crashes. The quick start takes a few minutes. The thing to watch is the moment the flight plan dies.