test: gate V1 side files and V3 legacy receipts; early output rejection
- analyze_jet_cv_continuation: samples are analyzed only if the sibling re*_s*.json receipt is the same case with run_status COMPLETE and source_recheck UNCHANGED; receipts without run_status (pre-recheck runners) are refused unless --legacy-receipts, and labelled LEGACY_NO_FINAL_SOURCE_RECHECK. Results carry receipt_gate. - V3: receipts are schema 2 and need source_recheck UNCHANGED; a missing recheck is accepted only for frozen-mode schema 1 receipts whose run_case.py hash is one of the pre-recheck runners (9805383,2cf9853, db3d098; hashes checked against git history in a test). - V1/V3 refuse --output inside the checkout before source checks or CUDA (shared source_provenance.reject_output_inside). - A failing recheck is recorded as RECHECK_FAILED (still invalid); the in-run V1 receipt write is tmp+replace. Negative host tests for each gate. No threshold, solver or evidence edits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
df0f586331
commit
36ffc8b1b2
9 files changed
+185
-33
No files matched your search
@@ -209,15 +209,15 @@ class Host(unittest.TestCase):
|
||||
done = v.finish_receipt(path, payload, recorded, lambda: dict(recorded))
|
||||
self.assertEqual(json.loads(path.read_text()), done)
|
||||
self.assertEqual((done["run_status"], done["source_recheck"]), ("COMPLETE", "UNCHANGED"))
|
||||
for recheck, after in ((lambda: dict(recorded, checkout_dirty=True), True),
|
||||
(lambda: v.verify(Path(d)), None)):
|
||||
for recheck, state in ((lambda: dict(recorded, checkout_dirty=True), "CHANGED"),
|
||||
(lambda: v.verify(Path(d)), "RECHECK_FAILED")):
|
||||
path.write_text(json.dumps(payload))
|
||||
with self.assertRaisesRegex(RuntimeError, "Source changed during the run"):
|
||||
v.finish_receipt(path, payload, recorded, recheck)
|
||||
bad = json.loads(path.read_text())
|
||||
self.assertEqual((bad["run_status"], bad["source_recheck"]),
|
||||
("INVALID_SOURCE_CHANGED", "CHANGED"))
|
||||
self.assertEqual(bad["source_after"] is None, after is None)
|
||||
("INVALID_SOURCE_CHANGED", state))
|
||||
self.assertEqual(bad["source_after"] is None, state == "RECHECK_FAILED")
|
||||
self.assertEqual(bad["windows"], [1, 2])
|
||||
self.assertFalse(Path(str(path) + ".tmp").exists())
|
||||
|
||||
@@ -231,5 +231,16 @@ class Host(unittest.TestCase):
|
||||
self.assertIn("finish_receipt(", inspect.getsource(v.main))
|
||||
|
||||
|
||||
def test_output_inside_checkout_is_refused_before_source_or_cuda(self):
|
||||
from unittest import mock
|
||||
import run_jet_circle_cv as v
|
||||
argv = ["run_jet_circle_cv.py", "--repo", str(REPO), "--output", str(REPO / "v1-out")]
|
||||
with mock.patch("sys.argv", argv), mock.patch.dict("os.environ", CUDA_VISIBLE_DEVICES="0"), \
|
||||
mock.patch.object(v, "source_identity", side_effect=AssertionError("work started")):
|
||||
with self.assertRaisesRegex(SystemExit, "outside the source checkout"):
|
||||
v.main()
|
||||
self.assertFalse((REPO / "v1-out").exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user