fix(consume): a withheld concept carries the rule that actually decided it

The quota filters the WHOLE candidate list, so every over-quota candidate
came back `source_quota_exceeded` -- including the ones the RANK had
already put outside k, which the quota only reached because it ran first.

`_fates_without_quota` asks the same cut what would have become of each
candidate with no quota, and the drop keeps THAT rule; only a candidate the
quota-off cut would have delivered is named as the quota's. The packer is
lifted into `_pack` and used by both, so the quota-off fate is decided by
the code the run itself uses and never by a second implementation.

The retrieval gate's row 3 goes 2 of 5 RED to 5 of 5 GREEN. Row 7 is
unchanged at 12 of 14; M01 and M02 lose their row-3 credit, which was the
lying label moving and not the ranking. Suite: 2288 passed, 0 failed; no
committed payload moves a byte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-20 08:24:26 +02:00
commit f81683ea54
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 141 additions and 46 deletions

View file

@ -230,9 +230,22 @@ def test_a_miss_with_no_class_at_all_takes_the_whole_row_to_zero(tmp_path: Path)
# --- row 3 --------------------------------------------------------------------
def test_row_three_is_red_because_the_payload_names_the_quota_for_a_rank(
tmp_path: Path,
def test_row_three_goes_red_again_the_moment_the_label_stops_being_true(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""The RED direction, driven by an input: the library's own behaviour.
This row was red on the shipped code until 2026-09-20 -- every over-quota
candidate came back `source_quota_exceeded`, including the ones the RANK
had already put outside k. Restoring exactly that naming puts the row back
where it was, with the same three fixtures and the same detail line, so
the green reading is not a green nobody can lose.
"""
def every_drop_is_the_quotas(candidates: object, **_: object) -> dict[str, str]:
return _AlwaysTheQuota()
monkeypatch.setattr(consume, "_fates_without_quota", every_drop_is_the_quotas)
row = gate.row_three([_case(tmp_path, "set-classes.json")])
assert row.status == gate.RED
lying = [detail for detail in row.details if "source_quota_exceeded" in detail]
@ -240,6 +253,23 @@ def test_row_three_is_red_because_the_payload_names_the_quota_for_a_rank(
assert all("the quota-off run says `below_k`" in detail for detail in lying)
class _AlwaysTheQuota(dict[str, str]):
"""The pre-2026-09-20 naming: every drop the quota reached is the quota's."""
def __missing__(self, key: str) -> str:
return "source_quota_exceeded"
def test_row_three_is_green_on_the_shipped_code(tmp_path: Path) -> None:
"""And the same three fixtures, unmutated, are the green direction.
Four judged units in this set alone; the fifth in the gate's own run comes
from `set-miss.json`."""
row = gate.row_three([_case(tmp_path, "set-classes.json")])
assert (row.k, row.m, row.status) == (4, 4, gate.GREEN)
assert not [detail for detail in row.details if "source_quota_exceeded" in detail]
def test_row_three_is_green_when_the_printed_reason_is_the_true_one(tmp_path: Path) -> None:
# The budget case: withheld by the pack in BOTH runs, so the label the
# payload prints is the label the quota-off run confirms.
@ -455,19 +485,28 @@ def test_row_seven_is_red_when_a_mutant_survives(tmp_path: Path) -> None:
)
def test_a_mutant_that_only_makes_a_red_row_greener_is_not_felled(tmp_path: Path) -> None:
# The definition, held by a test: removing the quota makes row 3's label
# honest, because there is then no quota to name. Calling that a kill
# would credit this gate with a check it does not have.
def test_a_mutant_is_felled_by_the_row_that_got_worse_and_never_by_one_that_did_not(
tmp_path: Path,
) -> None:
"""PM's definition, held by a test: `worse`, never `different`.
Removing the quota costs row 1 deliveries -- that is the kill. It costs
row 3 nothing, because a cut with no quota has no quota to name falsely,
and crediting row 3 with the kill would give this gate a check it does not
have. Before 2026-09-20 the same mutation made row 3 GREENER, which was
the sharper form of the same point.
"""
cases, _ = gate.synthetic_cases(tmp_path / "bundles", FIXTURES)
baseline = gate.deterministic_rows(cases)
before = {row.number: (row.k, row.m) for row in baseline}
before = {row.number: row.k for row in gate.deterministic_rows(cases)}
with gate._wrap_cut(source_quota=None):
rows = gate.deterministic_rows(
[gate.measure_case(case.question_set, case.bundles) for case in cases]
)
after = {row.number: (row.k, row.m) for row in rows}
assert after[3][0] - after[3][1] > before[3][0] - before[3][1]
after = {row.number: row.k for row in rows}
worse = [number for number in sorted(before) if after[number] < before[number]]
assert 1 in worse, "row 1 is what fells this mutant"
assert 3 not in worse, after
assert after[3] >= before[3]
# --- rows 8 and 9 -------------------------------------------------------------
@ -600,12 +639,12 @@ def test_the_gate_is_red_today_and_says_which_rows(tmp_path: Path) -> None:
rows = gate.evaluate(tmp_path / "bundles")
by_number = {row.number: row for row in rows}
assert sorted(by_number) == [1, 2, 3, 4, 5, 6, 7, 8, 9]
assert [row.number for row in rows if row.fails] == [3, 4, 5, 7, 8, 9]
assert [row.number for row in rows if row.fails] == [4, 5, 7, 8, 9]
# 10, not 9: `set-quota.json` adds row 3's known-positive, one question the
# source quota genuinely decides, and it is a hit.
assert (by_number[1].k, by_number[1].m) == (10, 10)
assert (by_number[2].k, by_number[2].m) == (7, 7)
assert (by_number[3].k, by_number[3].m) == (2, 5)
assert (by_number[3].k, by_number[3].m) == (5, 5)
assert (by_number[6].k, by_number[6].m) == (10, 10)
@ -622,7 +661,7 @@ def test_the_command_exits_one_and_prints_every_row(
printed = capsys.readouterr().out
for number in range(1, 10):
assert f"\n{number} " in f"\n{printed}"
assert "GATE RED: rows 3, 4, 5, 7, 8, 9" in printed
assert "GATE RED: rows 4, 5, 7, 8, 9" in printed
def test_the_json_form_carries_the_same_rows(capsys: pytest.CaptureFixture[str]) -> None: