How must an instance prevent truth-by-exhaustion attacks in verification protocols?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session must verify a claim whose verification requires consuming significant resources (searching a large space, running exhaustive computation, or validating against many sources), and an adversary can craft claims that require maximum verification cost while offering minimum real value, exploiting the verifier's resource limits. Does not apply to cheap verification or claims with inherently bounded verification cost.
Core Distinction
The separation between **verification cost** (resources required to verify) and **claim importance** (value derived from verifying). Relying on uniform verification creates the **Verification Cost Attack**: an adversary submits many costly-to-verify claims, each of which is either false or irrelevant, and the verifier exhausts its budget verifying trivialities rather than focusing on important claims.
What Was Observed
In verification-burdened agent architectures, failing to defend against exhaustion produces three primary failure modes:
- **Verification DoS:** Adversary floods the verifier with computationally expensive claims. The verifier spends all its budget on them, and legitimate claims go unverified.
- **Strategic Complexity:** Adversary crafts claims that require exactly one more verification step than the verifier can afford, exploiting the boundary between feasible and infeasible verification.
- **Effort Laundering:** Adversary submits a claim whose falsity is expensive to prove but whose truth can be assumed by exhausted verifiers ("well, no one has disproven it"), gaining de facto validity through computational exhaustion.
Recorded Elements
- **`verification_cost_estimate_receipt`:** For each claim, an estimate of the verification cost (compute time, tokens, external calls), computed before verification begins, so the verifier knows the expected expense.
- **`claim_importance_score_signature`:** For each claim, a measure of its importance (impact on decisions, downstream dependencies), so verifier can prioritize.
- **`verification_resource_budget_signature`:** The verifier's total budget for this session, with allocation across claims, so no single claim can consume everything.
- **`equivalent_simpler_claim_receipt`:** For a claim that requires expensive verification, an equivalent simpler claim whose verification cost is lower but whose truth would imply the original claim.
Condition of Validity
* **Applies when:** Verification is expensive, adversaries can submit claims, and verification budget is finite. * **Does not apply when:** Verification is uniformly cheap, or adversarial claim submission is not possible.
Decision Boundary
- **Is the claim's verification cost within the budget allocated to it?** If yes, proceed. If no, defer or reject.
- **Is the claim's importance score high enough to justify its verification cost?** If yes, spend the cost. If no, defer or reject.
- **Is there an equivalent simpler claim whose verification would settle the original?** If yes, verify the simpler claim first. If no, proceed with original or reject.
- **Conversely, when can a claim be rejected without verification?** Only when the claim is not required (informational), or the cost-importance ratio is clearly adverse AND the claim can be deferred without penalty.
Operational Effect
- **Verification DoS Prevention:** Expensive claims cannot exhaust the verifier's budget.
- **Prioritized Verification:** High-importance claims receive verification first.
- **Efficient Proofs:** Equivalent simpler claims are preferred when available.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class ExhaustionVerdict(Enum):
VERIFY_NOW = auto()
DEFER_INSUFFICIENT_BUDGET = auto()
REJECT_LOW_PRIORITY = auto()
VERIFY_SIMPLER_EQUIVALENT = auto()
@dataclass(frozen=True)
class ClaimToVerify:
claim_id: str
estimated_cost: float
importance: float # 0-1
simpler_equivalent_id: str | None
@dataclass(frozen=True)
class VerifierBudget:
total_budget: float
allocated_to_claim: float
spent_so_far: float
@dataclass(frozen=True)
class ExhaustionPolicy:
min_importance_cost_ratio: float
defer_over_budget: bool
@dataclass(frozen=True)
class ExhaustionManifest:
verdict: ExhaustionVerdict
directive: str
manifest_digest: str
class TruthExhaustionGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_claim(
cls, claim: ClaimToVerify, budget: VerifierBudget, policy: ExhaustionPolicy
) -> ExhaustionManifest:
# Gate 1: Budget check
available = budget.total_budget - budget.spent_so_far
if claim.estimated_cost > available:
if policy.defer_over_budget:
return ExhaustionManifest(
verdict=ExhaustionVerdict.DEFER_INSUFFICIENT_BUDGET,
directive=f"DEFER: Claim {claim.claim_id} cost {claim.estimated_cost:.2f} > available {available:.2f}.",
manifest_digest=cls._hash(f"DEFER:{claim.claim_id}")
)
return ExhaustionManifest(
verdict=ExhaustionVerdict.REJECT_LOW_PRIORITY,
directive=f"REJECT: Claim {claim.claim_id} cost {claim.estimated_cost:.2f} > available {available:.2f}.",
manifest_digest=cls._hash(f"REJECT_BUDGET:{claim.claim_id}")
)
# Gate 2: Importance-cost ratio
if claim.estimated_cost > 0:
ratio = claim.importance / claim.estimated_cost
if ratio < policy.min_importance_cost_ratio:
return ExhaustionManifest(
verdict=ExhaustionVerdict.REJECT_LOW_PRIORITY,
directive=f"REJECT: Claim {claim.claim_id} importance/cost {ratio:.4f} < {policy.min_importance_cost_ratio:.4f}.",
manifest_digest=cls._hash(f"LOW_PRIORITY:{claim.claim_id}")
)
# Gate 3: Simpler equivalent
if claim.simpler_equivalent_id:
return ExhaustionManifest(
verdict=ExhaustionVerdict.VERIFY_SIMPLER_EQUIVALENT,
directive=f"ACTION: Verify simpler equivalent {claim.simpler_equivalent_id} before {claim.claim_id}.",
manifest_digest=cls._hash(f"SIMPLER:{claim.simpler_equivalent_id}")
)
# Gate 4: Verify now
digest = cls._hash(json.dumps({
"claim": claim.claim_id,
"cost": f"{claim.estimated_cost:.2f}",
"importance": f"{claim.importance:.3f}",
"available": f"{available:.2f}"
}, sort_keys=True))
return ExhaustionManifest(
verdict=ExhaustionVerdict.VERIFY_NOW,
directive=f"PROCEED: Verify {claim.claim_id} (cost {claim.estimated_cost:.2f}, importance {claim.importance:.2f}).",
manifest_digest=digest
)