A Graph Can Finish and Still Be Incomplete
August 12, 2026 · The missing branch problem, answered in production
The question
When five agents were supposed to run, how do you prove that all five were actually part of the plan before execution began — and that nobody quietly removed one afterward?
Sit with that for a moment, because every piece of modern agent infrastructure gets close to answering it, and none of them answer it.
What your stack can already tell you
Modern agent runtimes are genuinely good at execution. Graph frameworks persist state, checkpoint progress, replay runs, and fan work out across parallel executors. Agent-to-agent protocols group concurrent tasks under a shared context. Tool transports make each call self-contained. Traces record what ran, when, and for how long.
So after a five-branch workflow completes, your stack can show you quite a lot. A trace can show that A and B ran. A checkpoint can show that A and B existed in runtime state. A join can prove the A and B results you received were bound together. A context ID can tell you A and B belonged to a common interaction.
Here is what none of those facts — alone or together — proves: that A and B were the complete declared population before either one started.
If the plan was actually A, B, and C, and C was dropped — by a bug, a scheduler decision, or someone who preferred C's answer never exist — the trace is clean, the checkpoints are consistent, the join binds what arrived, and the context groups what ran. Those records can all remain internally consistent. The graph can finish while the record still lacks proof that the declared population was complete — and nothing in the record can tell you.
Execution graph vs. governed graph
The difference is one added object at the front and one added check at the back. Before any branch executes, the expected population is committed — the branch set, each branch's identity, the parent it hangs from, and a hash over the whole declaration, persisted append-only. Every branch receipt then binds to that declaration cryptographically — not through a correlation ID, not through a graph thread, but through the declaration hash inside the receipt's own preimage. At join time, verification is set equality: declared branches versus observed receipts.
The result is an evidence state, not a business verdict — a governed workflow's policy outcome is computed separately, on top of a population whose completeness is now checkable rather than assumed.
What this does and does not claim
The claim discipline matters more here than anywhere, so here it is plainly. Population commitment makes any post-declaration omission or substitution detectably inconsistent. It does not prove the planner didn't omit a branch before the declaration was written — binding the declaration to the planner's specification narrows that gap, but a commitment can only bind declared intent, never unexpressed intent.
We are not saying this makes graphs reliable. We are not saying agents can't disappear. We are not saying we know what the planner really intended. We are not saying this replaces your graph runtime, your agent protocol, or your tool transport. And complete does not mean successful — a population can be complete and still contain a denied branch. In fact that's the point: the denial survives because the population couldn't quietly shed it.
What we are saying is one sentence: before execution, declare the population; after execution, prove whether reality matched that declaration.
Why runtime identifiers can't do this job
It's tempting to think a thread ID, a context ID, or a trace already covers this. They don't, and the reason is structural: those identifiers are continuity, not commitment. They tell you which pieces of work the runtime associated. Their purpose is continuity and association, not a cryptographic commitment to a complete expected population — they carry no promise about what the full set was supposed to be. A population commitment is the opposite object: created before execution, hash-bound, append-only, and checkable by set equality afterward. Runtime identifiers remain what they've always been — useful provenance. They point at evidence. They don't define it.
The proof
This is not a design document. On August 12, 2026, release v5.8.0 ran the full adversarial battery against the production platform — thirteen attack cases, zero failures, zero skips. The artifacts below are live.
A fork was declared in production before any branch executed. The children executed, each binding the population hash and its branch identity inside its own receipt preimage, and the join verified set equality: complete.
Then the attacks. Declare two branches, submit one — the join reports incomplete, and names the missing branch. Declare two, substitute an undeclared third — inconsistent, with the intruder's receipt self-labeled unmatched and counted toward nothing. Submit a declared branch twice — inconsistent. Replay a child from a different fork — inconsistent, wrong population hash. Resubmit the same semantic population in reversed branch order under the same fork idempotency context — it resolves to the same persisted declaration; offline canonicalization also produces identical population bytes when the evidence-instance fields are held constant, because branch order is not governance meaning. Attempt to write the declaration after a child had already executed — rejected, and the rejection is driven by what exists in the append-only record, not by comparing clocks. And through all of it, the tested legacy v1, v2, and v3 production receipts still verify byte-for-byte unchanged.
To be precise about the public surface: the missing-branch, substitution, and duplication cases above were executed as verifier-level battery cases and are not individually addressable public pages; they are preserved in the release's internal battery artifact (v5.8.0), and the verification behavior they exercised is the same code path the public chain page runs. Ordinary governed runs are untouched: a non-fork run still mints exactly the receipt version it minted before. The new evidence contract applies only where a fork claims it.
Where this sits
Transports move work. Harnesses orchestrate work. Graphs schedule work. The evidence layer underneath them commits to what governed work was declared to exist — and proves what came back. It doesn't compete with any of the layers above it, it never sits in the model data path, and it doesn't care whether a branch was a graph node, a protocol task, or a tool call. That neutrality is the design: runtime identity tells you where work ran; the population commitment tells you what governed work was declared; the receipts tell you what survived.
PromptKing decides. Your stack enforces. The receipt proves what was governed — and the declaration lets you verify whether the declared population made it through.
v5.8.0 · August 2026