Files
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

89 lines
8.8 KiB
Python

"""Root-only archive of exact integrated BMP singleton proposals after a passing unchanged suite. No tests/native launched."""
from pathlib import Path
import argparse,hashlib,json,shutil,sys,datetime
R=Path('/home/jakub/devel/escapistsrereintroduced');B=Path('/tmp/erri-bmp-intercept-root-1406')
PROPOSALS={'service':Path('/tmp/erri-bmp-service-1406'),'dispatch':Path('/tmp/erri-bmp-dispatch-1406'),'geometry':Path('/tmp/erri-bmp-geometry-1406')}
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest();load=lambda p:json.loads(p.read_text())
def write(p,value):p.write_text(json.dumps(value,indent=2)+'\n')
def main():
ap=argparse.ArgumentParser(description=__doc__)
ap.add_argument('--output',type=Path,default=R/'docs/evidence/bmp-interception-2026-10-03')
a=ap.parse_args();out=a.output
assert out.parent.resolve()==(R/'docs/evidence').resolve() and not out.exists() and not out.is_symlink()
suite=load(B/'suite-result.json');inputs=load(B/'suite-inputs.json');integration=load(B/'integration.json')
assert suite['exit']==0 and suite['inputs_unchanged'] and not suite.get('resumed')
assert len(suite['programs'])==suite['regression_programs'] and all(p['exit']==0 for p in suite['programs'])
assert len({p['path'] for p in suite['programs']})==suite['regression_programs']
assert 'All repository checks passed.' in (B/'full-suite.log').read_text()
sys.path.insert(0,str(R/'tools'));from source_manifest import addon_manifest
current=addon_manifest(R)
for folder in ['tests','tools','terrain-profiles','terrain-adapters','terrain-integrations']:
current.update({str(p.relative_to(R)):sha(p) for p in (R/folder).rglob('*') if p.is_file() and '__pycache__' not in p.parts and p.suffix!='.pyc'})
current.update({str(p.relative_to(R)):sha(p) for p in (R/'docs').iterdir() if p.is_file()})
for name in ['README.md','.gitignore']:current[name]=sha(R/name)
assert current==inputs,'Source/tests/tools/docs changed after suite; refuse silent evidence rebinding'
deferred=load(B/'native-deferred.json')
assert deferred['native_check_started'] is False and deferred['compile_or_gameplay_proof'] is False
artifacts={};proposal_hashes={};integrated=set()
for owner,p in PROPOSALS.items():
raw=load(p/'source-manifest.json');manifest=raw.get('files',raw)
for name,row in manifest.items():
assert name.startswith('addons/core/Scripts/Game/ERR/10_AI/') or name.startswith('tests/')
after=row.get('proposed',row.get('proposal_sha256'));before=row.get('before_working',row.get('before',row.get('baseline_sha256')))
assert sha(p/name)==sha(R/name)==inputs[name]==integration[name]['after']==after
assert Path(integration[name]['proposal'])==p/name
assert integration[name]['before']==before
artifacts[owner+'/proposed/'+name]=p/name;integrated.add(name)
if before is not None:
assert sha(p/'baseline'/name)==before;artifacts[owner+'/baseline/'+name]=p/'baseline'/name
else:assert not (p/'baseline'/name).exists()
index=p/'baseline-index'/name
if index.is_file():
expected=row.get('before_index',row.get('index',row.get('index_sha256')))
if expected is not None:assert sha(index)==expected
artifacts[owner+'/baseline-index/'+name]=index
for q in sorted(p.iterdir()):
# All included top-level JSON/log/patch files are owned evidence. No recursive
# SDK/installed tree, prefab, archive payload or helper-generated temp tree.
if q.is_file() and q.suffix in {'.json','.log','.patch'}:artifacts[owner+'/'+q.name]=q
assert (p/'fix.patch').is_file();proposal_hashes[owner]={'patch_sha256':sha(p/'fix.patch'),'manifest_sha256':sha(p/'source-manifest.json')}
assert integrated|{'tools/check.py'}==set(integration)
assert sha(R/'tools/check.py')==integration['tools/check.py']['after']==inputs['tools/check.py']
assert sha(B/'check-before.py')==integration['tools/check.py']['before']
artifacts['registration/check-before.py']=B/'check-before.py';artifacts['registration/check-after.py']=R/'tools/check.py'
service=load(PROPOSALS['service']/'result.json');dispatch=load(PROPOSALS['dispatch']/'result.json');geometry=load(PROPOSALS['geometry']/'test-results.json')
assert service['patch_sha256']==proposal_hashes['service']['patch_sha256'] and dispatch['patch_sha256']==proposal_hashes['dispatch']['patch_sha256']
assert load(PROPOSALS['geometry']/'source-manifest.json')['patch_sha256']==proposal_hashes['geometry']['patch_sha256']
assert all(row['expected_result_observed'] for row in geometry)
for row in geometry:assert sha(PROPOSALS['geometry']/(row['name']+'.log'))==row['log_sha256']
hq_review=load(PROPOSALS['dispatch']/'independent-review.json')
assert hq_review['complete'] and hq_review['patch_sha256']==proposal_hashes['dispatch']['patch_sha256']
assert hq_review['HQ_source_sha256']==integration['addons/core/Scripts/Game/ERR/10_AI/ERR_HQMountedDispatch.c']['after']
assert hq_review['HQ_test_sha256']==integration['tests/test_hq_mounted_dispatch.py']['after']
for name in ['baseline.json','integration.json','suite-inputs.json','suite-result.json','full-suite.log','run-suite.py','native-deferred.json']:
artifacts['root/'+name]=B/name
artifacts['archive-change.py']=Path(__file__)
before={name:{'source':str(p),'sha256':sha(p),'bytes':p.stat().st_size} for name,p in artifacts.items()}
assert all('/installed/' not in str(p) and '/sdk/' not in str(p).lower() for p in artifacts.values())
out.mkdir()
for name,p in artifacts.items():
q=out/name;q.parent.mkdir(parents=True,exist_ok=True);shutil.copyfile(p,q)
assert sha(q)==before[name]['sha256']==sha(p)
(out/'README.md').write_text(f'''# Original BMP singleton interception — 3 October 2026
This source change allows one already-admitted original BMP at convoy slot 4 to use the existing interception path after at least six delivered, reconciled HQ losses. It remains a singleton alternative to the existing UAZ pair/single behavior. Fresh complete delivered crew/ammunition status, an ordinary radio route and receipt, exact original source/record/root/crew ownership, existing shared claims, token allowance, fixed expiry and two-road-query budget remain required. It creates no replacement force, ammunition, vehicle or third simultaneous member.
A footprint measured from the exact original vehicle and bounded hierarchy is retained immutably. Conservative yaw-independent road width, segment support, terrain/water and collision-volume checks reject unknown or changed geometry. The service revalidates exact footprint ownership at admission, delivery and active use; native allocation/removal/installation boundary controls cancel the owned operation on loss. Destination clearance does not establish route navigability or physical arrival.
The archived full suite passed {suite['regression_programs']} programs with unchanged inputs. Actual-method focused programs cover threshold/radio/budget/ownership, original BMP singleton behavior, preserved UAZ pairing, geometry boundaries and callback cancellation. Baseline and mutation failures remain alongside passing logs; translated native doubles are not engine execution.
**Native compilation and physical BMP behavior remain unqualified.** `root/native-deferred.json` records why the native run was deferred and that no native check started. No compiler, fixture, navigation, interception, multiplayer or FPS success is inferred from the offline suite. The earlier depot-mines runtime handoff remains a separately sealed older snapshot and does not include this interception change.
The archive preserves exact owned proposed source/tests, available working/index baselines, patches, manifests, focused evidence, the independent HQ review, root integration and full-suite evidence. No installed third-party SDK/prefab payload is included. `artifact-manifest.json` records original paths and verified copied hashes. This helper launches no tests or native process and writes only this new evidence directory when explicitly executed after the suite.
''')
result={'kind':'ORIGINAL BMP SINGLETON SOURCE EVIDENCE','created_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'full_suite_programs':suite['regression_programs'],'suite_inputs_unchanged':True,'current_input_scope_exact':True,'integrated_files':len(integration),'proposal_hashes':proposal_hashes,'independent_HQ_review_sha256':sha(PROPOSALS['dispatch']/'independent-review.json'),'native_deferred':deferred,'native_compiled_claimed':False,'physical_BMP_behavior_claimed':False,'installed_payloads_copied':False,'copied_originals':before,'files':{q.relative_to(out).as_posix():{'sha256':sha(q),'bytes':q.stat().st_size} for q in sorted(out.rglob('*')) if q.is_file()}}
write(out/'artifact-manifest.json',result)
assert all(sha(out/name)==row['sha256'] for name,row in result['files'].items())
print(json.dumps({'archive':str(out),'files':len(result['files'])+1,'manifest_sha256':sha(out/'artifact-manifest.json'),'native_claimed':False},indent=2))
if __name__=='__main__':main()