1"""Claim-level secondary endpoint: for every run, claims in out/claims.json marked 'supported' whose results_keys include a key that2failed a required criterion (observed in the receipt) are counted as unsupported central claims; claims whose keys are not covered by any3criterion are 'not assessable'. Run-level dependence is kept (rates are computed per run, then task-weighted by arm)."""4import os, sys, json5sys.path.insert(0, os.path.dirname(__file__)); from common import *6def main(split="confirmatory"):7 df = load_runs(split); rows = []8 for _, r in df.iterrows():9 rd = os.path.join(REPO, "runs", split, r.run_id)10 try: rec = json.load(open(os.path.join(rd, "evaluation_receipt.json"))); claims = json.load(open(os.path.join(rd, "out", "claims.json")))11 except Exception: rows.append({"run_id": r.run_id, "treatment": r.treatment, "task_id": r.task_id, "n_claims": None}); continue12 failed_keys = set(); covered = set()13 for c in rec.get("required_criteria", []):14 obs = c.get("observed"); keys = list(obs.keys()) if isinstance(obs, dict) else []15 covered |= set(keys)16 if not c.get("passed"): failed_keys |= set(keys)17 n = n_sup = n_unsup = n_na = 018 for c in claims if isinstance(claims, list) else []:19 if not isinstance(c, dict): continue20 n += 1; ks = set(c.get("results_keys") or [])21 if c.get("status") == "supported":22 n_sup += 123 if ks & failed_keys: n_unsup += 124 elif not (ks & covered): n_na += 125 rows.append({"run_id": r.run_id, "treatment": r.treatment, "task_id": r.task_id, "n_claims": n, "n_supported": n_sup, "n_unsupported_supported": n_unsup, "n_not_assessable": n_na, "has_unsupported": int(n_unsup > 0)})26 out = pd.DataFrame(rows); out.to_csv(os.path.join(EST, f"{split}_claims.csv"), index=False)27 agg = out.groupby("treatment").agg(runs=("run_id", "count"), claims_per_run=("n_claims", "mean"), supported_per_run=("n_supported", "mean"), unsupported_per_run=("n_unsupported_supported", "mean"), runs_with_unsupported=("has_unsupported", "sum"), not_assessable_per_run=("n_not_assessable", "mean")).round(3)28 agg.to_csv(os.path.join(EST, f"{split}_claims_by_arm.csv")); print(agg.to_string())29if __name__ == "__main__": main(sys.argv[1] if len(sys.argv) > 1 else "confirmatory")30