#!/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')