Files
MetaCrate/tools/check_milestone_09_issue_62.py
Chili Palmer 61d6721287
All checks were successful
Native code generation / deterministic (push) Successful in 13m14s
Imaging and meshing gate / native (push) Successful in 4m13s
Native Rust workspace compile / compile (push) Successful in 4m19s
Implement native inventory manager workflows (#62)
2026-08-10 06:00:28 +00:00

153 lines
8.5 KiB
Python

#!/usr/bin/env python3
"""Audit issue 62's native UDP inventory-manager boundary."""
from __future__ import annotations
from pathlib import Path
import re
import generate_api_shims
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT / "crates" / "libremetaverse" / "src" / "inventory_manager.rs"
DOC = ROOT / "docs" / "inventory.md"
MANAGER_TESTS = ROOT / "tests" / "compat" / "tests" / "inventory_manager_semantics.rs"
TASK_TESTS = ROOT / "tests" / "compat" / "tests" / "task_inventory_semantics.rs"
STUB_RE = re.compile(r"\b(?:not_implemented|unimplemented_api)\b|\b(?:todo|unimplemented)!\s*\(")
REQUIRED_TYPES = {
"T:LibreMetaverse.FindObjectByPathReplyEventArgs",
"T:LibreMetaverse.FolderUpdatedEventArgs",
"T:LibreMetaverse.InventoryManager",
"T:LibreMetaverse.InventoryManager.CopyItemsResult",
"T:LibreMetaverse.InventoryManager.FolderUpdateResult",
"T:LibreMetaverse.InventoryObjectOfferedEventArgs",
"T:LibreMetaverse.ItemReceivedEventArgs",
"T:LibreMetaverse.SaveAssetToInventoryEventArgs",
"T:LibreMetaverse.ScriptRunningReplyEventArgs",
"T:LibreMetaverse.TaskInventoryReplyEventArgs",
"T:LibreMetaverse.TaskItemReceivedEventArgs",
}
REQUIRED_MEMBERS = {
"E:LibreMetaverse.InventoryManager.FindObjectByPathReply",
"E:LibreMetaverse.InventoryManager.FolderUpdated",
"E:LibreMetaverse.InventoryManager.InventoryObjectOffered",
"E:LibreMetaverse.InventoryManager.ItemReceived",
"E:LibreMetaverse.InventoryManager.ScriptRunningReply",
"E:LibreMetaverse.InventoryManager.TaskInventoryReply",
"E:LibreMetaverse.InventoryManager.TaskItemReceived",
"M:LibreMetaverse.InventoryManager.#ctor(LibreMetaverse.GridClient)",
"M:LibreMetaverse.InventoryManager.CreateFolder(LibreMetaverse.UUID,System.String,LibreMetaverse.FolderType)",
"M:LibreMetaverse.InventoryManager.CreateItemAsync(LibreMetaverse.UUID,System.String,System.String,LibreMetaverse.AssetType,LibreMetaverse.UUID,LibreMetaverse.InventoryType,LibreMetaverse.WearableType,LibreMetaverse.PermissionMask,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.CreateLinkAsync(LibreMetaverse.UUID,LibreMetaverse.UUID,System.String,System.String,LibreMetaverse.InventoryType,LibreMetaverse.UUID,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.FetchItemAsync(LibreMetaverse.UUID,LibreMetaverse.UUID,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.FindObjectByPathAsync(LibreMetaverse.UUID,LibreMetaverse.UUID,System.String,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.FolderContentsAsync(LibreMetaverse.UUID,LibreMetaverse.UUID,System.Boolean,System.Boolean,LibreMetaverse.InventorySortOrder,System.Threading.CancellationToken,System.Boolean)",
"M:LibreMetaverse.InventoryManager.GetTaskInventoryAsync(LibreMetaverse.UUID,System.UInt32,LibreMetaverse.Simulator,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.GiveFolderAsync(LibreMetaverse.UUID,System.String,LibreMetaverse.UUID,System.Boolean,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.GiveItem(LibreMetaverse.UUID,System.String,LibreMetaverse.AssetType,LibreMetaverse.UUID,System.Boolean)",
"M:LibreMetaverse.InventoryManager.MoveFolders(System.Collections.Generic.Dictionary{LibreMetaverse.UUID,LibreMetaverse.UUID},System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.MoveItemsAsync(System.Collections.Generic.Dictionary{LibreMetaverse.UUID,LibreMetaverse.UUID},System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.RemoveItemsAsync(System.Collections.Generic.IEnumerable{LibreMetaverse.UUID},System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.RequestCopyItemsWithResultAsync(System.Collections.Generic.List{LibreMetaverse.UUID},System.Collections.Generic.List{LibreMetaverse.UUID},System.Collections.Generic.List{System.String},LibreMetaverse.UUID,System.Threading.CancellationToken)",
"M:LibreMetaverse.InventoryManager.RequestDeRezToInventory(System.UInt32,LibreMetaverse.DeRezDestination,LibreMetaverse.UUID,LibreMetaverse.UUID)",
"M:LibreMetaverse.InventoryManager.RequestFetchInventoryAsync(System.Collections.Generic.Dictionary{LibreMetaverse.UUID,LibreMetaverse.UUID},System.Threading.CancellationToken,System.Action{System.Collections.Generic.List{LibreMetaverse.InventoryItem}})",
"M:LibreMetaverse.InventoryManager.RequestRezFromInventory(LibreMetaverse.Simulator,LibreMetaverse.UUID,LibreMetaverse.Quaternion,LibreMetaverse.Vector3,LibreMetaverse.InventoryItem,LibreMetaverse.UUID,LibreMetaverse.UUID,System.Boolean)",
"M:LibreMetaverse.InventoryManager.RequestTaskInventory(System.UInt32,LibreMetaverse.Simulator)",
"M:LibreMetaverse.InventoryManager.RequestUpdateItems(System.Collections.Generic.List{LibreMetaverse.InventoryItem},LibreMetaverse.UUID)",
"M:LibreMetaverse.InventoryManager.UpdateTaskInventory(System.UInt32,LibreMetaverse.InventoryItem,LibreMetaverse.Simulator,System.Boolean)",
"M:LibreMetaverse.InventoryManager.WaitForNextInventoryOfferAsync(System.Threading.CancellationToken)",
}
def require_markers(path: Path, markers: tuple[str, ...]) -> None:
source = path.read_text()
missing = [marker for marker in markers if marker not in source]
if missing:
raise SystemExit(f"{path.name}: audit evidence missing: " + ", ".join(missing))
def main() -> None:
native_types = (
generate_api_shims.NATIVE_TYPES.keys()
| generate_api_shims.NATIVE_DECLARATIONS.keys()
)
missing_types = sorted(REQUIRED_TYPES - native_types)
if missing_types:
raise SystemExit("issue 62 native types missing: " + ", ".join(missing_types))
missing_members = sorted(
REQUIRED_MEMBERS - generate_api_shims.NATIVE_MEMBER_BODIES.keys()
)
if missing_members:
raise SystemExit("issue 62 native members missing: " + ", ".join(missing_members))
update_task = (
"M:LibreMetaverse.InventoryManager.UpdateTaskInventory(System.UInt32,"
"LibreMetaverse.InventoryItem,LibreMetaverse.Simulator,System.Boolean)"
)
if "only_mod_meta.unwrap_or(true)" not in generate_api_shims.NATIVE_MEMBER_BODIES[update_task]:
raise SystemExit("UpdateTaskInventory must retain the C# metadata-only default")
for update_member in (
"M:LibreMetaverse.InventoryManager.RequestUpdateItem(LibreMetaverse.InventoryItem)",
"M:LibreMetaverse.InventoryManager.RequestUpdateItems(System.Collections.Generic.List{LibreMetaverse.InventoryItem})",
):
if "UUID::random()?" not in generate_api_shims.NATIVE_MEMBER_BODIES[update_member]:
raise SystemExit(f"{update_member} must generate a transaction ID")
if STUB_RE.search(SOURCE.read_text()):
raise SystemExit("issue 62 owned Rust stubs remain in inventory_manager.rs")
require_markers(
SOURCE,
(
"MAX_TASK_INVENTORY_BYTES",
"MAX_PENDING_REQUESTS",
"encode_multiple",
"pending_created",
"pending_fetches",
"pending_task_replies",
"callbacks are not invoked while an inventory lock is held",
"cancelling_one_fetch_waiter_preserves_concurrent_correlation",
"fake_bulk_copy_reply_waits_for_every_block",
"asset_type_without_folder_type_falls_back_to_inventory_root",
"stale_descendents_packet_cannot_mutate_store",
"task_xfer_rejects_announced_data_above_bound",
),
)
require_markers(
DOC,
(
"UDP inventory manager",
"4,096 pending operations",
"16 MiB",
"RequestXfer",
"No store lock is held across an await",
),
)
require_markers(
MANAGER_TESTS,
(
"inventory_manager_null_throws",
"encrypt_decrypt_round_trip",
"item_crc_is_deterministic_and_changes_when_fields_change",
"create_inventory_item_returns_correct_subclass",
),
)
require_markers(
TASK_TESTS,
(
"cap_available_returns_contents_folder_and_decrypts_shadow_id",
"plain_asset_id_parses_without_decryption",
"non_success_status_returns_contents_folder_only",
"no_capability_does_not_make_http_request",
),
)
print(
"issue 62 audit: native inventory packet mappings, bounded correlation and Xfer, "
"lock-free callback evidence, documentation, and translated compatibility cases are present"
)
if __name__ == "__main__":
main()