#!/usr/bin/env python3 """Audit issue 64's native asset, transfer, cache, and download boundary.""" from __future__ import annotations from pathlib import Path import re import generate_api_shims ROOT = Path(__file__).resolve().parents[1] SOURCES = tuple( ROOT / "crates" / "libremetaverse" / "src" / name for name in ( "asset_cache.rs", "asset_manager.rs", "asset_material.rs", "asset_models.rs", "mesh_asset.rs", "object_material.rs", "transfers.rs", ) ) DOC = ROOT / "docs" / "assets.md" NATIVE_TESTS = ROOT / "crates" / "libremetaverse" / "src" / "asset_pipeline_semantics.rs" HTTP_TESTS = ROOT / "crates" / "libremetaverse" / "tests" / "caps_http.rs" STUB_RE = re.compile(r"\b(?:not_implemented|unimplemented_api)\b|\b(?:todo|unimplemented)!\s*\(") REQUIRED_TYPES = { "T:LibreMetaverse.AssetCache", "T:LibreMetaverse.AssetManager", "T:LibreMetaverse.AssetDownload", "T:LibreMetaverse.AssetUpload", "T:LibreMetaverse.AssetUploadEventArgs", "T:LibreMetaverse.ImageDownload", "T:LibreMetaverse.ImageReceiveProgressEventArgs", "T:LibreMetaverse.InitiateDownloadEventArgs", "T:LibreMetaverse.Transfer", "T:LibreMetaverse.XferDownload", "T:LibreMetaverse.XferReceivedEventArgs", "T:LibreMetaverse.Assets.Asset", "T:LibreMetaverse.Assets.AssetMaterial", "T:LibreMetaverse.Assets.AssetMesh", "T:LibreMetaverse.Assets.AssetTexture", } 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.name}: audit evidence missing: " + ", ".join(missing)) def main() -> None: native = set(generate_api_shims.NATIVE_TYPES) | set(generate_api_shims.NATIVE_DECLARATIONS) missing = sorted(REQUIRED_TYPES - native) if missing: raise SystemExit("issue 64 native types missing: " + ", ".join(missing)) for source in SOURCES: if STUB_RE.search(source.read_text()): raise SystemExit(f"issue 64 owned Rust stubs remain in {source.name}") require_markers(SOURCES[0], ("create_new(true)", "fs::rename", "CACHE_TARGET_PERCENT", "maybe_begin_prune")) require_markers(SOURCES[1], ("ViewerAsset", "TransferRequest", "TransferAbort", "UploadBakedTexture", "AssetUploadRequest")) require_markers(SOURCES[3], ("MAX_ASSET_BYTES", "VorbisEncoderBuilder", "J2kCodec", "crate::mesh_asset::decode_asset_map")) require_markers(SOURCES[4], ("deserialize_llsd_binary_prefix", "ZlibDecoder", "MAX_SECTION_BYTES")) require_markers(NATIVE_TESTS, ("sound_codec_produces_real_valid_payload", "texture_codec_produces_real_valid_payload", "cache_writes_are_atomic_and_corruption_is_typed", "cache_pruning_reclaims_old_entries")) require_markers(HTTP_TESTS, ("deduplicated_subscriber_cancellation_is_independent", "attempts.load(Ordering::Acquire), 1")) require_markers(DOC, ("64 MiB", "independent cancellation", "out-of-order", "atomically rename", "90%")) print("issue 64 audit: native models/codecs, bounded LLUDP and capability transfers, independent dedup cancellation, atomic cache, documentation, and focused tests are present") if __name__ == "__main__": main()