test(retrieval-gate): row 5 must read the threshold as a number and compare it with the hold-out

Red first, on behaviour: both assertions are about the checks the row
prints, neither is an import or an attribute error.

Measured by PM on 23588e5: `bool(threshold)` was the whole check, so the
threshold `report-only; any number is acceptable for v1` read as `a
threshold is written: yes`. A threshold that is never compared with a
number cannot fell anything.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-20 08:07:27 +02:00
commit 7e73257f30
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q

View file

@ -1200,3 +1200,85 @@ def test_a_wiki_set_of_one_question_is_refused_on_the_command_line(
with pytest.raises(gate.GateUsage) as refusal:
gate._real_sets([("wiki", str(path), gate.sha256_of(path), str(bundle))])
assert "wiki-20" in str(refusal.value)
# --- step 0: the threshold is a number, and it is compared with something ----
def _registration(
tmp_path: Path,
*,
set_path: Path,
bundle: Path,
threshold: object,
name: str = "registration.json",
) -> Path:
registration = tmp_path / name
registration.write_text(
json.dumps(
{
"set": str(set_path),
"sha256": gate.sha256_of(set_path),
"bundle": str(bundle),
"metric": "questions answered over questions asked",
"threshold": threshold,
"threshold_written_at": "2026-09-19T10:00:00Z",
"written_by": "the session that wrote the eval",
"readings": [{"at": "2026-09-20T09:00:00Z", "value": "not read yet"}],
}
),
encoding="utf-8",
)
return registration
def test_a_threshold_that_is_not_a_number_is_refused(tmp_path: Path) -> None:
"""`bool(threshold)` was the whole check, so `report-only; any number is
acceptable for v1` read as `a threshold is written: yes`. A threshold that
cannot be compared with a number cannot fell anything."""
bundles = _bundles(tmp_path)
registration = _registration(
tmp_path,
set_path=FIXTURES / "set-positive.json",
bundle=bundles["positive"],
threshold="report-only; any number is acceptable for v1",
)
row = gate.row_five(registration, provenance=lambda _: _carried_by_git())
assert any("the threshold is a number: NO" in detail for detail in row.details)
assert row.fails
def test_the_threshold_is_compared_with_the_measured_hold_out(tmp_path: Path) -> None:
"""Both directions, from the same code path: a set the bundle answers
clears a threshold under it, and a set it does not answer falls under one
over it. The measured share is counted here as well, off the set's own
questions, so the row is not the only thing that knows it."""
bundles = _bundles(tmp_path)
clears = gate.row_five(
_registration(
tmp_path,
set_path=FIXTURES / "set-positive.json",
bundle=bundles["positive"],
threshold=0.8,
name="clears.json",
),
provenance=lambda _: _carried_by_git(),
)
assert any("clears the threshold: yes" in detail for detail in clears.details)
assert (clears.k, clears.m, clears.status) == (11, 11, gate.GREEN)
# The independent count: set-miss carries one question, forced to miss.
missing = json.loads((FIXTURES / "set-miss.json").read_text(encoding="utf-8"))
assert len(missing["questions"]) == 1
falls = gate.row_five(
_registration(
tmp_path,
set_path=FIXTURES / "set-miss.json",
bundle=bundles["miss"],
threshold=0.5,
name="falls.json",
),
provenance=lambda _: _carried_by_git(),
)
assert any("clears the threshold: NO" in detail for detail in falls.details)
assert (falls.k, falls.m, falls.status) == (10, 11, gate.RED)