# Concurrency, cancellation, and resource audit `metacrate-concurrency-audit` is the deterministic native Rust stress/soak gate for client lifetime and resource ownership. Every run executes the work; there are no ignored tests, environment-dependent skips, or success paths that merely report an unavailable service. The default mode is deliberately offline. It does not read `.env`, authenticate, or contact Second Life or an OpenSim grid. Those credentials are reserved for the separately documented live-grid smoke gate. This audit instead uses injected HTTP responses, temporary files it owns, localhost UDP sockets, and the real native encrypted WebRTC/Opus loopback transport. That makes saturation, races, and resource baselines reproducible without mutating a grid account. ## Scenarios and invariants After one unmeasured warm-up, every measured cycle performs all of these steps: - start a client-owned task and stop/join it through four concurrent, idempotent `GridClient` shutdown calls; - run concurrent deduplicated downloads, independent cancellation, and a saturated 256-entry dispatcher queue whose excess requests must be rejected; - create, mutate, and remove inventory folders/items while an actual inventory cleanup worker is alive; - attach and release inventory, appearance, and asset subscriptions, verified with weak-reference retention probes; - create, read, close, and delete temporary files and their owned directory; - repeatedly open localhost UDP clients, exchange datagrams, close them, and rebind the server address to prove socket release; - establish and shut down a real native WebRTC loopback session and require both the peer and signaling task counters to return to zero. The focused library regressions additionally prove that asset and appearance subscriber panics cannot prevent later handlers from running, client service shutdown callbacks execute outside the registry lock, and saturated download queues drain completely when cancelled. Concurrent voice provisioning admits exactly one session without holding the signaling state lock across awaited I/O or leaking the rejected attempt. ## Thresholds and evidence [`ci/concurrency-thresholds.json`](../ci/concurrency-thresholds.json) is the reviewed policy. It requires at least four and at most 256 cycles, fixes 32 operations per cycle, permits at most 16 MiB of retained allocator growth after warm-up, and limits a run to 180 seconds. Task, dispatcher, download, inventory-worker, subscription, file, socket, voice, and signaling counts must all exactly match the zero baseline after shutdown; the memory allowance does not relax those exact resource checks. Run the minimum deterministic stress gate with: ```sh cargo run --locked -p metacrate-concurrency-audit -- \ --cycles 4 --evidence /tmp/metacrate-concurrency-audit.json ``` Run the CI soak length with `--cycles 16`. Evidence contains only scenario names, counts, allocation deltas, elapsed time, thresholds, and outcome. It does not contain credentials, hostnames, capability URLs, temporary paths, or grid identities. Gitea uploads the evidence produced by the 16-cycle run. The resource counters are portable Rust ownership counters rather than Linux-only `/proc` measurements, so the same runner and invariants apply on Linux, macOS, and Windows. Repository CI runs on `ubuntu-latest` as required.