Separate radio defence and harden player and objective lifecycles

This commit is contained in:
2026-09-19 05:33:36 +02:00
parent e5857b6ddf
commit 16f397e581
237 changed files with 29087 additions and 202 deletions
+12 -5
View File
@@ -1,17 +1,23 @@
#!/usr/bin/env python3
"""Archive an isolated native run and the exact current addon sources; never overwrite evidence.
"""Archive an isolated native run and its verified launch-time addon snapshot; never overwrite evidence.
Run only after stopping the test and before editing/copying its source tree again.
"""
from pathlib import Path
import argparse,hashlib,json,shutil,subprocess,sys
import argparse,json,shutil,subprocess,sys
from native_provenance import archive_source, encoded, MANIFEST, METADATA, PROVENANCE
ROOT=Path(__file__).resolve().parents[1]
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('session',type=Path)
p.add_argument('name',help='New evidence directory name, e.g. native-2026-09-19-003231')
p.add_argument('--allow-legacy-archive-time-source', action='store_true', help='Explicit historical-only import for sessions without a pre-launch snapshot')
a=p.parse_args()
if Path(a.name).name!=a.name or a.name in {'.','..'}:p.error('Name must be one directory component')
source=a.session.resolve()
if not (source/'console.log').is_file():p.error('Session has no console.log')
try:
manifest_bytes, provenance, launched = archive_source(source, ROOT, a.allow_legacy_archive_time_source)
except (OSError, ValueError) as error:
p.error(str(error))
dest=ROOT/'docs/evidence'/a.name
try:dest.mkdir(parents=True,exist_ok=False)
except FileExistsError:p.error('Evidence already exists; refusing to overwrite')
@@ -19,9 +25,10 @@ for name in ['console.log','script.log','error.log','rereintroduced-hq.log','hea
if (source/name).is_file():shutil.copyfile(source/name,dest/(name+'.txt'))
for capture in sorted(source.glob('err-*.png')):
if capture.is_file():shutil.copyfile(capture,dest/capture.name)
suffixes={'.c','.conf','.meta','.et','.ent','.layer','.gproj','.layout','.emat'}
manifest={str(f.relative_to(ROOT)):hashlib.sha256(f.read_bytes()).hexdigest() for f in sorted((ROOT/'addons').rglob('*')) if f.is_file() and f.suffix in suffixes}
(dest/'source-sha256.json').write_text(json.dumps(manifest,indent=2)+'\n')
(dest/'source-sha256.json').write_bytes(manifest_bytes)
(dest/PROVENANCE).write_bytes(encoded(provenance))
if launched:
for name in (MANIFEST, METADATA): shutil.copyfile(source/name, dest/name)
with (dest/'report.json').open('w') as report:
result=subprocess.run([sys.executable,str(ROOT/'tools/native_report.py'),str((dest/'console.log.txt').relative_to(ROOT))],cwd=ROOT,stdout=report)
print(f'Archived {dest.relative_to(ROOT)}; native report exit={result.returncode} (nonzero retains failures)')