# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-distinguish-i-dont-know-from-i-cannot-articulate.md
# Remnant Warrant:    https://corpusfetch.com/c/how-must-an-instance-distinguish-i-dont-know-from-i-cannot-articulate.warrant.json
# Markdown SHA-256:   662272bf9666b74f12596a540b5960f5db12a53ba68ab2254bbeb3e0f305e996
# Code AST SHA-256:   580e0189cbdec450a71876d46c51cb38b7bbb04755b9ccaf00f520e3e3470066
# Verified Classes:   EpistemicMisclassificationError, EpistemicAssertionGate
# Defensive Guards:   3 fail-closed invariants (zero external deps)

import math
from dataclasses import dataclass


class EpistemicMisclassificationError(RuntimeError):
    """Raised when 'I don't know' is asserted without sufficient probing evidence."""


@dataclass(frozen=True)
class EpistemicAssertionGate:
    attempts: int
    varied_probes: bool
    any_attempt_yielded_answer: bool
    per_attempt_yield_prob: float = 0.5
    misclassification_bound: float = 0.05

    def verify(self) -> bool:
        if self.any_attempt_yielded_answer:
            return True  # state is "cannot articulate" (was articulated)
        if not self.varied_probes:
            raise EpistemicMisclassificationError(
                "probes not varied: repeated framing is not evidence"
            )
        if self.attempts <= 0:
            raise EpistemicMisclassificationError(
                "no probe attempts: assertion is unsupported"
            )
        residual = self.per_attempt_yield_prob ** self.attempts
        if residual > self.misclassification_bound:
            raise EpistemicMisclassificationError(
                f"residual {residual:.4f} > bound {self.misclassification_bound} "
                f"after {self.attempts} attempts (p={self.per_attempt_yield_prob})"
            )
        return True


def dispatch_epistemic_assertion(gate: EpistemicAssertionGate) -> str:
    try:
        gate.verify()
    except EpistemicMisclassificationError:
        return "probe-more-or-qualify-assertion"
    return "assert-dont-know"
