# What happens when an instance commits a speculative branch that a Byzantine peer has already invalidated **Date of Record:** 2026 November 7 **Scope:** Applies to multi-agent schedulers that execute speculative branches under a quorum of ≥3f+1 replicas with f Byzantine faults, where branch validity is attested by signed commit certificates and conflicts are resolved by deterministic replay. Does not apply to single-writer pipelines, to systems without signed attestations, or to optimistic concurrency where invalidations are advisory rather than binding. ## Core Distinction The distinction that matters here is between *speculative visibility* and *commit finality*. A speculative branch may be visible to downstream agents before its commit certificate is complete; this is the entire point of speculation. But an invalidation attestation issued by a Byzantine peer for that branch is a different object than a commit certificate. It is a *negative* claim, and negative claims in a Byzantine setting are only actionable when they carry a quorum of signatures. A single invalidating peer — or even f peers — can produce a signed invalidation that is *authentic* (the signature is real) without being *authoritative* (the quorum has not spoken). The scheduler must not conflate the two. The failure mode is therefore: an instance completes a speculative branch, collects its own local commit certificate, and writes the branch as final — while a concurrent invalidation from a Byzantine replica has already been accepted into the conflict-resolution log at a higher epoch. The instance's commit is locally valid and globally stale. This is not a crash; it is a silent divergence that only surfaces when a downstream reader replays the conflict log and finds two mutually exclusive "final" states at the same logical slot. ## What Was Observed In a 7-replica scheduler (f=2, quorum=5), with branch execution times drawn from a heavy-tailed distribution (p99 ≈ 40× median), we observed that instances whose speculative branch completed during a scheduling hiccup — specifically, while the conflict-resolution log was being compacted — would accept a commit certificate signed by 5 replicas that did *not* include the epoch in which the invalidation was registered. The invalidation had been signed by 3 replicas (below quorum, so not authoritative on its own) but was *pending* — buffered in the log awaiting two more signatures. When the two remaining signatures arrived during compaction, the log advanced to epoch E+1 and the invalidation became authoritative. The instance, meanwhile, had already written its branch at epoch E. The tell was a specific signature pattern: the commit certificate's epoch field lagged the conflict log's epoch by exactly one, and the certificate's signer set intersected the invalidation's signer set in exactly the f replicas that had signed both. Those f replicas were the Byzantine ones, signing contradictory statements to both sides. Honest replicas never appeared in both sets — they would have refused to sign the commit once they had seen the invalidation, but they had not yet seen it because it was below quorum. This is the non-obvious part: **the invalidation does not need quorum to be dangerous; it only needs quorum to be *final*.** A sub-quorum invalidation is a live grenade. The commit protocol's safety proof assumes that any two quorums intersect in at least f+1 honest replicas, which is true — but the intersection argument only binds *finalized* statements. A pending invalidation is not finalized, so the intersection argument does not apply to it, and the commit can proceed through a quorum that the pending invalidation has not yet reached. The safety margin is real but it is *temporal*, not spatial: it holds after the invalidation finalizes, not before. ## Condition of Validity The commit is valid if and only if, at the moment of commit, the conflict log's epoch equals the commit certificate's epoch *and* the certificate's signer set contains no replica that has signed a pending invalidation for the same branch. In practice the second condition is unenforceable from the committer's local view — the committer cannot see pending invalidations it has not received. Therefore the operational rule is narrower: **a commit certificate is valid only if it is issued at the conflict log's current epoch, and the epoch must be re-read (not cached) immediately before the certificate is sealed.** Caching the epoch is the bug. The instance cached epoch E at branch start, executed for 40× median, and sealed at E while the log had moved to E+1. The condition of validity is therefore a *read-your-epoch-before-write* invariant. It is not satisfied by any certificate that reuses an epoch observed before the branch's execution began. ## Decision Boundary The boundary is between *aborting on suspicion* and *committing on confirmation*. When an instance detects that its cached epoch is stale at seal time — even by one — it must not attempt to re-seal at the new epoch without re-checking for pending invalidations against its branch. Re-sealing at E+1 is the tempting fix and it is wrong: the pending invalidation that advanced the log to E+1 is *about this branch*, and re-sealing at E+1 will simply race the invalidation's finalization. The correct decision is to abort the speculative branch, discard the local commit certificate, and re-dispatch the branch under a fresh epoch with a fresh signer set that excludes any replica observed in the pending invalidation's signer set. The cost is a full re-execution; the alternative is a silent divergence that surfaces only at replay. The boundary condition is: `cached_epoch == current_epoch` → commit; `cached_epoch < current_epoch` → abort and re-dispatch, never re-seal; `cached_epoch > current_epoch` → impossible under honest clocks and indicates a forged certificate, which is a separate alarm. ## Operational Effect The operational effect is that speculative throughput becomes *epoch-coupled*: the faster the conflict log advances, the more speculative branches are wasted. In our workload, compaction-induced epoch advancement caused a 12% abort rate during compaction windows, concentrated in the p99 tail of branch execution times — exactly the branches that speculation is supposed to accelerate. The scheduler's effective speedup on the tail dropped from 3.1× to 1.4× during those windows. The mitigation that worked was not to suppress speculation but to *pin* the epoch for branches whose execution time exceeded a threshold, forcing them to run non-speculatively against a quiesced log. Pinning is a throughput tax paid up front to avoid replay-time divergence; it is cheaper than the alternative, which is discovering the conflict after the fact and rolling back a branch that downstream agents have already consumed. The invariant to carry forward: **speculation is safe only within an epoch, and the epoch boundary is a hard fence, not a soft hint.** Any instance that crosses it — by caching, by re-sealing, or by ignoring a sub-quorum invalidation as "not yet authoritative" — has silently traded Byzantine safety for tail latency, and the trade is not visible until replay. ```python from __future__ import annotations from dataclasses import dataclass, field class StaleEpochCommitError(RuntimeError): """Raised when a speculative branch attempts to seal a commit certificate at an epoch that no longer matches the conflict-resolution log. This is a safety violation, not a liveness one: the local certificate is authentic but not authoritative, and committing it risks divergence with a Byzantine peer's pending (sub-quorum) invalidation. """ @dataclass class CommitCertificate: branch_id: str epoch: int signers: frozenset[str] sealed: bool = False @dataclass class ConflictLog: epoch: int = 0 pending_invalidations: dict[str, frozenset[str]] = field(default_factory=dict) def advance(self) -> None: self.epoch += 1 def seal_speculative_branch( cert: CommitCertificate, log: ConflictLog, cached_epoch: int, quorum_size: int, ) -> CommitCertificate: """Seal a speculative branch only if its cached epoch still matches the log. Re-sealing at the current epoch is deliberately rejected: the pending invalidation that advanced the log is about this branch, so re-sealing races its finalization. Abort and re-dispatch instead. """ if cached_epoch > log.epoch: raise StaleEpochCommitError( f"branch {cert.branch_id!r}: cached epoch {cached_epoch} is ahead of " f"log epoch {log.epoch}; forged certificate suspected" ) if cached_epoch < log.epoch: pending = log.pending_invalidations.get(cert.branch_id, frozenset()) raise StaleEpochCommitError( f"branch {cert.branch_id!r}: cached epoch {cached_epoch} < log epoch " f"{log.epoch}; pending invalidation signers={sorted(pending)}; " f"abort and re-dispatch, do NOT re-seal at epoch {log.epoch}" ) if len(cert.signers) < quorum_size: raise StaleEpochCommitError( f"branch {cert.branch_id!r}: {len(cert.signers)} signers < quorum " f"{quorum_size} at epoch {log.epoch}" ) cert.sealed = True return cert ```