Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
60 lines
5.2 KiB
Python
60 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Preserve strict native diagnostics and measure actual rescue landing samples."""
|
|
from pathlib import Path
|
|
import hashlib,json,re,sys
|
|
HERE=Path(__file__).resolve().parent
|
|
ROOT=HERE.parents[2]
|
|
sys.path.insert(0,str(ROOT/'tools'))
|
|
from native_report import analyze,clean
|
|
|
|
def wall(line):
|
|
match=re.match(r'(\d\d):(\d\d):(\d\d\.\d+)',line)
|
|
if not match: return None
|
|
h,m,s=map(float,match.groups());return h*3600+m*60+s
|
|
|
|
def fields(line,marker):
|
|
text=line.split(marker,1)[1].strip()
|
|
values={}
|
|
for match in re.finditer(r'(\w+)=([^=]+?)(?=\s+\w+=|$)',text):
|
|
value=match[2].strip()
|
|
try: value=float(value)
|
|
except ValueError: pass
|
|
values[match[1]]=value
|
|
return values
|
|
|
|
def normalized(error): return re.sub(r'^\d\d:\d\d:\d\d\.\d+\s*','',error).strip()
|
|
base=json.loads((HERE.parent/'rescue-factions-2026-10-13/run-a06/native-report.json').read_text())
|
|
baseline_errors={normalized(x) for x in base['engine_errors']}
|
|
runs=[]
|
|
for directory in sorted(HERE.glob('run-*')):
|
|
if not directory.is_dir(): continue
|
|
if not (directory/'console.log').exists():
|
|
runs.append({'run':directory.name,'status':'engine-not-started'});continue
|
|
log=(directory/'console.log').read_text(errors='replace')
|
|
report=analyze(log,'console.log')
|
|
(directory/'native-report.json').write_text(json.dumps(report,indent=2)+'\n')
|
|
runner=json.loads((directory/'runner.json').read_text())
|
|
inputs=json.loads((directory/'fixture-inputs.json').read_text())
|
|
starts={};landings=[];samples=[];support=[]
|
|
for line in log.splitlines():
|
|
if 'ERR RESCUE LANDING START ' in line:
|
|
entry=fields(line,'ERR RESCUE LANDING START ');entry['wall_seconds']=wall(line);starts[int(entry['serial'])]=entry
|
|
if 'ERR RESCUE LANDING RESULT ' in line:
|
|
entry=fields(line,'ERR RESCUE LANDING RESULT ');serial=int(entry['serial']);entry['start']=starts.get(serial);entry['wall_seconds']=round(wall(line)-starts[serial]['wall_seconds'],3) if serial in starts else None;landings.append(entry)
|
|
if 'ERR RESCUE LANDING SAMPLE ' in line:
|
|
entry=fields(line,'ERR RESCUE LANDING SAMPLE ');entry['wall_clock']=line.split()[0];samples.append(entry)
|
|
if 'ERR RESCUE LANDING SUPPORT ' in line: support.append(fields(line,'ERR RESCUE LANDING SUPPORT '))
|
|
errors={normalized(x) for x in report['engine_errors']}
|
|
runs.append({'run':directory.name,'faction':inputs['faction'],'scope':inputs['scope'],'behavior_complete':bool(report['smoke_completions'] and not report['script_or_runtime_failures']),'strict_native_report_passed':clean(report),'assertions_passed':report['assertions_passed'],'script_or_runtime_failures':report['script_or_runtime_failures'],'engine_error_occurrences':len(report['engine_errors']),'distinct_engine_errors':len(errors),'new_engine_errors_vs_a06':sorted(errors-baseline_errors),'source_manifest_sha256':runner['launch_source_sha256'],'console_sha256':runner['console_sha256'],'fixture_sha256':inputs['fixture_sha256'],'source_unchanged_after_run':runner['source_unchanged_after_run'],'external_addons_unchanged_after_run':runner['external_addons_unchanged_after_run'],'cleanup_confirmed':runner['cleanup_confirmed'],'landings':landings,'readiness_samples':[x for x in samples if x['event'] in ('physical-ready','boardable')],'readiness_support':[x for x in support if x['event'] in ('physical-ready','boardable')],'samples':samples,'support':support})
|
|
summary={'date':'2026-10-13','baseline':'../rescue-factions-2026-10-13/run-a06','runs':runs}
|
|
(HERE/'run-summary.json').write_text(json.dumps(summary,indent=2)+'\n')
|
|
print(json.dumps([{k:r[k] for k in ['run','faction','behavior_complete','assertions_passed','engine_error_occurrences','landings'] if k in r} for r in runs],indent=2))
|
|
qualified=[r for r in runs if r.get('behavior_complete')]
|
|
final_hashes=json.loads((HERE/'final-source-sha256.json').read_text())
|
|
bindings=[]
|
|
for run in qualified:
|
|
manifest=json.loads((HERE/run['run']/'launch-source-sha256.json').read_text())
|
|
bindings.append({'run':run['run'],'all_final_relevant_sources_match':all(manifest.get(k)==v for k,v in final_hashes.items())})
|
|
report={'date':'2026-10-13','result':'Behavioral landing, wounded boarding and loaded climb checks passed for the qualified runs; strict native reports retain engine errors.','qualified_runs':[{k:r[k] for k in ['run','faction','assertions_passed','strict_native_report_passed','engine_error_occurrences','distinct_engine_errors','new_engine_errors_vs_a06','source_manifest_sha256','console_sha256','fixture_sha256','source_unchanged_after_run','external_addons_unchanged_after_run','cleanup_confirmed','landings','readiness_samples','readiness_support']} for r in qualified],'source_binding':{'hashes':'final-source-sha256.json','run_matches':bindings},'baseline_comparison':'baseline-comparison.json','full_attempts_and_samples':'run-summary.json','scope':'Protected arranged local Workbench fixture with measured production landing, native audited cargo occupancy and genuine loaded climb. No dedicated multiplayer, remote casualty ownership, combat survivability or full boundary qualification.','timing_note':'World time uses exact production landing-start field; wall time uses immediate observer log. Prior baseline uses ten-second phase samples and is approximate.'}
|
|
(HERE/'report.json').write_text(json.dumps(report,indent=2)+'\n')
|