From eb12006d38e2255c6865057072b8458afd289f01 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Fri, 17 Jul 2026 05:29:20 -0400 Subject: [PATCH] fix: idempotent ladder_rank migration for legacy gate_evidence tables --- app/harness/observation.py | 6 +++++ tests/unit/test_harness_observation.py | 36 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/app/harness/observation.py b/app/harness/observation.py index c8e8b5a..469053b 100644 --- a/app/harness/observation.py +++ b/app/harness/observation.py @@ -358,6 +358,12 @@ def write_gate_evidence( with HarnessLog(db_path, run_id) as log: log.create_table("gate_evidence", _GATE_EVIDENCE_COLS) + # 幂等迁移(对齐 question_gen/run_store 先例):块序贯时代的旧表只有 + # block_idx 列,CREATE TABLE IF NOT EXISTS 不补列,直接插 ladder_rank + # 会 OperationalError——为旧 workspace 复用补列,新表恒为 no-op。 + cols = {r["name"] for r in log.query("PRAGMA table_info(gate_evidence)")} + if "ladder_rank" not in cols: + log.execute("ALTER TABLE gate_evidence ADD COLUMN ladder_rank INTEGER") for row in rows: log.insert("gate_evidence", {"epoch": epoch, "step": step, **row}) diff --git a/tests/unit/test_harness_observation.py b/tests/unit/test_harness_observation.py index 8b816cc..e3daadc 100644 --- a/tests/unit/test_harness_observation.py +++ b/tests/unit/test_harness_observation.py @@ -383,3 +383,39 @@ def test_write_epoch_report(tmp_path: Path) -> None: assert data["system_tool_action"] == "updated" assert data["momentum_updated_task_types"] == ["temporal", "causal"] assert data["best_val_acc"] == pytest.approx(0.88) + + +def test_write_gate_evidence_migrates_legacy_block_idx_table(tmp_path) -> None: + """旧块序贯表(含 block_idx 无 ladder_rank)复用:幂等补列后写入成功(终审 C1 回归锁)。""" + import sqlite3 + + db = tmp_path / "harness.db" + conn = sqlite3.connect(db) + conn.execute( + "CREATE TABLE gate_evidence (run_id TEXT, timestamp TEXT, epoch INTEGER," + " step INTEGER, question_id TEXT, task_type TEXT, block_idx INTEGER," + " baseline_correct INTEGER, candidate_correct INTEGER, e_value REAL," + " stop_reason TEXT)" + ) + conn.commit() + conn.close() + + write_gate_evidence( + str(db), + run_id="r1", + epoch=1, + step=0, + rows=[ + { + "question_id": "q1", + "task_type": "Action Reasoning", + "ladder_rank": 0, + "baseline_correct": False, + "candidate_correct": True, + "e_value": 1.5, + "stop_reason": "", + } + ], + ) + got = read_gate_evidence(str(db), run_id="r1") + assert len(got) == 1 and got[0]["ladder_rank"] == 0