diff options
| author | YurenHao0426 <Blackhao0426@gmail.com> | 2026-07-26 14:47:23 -0500 |
|---|---|---|
| committer | YurenHao0426 <Blackhao0426@gmail.com> | 2026-07-26 14:47:23 -0500 |
| commit | ff0069f8d0dabbb8819a726bd899381e8a95462c (patch) | |
| tree | b10cfc173d6757c2eec16d93c0c43a0ff5cc336e | |
| parent | 31b70e1b1f2e7fd26c9c3228f525fc0b5192cd81 (diff) | |
fix: audit sham projection before terminal collapse
| -rw-r--r-- | experiments/analyze_kp_teaching_signal.py | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/experiments/analyze_kp_teaching_signal.py b/experiments/analyze_kp_teaching_signal.py index db8649a..b850a81 100644 --- a/experiments/analyze_kp_teaching_signal.py +++ b/experiments/analyze_kp_teaching_signal.py @@ -127,12 +127,22 @@ def validate_record(path, rule, source_commit, bp_reference_macs): and max(value["maximum_observations"] for value in projections) <= 128, f"{path}: projection batch observations") - require(max(value["maximum_post_projection_traffic_rms_ratio"] - for value in projections) <= 1e-5, - f"{path}: projected traffic remainder") - require(max(value["maximum_absolute_post_projection_soma_slope"] - for value in projections) <= 1e-5, - f"{path}: projected soma slope") + # Once a sham control has become nonfinite, numerical orthogonality of a + # projection that is not applied to its update is undefined. The frozen + # protocol explicitly retains such terminal collapses. Observation count + # and instruction leakage remain auditable for every batch; numerical + # projection quality is required only for a finite trajectory. Pretask + # predictor quality remains required for both cases. + require(finite(warmup["post_warmup_traffic_residual_rms_ratio"]) + and warmup["post_warmup_traffic_residual_rms_ratio"] <= 1e-5, + f"{path}: pretask predictor residual") + if row["final"]["finite"]: + require(max(value["maximum_post_projection_traffic_rms_ratio"] + for value in projections) <= 1e-5, + f"{path}: projected traffic remainder") + require(max(value["maximum_absolute_post_projection_soma_slope"] + for value in projections) <= 1e-5, + f"{path}: projected soma slope") diagnostics = row["diagnostics"] if rule == "raw": @@ -188,7 +198,7 @@ def main(): ["git", "status", "--porcelain", "--untracked-files=no"], cwd=ROOT, check=True, capture_output=True, text=True).stdout.strip() require(not tracked_dirty, "analysis requires a clean tracked source") - source_commit = subprocess.run( + analysis_commit = subprocess.run( ["git", "rev-parse", "HEAD"], cwd=ROOT, check=True, capture_output=True, text=True).stdout.strip() with open(args.prerequisite) as handle: @@ -203,9 +213,31 @@ def main(): prerequisite["metrics"]["accuracy"]), "dynamic record/gate mismatch") + record_paths = { + rule: os.path.join(args.outdir, f"{rule}.json") for rule in RULES + } + record_commits = set() + for path in record_paths.values(): + with open(path) as handle: + record_commits.add(json.load(handle)["provenance"]["git_commit"]) + require(len(record_commits) == 1, + "raw and matched controls must share one training source") + training_commit = record_commits.pop() + critical_training_paths = [ + "KP_TEACHING_SIGNAL_ABLATION.md", + "experiments/conv_local_smoke.py", + "experiments/conv_run.py", + "experiments/kp_teaching_signal_ablation.py", + "sdil/conv.py", + ] + require(subprocess.run( + ["git", "diff", "--quiet", training_commit, analysis_commit, "--", + *critical_training_paths], + cwd=ROOT).returncode == 0, + "analysis revision changes a frozen training-critical path") rows = { rule: validate_record( - os.path.join(args.outdir, f"{rule}.json"), rule, source_commit, + record_paths[rule], rule, training_commit, prerequisite["metrics"]["bp_total_macs"]) for rule in RULES } @@ -246,7 +278,8 @@ def main(): "control_mean_wall_s": statistics.mean( row["timing"]["total_timed_wall_s"] for row in rows.values()), - "source_commit": source_commit, + "training_source_commit": training_commit, + "analysis_source_commit": analysis_commit, "prerequisite_sha256": sha256(args.prerequisite), }, "claim": ( |
