anhtld commited on
Commit
66516a9
·
verified ·
1 Parent(s): 5f5a8f5

manual-outcome-gate-sync 2026-07-04T04:15:33Z workspace (part 5)

Browse files
workspace/tests/test_ctt_outcome_gate.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ from scripts import build_ctt_outcome_gate as outcome_gate
7
+
8
+
9
+ def _micro(mean: float) -> dict:
10
+ return {"micro": {"mean": mean, "low": mean, "high": mean}}
11
+
12
+
13
+ def test_ctt_outcome_gate_records_acceptance_failures_without_markdown(tmp_path) -> None:
14
+ rollout_dir = tmp_path / "rollout"
15
+ selector_dir = tmp_path / "selector"
16
+ rollout_dir.mkdir()
17
+ selector_dir.mkdir()
18
+ rollout_metrics = rollout_dir / "metrics.json"
19
+ selector_metrics = selector_dir / "metrics.json"
20
+ rollout_metrics.write_text(
21
+ json.dumps(
22
+ {
23
+ "data_hash": "rollout-data",
24
+ "split_hash": "rollout-split",
25
+ "train_seeds": ["0", "1", "2"],
26
+ "summary": {
27
+ "outcome_ptr_at_16": _micro(0.55),
28
+ "proposal_oracle_success_at_16": _micro(0.57),
29
+ "success_support_gap_at_16": _micro(0.20),
30
+ "generated_unsafe_rate_known_at_16": _micro(0.0),
31
+ "selected_unsafe_known_at_16": _micro(0.0),
32
+ "base_unsafe_known": _micro(0.0),
33
+ },
34
+ }
35
+ )
36
+ + "\n"
37
+ )
38
+ selector_metrics.write_text(
39
+ json.dumps(
40
+ {
41
+ "data_hash": "selector-data",
42
+ "split_hash": "selector-split",
43
+ "eval_summary": {
44
+ "base_success": 0.29,
45
+ "selected_success": 0.35,
46
+ "proposal_oracle_success": 0.57,
47
+ "hidden_chart_oracle_success": 0.73,
48
+ "success_support_gap": 0.20,
49
+ "success_selector_gap": 0.24,
50
+ "pairwise_causal_calibration_ece": 0.01,
51
+ },
52
+ "summary": {
53
+ "selected_success": _micro(0.35),
54
+ "proposal_oracle_success": _micro(0.57),
55
+ "success_selector_gap": _micro(0.24),
56
+ },
57
+ "rows": [{"train_seed": "0"}, {"train_seed": "1"}, {"train_seed": "2"}],
58
+ }
59
+ )
60
+ + "\n"
61
+ )
62
+ (rollout_dir / "metrics_by_task.json").write_text('{"rollout": {}}\n')
63
+ (selector_dir / "metrics_by_task.json").write_text('{"selector": {}}\n')
64
+ (rollout_dir / "metrics_by_seed.json").write_text('{"rollout": {}}\n')
65
+ (selector_dir / "metrics_by_seed.json").write_text('{"selector": {}}\n')
66
+
67
+ out_dir = tmp_path / "gate"
68
+ assert (
69
+ outcome_gate.main(
70
+ [
71
+ "--rollout-metrics",
72
+ str(rollout_metrics),
73
+ "--selector-metrics",
74
+ str(selector_metrics),
75
+ "--out-dir",
76
+ str(out_dir),
77
+ ]
78
+ )
79
+ == 0
80
+ )
81
+
82
+ metrics = json.loads((out_dir / "metrics.json").read_text())
83
+ gates = {gate["name"]: gate for gate in metrics["gates"]}
84
+ by_task = json.loads((out_dir / "metrics_by_task.json").read_text())
85
+
86
+ assert metrics["overall_pass"] is False
87
+ assert metrics["status"] == "diagnostic_not_method_success"
88
+ assert gates["proposal oracle success"]["pass"] is True
89
+ assert gates["true OutcomePTR@16 vs V0"]["pass"] is True
90
+ assert gates["selected clean success"]["pass"] is False
91
+ assert gates["success support gap"]["pass"] is False
92
+ assert gates["success selector gap"]["pass"] is False
93
+ assert gates["three train seeds"]["pass"] is True
94
+ assert by_task["selector_summary"] == {"selector": {}}
95
+ assert by_task["rollout_summary"] == {"rollout": {}}
96
+ assert "selected clean success" in (out_dir / "table.tex").read_text()
97
+ assert not (out_dir / "report.md").exists()
workspace/tests/test_ctt_proxy_comparison.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ from scripts import build_ctt_proxy_comparison as comparison
7
+
8
+
9
+ def _write_proxy_run(
10
+ run_dir: Path,
11
+ *,
12
+ pptc20: float,
13
+ pptc40: float,
14
+ neg20: float,
15
+ neg40: float,
16
+ pos_closer: float,
17
+ mean_pos: float,
18
+ mean_neg: float,
19
+ diversity: float,
20
+ collapse: float,
21
+ ) -> None:
22
+ run_dir.mkdir(parents=True)
23
+ row = {
24
+ "chart_id": "c0",
25
+ "task_id": "PickCube-v1",
26
+ "seed": "0",
27
+ "pptc_at_16_thr_0p20": pptc20,
28
+ "pptc_at_16_thr_0p40": pptc40,
29
+ "negative_near_at_16_thr_0p20": neg20,
30
+ "negative_near_at_16_thr_0p40": neg40,
31
+ "pos_closer_than_neg_at_16": pos_closer,
32
+ "mean_positive_distance_at_16": mean_pos,
33
+ "mean_negative_distance_at_16": mean_neg,
34
+ "candidate_diversity_at_16": diversity,
35
+ "collapse_rate_at_16": collapse,
36
+ "proxy_support_distance_at_16": mean_pos,
37
+ }
38
+ summary = {
39
+ key: {"micro": {"mean": value}}
40
+ for key, value in row.items()
41
+ if isinstance(value, float)
42
+ }
43
+ (run_dir / "metrics.json").write_text(
44
+ json.dumps(
45
+ {
46
+ "num_rows": 1,
47
+ "summary": summary,
48
+ "rows": [row],
49
+ "data_hash": "data",
50
+ "target_split_hash": "split",
51
+ },
52
+ indent=2,
53
+ )
54
+ + "\n"
55
+ )
56
+
57
+
58
+ def test_ctt_proxy_comparison_writes_full_proxy_gate_without_markdown(
59
+ tmp_path, monkeypatch
60
+ ) -> None:
61
+ local = tmp_path / "local_atlas"
62
+ ctt = tmp_path / "ctt_residual"
63
+ _write_proxy_run(
64
+ local,
65
+ pptc20=0.4,
66
+ pptc40=0.7,
67
+ neg20=0.03,
68
+ neg40=0.2,
69
+ pos_closer=0.6,
70
+ mean_pos=0.7,
71
+ mean_neg=0.8,
72
+ diversity=0.9,
73
+ collapse=0.05,
74
+ )
75
+ _write_proxy_run(
76
+ ctt,
77
+ pptc20=0.2,
78
+ pptc40=0.6,
79
+ neg20=0.035,
80
+ neg40=0.25,
81
+ pos_closer=0.8,
82
+ mean_pos=0.4,
83
+ mean_neg=0.5,
84
+ diversity=0.3,
85
+ collapse=0.06,
86
+ )
87
+ monkeypatch.setattr(
88
+ comparison,
89
+ "DEFAULT_RUNS",
90
+ [("local_atlas", [local]), ("ctt_residual", [ctt])],
91
+ )
92
+
93
+ out_dir = tmp_path / "comparison"
94
+ assert comparison.main(["--out-dir", str(out_dir), "--no-markdown-report"]) == 0
95
+
96
+ metrics = json.loads((out_dir / "metrics.json").read_text())
97
+ ctt_row = next(row for row in metrics["rows"] if row["method"] == "ctt_residual")
98
+ by_task = json.loads((out_dir / "metrics_by_task.json").read_text())
99
+ by_seed = json.loads((out_dir / "metrics_by_seed.json").read_text())
100
+
101
+ assert ctt_row["proxy_gate_pass"] is True
102
+ assert ctt_row["pos_closer_than_neg"] == 0.8
103
+ assert ctt_row["mean_negative_distance"] == 0.5
104
+ assert ctt_row["collapse_rate"] == 0.06
105
+ assert by_task["ctt_residual"]["PickCube-v1"]["pos_closer_than_neg"] == 0.8
106
+ assert by_seed["ctt_residual"]["0"]["mean_negative_distance"] == 0.5
107
+ assert "Pos<Neg" in (out_dir / "table.tex").read_text()
108
+ assert not (out_dir / "report.md").exists()