#!/usr/bin/env python3 """Audit the complete native world-services milestone boundary.""" from __future__ import annotations import json from pathlib import Path import re import generate_api_shims ROOT = Path(__file__).resolve().parents[1] SOURCE_ROOT = ROOT / "crates" / "libremetaverse" / "src" OWNED_SOURCES = ( "agent_manager.rs", "agent_messages.rs", "agent_movement.rs", "animation.rs", "animesh.rs", "animesh_skinning.rs", "appearance_baker.rs", "appearance_manager.rs", "asset_archive.rs", "asset_cache.rs", "asset_manager.rs", "asset_material.rs", "asset_models.rs", "avatar_manager.rs", "avatar_rig.rs", "baking_texture_provider.rs", "current_outfit.rs", "directory_manager.rs", "environment_manager.rs", "estate_tools.rs", "friends_manager.rs", "gesture.rs", "gltf.rs", "grid_manager.rs", "group_manager.rs", "initial_outfit.rs", "interest_list.rs", "inventory.rs", "inventory_ais.rs", "inventory_manager.rs", "marketplace.rs", "model_workflow.rs", "object_manager.rs", "object_material.rs", "object_model.rs", "parcel_manager.rs", "slurl.rs", "sound_manager.rs", "terrain_codec.rs", "terrain_manager.rs", "transfers.rs", "user_report.rs", ) REQUIRED_NATIVE_TYPES = { "T:LibreMetaverse.AgentManager", "T:LibreMetaverse.AgentManager.AgentMovement", "T:LibreMetaverse.Animesh.AnimeshManager", "T:LibreMetaverse.AppearanceManager", "T:LibreMetaverse.AssetManager", "T:LibreMetaverse.AvatarManager", "T:LibreMetaverse.DirectoryManager", "T:LibreMetaverse.EnvironmentManager", "T:LibreMetaverse.EstateTools", "T:LibreMetaverse.FriendsManager", "T:LibreMetaverse.GridManager", "T:LibreMetaverse.GroupManager", "T:LibreMetaverse.InventoryAISClient", "T:LibreMetaverse.InventoryManager", "T:LibreMetaverse.Marketplace.MarketplaceManager", "T:LibreMetaverse.ObjectManager", "T:LibreMetaverse.ParcelManager", "T:LibreMetaverse.SoundManager", "T:LibreMetaverse.TerrainManager", } REQUIRED_NATIVE_MEMBERS = { "M:LibreMetaverse.InventoryManager.UploadThumbnailAsync(LibreMetaverse.UUID,LibreMetaverse.UUID,System.Byte[],System.Threading.CancellationToken,System.IProgress{LibreMetaverse.HttpCapsClient.ProgressReport})", "P:LibreMetaverse.GridClient.Marketplace", "P:LibreMetaverse.GridClient.Marketplace#set", } RELATED_UPSTREAM_SOURCES = { "LibreMetaverse.Tests/AnimationTrackTests.cs", "LibreMetaverse.Tests/AnimeshPlayerTests.cs", "LibreMetaverse.Tests/AnimeshSkinningTests.cs", "LibreMetaverse.Tests/AppearanceLiveTests.cs", "LibreMetaverse.Tests/AppearanceManagerTests.cs", "LibreMetaverse.Tests/AppearanceTests.cs", "LibreMetaverse.Tests/AssetMaterialOverrideTests.cs", "LibreMetaverse.Tests/AvatarManagerTests.cs", "LibreMetaverse.Tests/BakerTests.cs", "LibreMetaverse.Tests/BatchLinkTests.cs", "LibreMetaverse.Tests/CurrentOutfitFolderTests.cs", "LibreMetaverse.Tests/EnvironmentManagerTests.cs", "LibreMetaverse.Tests/EstateExperienceReplyTests.cs", "LibreMetaverse.Tests/EstateToolsTests.cs", "LibreMetaverse.Tests/ExperienceListAndRegionMessageTests.cs", "LibreMetaverse.Tests/ExperiencePreferencesMessageTests.cs", "LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs", "LibreMetaverse.Tests/GLTFMaterialUploadTests.cs", "LibreMetaverse.Tests/GltfDocumentTests.cs", "LibreMetaverse.Tests/InventoryAISClientTests.cs", "LibreMetaverse.Tests/InventoryFetchTests.cs", "LibreMetaverse.Tests/InventoryManagerTests.cs", "LibreMetaverse.Tests/InventoryTests.cs", "LibreMetaverse.Tests/LibraryInventoryTests.cs", "LibreMetaverse.Tests/MarketplaceFolderClassifierTests.cs", "LibreMetaverse.Tests/MarketplaceManagerTests.cs", "LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs", "LibreMetaverse.Tests/OarFileTerrainTests.cs", "LibreMetaverse.Tests/OfflineMessagesTests.cs", "LibreMetaverse.Tests/PrimObjectTests.cs", "LibreMetaverse.Tests/PrimitiveTests.cs", "LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs", "LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs", "LibreMetaverse.Tests/RegionScheduleTests.cs", "LibreMetaverse.Tests/RequestTaskInventoryCapTests.cs", "LibreMetaverse.Tests/SendPostcardTests.cs", "LibreMetaverse.Tests/SimConsoleTests.cs", "LibreMetaverse.Tests/SlurlParserTests.cs", "LibreMetaverse.Tests/StartAuctionTests.cs", "LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs", "LibreMetaverse.Tests/TextureEntryTests.cs", "LibreMetaverse.Tests/UploadThumbnailTests.cs", } STUB_RE = re.compile(r"\b(?:not_implemented|unimplemented_api)\b|\b(?:todo|unimplemented)!\s*\(") def require_markers(path: Path, markers: tuple[str, ...]) -> None: text = path.read_text() missing = [marker for marker in markers if marker not in text] if missing: raise SystemExit(f"{path}: audit evidence missing: " + ", ".join(missing)) def check_owned_sources() -> None: offenders = [ name for name in OWNED_SOURCES if STUB_RE.search((SOURCE_ROOT / name).read_text()) ] if offenders: raise SystemExit("milestone 09 owned Rust stubs remain: " + ", ".join(offenders)) def check_native_mappings() -> None: native = set(generate_api_shims.NATIVE_TYPES) | set(generate_api_shims.NATIVE_DECLARATIONS) missing_types = sorted(REQUIRED_NATIVE_TYPES - native) if missing_types: raise SystemExit("milestone 09 native types missing: " + ", ".join(missing_types)) missing_members = sorted( REQUIRED_NATIVE_MEMBERS - set(generate_api_shims.NATIVE_MEMBER_BODIES) ) if missing_members: raise SystemExit("milestone 09 native members missing: " + ", ".join(missing_members)) def check_parity_catalog() -> None: catalog = json.loads((ROOT / "tests" / "upstream-tests.json").read_text()) related = [test for test in catalog["tests"] if test["source"] in RELATED_UPSTREAM_SOURCES] present_sources = {test["source"] for test in related} missing_sources = sorted(RELATED_UPSTREAM_SOURCES - present_sources) if missing_sources: raise SystemExit("milestone 09 parity sources missing: " + ", ".join(missing_sources)) bad = [ test["id"] for test in related if test["status"] not in {"translated", "ignored-live"} or test.get("semantic_review") != "reviewed" ] if bad: raise SystemExit("milestone 09 parity cases are not reviewed: " + ", ".join(bad)) missing_rust = sorted( { test["rust_file"] for test in related if test["status"] == "translated" and not (ROOT / test["rust_file"]).is_file() } ) if missing_rust: raise SystemExit("milestone 09 translated files missing: " + ", ".join(missing_rust)) def check_fake_grid_gate() -> None: require_markers( ROOT / "crates" / "libremetaverse" / "tests" / "network_manager.rs", ( "offline_fake_grid_drives_the_complete_networking_lifecycle_without_task_leaks", "event_queue_running", "fake-grid inventory marker", "create_asset_wrapper", "get_player", "request_object", "current_parcel", "friend_list", "current_group_count", "marketplace_error", "search_people", "pending_logout_tasks", "dispatcher_running", "is_cancellation_requested", "seed-secret", "queue-secret", "asset-secret", ), ) def check_docs_and_program_prerequisites() -> None: require_markers( ROOT / "docs" / "world-milestone-gate.md", ( "Cross-manager fake grid", "Cancellation and teardown", "Live actions remain opt-in", "tools/test_milestone_09.py", "RUN_LIVE_TESTS=1", ), ) projects = json.loads((ROOT / "programs" / "upstream-programs.json").read_text())[ "projects" ] if len(projects) != 9: raise SystemExit("milestone 09 expected all nine program prerequisite inventories") manifest = (ROOT / "programs" / "Cargo.toml").read_text() if manifest.count("[[bin]]") != 9: raise SystemExit("milestone 09 expected all nine Rust program targets") def main() -> None: check_owned_sources() check_native_mappings() check_parity_catalog() check_fake_grid_gate() check_docs_and_program_prerequisites() print( "milestone 09 audit: owned world sources contain no stubs; native mappings, " "reviewed parity cases, fake-grid integration, docs, and program prerequisites are present" ) if __name__ == "__main__": main()