Introduced in v5.2.0. The DiagnosticResult model is an additive contract — no existing engine return types are changed. Engines migrate incrementally.
QWED verification engines historically returned ad-hoc Dict[str, Any] results with no consistent structure. Three incompatible VerificationResult dataclasses existed. Some engines returned (bool, str) tuples. Verification diagnostics were not separable by audience — agents saw internal detection patterns, developers couldn’t reliably find expected vs actual values, and auditors had no proof artifact references.v5.2.0 introduces a unified DiagnosticResult type with three disclosure layers, each targeted at a specific audience.
Field:proof_ref: Optional[str]Cryptographic hash (sha256:...) of retained proof artifact. Present only when status == VERIFIED and proof was established. None for UNVERIFIABLE / BLOCKED.This is the authority bit. Downstream gates use a mechanical rule:
if result.proof_ref is not None: # Authoritative — admissible for control flow admit()else: # Non-authoritative — reject for control flow block()
Richer distinctions (ambiguity, insufficient evidence, non-convergence, provider drift) live in developer_fields.constraint_id, not in status values. This keeps the taxonomy small while preserving diagnostic richness.
No HEURISTIC, AMBIGUOUS, or CORRECTION_NEEDED statuses. Ambiguity IS unverifiability — the distinction is structured in constraint_id, not in the status string.
__post_init__ raises ValueError if status == VERIFIED and proof_ref is None or empty. “VERIFIED without proof” is impossible to construct — not a caller convention, a type-level invariant.
Both DiagnosticResult and AdvisoryCheck are frozen=True. Post-construction mutation of proof_ref or status is blocked — prevents bypassing the authority contract.
r = DiagnosticResult.unverifiable("no", {})r.proof_ref = "sha256:fake" # ← raises FrozenInstanceError
AdvisoryCheck represents non-proof-bearing analysis (LLM fallback, NLI entailment, VLM interpretation, heuristic consistency checks). It populates developer_fields.advisory_checks with advisory_only=True enforced via __post_init__.Advisory checks never set status or proof_ref. This structurally enforces the constraint: diagnostics must never originate from model reasoning, confidence, or self-assessment.
from_legacy_dictraises for legacy VERIFIED results — proof artifacts were discarded by pre-v5.2.0 engines, so backfilling is impossible. Use DiagnosticResult.verified() with explicit evidence for true verified results.