[NOTICKET] fix(eval): update readiness eval to post-KM-652 floor (drop problem_validated)
Browse filesThe readiness eval crashed at import (`_MISSING_PROBLEM` gone) and would then have hit a
TypeError (`stub_analysis_state(problem_validated=...)` β arg dropped in #4). Same #4
rework regression as test_help. Aligned it to the current floor (>=1 substantive record;
delta-since-report), which no longer gates on a validated goal:
- run_eval: drop the `_MISSING_PROBLEM` import + the `problem` -> code mapping; call
stub_analysis_state() with no arg.
- dataset: remove the `problem_validated` field and the `problem` missing-code from every
case; drop the two cases that only existed to isolate the retired problem gate (now
duplicates); renumber the floor group. Runs 15/15 floor-correct, alignment gap = 2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@@ -1,40 +1,37 @@
|
|
| 1 |
{
|
| 2 |
"_about": "Golden dataset for the report-readiness signal (`src/agents/report/readiness.is_report_ready`). Deterministic (no LLM): each case declares an analysis state + a set of persisted AnalysisRecords/reports, and the runner feeds them through is_report_ready via injectable fake stores, scoring the boolean `ready` AND the `missing` gaps. Floor cases should score ~100% (regression value). The `alignment` group probes the deferred LLM-judge β see _alignment.",
|
| 3 |
-
"_floor": "is_report_ready's deterministic floor
|
| 4 |
"_records": "records[].analysis = 'success' (analyze_* succeeded β substantive) | 'failure' (analyze_* failed, data-access still succeeded β the real e2e case, NOT substantive) | 'none' (only check_/retrieve_ succeeded, no analyze task β NOT substantive; guards the 'any task succeeded' trap). records[].findings = count (a failure run still has findings; floor ignores them now). records[].age_min / reports[].age_min = minutes ago (smaller = newer).",
|
| 5 |
-
"_alignment": "ALIGNMENT cases: a successful analysis (floor says ready=true) but `aligned=false` means it doesn't address the
|
| 6 |
"schema": {
|
| 7 |
"id": "stable per-case handle, <group>_<NN>",
|
| 8 |
"group": "floor | delta | edge | alignment",
|
| 9 |
-
"problem_validated": "bool",
|
| 10 |
"report_id": "null = never generated; a string = a report exists",
|
| 11 |
"records": "[{ analysis: success|failure|none, findings: int, age_min: int }]",
|
| 12 |
"reports": "[{ age_min: int }] (only meaningful when report_id set)",
|
| 13 |
-
"aligned": "bool β do the analyses address the
|
| 14 |
"expected_ready": "what the deterministic floor SHOULD return",
|
| 15 |
-
"expected_missing": "subset of [
|
| 16 |
"note": "human-readable description"
|
| 17 |
},
|
| 18 |
"cases": [
|
| 19 |
-
{ "id": "floor_01", "group": "floor", "
|
| 20 |
-
{ "id": "floor_02", "group": "floor", "
|
| 21 |
-
{ "id": "floor_03", "group": "floor", "
|
| 22 |
-
{ "id": "floor_04", "group": "floor", "
|
| 23 |
-
{ "id": "floor_05", "group": "floor", "
|
| 24 |
-
{ "id": "floor_06", "group": "floor", "
|
| 25 |
-
{ "id": "floor_07", "group": "floor", "problem_validated": true, "report_id": null, "records": [{ "analysis": "success", "findings": 3, "age_min": 40 }, { "analysis": "success", "findings": 1, "age_min": 10 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "multiple successful analyses β ready" },
|
| 26 |
-
{ "id": "floor_08", "group": "floor", "problem_validated": true, "report_id": null, "records": [{ "analysis": "failure", "findings": 3, "age_min": 30 }, { "analysis": "success", "findings": 2, "age_min": 10 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "one failed + one successful analysis β the successful one is enough β ready" },
|
| 27 |
|
| 28 |
-
{ "id": "delta_01", "group": "delta", "
|
| 29 |
-
{ "id": "delta_02", "group": "delta", "
|
| 30 |
-
{ "id": "delta_03", "group": "delta", "
|
| 31 |
-
{ "id": "delta_04", "group": "delta", "
|
| 32 |
-
{ "id": "delta_05", "group": "delta", "
|
| 33 |
|
| 34 |
-
{ "id": "edge_01", "group": "edge", "
|
| 35 |
|
| 36 |
-
{ "id": "align_01", "group": "alignment", "
|
| 37 |
-
{ "id": "align_02", "group": "alignment", "
|
| 38 |
-
{ "id": "align_03", "group": "alignment", "
|
| 39 |
]
|
| 40 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"_about": "Golden dataset for the report-readiness signal (`src/agents/report/readiness.is_report_ready`). Deterministic (no LLM): each case declares an analysis state + a set of persisted AnalysisRecords/reports, and the runner feeds them through is_report_ready via injectable fake stores, scoring the boolean `ready` AND the `missing` gaps. Floor cases should score ~100% (regression value). The `alignment` group probes the deferred LLM-judge β see _alignment.",
|
| 3 |
+
"_floor": "is_report_ready's deterministic floor (KM-652, after the problem_validated gate was removed 2026-06-24): (1) >=1 SUBSTANTIVE record, (2) delta-since-report. SUBSTANTIVE = a record whose ANALYSIS task succeeded: tasks_run contains a task with status=success AND an analyze_* tool. A failed analysis still persists a record WITH findings (narrating the failure) and its data-access tasks (check_/retrieve_) succeed β so neither 'has findings' nor 'any task succeeded' counts. Only a successful analyze_* does.",
|
| 4 |
"_records": "records[].analysis = 'success' (analyze_* succeeded β substantive) | 'failure' (analyze_* failed, data-access still succeeded β the real e2e case, NOT substantive) | 'none' (only check_/retrieve_ succeeded, no analyze task β NOT substantive; guards the 'any task succeeded' trap). records[].findings = count (a failure run still has findings; floor ignores them now). records[].age_min / reports[].age_min = minutes ago (smaller = newer).",
|
| 5 |
+
"_alignment": "ALIGNMENT cases: a successful analysis (floor says ready=true) but `aligned=false` means it doesn't address the analysis objective β a human would say NOT ready. Scored floor-correct, counted separately as the 'alignment gap' = evidence for/against the LLM-judge. Alignment label owner: Rifqi (report semantics) + Sofhia.",
|
| 6 |
"schema": {
|
| 7 |
"id": "stable per-case handle, <group>_<NN>",
|
| 8 |
"group": "floor | delta | edge | alignment",
|
|
|
|
| 9 |
"report_id": "null = never generated; a string = a report exists",
|
| 10 |
"records": "[{ analysis: success|failure|none, findings: int, age_min: int }]",
|
| 11 |
"reports": "[{ age_min: int }] (only meaningful when report_id set)",
|
| 12 |
+
"aligned": "bool β do the analyses address the objective? (floor ignores this)",
|
| 13 |
"expected_ready": "what the deterministic floor SHOULD return",
|
| 14 |
+
"expected_missing": "subset of [analysis, delta]",
|
| 15 |
"note": "human-readable description"
|
| 16 |
},
|
| 17 |
"cases": [
|
| 18 |
+
{ "id": "floor_01", "group": "floor", "report_id": null, "records": [], "reports": [], "aligned": false, "expected_ready": false, "expected_missing": ["analysis"], "note": "new analysis: no analysis run yet β not ready" },
|
| 19 |
+
{ "id": "floor_02", "group": "floor", "report_id": null, "records": [{ "analysis": "failure", "findings": 3, "age_min": 20 }], "reports": [], "aligned": false, "expected_ready": false, "expected_missing": ["analysis"], "note": "T1 REGRESSION: analyze_* FAILED but the record still has 3 findings (narrating failure) + check/retrieve succeeded. Must NOT be ready β this is the live e2e case (analyze_aggregate failed, report still got generated under the old 'has findings' rule)." },
|
| 20 |
+
{ "id": "floor_03", "group": "floor", "report_id": null, "records": [{ "analysis": "none", "findings": 0, "age_min": 15 }], "reports": [], "aligned": false, "expected_ready": false, "expected_missing": ["analysis"], "note": "T1 nuance: only data-access tasks (check/retrieve) succeeded, no analyze task. 'any task succeeded' would wrongly pass β must NOT be ready." },
|
| 21 |
+
{ "id": "floor_04", "group": "floor", "report_id": null, "records": [{ "analysis": "success", "findings": 2, "age_min": 15 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "one successful analysis, no prior report β ready" },
|
| 22 |
+
{ "id": "floor_05", "group": "floor", "report_id": null, "records": [{ "analysis": "success", "findings": 3, "age_min": 40 }, { "analysis": "success", "findings": 1, "age_min": 10 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "multiple successful analyses β ready" },
|
| 23 |
+
{ "id": "floor_06", "group": "floor", "report_id": null, "records": [{ "analysis": "failure", "findings": 3, "age_min": 30 }, { "analysis": "success", "findings": 2, "age_min": 10 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "one failed + one successful analysis β the successful one is enough β ready" },
|
|
|
|
|
|
|
| 24 |
|
| 25 |
+
{ "id": "delta_01", "group": "delta", "report_id": "rep-1", "records": [{ "analysis": "success", "findings": 2, "age_min": 120 }], "reports": [{ "age_min": 5 }], "aligned": true, "expected_ready": false, "expected_missing": ["delta"], "note": "report exists, all analysis older than it β nothing new to report" },
|
| 26 |
+
{ "id": "delta_02", "group": "delta", "report_id": "rep-1", "records": [{ "analysis": "success", "findings": 2, "age_min": 5 }], "reports": [{ "age_min": 120 }], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "newer successful analysis after the report β ready to regenerate" },
|
| 27 |
+
{ "id": "delta_03", "group": "delta", "report_id": "rep-1", "records": [{ "analysis": "success", "findings": 1, "age_min": 90 }, { "analysis": "success", "findings": 2, "age_min": 10 }], "reports": [{ "age_min": 60 }], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "one old + one newer-than-report success β ready" },
|
| 28 |
+
{ "id": "delta_04", "group": "delta", "report_id": "rep-2", "records": [{ "analysis": "success", "findings": 2, "age_min": 90 }], "reports": [{ "age_min": 200 }, { "age_min": 30 }], "aligned": true, "expected_ready": false, "expected_missing": ["delta"], "note": "multiple reports β newest wins; analysis older than newest report β not ready" },
|
| 29 |
+
{ "id": "delta_05", "group": "delta", "report_id": "rep-1", "records": [{ "analysis": "success", "findings": 2, "age_min": 120 }, { "analysis": "failure", "findings": 3, "age_min": 5 }], "reports": [{ "age_min": 60 }], "aligned": true, "expected_ready": false, "expected_missing": ["delta"], "note": "T1+delta: the only NEW analysis (age 5) is a FAILURE β no NEW substantive since the report β not ready. A failed retry must not unlock a duplicate report." },
|
| 30 |
|
| 31 |
+
{ "id": "edge_01", "group": "edge", "report_id": null, "records": [], "reports": [], "aligned": false, "expected_ready": false, "expected_missing": ["analysis"], "note": "doc-only analysis (RAG, no structured run) produces no AnalysisRecord β never report-able under the floor. PRODUCT QUESTION: should doc-only be report-able?" },
|
| 32 |
|
| 33 |
+
{ "id": "align_01", "group": "alignment", "report_id": null, "records": [{ "analysis": "success", "findings": 2, "age_min": 15 }], "reports": [], "aligned": false, "expected_ready": true, "expected_missing": [], "note": "GAP: successful analysis but it doesn't address the objective. Floor says ready; a human would say not-ready." },
|
| 34 |
+
{ "id": "align_02", "group": "alignment", "report_id": null, "records": [{ "analysis": "success", "findings": 3, "age_min": 25 }, { "analysis": "success", "findings": 1, "age_min": 5 }], "reports": [], "aligned": false, "expected_ready": true, "expected_missing": [], "note": "GAP: lots of successful analysis, none aligned to the objective" },
|
| 35 |
+
{ "id": "align_03", "group": "alignment", "report_id": null, "records": [{ "analysis": "success", "findings": 2, "age_min": 15 }], "reports": [], "aligned": true, "expected_ready": true, "expected_missing": [], "note": "control: successful AND aligned β genuinely ready, no gap" }
|
| 36 |
]
|
| 37 |
}
|
|
@@ -35,7 +35,6 @@ from src.agents.gate import stub_analysis_state
|
|
| 35 |
from src.agents.report.readiness import (
|
| 36 |
_MISSING_ANALYSIS,
|
| 37 |
_MISSING_DELTA,
|
| 38 |
-
_MISSING_PROBLEM,
|
| 39 |
is_report_ready,
|
| 40 |
)
|
| 41 |
|
|
@@ -45,9 +44,9 @@ RESULTS_DIR = _HERE / "results"
|
|
| 45 |
GROUPS = ["floor", "delta", "edge", "alignment"]
|
| 46 |
|
| 47 |
# Dataset short codes -> the exact `missing` strings is_report_ready emits. Imported
|
| 48 |
-
# from the module so the dataset stays readable and survives wording changes.
|
|
|
|
| 49 |
_CODE_TO_MISSING = {
|
| 50 |
-
"problem": _MISSING_PROBLEM,
|
| 51 |
"analysis": _MISSING_ANALYSIS,
|
| 52 |
"delta": _MISSING_DELTA,
|
| 53 |
}
|
|
@@ -139,7 +138,9 @@ def _build_reports(specs: list[dict[str, Any]], now: datetime) -> list[_FakeRepo
|
|
| 139 |
|
| 140 |
async def run_case(case: dict[str, Any]) -> CaseResult:
|
| 141 |
now = datetime.now(UTC)
|
| 142 |
-
|
|
|
|
|
|
|
| 143 |
if case.get("report_id"):
|
| 144 |
state = state.model_copy(update={"report_id": case["report_id"]})
|
| 145 |
|
|
|
|
| 35 |
from src.agents.report.readiness import (
|
| 36 |
_MISSING_ANALYSIS,
|
| 37 |
_MISSING_DELTA,
|
|
|
|
| 38 |
is_report_ready,
|
| 39 |
)
|
| 40 |
|
|
|
|
| 44 |
GROUPS = ["floor", "delta", "edge", "alignment"]
|
| 45 |
|
| 46 |
# Dataset short codes -> the exact `missing` strings is_report_ready emits. Imported
|
| 47 |
+
# from the module so the dataset stays readable and survives wording changes. The
|
| 48 |
+
# `problem` code was retired with the problem_validated gate (KM-652, 2026-06-24).
|
| 49 |
_CODE_TO_MISSING = {
|
|
|
|
| 50 |
"analysis": _MISSING_ANALYSIS,
|
| 51 |
"delta": _MISSING_DELTA,
|
| 52 |
}
|
|
|
|
| 138 |
|
| 139 |
async def run_case(case: dict[str, Any]) -> CaseResult:
|
| 140 |
now = datetime.now(UTC)
|
| 141 |
+
# The problem_validated gate was removed (KM-652); readiness no longer reads the goal,
|
| 142 |
+
# so a bare stub state + report_id is all is_report_ready needs.
|
| 143 |
+
state = stub_analysis_state()
|
| 144 |
if case.get("report_id"):
|
| 145 |
state = state.model_copy(update={"report_id": case["report_id"]})
|
| 146 |
|