agent-harness / scripts /check_study2_paper_consistency.py
cuber12's picture
Publish agent harness research code and paper artifacts
d61821a verified
Raw
History Blame Contribute Delete
6.3 kB
"""Fail closed when Study 2--4 evidence and manuscript claims drift apart."""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
def _require(condition: bool, message: str) -> None:
if not condition:
raise AssertionError(message)
def audit(root: Path = ROOT) -> dict[str, Any]:
analysis_path = root / "results" / "derived" / "study2" / "e08_analysis.json"
paper_path = root / "paper" / "main.tex"
report = json.loads(analysis_path.read_text(encoding="utf-8"))
study3 = json.loads(
(root / "results/derived/study3/e09_analysis.json").read_text(encoding="utf-8")
)
study4 = json.loads(
(root / "results/derived/study4/e10_analysis.json").read_text(encoding="utf-8")
)
ancillary = json.loads(
(root / "results/derived/study4_ancillary/e11_e12_analysis.json").read_text(
encoding="utf-8"
)
)
paper = paper_path.read_text(encoding="utf-8")
manifest = report["analysis_manifest"]
run_audit = report["audit"]
contrasts = report["contrasts"]
primary = next(row for row in contrasts if row["family"] == "confirmatory_primary")
secondary = [row for row in contrasts if row["family"] != "confirmatory_primary"]
failures = report["failure_analysis"]["failure_stages"]
reliability = report["reliability"]
diagnostic = report["exploratory_tool_protocol_diagnostic"]["by_model"]
_require(manifest["input_cells"] == 912, "analysis must consume 912 E08 cells")
_require(run_audit["main_cells"] == 840, "main cell count drift")
_require(run_audit["reliability_cells"] == 72, "reliability cell count drift")
_require(run_audit["unique_run_ids"] == 912, "run IDs are not unique/complete")
_require(run_audit["model_keys"] == {
"openai/gpt-oss-20b": 456,
"qwen/qwen3.6-35b-a3b": 456,
}, "model assignment is not balanced")
_require(run_audit["execution_revision"] ==
"58933d6fa8af09fcc5a832fb3b523ffb4182bc50", "execution revision drift")
_require(primary["contrast"] == "P1_H007_vs_H000_M002", "primary contrast drift")
_require(primary["tasks"] == 60, "primary task count drift")
_require(primary["left_resolved"] == primary["right_resolved"] == 2,
"primary resolution counts drift")
_require(primary["paired_risk_difference"] == 0.0, "primary effect drift")
_require(primary["risk_difference_ci_low"] == -0.05 and
primary["risk_difference_ci_high"] == 0.05, "primary CI drift")
_require(primary["mcnemar_p"] == 1.0, "primary exact p-value drift")
_require(len(secondary) == 13, "secondary contrast-family size drift")
_require(all(row["mcnemar_p_holm"] == 1.0 for row in secondary),
"a secondary Holm-adjusted p-value changed")
_require(failures == {"empty_patch": 804, "resolved": 16, "tests": 20},
"main endpoint accounting drift")
_require(reliability["observations"] == 72 and reliability["successes"] == 0,
"reliability outcome drift")
_require(reliability["fleiss_kappa"] is None and
reliability["krippendorff_alpha_nominal"] is None and
reliability["icc_1_1"] is None, "degenerate reliability must remain undefined")
_require(diagnostic["M003"]["patch_attempts"] == 887 and
diagnostic["M003"]["patch_protocol_errors"] == 877,
"exploratory protocol diagnostic drift")
study3_primary = next(
row for row in study3["contrasts"] if row["family"] == "confirmatory_primary"
)
_require(study3["audit"]["cells"] == 540, "E09 cell count drift")
_require(
study3_primary["left_count"] == 27
and study3_primary["right_count"] == 0
and study3_primary["paired_risk_difference"] == 0.45,
"E09 primary result drift",
)
_require(
{model: value["selected_interface"] for model, value in
study3["compatibility_gate"]["models"].items()}
== {"M002": "P002", "M003": "P003", "M004": "P003"},
"E09 compatibility gate drift",
)
_require(study4["audit"]["input_cells"] == 180, "E10 cell count drift")
_require(
study4["primary"]["h007_count"] == 1
and study4["primary"]["h000_count"] == 0
and study4["primary"]["exact_task_cluster_sign_flip_p"] == 1.0,
"E10 primary result drift",
)
_require(
all(row["mcnemar_p_holm"] == 1.0 for row in study4["secondary_contrasts"]),
"E10 secondary family drift",
)
_require(ancillary["input_cells"] == 30, "E11/E12 cell count drift")
_require(
ancillary["reliability"]["unanimous_resolution_rate"] == 1.0
and ancillary["reliability"]["unanimous_trajectory_rate"] == 0.0,
"E11 reliability result drift",
)
_require(
ancillary["context_scarcity"]["resolution_by_context"]
== {"16384": 0, "65536": 0},
"E12 context result drift",
)
manuscript_markers = [
"5,453 scored cells",
"resolve 2/60 tasks",
"13 secondary exact tests",
"Only 36/840 main cells",
"877/887",
"912/912 finalized identities",
"exact replacement produces accepted edits on 27/60",
"one H007 resolution and zero H000",
"trajectories match in 0/6",
manifest["analysis_code_revision"][:12],
run_audit["execution_revision"][:12],
]
missing = [marker for marker in manuscript_markers if marker not in paper]
_require(not missing, f"manuscript is missing generated-evidence markers: {missing}")
return {
"status": "pass",
"analysis_revision": manifest["analysis_code_revision"],
"execution_revision": run_audit["execution_revision"],
"cells": manifest["input_cells"],
"primary": primary["contrast"],
"secondary_tests": len(secondary),
"study3_cells": study3["audit"]["cells"],
"study4_main_cells": study4["audit"]["input_cells"],
"study4_ancillary_cells": ancillary["input_cells"],
"paper_markers_checked": len(manuscript_markers),
}
def main() -> None:
print(json.dumps(audit(), indent=2, sort_keys=True))
if __name__ == "__main__":
main()