test: final source recheck for V1 jet CV and V3 Taylor-Green runs
Both runners now re-derive the recorded source identity after the run (source_provenance.final_source_check) and only then mark the receipt complete. A changed source, or a recheck that fails, rewrites the receipt as invalid and raises: - V1: in-run receipts carry run_status=INCOMPLETE; finish_receipt sets COMPLETE or INVALID_SOURCE_CHANGED (+ source_recheck/source_after). - V3: completed stays False, invalid=SOURCE_CHANGED_DURING_RUN, no screening_pass; the assessor requires source_recheck UNCHANGED (frozen mode still accepts receipts from before the field existed). Interrupted runs keep INCOMPLETE / completed=False. Host tests cover unchanged, changed and failed rechecks and incomplete runs. No threshold or solver change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8cae58cdf1
commit
df0f586331
7 files changed
+159
-15
No files matched your search
@@ -244,6 +244,37 @@ def current_checkout(repo):
|
||||
for f in files})
|
||||
|
||||
|
||||
def source_identity(repo, current):
|
||||
"""Recorded source of a run; recomputed after the run by finish_receipt."""
|
||||
if current:
|
||||
provenance = dict(**checkout_provenance(repo), **current_checkout(repo))
|
||||
if provenance["checkout_dirty"]:
|
||||
raise RuntimeError("Current-checkout runs require a clean checkout")
|
||||
return provenance
|
||||
source = verify(repo)
|
||||
return dict(source_experiment=source["experiment"], source_mode="pinned",
|
||||
**checkout_provenance(repo))
|
||||
|
||||
|
||||
def finish_receipt(path, payload, provenance, recheck):
|
||||
"""Mark the receipt COMPLETE only if the source is unchanged; otherwise INVALID.
|
||||
|
||||
Receipts written during the run carry run_status="INCOMPLETE", so an interrupted
|
||||
run never leaves a complete-looking receipt.
|
||||
"""
|
||||
from source_provenance import final_source_check
|
||||
fields = final_source_check(provenance, recheck)
|
||||
unchanged = fields["source_recheck"] == "UNCHANGED"
|
||||
payload = dict(payload, **fields,
|
||||
run_status="COMPLETE" if unchanged else "INVALID_SOURCE_CHANGED")
|
||||
temporary = Path(str(path) + ".tmp")
|
||||
temporary.write_text(json.dumps(payload, indent=2) + "\n")
|
||||
temporary.replace(path)
|
||||
if not unchanged:
|
||||
raise RuntimeError("Source changed during the run; receipt marked invalid")
|
||||
return payload
|
||||
|
||||
|
||||
def run_case(c, ctx, output, provenance, continuation=False):
|
||||
from CelerisLab.body.geometry.circle import CircleGeometry
|
||||
from CelerisLab.body.objects import SimObject
|
||||
@@ -556,6 +587,7 @@ def run_case(c, ctx, output, provenance, continuation=False):
|
||||
case=c,
|
||||
**{"source_revision": PIN, **provenance},
|
||||
status="PILOT_DIAGNOSTIC_ONLY",
|
||||
run_status="INCOMPLETE", # final source recheck in main() completes it
|
||||
windows=rows,
|
||||
physics_validation_pass=False,
|
||||
precision="FP32 evolution, FP64 host diagnostics",
|
||||
@@ -638,16 +670,7 @@ def main():
|
||||
):
|
||||
p.error("Root must select one verified idle GPU via CUDA_VISIBLE_DEVICES")
|
||||
repo = a.repo.resolve()
|
||||
if a.current_checkout:
|
||||
provenance = dict(**checkout_provenance(repo), **current_checkout(repo))
|
||||
if provenance["checkout_dirty"]:
|
||||
raise RuntimeError("Current-checkout runs require a clean checkout")
|
||||
else:
|
||||
source = verify(repo)
|
||||
provenance = dict(
|
||||
source_experiment=source["experiment"], source_mode="pinned",
|
||||
**checkout_provenance(repo)
|
||||
)
|
||||
provenance = source_identity(repo, a.current_checkout)
|
||||
sys.path.insert(0, str(repo / "src"))
|
||||
import CelerisLab
|
||||
|
||||
@@ -663,7 +686,9 @@ def main():
|
||||
free, total = cuda.mem_get_info()
|
||||
if free < max(1024, 2 * plan["estimated_peak_device_mib"]) * 1024**2:
|
||||
raise RuntimeError("Insufficient free device memory")
|
||||
run_case(c, ctx, a.output, provenance, continuation=a.continuation)
|
||||
payload = run_case(c, ctx, a.output, provenance, continuation=a.continuation)
|
||||
finish_receipt(a.output / f"re{c['re_d']}_s{c['scale']}.json", payload, provenance,
|
||||
lambda: source_identity(repo, a.current_checkout))
|
||||
print(
|
||||
json.dumps(
|
||||
dict(status="COMPLETE_DIAGNOSTIC_ONLY", physics_validation_pass=False)
|
||||
|
||||
Reference in new issue
Block a user