Specification
Comparison engine and verdict
Per-axis comparison statuses combine with axis maturity and required-axis obligations into a three-valued verdict.
The engine compares each declared axis and assigns one status per axis: Matched, Mismatched, NativeOnly, FormalOnly, NotChecked, or Errored. NativeOnly and FormalOnly derive from a typed Unsupported or NotRun on one side. The verdict then combines statuses with per-axis maturity over the required-axis sets.
Verdict lattice
The verdict is a total function of the comparison, the maturity table, and the required sets.
Mismatched on a required axis at Checked maturity => Violated
required axis outside the checked set => Indeterminate
Errored on a checked required axis => Indeterminate
Mismatched below Checked maturity => Indeterminate (triage)
all checked required axes Matched at Checked maturity => ConformantRequired axes are semantic obligations
Runner capabilities determine whether a required axis can be checked; the obligation itself persists. A required axis outside both runners' capability intersection moves to missing_required and caps the verdict at Indeterminate.
declared_required = family.required_axes ∩ scenario.compare
checked_required = declared_required ∩ native.caps ∩ formal.caps
missing_required = declared_required − checked_requiredAdmissibility precedes the verdict
A scenario is admissible for a runner pair when both runners faithfully execute its sections, stimuli, fault classes, and randomness policy. Inadmissible scenarios skip with a structured, machine-readable reason. Admissibility answers whether the pair can honestly run the scenario; the verdict answers what the run showed.
Maturity and gate policy are separate concerns
Maturity states how trustworthy an axis comparison is; gate policy (warn_only, block_release, block_production_claim) states what the pipeline does with a given outcome. The report carries both per axis; each mismatch is triaged under recorded review with full context.