#!/usr/bin/env python3 """Validate addon/resource isolation and execute policy regressions. Not an engine compiler.""" from pathlib import Path import json,re,subprocess,sys ROOT=Path(__file__).resolve().parents[1] BASE='58D0FB3206B6F859' def check(): ids={};graph={};resources={};paths={};owners={} for p in sorted((ROOT/'addons').glob('*/addon.gproj')): text=p.read_text();g=re.search(r'GUID "([A-F0-9]{16})"',text)[1] assert g not in ids,f'Duplicate addon GUID: {p}' ids[g]=p.parent.name;graph[g]=re.findall(r'"([A-F0-9]{16})"',text[text.index('Dependencies'):]) assert len(ids)==5,'Expected five addon projects' def walk(g,stack): assert g not in stack,'Dependency cycle: '+str(stack+[g]) for dep in graph[g]: assert dep==BASE or dep in ids,f'External addon dependency {dep}' if dep!=BASE:walk(dep,stack+[g]) for g in ids:walk(g,[]) for p in (ROOT/'addons').rglob('*.meta'): m=re.search(r'Name "\{([A-F0-9]{16})\}([^"\n]+)"',p.read_text()) assert m,f'Malformed metadata: {p}' g,path=m.groups();assert g not in resources,f'Duplicate resource GUID {g}' addon=p.relative_to(ROOT/'addons').parts[0] assert p.with_suffix('')==ROOT/'addons'/addon/path, f'Resource path mismatch: {p}' assert p.with_suffix('').is_file(),f'Missing resource for {p}' resources[g]=path;paths[path]=g owners[g]=addon def visible(g): result={ids[g]} for dep in graph[g]: if dep!=BASE:result.update(visible(dep)) return result visibility={ids[g]:visible(g) for g in ids} vanilla=json.loads((ROOT/'docs/vanilla-resources.json').read_text()) for p in (ROOT/'addons').rglob('*'): if not p.is_file() or p.suffix not in ['.c','.et','.conf','.ent','.layer','.layout','.emat']:continue s=p.read_text() assert not re.search(r'\b(?:ESCT\w*|SCRTC_\w+|SCRT_\w+|EAI_\w+)\b',s),f'Original ecosystem dependency: {p}' for g,path in re.findall(r'\{([A-F0-9]{16})\}([^"\n]+)',s): assert resources.get(g)==path or vanilla.get(path)==g,f'Unresolved/mismatched resource in {p}: {g} {path}' if g in owners: addon=p.relative_to(ROOT/'addons').parts[0] assert owners[g] in visibility[addon],f'Resource outside declared dependency graph in {p}: {g} {path}' if p.suffix in ['.et','.conf','.ent','.layout','.emat']: assert p.with_name(p.name+'.meta').exists(),f'Missing metadata: {p}' inventory=json.loads((ROOT/'docs/original-resource-inventory.json').read_text()) coverage=json.loads((ROOT/'docs/original-feature-coverage.json').read_text()) mapped=[];feature_ids=set() for feature in coverage['features']: assert feature['id'] not in feature_ids,'Duplicate feature responsibility' feature_ids.add(feature['id']) assert feature['status'] in {'pending','partial'},'Completion requires a separately reviewed acceptance update' assert feature['remaining'],'Unfinished responsibilities must describe remaining work' mapped.extend(feature['original_scripts']) for path in feature['replacement_files']: assert (ROOT/path).is_file(),f'Missing replacement reference: {path}' assert len(mapped)==len(set(mapped)), 'Original scripts assigned more than once' assert set(mapped)==set(inventory['script_paths']), 'Original inventory has untracked or unknown entries' print(f'PASS: {len(mapped)} original script entries tracked across {len(feature_ids)} unfinished responsibilities') print(f'PASS: {len(ids)} isolated addons, acyclic dependencies, {len(resources)} unique resources, exact vanilla references') for name in ['test_mortar_activity_completion.py', 'test_packed_chat_game.py', 'test_native_mortar_refresh.py', 'test_archive_packed.py', 'test_mortar_refresh.py', 'test_packed_core_game.py', 'test_pak_inventory.py', 'test_native_mortar_salvo.py', 'test_spectator_guidance.py', 'test_native_package.py', 'test_item_station_teardown.py', 'test_source_bundle.py', 'test_native_flight_footprint.py', 'test_native_flight_input_diagnostics.py', 'test_mortar_logistics.py', 'test_mortar_courier_storage.py','test_powered_flight_pad.py','test_prison_escape_policy.py','test_powered_flight_policy.py','test_flight_action_runner.py','test_native_local_admission_probe.py','test_mortar_report_ledger.py','test_dedicated_native.py','test_native_mortar_transfer.py','test_mortar_aim_renewal.py','test_dedicated_preflight.py','test_mortar_transactions.py','test_native_mortar_probe.py','test_diagnostic_no_splash.py','test_casualty_incapacitation.py','test_casualty_remove_probe.py','test_extraction_placement_policy.py','test_guard_cancellation_policy.py','test_casualty_ground_policy.py','test_casualty_reservation_death.py','test_casualty_loading_policy.py','test_initial_guard_policy.py','test_headless_game_runner.py','test_vanilla_game_control.py','test_archive_game_control.py','test_site_discovery_policy.py','test_faction_catalog_scope.py','test_mission_rules.py','test_admin_setting_policy.py', 'test_player_admission_policy.py','test_progression_identity.py','test_discovery_map_position.py','test_local_admission.py','test_prison_placement_policy.py', 'test_recovery_policy.py','test_time_policy.py','test_environment_policy.py','test_environment_restart_runner.py', 'test_inventory_enumeration_policy.py','test_radio_defence_policy.py','test_radio_feedback_policy.py','test_performance_comparison.py','test_release_check.py','test_settings_migration.py','hq_network_regression.py','helicopter_availability_regression.py','mortar_salvo_regression.py']: subprocess.run([sys.executable,str(ROOT/'tests'/name)],check=True) print('All repository checks passed. Native compilation and multiplayer tests are separate requirements.') if __name__=='__main__':check()