core/tests/test_setup_router.py
Shay 6a75f5203a feat(contemplation): wire CMB into multi-organ router and failure registry (CMB-d)
CMB (r4_combined_rate) now participates in route_setup and bounded contemplation. R1/R2/R3 readers/
solvers, the CMB reader/solver/oracle, and serving are all UNCHANGED — pure shared-infra integration,
no new comprehension capability (that was CMB-c).

- model.py: Organ += r4_combined_rate.
- classify.py: classify_cmb + _cmb_signature (organ-tagged, cross-organ-distinct) + cmb_reason —
  namespaces CMB reasons cmb_* before the reason-string-keyed registry sees them, so a CMB boundary
  never inherits R2/R3's family for the SAME bare string (R3 rate_unit_mismatch is a GROWTH surface;
  R2/R3 non_integer_solution carry other owners). not_combined_rate_shaped/empty stay bare -> the
  cross input_shape family (router hygiene).
- failure_family.py: Owner += r4; input_shape += not_combined_rate_shaped; 8 CMB families
  (must_remain_refused: cmb_unit_mismatch [until a dimension registry exists — NOT forever],
  cmb_combine_ambiguous, cmb_underdetermined, cmb_non_positive_net, cmb_non_integer; proposal_allowed
  -> cmb_gold_fixture: cmb_unsupported_rate_count/_reciprocal/_clock_interval).
- pass_manager.py: _solve_and_verify_cmb (solver Refusal -> REFUSED_KNOWN_BOUNDARY, never a proposal).

CMB-over-R3 domain-precedence rule (cmb_is_authoritative): when CMB POSITIVELY recognizes
combined-rate shape (a setup, or a substantive cmb_* refusal — NOT the input_shape step-aside), R3's
broader single-rate over-read of the SAME text is inadmissible — for BOTH routing (veto R3
setup_correct) and family attribution (suppress R3 so CMB's sharper diagnosis owns the
terminal/proposal). This came from a pre-build cross-organ pressure-test: R3 reads 'Anna and Ben
paint together; Anna paints 3 rooms/hour. How many do THEY paint in 4 hours?' as a single rate and
would confidently answer a wrong 12. The rule fixes that (-> REFUSED) without touching R3. It does
NOT mean 'CMB always wins': on input_shape CMB cedes (a plain single-rate car problem routes to R3
and solves 180). Narrow CMB<->R3 instance of a future general domain-specificity adjudication.

Tests: new test_cmb_router_contemplation (full terminal matrix; cmb-11 veto-no-wrong-answer; cmb-15
cede-to-R3; solver-refusal-never-proposes; CMB-owned proposal-only artifacts mounted:false; no gold
ambiguous; off-serving AST). Extended router-organ-hygiene to CMB x R1/R2/R3 (0 breaches).
test_setup_router/test_r3_router_contemplation attempt-count 3->4; test_failure_family ALL_REASONS +
growth set. 97 CMB-d tests; 597 broad-net pass (1 unrelated pre-existing red); CMB organ lanes green.
2026-06-08 13:58:48 -07:00

52 lines
2.3 KiB
Python

"""Tests for the deterministic multi-organ setup router (N3).
Pins that each problem routes to exactly the organ that owns it (R1 relational, R2 constraint),
that unreadable problems refuse, that no gold problem is read by both organs (no ambiguity), and
— the wrong=0 invariant — that every routed R2 setup matches the independent gold signature.
"""
from __future__ import annotations
from core.comprehension_attempt import route_setup
from core.comprehension_attempt.classify import _r2_signature
from evals.constraint_oracle.runner import _load_r2_gold, gold_to_problem
from evals.setup_oracle.runner import _load_r1_gold
def test_r2_well_formed_routes_to_r2_and_matches_gold_signature() -> None:
for fx in _load_r2_gold():
result = route_setup(fx["text"], case_id=fx["id"])
if fx["expect"] in ("solved", "solver_refuses"):
assert result.status == "routed", f"{fx['id']}: {result.status}"
assert result.selected is not None and result.selected.organ == "r2_constraints"
# wrong=0: the routed setup is byte-equal to the independent gold setup.
assert result.selected.setup_signature == _r2_signature(gold_to_problem(fx)), fx["id"]
else: # reader_refuses
assert result.status == "all_refused" and result.selected is None
def test_r1_admitted_routes_to_r1_refused_all_refused() -> None:
routed = refused = 0
for fx in _load_r1_gold():
result = route_setup(fx["text"], case_id=fx["id"])
if result.status == "routed":
routed += 1
assert result.selected.organ == "r1_quantitative", fx["id"]
else:
refused += 1
assert result.status == "all_refused"
assert routed == 7 and refused == 3
def test_no_gold_problem_is_ambiguous() -> None:
# Each organ is exclusive on the gold corpora — no text is admitted by both.
for fx in _load_r2_gold() + _load_r1_gold():
assert route_setup(fx["text"]).status != "ambiguous", fx.get("id")
def test_router_never_selects_a_refusal() -> None:
for fx in _load_r2_gold() + _load_r1_gold():
result = route_setup(fx["text"])
if result.selected is not None:
assert result.selected.outcome == "setup_correct"
assert len(result.attempts) == 4 # always one R1 + R2 + R3 + R4(combined-rate) attempt