Files
EscapistsReintroduced/docs/evidence/hunter-capture-2026-10-02/finish.py
T
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

47 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pathlib import Path
import hashlib,json,shutil,subprocess,sys
r=Path('/home/jakub/devel/escapistsrereintroduced');b=Path('/tmp/erri-gameplay-root-2237')
e=r/'docs/evidence/hunter-capture-2026-10-02';ne=r/'docs/evidence/native-2026-10-02-hunter-capture-normal'
load=lambda p:json.loads(p.read_text())
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
def write(p,v):p.write_text(json.dumps(v,indent=2)+'\n')
baseline=load(b/'baseline.json');suite=load(b/'suite-result.json');inputs=load(b/'suite-inputs.json')
assert suite['exit']==0 and suite['inputs_unchanged'] and suite['regression_programs']==292
assert len({x['path'] for x in suite['programs']})==292 and all(x['exit']==0 for x in suite['programs'])
assert all(sha(r/n)==h for n,h in inputs.items())
sys.path.insert(0,str(r/'tools'));from source_manifest import addon_manifest
source=addon_manifest(r);nr=load(ne/'runner.json.txt');report=load(ne/'report.json')
assert source==load(ne/'source-sha256.json')==load(ne/'launch-source-sha256.json')
assert report['assertions_passed']==63 and report['smoke_completions']==1 and not report['script_or_runtime_failures'] and len(report['engine_errors'])==13
assert nr['cleanup_confirmed'] and nr['source_unchanged_after_run'] and nr['external_addons_unchanged_after_run']
assert sha(ne/'console.log.txt')==nr['console_sha256']
allowed={'tests/test_convoy_survivors.py','addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyService.c','addons/core/Scripts/Game/ERR/10_AI/ERR_HunterService.c','tests/test_hunter_lifecycle.py','tools/check.py'}
changed=[n for n,h in baseline['files'].items() if not (r/n).is_file() or sha(r/n)!=h]
assert set(changed)==allowed,changed
index=hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=r)).hexdigest();assert index==baseline['index_diff_sha256']
original=load(Path('/tmp/erri-heartbeat-20260930-1542-reference.json'))
assert all(sha(Path('/home/jakub/devel/escapists')/n)==h for n,h in original.items())
candidate=r/'.build/playtest-2026-10-02-convoy-survivors'
seal=load(r/'docs/evidence/playtest-refresh-2026-10-02-convoy-survivors/candidate-sha256.json')
assert {str(p.relative_to(candidate)):sha(p) for p in candidate.rglob('*') if p.is_file()}==seal
e.mkdir(exist_ok=False)
for n in ['baseline.json','suite-result.json','suite-inputs.json','regressions.log','run-suite.py','native-normal.log','finish.py']:shutil.copyfile(b/n,e/n)
shutil.copytree(b/'aborted-preintegration-check',e/'aborted-preintegration-check')
for folder,name in [('/tmp/erri-hunter-capture-2237','proposal'),('/tmp/erri-hunter-capture-review-2237','independent'),('/tmp/erri-hunter-capture-admission-2237','sdk-review')]:
shutil.copytree(folder,e/name,ignore=shutil.ignore_patterns('__pycache__','*.pyc'))
write(e/'source-after.json',source)
result={'kind':'Active original hunter capture fix','authored_files':len(source),'regression_programs':292,'normal_assertions':63,'normal_completions':1,'normal_script_failures':0,'normal_engine_errors':13,'cleanup_source_external_unchanged':True,'strict_native_failure_retained':True,'native_capture_callback_tested':False,'multiplayer_tested':False,'performance_tested':False,'new_package_created':False,'latest_candidate_preserved_files':len(seal),'original_reference_files_unchanged':len(original),'baseline_paths':len(baseline['files']),'changed_existing_paths':changed,'added_test':'tests/test_hunter_capture.py','index_diff_sha256':index,'scope':'Current admitted player entering active tracked hunter; entry before native callbacks latches capture and releases existing HQ ownership. Already-released infantry roles remain independent. No replacement/refund or actor deletion.','limits':'Actual-method regression doubles native boundaries; normal native run verifies compilation and base-loop integration, not player capture timing or remote-client behavior.'}
write(e/'review.json',result)
status=r/'docs/current-status.md';before=status.read_text();first,tail=before.split('\n',1)
section='''**2 October 2026 — active hunter capture is remembered at vehicle entry:** when a current admitted player enters an active original HQ hunter vehicle, the server records capture before native entry callbacks can change player ownership. The existing driving/recovery order and HQ registration are released once, even if current occupancy disappears before the next one-second poll. Vehicles, crew and spent deployment allowances remain physical and unchanged. Entering an already-released vehicle does not revoke its former crew’s independent infantry role.
All **292 registered regression programs pass**. Independent actual-method tests reproduce the old event gap and a missing survivor-retention guard, then pass with the fix. The installed SDK signature and callback ordering are verified. A hidden/muted normal Everon run completes **63 assertions and one round**, with **zero script/runtime failures and thirteen retained engine errors**, confirmed cleanup and unchanged inputs. This proves compilation and ordinary-loop integration; native capture-event timing, remote multiplayer and performance remain unverified.
The existing convoy-survivors package is unchanged and predates this source fix. Original missions and inherited work are preserved; nothing was committed or published. [Implementation and evidence](evidence/hunter-capture-2026-10-02/review.json).
'''
assert sha(status)==baseline['files']['docs/current-status.md']
status.write_text(first+'\n\n'+section+'\n'+tail.lstrip('\n'))
write(e/'documentation.json',{'before':baseline['files']['docs/current-status.md'],'after':sha(status)})
write(e/'evidence-sha256.json',{str(p.relative_to(e)):sha(p) for p in sorted(e.rglob('*')) if p.is_file()})
print(json.dumps(result,indent=2))