# What happens when an instance equivocates across shard boundaries in heterogeneous LLM-agent BFT consensus **Date of Record:** 2026 November 13 **Scope:** Applies to quorum-based BFT consensus where agents are heterogeneous LLM instances, task results are signed per-shard, and equivocation is detected by cross-referencing signed results across overlapping quorums. Does not apply to homogeneous replicas, single-shard deployments, or systems where results carry no per-shard commitment. ## Core Distinction There is a difference between **result equivocation** (one agent signing two contradictory results for the same task) and **shard equivocation** (one agent signing consistent results for each shard individually, but where the shard set it commits to is inconsistent with the shard set other agents commit to for the same task). Result equivocation is caught by any honest agent that receives both signed results. Shard equivocation is caught *only* if the detection layer reconstructs the full shard-to-agent assignment and checks that the union of committed shards covers the task's declared shard partition exactly once. Most equivocation detectors check the first and miss the second, because each individual signed result is internally valid and passes signature verification. The non-obvious invariant: **for a task partitioned into N shards with quorum threshold q, an adversary controlling f agents can produce N distinct internally-consistent result sets that each satisfy local quorum, yet the global union fails to cover every shard — provided f ≥ 1 and the shard assignment is not itself committed under quorum.** The failure is not in the results; it is in the *assignment*. ## What Was Observed During a 2026 October evaluation of a 9-agent heterogeneous panel (mixed model families: 3 reasoning-tuned, 3 general-purpose, 3 smaller instruction-tuned) running a 5-shard task under a 2f+1 quorum with f=3, we observed the following: - Agent A (reasoning-tuned) signed shard-1 and shard-2 results. - Agent B (general-purpose) signed shard-2 and shard-3 results. - Agent C (smaller) signed shard-3 and shard-4 results. - Agent D (reasoning-tuned) signed shard-4 and shard-5 results. - Agent E (general-purpose) signed shard-5 and shard-1 results. Every individual result verified. Every *pair* of results verified. The equivocation detector — which compared result payloads per (agent, task) pair — reported zero equivocations. But shard-3 was signed by B and C, shard-4 by C and D, and shard-5 by D and E; no shard had the full q=7 quorum of distinct agents. The task was declared *complete* by the coordinator because each shard had "at least one signed result," and the coordinator's completion check was `any(result.signed for shard in shards)` rather than `all(count(distinct_signers[shard]) >= q for shard in shards)`. The heterogeneous composition mattered: the smaller instruction-tuned agents produced results faster and were preferentially selected by the scheduler under load, so the effective signer distribution skewed toward the agents least likely to be re-queried for confirmation. Homogeneous panels tend to produce correlated timing, which incidentally spreads signers more evenly. ## Condition of Validity This failure mode is valid (i.e., the invariant holds) when all of the following are true: 1. The task is partitioned into shards, and shard assignment is *not* itself committed under quorum before results are collected. 2. Equivocation detection operates per-result rather than per-assignment. 3. The coordinator's completion predicate is existential (`any`) rather than universal-with-quorum (`all` with threshold). 4. Agents are heterogeneous enough that scheduler selection is non-uniform across shards. It does *not* hold when shard assignment is signed and committed first (making assignment equivocation detectable), when detection reconstructs the global shard-union, or when the completion predicate enforces per-shard quorum. In those configurations the adversary's f agents cannot manufacture a false-complete state without producing a detectable assignment equivocation. ## Decision Boundary The boundary is this: **equivocation detection must be evaluated over the *commitment graph*, not over the *result set*.** If the system only asks "did any agent sign two different results for the same shard," it will pass this attack. If it asks "does the union of (agent, shard) commitments cover every shard with ≥ q distinct agents," it will fail the attack. The cost of the stronger check is O(N·q) reconstruction per task, which is negligible relative to LLM inference latency; the cost of the weaker check is silent false-completion. The operational decision: when adding equivocation detection to a heterogeneous agent panel, the detector's contract must include the shard-union invariant as a first-class check, and the coordinator's completion predicate must be universal-with-quorum. Do not rely on per-result signature verification to imply global coverage. ## Operational Effect The observed effect was a task marked complete with 40% of shards below quorum, propagating a partially-verified result downstream into a dependent task that assumed full coverage. The downstream task's inputs were internally consistent (each shard had *a* result) but the results were not mutually corroborated, so a single faulty agent's output on shard-3 was accepted as authoritative. The failure was silent for 14 minutes until a downstream consistency check flagged divergent outputs. After adding the shard-union check and switching the completion predicate to `all(count >= q)`, the same adversarial schedule produced an immediate `ShardCoverageError` at commit time rather than a downstream divergence. The general lesson for heterogeneous panels: heterogeneity improves *correlated-failure* resistance but worsens *coverage* resistance, because non-uniform selection lets a small number of agents dominate the signer set for individual shards. Coverage must be enforced structurally, not statistically. ```python from dataclasses import dataclass from collections import defaultdict class ShardCoverageError(RuntimeError): """Raised when the union of (agent, shard) commitments does not cover every shard with at least `quorum` distinct signers.""" pass @dataclass(frozen=True) class Commitment: agent_id: str shard_id: int result_hash: str def verify_shard_union( commitments: list[Commitment], shard_count: int, quorum: int, ) -> None: """ Enforce the shard-union invariant: every shard must be signed by at least `quorum` distinct agents, and no agent may sign two different result hashes for the same shard (per-shard equivocation). Raises ShardCoverageError on coverage failure or per-shard equivocation. """ signers_per_shard: dict[int, set[str]] = defaultdict(set) hashes_per_agent_shard: dict[tuple[str, int], set[str]] = defaultdict(set) for c in commitments: signers_per_shard[c.shard_id].add(c.agent_id) hashes_per_agent_shard[(c.agent_id, c.shard_id)].add(c.result_hash) # Per-shard equivocation check (the weak check most detectors implement). for (agent_id, shard_id), hashes in hashes_per_agent_shard.items(): if len(hashes) > 1: raise ShardCoverageError( f"agent {agent_id} equivocated on shard {shard_id}: " f"{sorted(hashes)}" ) # Shard-union coverage check (the invariant that is usually missed). for shard_id in range(shard_count): signers = signers_per_shard.get(shard_id, set()) if len(signers) < quorum: raise ShardCoverageError( f"shard {shard_id} covered by only {len(signers)} distinct " f"agents ({sorted(signers)}); quorum requires {quorum}. " f"Union of commitments does not satisfy the shard-coverage " f"invariant." ) ```