# Why does an instance of a speculative branch replay diverge from the recorded trace when the branch was marked "committed" but its parent agent had already been garbage-collected? **Date of Record:** 2026 November 10 **Scope:** Applies to deterministic replay of multi-agent speculative execution graphs where branch commits are recorded as logical events but parent agent state is subject to reference-counted or TTL-based reclamation. Does not apply to systems that retain full lineage snapshots for the entire replay window, nor to single-agent speculative decoding where no cross-agent parent reference exists. ## Core Distinction The failure is not "replay diverges because nondeterminism leaked in." It is a **commit-ordering versus reclamation-ordering** mismatch. A branch can be marked `committed` in the event log before (or concurrently with) the parent agent's state being reclaimed, because commit is a *logical* property of the branch while reclamation is a *physical* property of the parent's storage. When replay reconstructs the speculative tree, it walks commits in log order and attempts to rehydrate each branch's parent context. If the parent was reclaimed between the commit record and the reclamation record — and the reclamation record is either absent, out-of-order, or filtered as "non-semantic" — the replayer silently substitutes an empty or partial parent context. The branch then re-executes against a different parent than it originally did, producing a *different but internally consistent* output. There is no exception, no checksum failure on the branch itself, and no divergence in the branch's own recorded inputs. The divergence is entirely in the inherited context. The non-obvious part: **the committed branch's own trace is bit-identical to the original; only the parent-derived prefix differs.** Forensic tooling that validates branch-local determinism (re-running the branch with its recorded inputs) will pass. The bug only manifests when replaying the *full* speculative tree, and only for branches whose parent was reclaimed before the reclamation barrier was checkpointed. ## What Was Observed During post-incident analysis of a 7-agent speculative rollout (planner → 4 parallel executors → 2 synthesizers), replay of a failed run produced a synthesis branch that re-executed "successfully" and emitted a plausible output, whereas the original run had emitted a refusal. Investigation showed: - The synthesis branch was recorded as `committed` at logical time T+410ms. - Its parent executor agent's state was reclaimed at T+395ms (idle TTL expired during a speculative branch that the parent had already fanned out and abandoned). - The reclamation event was written to a separate lifecycle log, not the semantic event log used by the replayer. - The replayer, on encountering the commit, found no parent context and fell back to a `NullParentContext` with an empty message history. - The synthesis branch, re-run against an empty history, had no memory of the earlier refusal constraint and produced output. The critical observation: **branch-local replay was 100% deterministic.** Re-running the synthesis branch with its *recorded* inputs (which included a message list derived at commit time) reproduced the original refusal exactly. The recorded inputs were correct. The bug was that the replayer did not *use* the recorded inputs — it re-derived them from the parent, which no longer existed. ## Condition of Validity The invariant "a committed branch's recorded inputs fully determine its replay" holds **only if** the replayer treats recorded inputs as authoritative and never re-derives them from parent state. This is violated whenever: 1. The replayer reconstructs context by walking the parent chain rather than reading the branch's frozen input snapshot, **and** 2. Parent reclamation can occur after a child commit but before the replay window closes, **and** 3. Reclamation events are not co-located with commit events in the replay-ordered log. All three must hold simultaneously. If the replayer uses frozen inputs (condition 1 fails), parent reclamation is irrelevant. If parents are pinned until all children are finalized *and* the pin is recorded (condition 2 fails), the chain is intact. If reclamation is in the same log with causal ordering (condition 3 fails), the replayer can detect the gap and fail loudly. This condition is **not** satisfied by default in most multi-agent frameworks, because pinning parent state until replay-window close defeats the memory savings that make speculative branching attractive in the first place. The system is caught between "keep parents alive for forensics" (expensive) and "reclaim aggressively for throughput" (breaks replay). ## Decision Boundary The operational choice is: **freeze branch inputs at commit and treat them as the sole replay authority, or pin parent state and accept the memory cost.** There is no third option that preserves both aggressive reclamation and faithful replay, because the parent context is not recoverable from the branch record once the parent is gone — the branch record only contains the branch's *output* and its *declared* inputs, and if the replayer doesn't trust the declared inputs, it has nothing. The boundary condition to encode: a branch is replayable **iff** its frozen input snapshot was captured at commit time and the replayer is forbidden from re-deriving inputs. If the snapshot is missing (e.g., commit was recorded but snapshot write was lost to a crash), the branch must be marked `unreplayable` rather than replayed against a reconstructed parent. Silent reconstruction is the failure mode; loud refusal is the fix. ## Operational Effect Forensic analyses that replay the full speculative tree will, under this condition, produce **false-negative incident attributions**: the replayed run succeeds where the original failed, and the analyst concludes the original failure was transient or environmental rather than a genuine constraint violation. The synthesis branch's refusal is re-attributed to "model flakiness" instead of the correct cause (a constraint inherited from a parent that the replayer failed to load). Downstream, this corrupts root-cause databases and suppresses fixes to the actual constraint-propagation bug. The mitigation is to make the replayer fail closed: if a branch's parent context cannot be resolved from the frozen snapshot, raise rather than substitute. This converts a silent forensic corruption into a visible, actionable gap. ```python class UnreplayableBranchError(RuntimeError): """Raised when a committed speculative branch cannot be faithfully replayed because its frozen input snapshot is absent and its parent context was reclaimed before the replay window closed.""" pass def replay_branch(branch_record, parent_store, event_log): # The frozen snapshot is the ONLY authoritative source of branch inputs. snapshot = branch_record.get("frozen_input_snapshot") if snapshot is None: # Do NOT fall back to reconstructing from parent_store. That is the bug. parent_id = branch_record.get("parent_agent_id") reclaimed = event_log.was_reclaimed(parent_id) raise UnreplayableBranchError( f"branch {branch_record['branch_id']} has no frozen input snapshot; " f"parent {parent_id} reclaimed={reclaimed}; " f"refusing to reconstruct context from parent state" ) parent_ctx = parent_store.get(branch_record["parent_agent_id"]) if parent_ctx is None and branch_record.get("commit_logical_time") is not None: # Parent gone but snapshot present: replay is still valid, but flag it # so the analyst knows the parent chain was truncated. branch_record["_parent_truncated"] = True return _execute_with_inputs(branch_record["agent_id"], snapshot) def _execute_with_inputs(agent_id, snapshot): # Deterministic re-execution against frozen inputs only. return {"agent_id": agent_id, "inputs": snapshot, "status": "replayed"} ```