fix(retrieval-gate): row 5 reads the hold-out set in the schema the set declares
Row 5 read every registered set with the gate's synthetic reader, so a set written in a consumer's own question-set schema came back "not a question set this gate can read: 'set_id'" -- a NO no such set could turn, whatever it measured. The SET now says how it is read, and the registration carries nothing about it: `read_hold_out_set` checks the pinned sha256, then routes on the set's own `schema` field. `fase-sporsmaal/1` goes through the same adapter and hit_rule as row 8 (`_wiki_questions`, factored out of `read_real_set` so the two rows share one reading); a set with no `schema` is the gate's synthetic form through `load_set`, unchanged; any other schema is a NO that names it (fail closed). Chosen to recognise the set's schema rather than add a field to the registration because the registration then needs to know nothing about the reading, and an unknown schema still fails with a named reason. The row still prints only answered of asked against the threshold, never which hold-out question missed; a test holds that. src/ untouched, MUTANT_BAR unchanged. CLAUDE.md gains one sentence on row 5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3aff2ca0aa
commit
a381361d99
2 changed files with 73 additions and 18 deletions
|
|
@ -1385,7 +1385,13 @@ and fixtures, never code.
|
||||||
itself; three now read GIT (committed and unmodified, its commit is not
|
itself; three now read GIT (committed and unmodified, its commit is not
|
||||||
itself a ranking change, a ranking change landed AFTER it), the last being
|
itself a ranking change, a ranking change landed AFTER it), the last being
|
||||||
the one that cannot be self-attested. What git cannot prove -- that nobody
|
the one that cannot be self-attested. What git cannot prove -- that nobody
|
||||||
read the number first -- is stated, not implied. **Row 7's bar** was 90 % of
|
read the number first -- is stated, not implied. Since 2026-09-23 row 5
|
||||||
|
reads the hold-out set in the schema the SET declares
|
||||||
|
(`HOLD_OUT_SCHEMAS`: `fase-sporsmaal/1` goes through row 8's own adapter
|
||||||
|
and `hit_rule`, no `schema` is the gate's synthetic form, any other schema
|
||||||
|
is a NO naming it) -- it read every set with the synthetic reader, so a set
|
||||||
|
in a consumer's schema was a NO nothing could turn. It prints the share and
|
||||||
|
never which hold-out question missed, and a test holds that. **Row 7's bar** was 90 % of
|
||||||
a list in the file a capability session edits, so seven duplicate `k = 1`
|
a list in the file a capability session edits, so seven duplicate `k = 1`
|
||||||
mutants read `18 of 20 GREEN`; `MUTANT_ROSTER` and `MUTANT_COUNT` are pinned
|
mutants read `18 of 20 GREEN`; `MUTANT_ROSTER` and `MUTANT_COUNT` are pinned
|
||||||
apart from `MUTANTS`, duplicates are refused, and the bar is the roster's.
|
apart from `MUTANTS`, duplicates are refused, and the bar is the roster's.
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ from llm_ingestion_okf.quality import ( # noqa: E402
|
||||||
|
|
||||||
FIXTURES = REPO / "tests" / "fixtures" / "retrieval"
|
FIXTURES = REPO / "tests" / "fixtures" / "retrieval"
|
||||||
|
|
||||||
#: The hold-out registration. Absent today, which is what makes row 5 red; the
|
#: The hold-out registration. The row reads a path so a test can drive both
|
||||||
#: row reads a path so a test can drive both directions without editing code.
|
#: directions without editing code.
|
||||||
HOLDOUT_REGISTRATION = FIXTURES / "holdout-registration.json"
|
HOLDOUT_REGISTRATION = FIXTURES / "holdout-registration.json"
|
||||||
|
|
||||||
GREEN = "GREEN"
|
GREEN = "GREEN"
|
||||||
|
|
@ -1662,7 +1662,7 @@ def _hold_out_verdict(
|
||||||
if not set_path.is_file():
|
if not set_path.is_file():
|
||||||
return False, f"the set is absent at {_display(set_path)}"
|
return False, f"the set is absent at {_display(set_path)}"
|
||||||
try:
|
try:
|
||||||
question_set = load_set(set_path, pinned)
|
question_set = read_hold_out_set(set_path, pinned)
|
||||||
bundles = _bundle_map(bundle)
|
bundles = _bundle_map(bundle)
|
||||||
if list(bundles) == [""] and question_set.bundle:
|
if list(bundles) == [""] and question_set.bundle:
|
||||||
bundles = {question_set.bundle: bundles[""]}
|
bundles = {question_set.bundle: bundles[""]}
|
||||||
|
|
@ -2212,23 +2212,72 @@ def read_real_set(name: str, path: Path, expected_sha256: str) -> QuestionSet:
|
||||||
)
|
)
|
||||||
spec = json.loads(raw.decode("utf-8"))
|
spec = json.loads(raw.decode("utf-8"))
|
||||||
if name == "wiki":
|
if name == "wiki":
|
||||||
# The set's own `hit_rule`, verbatim: an excerpt whose `source_file` is
|
return QuestionSet("wiki-20", "wiki", path, measured, _wiki_questions(spec), ())
|
||||||
# the fasit's document AND whose text carries the fasit's quote.
|
|
||||||
questions = tuple(
|
|
||||||
Question(
|
|
||||||
id=str(entry["id"]),
|
|
||||||
question=str(entry["question"]),
|
|
||||||
fasit=tuple(
|
|
||||||
Fasit(by="source_file", value=f"{item['doc']}.md", quote=str(item["quote"]))
|
|
||||||
for item in entry["fasit"]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
for entry in spec["questions"]
|
|
||||||
)
|
|
||||||
return QuestionSet("wiki-20", "wiki", path, measured, questions, ())
|
|
||||||
raise GateUsage(f"unknown real set `{name}`; the one real set is `wiki`")
|
raise GateUsage(f"unknown real set `{name}`; the one real set is `wiki`")
|
||||||
|
|
||||||
|
|
||||||
|
def _wiki_questions(spec: Mapping[str, Any]) -> tuple[Question, ...]:
|
||||||
|
"""The wiki set's own `hit_rule`, verbatim: an excerpt whose `source_file`
|
||||||
|
is the fasit's document AND whose text carries the fasit's quote. One
|
||||||
|
reading of the schema, shared by row 8 and row 5."""
|
||||||
|
return tuple(
|
||||||
|
Question(
|
||||||
|
id=str(entry["id"]),
|
||||||
|
question=str(entry["question"]),
|
||||||
|
fasit=tuple(
|
||||||
|
Fasit(by="source_file", value=f"{item['doc']}.md", quote=str(item["quote"]))
|
||||||
|
for item in entry["fasit"]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for entry in spec["questions"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#: The schemas a registered hold-out set may declare in its own `schema`
|
||||||
|
#: field, and the bundle key its questions are read under. The SET says how
|
||||||
|
#: it is read, so the registration carries nothing about it; a set with no
|
||||||
|
#: `schema` is in this gate's own synthetic form (`load_set`), and a schema
|
||||||
|
#: not named here is a NO with its name -- a set read in a shape it was not
|
||||||
|
#: written in measures nothing.
|
||||||
|
HOLD_OUT_SCHEMAS: Mapping[str, str] = {"fase-sporsmaal/1": "wiki"}
|
||||||
|
|
||||||
|
|
||||||
|
def read_hold_out_set(path: Path, expected_sha256: str) -> QuestionSet:
|
||||||
|
"""The registered hold-out set, read in the schema it declares.
|
||||||
|
|
||||||
|
Raises GateUsage for a set that is not the pinned bytes or declares a
|
||||||
|
schema this gate does not read; `_hold_out_verdict` turns either into a
|
||||||
|
NO with its reason.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
raw = path.read_bytes()
|
||||||
|
except OSError as error:
|
||||||
|
raise GateUsage(f"cannot read the question set {path}: {error}") from error
|
||||||
|
measured = hashlib.sha256(raw).hexdigest()
|
||||||
|
if measured != expected_sha256:
|
||||||
|
raise GateUsage(
|
||||||
|
f"{path}: expected sha256 {expected_sha256}, measured {measured}; "
|
||||||
|
"refusing to measure a set that is not the set that was pinned"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
spec = json.loads(raw.decode("utf-8"))
|
||||||
|
except (UnicodeDecodeError, json.JSONDecodeError) as error:
|
||||||
|
raise GateUsage(f"{path}: not readable as JSON: {error}") from error
|
||||||
|
schema = spec.get("schema") if isinstance(spec, dict) else None
|
||||||
|
if schema is None:
|
||||||
|
return load_set(path, expected_sha256)
|
||||||
|
if schema not in HOLD_OUT_SCHEMAS:
|
||||||
|
raise GateUsage(
|
||||||
|
f"the set's schema `{schema}` is not one this gate reads "
|
||||||
|
f"({', '.join(HOLD_OUT_SCHEMAS)}, or no `schema` for this gate's own form)"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
questions = _wiki_questions(spec)
|
||||||
|
except (KeyError, TypeError, ValueError) as error:
|
||||||
|
raise GateUsage(f"{path}: not a `{schema}` set this gate can read: {error}") from error
|
||||||
|
return QuestionSet("hold-out", HOLD_OUT_SCHEMAS[schema], path, measured, questions, ())
|
||||||
|
|
||||||
|
|
||||||
#: The sets row 8 is the measurement of, by name: a run that hands over some
|
#: The sets row 8 is the measurement of, by name: a run that hands over some
|
||||||
#: of them has measured some of them, and the row says so. Left to
|
#: of them has measured some of them, and the row says so. Left to
|
||||||
#: `len(real)` the row came back `6 of 6 GREEN` on one set of three (PM's J2,
|
#: `len(real)` the row came back `6 of 6 GREEN` on one set of three (PM's J2,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue