core/generate/derivation
Shay 0bdb3a441c feat(adr-0175-phase3a): self-verification gate (built before the search)
ADR-0175 Phase 3 splits wrong=0-first: build the gate (3a) and PROVE invariant #2
before the bounded search (3b) that could exploit gaps.

generate/derivation/:
- model.py: Quantity / Step / GroundedDerivation. A derivation is a left-fold over
  text-sourced quantities; each Step carries its licensing cue (the lexeme the
  search claims licenses the op).
- verify.py: self_verifies() — grounded operands ∧ grounded operation cues ∧ unit
  consistency ∧ no divide-by-zero. Grounding REUSES the canonical primitives from
  math_roundtrip (_tokens/_token_in/_value_grounds) so the gate cannot drift from
  the round-trip contract. select_self_verified() adds the uniqueness rule:
  unique self-verifying answer resolves; zero or disagreeing refuse (wrong=0).

INVARIANT #2 proven (TestInvariant2_NoSpuriousSelfVerification): the gate refuses
to self-verify a derivation that is not grounded+unit-consistent+unique even when
its value coincides with gold — the 20/5==4 class:
- invented operand not in text -> refused
- operation cue not in text -> refused (division not licensed by any present cue)
- value coincidence (20/5=4) with ungrounded op -> still refused
- add across units (pounds + reps) -> refused
- divide-by-zero -> refused
Plus uniqueness: disagreeing grounded derivations -> refuse; agreeing -> resolve.

Phase 3a is inert (nothing wires generate.derivation into serving). 3b is the
bounded search that produces derivations for this gate + measures the flip-curve
in the practice lane under perturbation.

Verified: 16/16; ruff clean; smoke 67/67; no serving import.
2026-05-28 15:19:02 -07:00
..
__init__.py feat(adr-0175-phase3a): self-verification gate (built before the search) 2026-05-28 15:19:02 -07:00
model.py feat(adr-0175-phase3a): self-verification gate (built before the search) 2026-05-28 15:19:02 -07:00
verify.py feat(adr-0175-phase3a): self-verification gate (built before the search) 2026-05-28 15:19:02 -07:00