test(reader-arc): Q3 hazard-close — lock q:difference fail-closed (no guessed direction)

Discharges Josh's Q3 ruling: defer the q:difference capability, close the
hazard now. _pattern_b_comparative_candidates is inert by construction
(returns []), so 'how many more/fewer … than …' questions refuse end-to-end
even when every statement injects cleanly. This suite LOCKS that so a future
D.5 wiring cannot reopen the guessed-direction hole without positively
determining the more/fewer direction. Verified inert-safe by 5 direct tests.
This commit is contained in:
Shay 2026-07-18 21:57:36 -07:00
parent 2da1a33839
commit 81688465a5

View file

@ -0,0 +1,39 @@
"""ADR-0250 increment 1 — Q3 hazard-close: q:difference is fail-closed.
Josh's Q3 ruling deferred the q:difference *capability* (its cases strand on
multi-compound) but required the hazard be CLOSED now: the partial Pattern-B
"how many more/fewer" path must never emit a guessed-direction answer. The
direction bit ("more…than" AB vs "fewer…than" BA) is a wrong=0 driver
that must be positively determined; until it is, the question MUST refuse.
`_pattern_b_comparative_candidates` is inert by construction (returns []), so
these questions refuse end-to-end. This suite LOCKS that so a future D.5 wiring
cannot silently reopen the hazard without the direction determination. The
critical cases are the ones where every STATEMENT injects cleanly a guessed
answer would be most likely there, and matching gold by luck would be a
sealed-test wrong wearing a success costume.
"""
from __future__ import annotations
import pytest
from generate.math_candidate_graph import parse_and_solve
# Each: statements parse cleanly; only the q:difference question is in play.
# Every one MUST refuse (answer is None) — never a signed-difference answer.
_Q_DIFFERENCE_PROBLEMS = [
"Alice has 10 apples. Bob has 4 apples. How many more apples does Alice have than Bob?",
"Alice has 10 apples. Bob has 4 apples. How many fewer apples does Bob have than Alice?",
"Whitney bought 9 books and 7 magazines. How many more books than magazines did Whitney buy?",
"Tom made 12 cookies. Sam made 5 cookies. How many more cookies did Tom make than Sam?",
"Mary has a bag holding 20 pounds. She buys 4 pounds of beans. How many more pounds can Mary fit?",
]
@pytest.mark.parametrize("problem", _Q_DIFFERENCE_PROBLEMS)
def test_q_difference_refuses_no_guessed_direction(problem: str) -> None:
result = parse_and_solve(problem)
assert result.answer is None, (
"q:difference must refuse (deferred capability, hazard closed): a "
f"guessed-direction answer {result.answer!r} is a wrong=0 hole. Problem: {problem!r}"
)