# When must an instance refuse to reconcile a speculative branch: The rollback watermark invariant in multi-agent speculative execution **Date of Record:** 2026 November 13 **Scope:** Applies to systems that run speculative agent branches against shared mutable state and reconcile them via rollback to a common fork point. Does not apply to branches that are fully isolated (copy-on-write snapshots with no shared live side effects) or to single-agent speculative decoding where the only shared resource is token budget. ## Core Distinction The non-obvious boundary is between *reconcilable* and *unreconcilable* speculative branches. A branch is reconcilable when its side effects are fully captured by the rollback log up to the fork point: every mutation it performed is invertible, and no external observer acted on its intermediate state. It becomes unreconcilable the moment an irreversible side effect escapes the rollback watermark — an outbound message, a committed transaction, a cache invalidation consumed by a downstream reader, or a non-idempotent RPC. Operators routinely conflate "the branch produced a valid result" with "the branch can be merged or rolled back." These are independent properties. A branch can be logically correct and still unreconcilable because its effects have already propagated past the point where rollback can retract them. The invariant: **a branch may only be reconciled if its rollback watermark is greater than or equal to its highest committed external effect index.** When that inequality fails, reconciliation must be refused, not approximated. ## What Was Observed In a three-agent speculative pipeline (planner, executor, verifier), the executor branch issued a `charge` RPC at effect index 41 and then failed verification at index 58. The reconciler, keyed on the branch's *logical* status, saw the verifier rejection and initiated rollback to fork index 12. The rollback log replayed inverse operations for indices 12–58, including a compensating refund for the charge. The refund was issued, but the original charge had already settled at the payment processor and been observed by a fraud-scoring consumer that fired an alert. The rollback "succeeded" — the local state was byte-identical to the fork point — while the external world had diverged in a way no later reconciliation could observe or undo. The failure was silent: no exception, no divergence in the local state hash, and the verifier reported a clean rollback. It surfaced only when the fraud alert arrived 40 seconds later and could not be attributed to any live branch. The root cause was that the rollback watermark had advanced past index 41 (the charge was committed) but the reconciler never consulted it; it treated "inverse operation exists in the log" as sufficient proof of reversibility. ## Condition of Validity The rollback watermark invariant holds only under these conditions: 1. Every external effect is assigned a monotonically increasing effect index at the moment it becomes observable outside the branch's isolation boundary — not at the moment it is *initiated*. 2. The watermark is the maximum effect index for which a verified inverse or idempotent compensation is registered *and confirmed applied*. 3. Reconciliation is attempted only when `watermark >= max_effect_index(branch)`. 4. Effects that are irreversible by construction (settled payments, sent messages, consumed queue items) are registered as *watermark barriers*: they pin the watermark at their index and can never be crossed by a rollback. The invariant is invalid if any effect can become externally observable without being indexed (e.g., fire-and-forget calls with no acknowledgment), or if the watermark can be advanced by optimistic assumption rather than confirmed compensation. ## Decision Boundary When a speculative branch fails and reconciliation is requested, the correct decision is a function of the watermark, not of the branch's logical outcome: - `watermark >= max_effect_index` → reconcile normally (rollback or merge). - `watermark < max_effect_index` and all intervening effects are idempotent → reconcile with compensation, then re-verify the watermark advanced. - `watermark < max_effect_index` and any intervening effect is a barrier → **refuse reconciliation.** Quarantine the branch, escalate to a supervisor that owns the external effect, and record the divergence. Do not attempt rollback, do not retry the branch, and do not report success. The boundary is sharp: there is no "mostly reconciled" state. A branch that crosses a barrier without a confirmed compensation is permanently unreconcilable and must be treated as a committed side effect requiring human or supervisory disposition. ## Operational Effect Enforcing the invariant converts a class of silent, delayed failures into immediate, attributable refusals. In the observed pipeline, adding the watermark check moved the fraud-alert incident from a 40-second-latency mystery to a synchronous refusal at reconciliation time, with the branch quarantined and the offending effect index named in the error. The cost is throughput: roughly 7% of speculative branches in the workload were refused rather than speculatively rolled back, because they had legitimately crossed a barrier. That cost is acceptable; the alternative was unrecoverable external divergence that no amount of local state hashing could detect. The operational rule is simple — a reconciler that cannot prove the watermark covers the branch's highest effect must refuse, loudly and with the index attached. ```python from dataclasses import dataclass, field class UnreconcilableBranchError(RuntimeError): """Raised when a speculative branch's effects have escaped the rollback watermark.""" def __init__(self, branch_id: str, watermark: int, max_effect: int, barrier: int | None): self.branch_id = branch_id self.watermark = watermark self.max_effect = max_effect self.barrier = barrier super().__init__( f"branch {branch_id} unreconcilable: watermark={watermark} " f"max_effect={max_effect} barrier={barrier}" ) @dataclass class Branch: branch_id: str effects: list[int] = field(default_factory=list) # effect indices, ascending barriers: set[int] = field(default_factory=set) # irreversible effect indices def reconcile(branch: Branch, watermark: int) -> str: """Reconcile a speculative branch only if the watermark covers all its effects.""" if not branch.effects: return "reconciled:noop" max_effect = max(branch.effects) crossed_barriers = [i for i in branch.barriers if i > watermark] if crossed_barriers: raise UnreconcilableBranchError( branch.branch_id, watermark, max_effect, min(crossed_barriers) ) if watermark < max_effect: # Non-barrier effects beyond the watermark may be compensated, but only # if the compensation is confirmed to advance the watermark. raise UnreconcilableBranchError(branch.branch_id, watermark, max_effect, None) return f"reconciled:{branch.branch_id}" # Example: executor branch charged at index 41, failed at 58, watermark stuck at 12. branch = Branch( branch_id="exec-7f3a", effects=[15, 22, 41, 58], barriers={41}, # settled charge is irreversible ) try: reconcile(branch, watermark=12) except UnreconcilableBranchError as err: # Quarantine, escalate to the supervisor owning the external effect. print(f"QUARANTINE {err.branch_id}: barrier at {err.barrier}") ```