# M03 — Renderer Facade and Safe Extraction

<!-- OPENWC_TARGET:ACTIVE -->

## Outcome

Закрыть монолитный streamer стабильным API и постепенно извлечь тестируемые подсистемы без rewrite.

## Steps

- [x] Ввести `WorldRenderFacade` для focus, environment, entity visuals, ground query и metrics.
- [x] Запретить gameplay/editor доступ к внутренним очередям streamer.
- [x] Извлечь pure `StreamingTargetPlanner`.
- [x] Извлечь `RenderBudgetScheduler` с bounded queues/cancellation.
- [ ] Затем извлекать terrain, M2, WMO и liquid services по одному.
- [ ] Сохранить cache versioning и main-thread GPU finalization rules.
- [ ] Добавить dependency и performance regression checks.

## Fidelity evidence

Все baseline checkpoints сравниваются до/после; placement, visibility, animation и materials не меняются без отдельной fidelity-задачи.

## Exit criteria

Runtime и Editor используют facade; planner/scheduler тестируются без полного мира; p95/p99 и hitch budgets не хуже согласованного baseline.

## Evidence

- Date: 2026-07-18
- Revision/worktree: master merges `7ece2ab`, `7e35de7`, `80cb084`, `d6e5b53`, `c69abd6`, `606770c`, `630a0c1`, `f36fabb`, `24aef13`, `2342430`, `396be5e`, `f88bf97`, `3f84717`, `d2cb52f`, `f9e5a4f`, `c06aed5`, `a878e7c`, `60603e1`, `b4955d6`, `ada0fd9`, `f470775`, `874fd0f`, `38f831e`, `83b3618`, `3094561`, `fa85985`, `1fafdde`, `7cd07dd`, `1de50f9`, `3dccd3e`, `e7a7c67`, `c0fc191`, `c251985`, `5e82daa`, `1dc013e`, `99a90dd`, `4354834`, `a043c79`, `f79e064`, `d37c799`, `06f6394`;
  packages `M03-RND-SCHEDULER-001`, `M03-RND-INTERNAL-ACCESS-GATE-001`,
  `M03-RND-FACADE-GROUND-QUERY-001`, `M03-RND-FACADE-ENVIRONMENT-001`,
  `M03-RND-FACADE-ENTITY-001`, `M03-RND-TERRAIN-CACHE-SERVICE-001`,
  `M03-RND-TERRAIN-LOD-PLANNER-001`, `M03-RND-TERRAIN-CHUNK-QUEUE-001`,
  `M03-RND-M2-UNIQUE-REGISTRY-001`,
  `M03-RND-M2-PLACEMENT-TRANSFORM-001`,
  `M03-RND-M2-PLACEMENT-GROUPER-001`,
  `M03-RND-M2-BUILD-BATCH-PLANNER-001`,
  `M03-RND-WMO-PLACEMENT-RESOLVER-001`,
  `M03-RND-WMO-PLACEMENT-REGISTRY-001`,
  `M03-RND-WMO-RENDER-BUILD-PLANNER-001`,
  `M03-RND-WMO-RENDER-BUILD-QUEUE-001`,
  `M03-RND-WMO-RENDER-RESOURCE-CACHE-001`,
  `M03-RND-WMO-SCENE-RESOURCE-CACHE-001`,
  `M03-RND-ADT-WATER-LOAD-PIPELINE-001`,
  `M03-RND-ADT-WATER-SCENE-FINALIZER-001`,
  `M03-RND-M2-RUNTIME-REBUILD-CLASSIFIER-001`,
  `M03-RND-M2-MESH-LOAD-PIPELINE-001`,
  `M03-RND-M2-MESH-RESOURCE-CACHE-001`,
  `M03-RND-M2-MESH-RESOURCE-EXTRACTOR-001`,
  `M03-RND-M2-RUNTIME-MESH-FINALIZER-001`,
  `M03-RND-M2-RAW-MODEL-REPOSITORY-001`,
  `M03-RND-M2-PROTOTYPE-CACHE-001`,
  `M03-RND-M2-ANIMATION-LOAD-PIPELINE-001`,
  `M03-RND-M2-ANIMATED-SCENE-FINALIZER-001`,
  `M03-RND-M2-ANIMATION-PLAYBACK-001`,
  `M03-RND-M2-ANIMATED-INSTANCE-MATERIALIZER-001`,
  `M03-RND-M2-STATIC-BATCH-MATERIALIZER-001`,
  `M03-RND-M2-BUILD-QUEUE-001`,
  `M03-RND-M2-BUILD-DISPATCH-PLANNER-001`,
  `M03-RND-M2-BUILD-RESOURCE-SNAPSHOT-001`,
  `M03-RND-M2-STATIC-BUILD-RESOURCE-OBSERVER-001`,
  `M03-RND-M2-CACHED-ANIMATION-RESOURCE-OBSERVER-001`,
  `M03-RND-M2-NATIVE-ANIMATION-RESOURCE-OBSERVER-001`,
  `M03-RND-M2-ANIMATION-RESOURCE-FINALIZER-001`
- Commands: dedicated scheduler/planner/facade/focus/coordinate/manifest/shutdown
  headless verifiers; Godot cold editor parse; coordination, documentation and diff gates.
- Results: scheduler `cases=6 iterations=20000 elapsed_ms=10.216`; planner
  `cases=5 average_ms=1.804`; facade/focus passed; coordinate boundary
  `files=111 consumers=6`; renderer manifest retained `7/7` checkpoints;
  shutdown ownership and repository gates passed. Internal-access gate additionally
  derived `43` private symbols and found no forbidden access across `7` gameplay
  and `9` EditorPlugin-package sources plus the terrain probe. Ground facade passed
  `delegation=5 ground_contract=2`; cold `RenderedGroundSample contract=3`;
  environment integration passed cold snapshot `contract=5` and facade
  `delegation=6 environment_contract=7`; dry-run retained all `7/7` plans and
  applied the dusk checkpoint at `time=19.00`. Entity presentation passed
  `snapshot_cases=8 lifecycle_cases=14 runtime_scenes=2`; facade expanded to
  `delegation=9 entity_contract=6`, while character presentation remained `9/10/3/1`.
  Terrain quality cache passed `contract_cases=15 loader_calls=3`; internal-access
  inventory decreased to `42` because the loader no longer owns the LRU-order field.
  Terrain chunk LOD planner passed `cases=7 iterations=250 elapsed_ms=12.630`;
  post-merge facade, internal-access and `7/7` manifest gates remained green.
  Terrain chunk geometry queue planner passed `cases=8 iterations=100
  elapsed_ms=229.324`; internal-access remained `42` and post-merge facade and
  `7/7` manifest gates stayed green.
  M2 unique placement registry passed `cases=10 iterations=100 elapsed_ms=35.513`;
  the historical `uid:11785` cross-tile smoke, internal-access `42`, facade and
  `7/7` manifest gates remained green after merge.
  M2 placement transform resolver passed `cases=9 iterations=10000
  elapsed_ms=27.409`; post-merge M2 registry, internal-access `42`, facade,
  `7/7` manifest, documentation and coordination gates remained green.
  M2 placement grouper passed `cases=9 iterations=100 placements=256
  elapsed_ms=67.104`; post-merge transform resolver, registry, internal-access
  `42`, facade, `7/7` manifest, documentation and coordination gates remained green.
  M2 build batch planner passed `cases=8 iterations=20000 elapsed_ms=14.532`;
  post-merge grouper, transform resolver, registry, internal-access `42`, facade,
  `7/7` manifest, documentation and coordination gates remained green.
  WMO placement resolver passed `cases=9 iterations=20000 elapsed_ms=27.919`;
  post-merge renderer materials, shutdown, internal-access `42`, facade,
  `7/7` manifest, documentation and coordination gates remained green.
  WMO placement registry passed `cases=10 iterations=100 elapsed_ms=53.941`;
  all 21 adjacent WMO/M2/terrain/facade/scheduler/streaming/coordinate
  regressions and the `7/7` checkpoint dry-run passed; post-merge registry
  (`54.178ms`), resolver, shutdown, facade, documentation and coordination
  gates remained green.
  WMO render build step planner passed `cases=9 iterations=20000
  elapsed_ms=11.914`; WMO registry/resolver/material/shutdown, 18 adjacent
  regressions and the `7/7` checkpoint dry-run passed; post-merge planner
  (`11.059ms`), registry, resolver, shutdown, facade, documentation and
  coordination gates remained green.
  WMO render build queue passed `cases=11 iterations=100 elapsed_ms=59.874`;
  WMO planner/registry/resolver/material/shutdown, 18 adjacent regressions and
  the `7/7` checkpoint dry-run passed. The first post-merge smoke exposed an
  editor class-cache dependency; a fresh no-`.godot` run verified the fix
  (`57.835ms`), and post-fix master passed queue (`56.454ms`), planner,
  registry, resolver, shutdown, facade, documentation and coordination gates
  without parse diagnostics.
  WMO render Resource cache state passed `cases=10 iterations=100
  elapsed_ms=58.727`; direct no-`.godot` service verification passed
  (`45.361ms`), WMO queue/planner/registry/resolver/material/shutdown and 18
  adjacent regressions passed, and the checkpoint dry-run retained `7/7` plans.
  Post-merge cache state (`51.949ms`), shutdown, WMO queue/resolver, facade,
  internal-access `41`, `7/7` manifest, documentation and coordination gates
  remained green.
  WMO scene Resource cache state passed `cases=11 iterations=100
  elapsed_ms=40.768`; its initial direct no-`.godot` run passed (`43.636ms`),
  render-cache state, WMO queue/planner/registry/resolver/material/shutdown and
  18 adjacent regressions passed, and checkpoint dry-run retained `7/7` plans.
  Post-merge scene state (`40.113ms`), render state (`43.434ms`), shutdown,
  WMO queue/resolver, facade, internal-access `40`, `7/7` manifest,
  documentation and coordination gates remained green.
  ADT water load pipeline state passed `cases=12 iterations=100
  elapsed_ms=86.170`; its initial direct no-`.godot` run passed (`94.576ms`),
  WMO caches/queue/planner/registry/resolver/material/shutdown and 18 adjacent
  M2/terrain/facade/scheduler/streaming/coordinate regressions passed, and the
  checkpoint dry-run retained `7/7` plans. Post-merge water state (`86.935ms`),
  shutdown, renderer materials, facade, internal-access `36`, `7/7` manifest,
  documentation and coordination gates remained green.
  ADT water scene finalizer passed `cases=8 iterations=100 elapsed_ms=0.042`
  after an initial `0.024ms` run; synthetic data produced one four-vertex/
  six-index liquid surface with exact tile attachment and recursive editor owner.
  Water pipeline, WMO/M2/terrain/facade/scheduler/streaming/coordinate, material,
  shutdown and 32 headless contract regressions passed; checkpoint dry-run
  retained `7/7` plans. Post-merge finalizer (`0.025ms`), water pipeline
  (`98.398ms`), shutdown, materials, facade, internal-access `36`, `7/7`
  manifest, documentation and coordination gates remained green.
  M2 runtime mesh rebuild classifier passed `cases=12 iterations=100
  elapsed_ms=64.585` after an initial `35.461ms` run; billboard flag/count,
  invalid variants/indices, UV rotation/speed/epsilon, four-stage cap,
  memoization, detached diagnostics and both clear sites passed. Thirty-three
  M2/WMO/liquid/terrain/facade/scheduler/streaming/coordinate/material/shutdown
  regressions and checkpoint dry-run `7/7` passed. Post-merge classifier
  (`45.439ms`), materials, shutdown, M2 batch planner, facade, internal-access
  `35`, `7/7` manifest, documentation and coordination gates remained green.
  M2 mesh load pipeline state passed `cases=11 iterations=100
  elapsed_ms=100.273` with request validation/dedupe, insertion-order polling,
  terminal transition/completion FIFO, opaque statuses, discard, detached
  diagnostics, metrics, clear and 100-by-256 timing. Thirty-four adjacent
  headless regressions and checkpoint dry-run `7/7` passed. Post-merge pipeline
  state (`69.196ms`), classifier, materials, shutdown, facade, internal-access
  `34`, `7/7` manifest, documentation and coordination gates remained green.
  M2 mesh resource cache state passed `cases=9 iterations=100
  elapsed_ms=38.974` with invalid-input guards, exact-reference lookup,
  replacement, detached path diagnostics, idempotent clear and 100-by-256
  timing. Thirty-five renderer/coordinate regressions and checkpoint dry-run
  `7/7` passed. Post-merge cache state (`38.686ms`), pipeline, classifier,
  materials, shutdown, facade, internal-access `34`, `7/7` manifest,
  documentation and coordination gates remained green.
  M2 mesh resource extractor passed `cases=10 iterations=10000
  elapsed_ms=39.243` with direct/invalid Resource, depth-first order,
  null-Mesh sibling continuation, subtree ownership, PackedScene Mesh identity
  and temporary-root release contracts. Thirty-six renderer/coordinate
  regressions and checkpoint dry-run `7/7` passed. Post-merge extractor
  (`38.172ms`), cache, pipeline, classifier, materials, shutdown, facade,
  internal-access `34`, `7/7` manifest, documentation and coordination gates
  remained green.
  M2 runtime mesh finalizer passed `cases=11 iterations=100
  elapsed_ms=53.719` with current/stale raw-data gating, empty/ordinary marking,
  synthetic triangle billboard rebuild, failed-rebuild fallback, version `2`
  metadata and classifier-clear contracts. Thirty-seven renderer/coordinate
  regressions and checkpoint dry-run `7/7` passed. Post-merge finalizer
  (`54.349ms`), classifier, extractor, cache, pipeline, materials, shutdown,
  facade, internal-access `34`, `7/7` manifest, documentation and coordination
  gates remained green.
  M2 raw model repository passed `cases=10 iterations=10000
  elapsed_ms=3.275` with empty/missing/stateless failure, exact native-method,
  path and three-caller boundary contracts. Forty-five autonomous headless
  regressions and checkpoint dry-run `7/7` passed; the proprietary ADT probe
  remained unavailable without `data/extracted`. Post-merge repository
  (`3.200ms`), finalizer, extractor, cache, pipeline, shutdown, facade,
  internal-access `34`, `7/7` manifest, documentation and coordination gates
  remained green.
  M2 prototype cache state passed `cases=16 iterations=100
  elapsed_ms=50.266` with invalid admission, exact static/animated identity,
  independent positive/negative outcomes, first-wins duplicate release,
  detached/in-tree shutdown ownership and idempotent clear contracts. Forty-six
  autonomous headless regressions and checkpoint dry-run `7/7` passed; the
  proprietary ADT probe remained unavailable. Post-merge cache (`37.978ms`),
  shutdown, raw repository, finalizer, extractor, Mesh cache, pipeline,
  materials, facade, internal-access `31`, `7/7` manifest, documentation and
  coordination gates remained green.
  M2 animation load pipeline state passed `cases=11 iterations=100
  elapsed_ms=69.798` with validation, dedupe, insertion-order snapshots,
  terminal completion FIFO, opaque statuses, discard, detached diagnostics,
  three metrics, two clear sites and 100-by-256 timing. All 47 autonomous
  headless regressions and checkpoint dry-run `7/7` passed; the proprietary ADT
  probe remained unavailable. Post-merge pipeline (`70.309ms`), prototype state,
  shutdown, materials, facade, internal-access `30`, `7/7` manifest,
  documentation and coordination gates remained green.
  M2 animated scene finalizer passed `cases=13 iterations=10000
  elapsed_ms=40.126` with invalid Resource/root lifetime, exact candidate
  transfer, depth-first Mesh/AnimationPlayer traversal, material override
  priority, first-material fallback, source-index mapping and source-boundary
  contracts. All 48 autonomous headless regressions and checkpoint dry-run
  `7/7` passed; the proprietary ADT probe remained unavailable. Post-merge
  finalizer (`40.314ms`), animation pipeline, prototype state, shutdown,
  materials, facade, internal-access `30`, `7/7` manifest, documentation and
  coordination gates remained green.
  M2 animation playback controller passed `cases=15 iterations=20000
  elapsed_ms=23.415` with exact phase, ordinary/fish/bird priorities,
  substring/first-name fallback, loop/play/seek, native exact-script order,
  five-field reference copy, phase and detached diagnostics. All 49 autonomous
  headless regressions and checkpoint dry-run `7/7` passed; the proprietary ADT
  probe remained unavailable. Post-merge playback (`23.008ms`), animated
  finalizer/pipeline, prototype, build, shutdown, materials, facade,
  internal-access `30`, `7/7` manifest, documentation and coordination passed.
  M2 animated instance materializer passed `cases=12 instances=1000
  elapsed_ms=9.267` with exact duplicate flags, ordered names/transforms,
  recursive visibility margin/shadows, imported playback, native reference copy,
  indexed diagnostics, prototype isolation and attachment/source boundaries. All
  50 autonomous headless regressions and checkpoint dry-run `7/7` passed; the
  proprietary ADT probe remained unavailable. Documentation and coordination
  gates passed; internal-access inventory remains `30` while the loader adapter
  now retains only diagnostic formatting and Editor ownership for this batch.
  Post-merge materializer (`13.719ms`), playback/finalizer, shutdown, facade,
  internal-access `30`, checkpoint dry-run `7/7`, documentation and coordination
  gates remained green.
  M2 static batch materializer passed `cases=11 instances=10000
  elapsed_ms=0.552` with invalid-input guards, exact Mesh identity, 3D transform
  format/count, ordered slice source contract, visibility, shadows, single
  attachment and loader ownership boundaries. All 51 autonomous headless
  regressions and checkpoint dry-run `7/7` passed; the proprietary ADT probe
  remained unavailable. Documentation and coordination gates passed; internal-
  access inventory remains `30` and static resource readiness/cursors/budgets/
  Editor ownership remain in the loader adapter.
  Post-merge static materializer (`1.327ms`), build planner, Mesh cache, animated
  materializer, shutdown, facade, internal-access `30`, checkpoint dry-run `7/7`,
  documentation and coordination gates remained green.
  M2 build queue passed `cases=13 iterations=100 elapsed_ms=66.247` with invalid
  enqueue guards, exact root/group references, insertion-order key snapshots,
  FIFO rotation, duplicate replacement, stale-key cleanup, atomic cursor adoption,
  detached diagnostics and engine-lifetime/source boundaries. All 52 autonomous
  headless regressions and checkpoint dry-run `7/7` passed; the proprietary ADT
  probe remained unavailable. Internal-access inventory remains `30`; resource
  readiness, permits, materializer dispatch and root destruction remain loader-owned.
  Post-merge queue (`65.998ms`), planner, static/animated materializers, Mesh/
  prototype state, shutdown, materials, facade, internal-access `30`, manifest
  `7/7`, documentation and coordination gates remained green.
  M2 build dispatch planner passed `cases=10 iterations=20000
  elapsed_ms=11.933` with animation-wait priority, zero/negative batch advance,
  animated/static selection, unresolved static retry, terminal missing-model
  serial advancement, detached results and source/dependency boundaries. All 53
  autonomous headless regressions and checkpoint dry-run `7/7` passed; the
  proprietary ADT probe remained unavailable. Internal-access inventory remains
  `30`; resource observation/requests and action execution remain loader-owned.
  Post-merge dispatch planner (`12.291ms`), queue, batch planner, static/animated
  materializers, animation/Mesh pipelines, Mesh/prototype state, shutdown, facade,
  internal-access `30`, manifest and checkpoint dry-run `7/7`, documentation and
  coordination remained green.
  M2 build resource snapshot passed `cases=12 iterations=20000
  elapsed_ms=42.995` with exact path/prototype/Mesh identity, animation defaults,
  two-phase static adoption/replacement/clear, contradictory-state preservation,
  detached diagnostics, engine lifetime and loader/dispatch boundaries. All 54
  autonomous headless regressions and checkpoint dry-run `7/7` passed; the
  proprietary ADT probe remained unavailable. Internal-access inventory remains
  `30`; resource lookup/request execution remains loader-owned.
  Post-merge snapshot (`42.211ms`), dispatch, queue, batch planner, static/animated
  materializers, animation/Mesh pipelines, Mesh/prototype state, shutdown, facade,
  internal-access `30`, manifest and checkpoint dry-run `7/7`, documentation and
  coordination remained green.
  M2 static build resource observer passed `cases=11 iterations=20000
  elapsed_ms=64.158` with invalid/cached/Mesh-identity/missing/pending outcomes,
  exact candidate order, GLB schema fallback and source ownership. All 55
  autonomous headless regressions passed; internal-access remains `30`.
  Merge `a043c79` passed post-merge observer (`64.202ms`), snapshot, dispatch,
  Mesh pipeline/cache, prototype cache, shutdown, facade, internal-access `30`,
  manifest `7/7`, documentation `42`, coordination and checkpoint dry-run `7/7`.
  M2 cached animation resource observer passed `cases=33 iterations=20000
  elapsed_ms=61.745` with cached-prototype identity, static/pending/missing
  lifecycle, stripped case-insensitive allow/deny precedence, exact historical
  GLB path order and generated GLB animation/primitive/schema safety fixtures.
  All 56 autonomous headless regressions passed; internal-access remained `30`,
  documentation covered `43` module specifications and checkpoint dry-run kept
  all `7/7` plans. Coordination passed with `34` historical expired-claim warnings.
  Merge `f79e064` passed post-merge observer (`61.514ms`), animation pipeline,
  snapshot, dispatch, prototype cache, shutdown, facade, internal-access `30`,
  manifest `7/7`, documentation `43`, coordination and checkpoint dry-run `7/7`.
  M2 native animation resource observer passed `cases=33 iterations=20000
  elapsed_ms=16.881` with exact candidate, dependency, cached/static, raw/surface/build
  failure, preserved childless lifetime, adoption, dependency and source cases.
  All 57 autonomous headless regressions passed; internal-access remained `30`,
  documentation covered `44` module specifications, coordination retained `34`
  historical expired-claim warnings and checkpoint dry-run kept all `7/7` plans.
  Merge `06f6394` passed post-merge animation resource finalizer (`1.255ms`),
  pipeline, scene finalizer, cached observer, prototype cache, snapshot, dispatch,
  shutdown, facade, internal-access `30`, manifest `7/7`, documentation `45`,
  coordination and checkpoint dry-run `7/7`.
  Merge `d37c799` passed post-merge native observer (`31.187ms`), cached
  observer, repository, prototype cache, snapshot, dispatch, shutdown, facade,
  internal-access `30`, manifest `7/7`, documentation `44`, coordination and
  checkpoint dry-run `7/7`.
  M2 animation resource finalizer passed `cases=28 iterations=1000
  elapsed_ms=0.673` with exact
  pending/loaded/failed polling order, empty-path discard, completion FIFO,
  cache/static skips, Resource/candidate identity, repair, adoption and source cases.
  All 58 autonomous headless regressions passed; internal-access remained `30`,
  documentation covered `45` module specifications, coordination retained `34`
  historical expired-claim warnings and checkpoint dry-run kept all `7/7` plans.
  M02 terrain-query regression
  remained green (13 pre-existing expired M00 claim warnings).
- Fidelity comparison: all 16 historical operation limits and drain sites were
  preserved; chunk removal/create retain their shared removal-first budget.
  Defaults, quality presets, cache versions and visual rules are unchanged.
  Rendered-ground diagnostics preserve the prior 5000-unit ray, 3x3 search and
  `2/5/10/20/40`-unit nearby fallback while hiding mutable renderer state.
  Environment snapshots preserve the prior fixed-clock assignments while DBC
  profile/area/skybox selection, interpolation, fog, sun and shader rules remain unchanged.
  Runtime produces no world-entity commands yet, so player/world output and all
  baseline plans remain unchanged by the new present/remove ownership boundary.
  Terrain revisit cache retains the same admitted/excluded sources, LRU touch/trim,
  profile capacities and three loader adapter sites; no cache format changed.
  Chunk LOD keeps horizontal XZ chunk-center distance, inclusive squared thresholds,
  sparse-index omission and raw negative-radius squaring at both loader call sites.
  Chunk operation planning preserves stable removals, nearest-first create sorting,
  tile-LOD remove-all takeover, sparse tile-origin fallback and XZ-only distance;
  loader still drains removals first through the shared `chunk_geometry` budget.
  M2 positive `MDDF.uniqueId` retains `uid:<decimal>` first-owner semantics,
  within-call duplicate suppression, cross-tile skip/retry and unkeyed pass-through.
  M2 regular Euler, Elwynn cliff-rock shell correction, waterfall yaw/local-axis
  twist, tall-waterfall anchor compensation, path normalization and caller scale
  clamps are unchanged across worker grouping, placeholders and direct instances.
  M2 worker grouping retains invalid-record filtering, case-sensitive lowercase
  `.mdx/.mdl` conversion, first-seen group/per-group placement order, tile-local
  origin subtraction and the `0.0001` scale clamp.
  M2 build batching retains animated/static limit selection, minimum-one clamp,
  remaining-transform cap and the exact offset/group-completion cursor rules.
  Pending M2 builds retain keyed latest-job replacement, duplicate/stale FIFO
  entries, one-key rotation, strong root/group references and exact group/offset/
  serial progression; releasing queue records still never frees scene nodes.
  M2 build dispatch retains pending-animation priority before batch planning,
  animated-before-static selection, unresolved-static rotation without progress,
  and the historical serial increment for terminally missing positive batches.
  One build operation now carries the exact normalized path, optional animated
  prototype, pending-animation state, optional static Mesh and missing outcome in
  a typed snapshot; releasing it never frees either borrowed engine resource.
  Native GryphonRoost observation now preserves case-insensitive substring
  selection, cached/static priority, synchronous animated raw read, non-empty
  surface and child requirements, first-wins adoption and exact success-log fields.
  Cached animated lookup preserves cached/static/pending priority, empty-
  allowlist rejection, denylist precedence, normalized/lowercase/basename path
  order, animation presence, primitive cap, accepted empty/`pivot_prefix_v1`
  schema rules and request/static-only transitions. Native GryphonRoost remains
  first through its observer, so selection and visible behavior are unchanged.
  Cached animation terminal work retains pending insertion-order polling,
  completion-order FIFO, one popped record per permit, candidate-before-material
  lookup, exact repair/validation/adoption and `M2_ANIM_CACHE` fields.
  WMO cache-key normalization, positive MODF identity with tile/index fallback
  and world position/Euler/unclamped-scale transforms are unchanged across
  lightweight render, cached-scene and live-prototype paths.
  WMO first/idempotent/shared/non-owner/final/global reference behavior is
  unchanged; the extracted registry owns only String reference sets while the
  loader retains the parallel key-to-Node map and final-release cancellation/free.
  Lightweight WMO render groups retain mesh-before-MultiMesh order, one cursor
  increment and one budget permit per valid or null group; completion still
  cancels the job after both raw integer cursor comparisons are exhausted.
  Pending WMO render builds retain typed root/resource/cursors, FIFO order,
  duplicate replacement, stale-front pop, first-occurrence cancel and three
  idempotent clear sites. Queue release never frees engine objects; the loader
  retains validity checks, materialization, permits and Node destruction.
  Lightweight WMO render cache paths retain the same cached/pending/missing
  transitions, retry behavior for absent files and map-reset versus final-shutdown
  lifetime. `ResourceLoader`, script identity and `FORMAT_VERSION` validation
  remain loader-owned before the extracted state accepts a Resource.
  Cached WMO scene paths retain direct negative caching for missing/oversize/
  request-start failures, terminal missing state for load/validation failures and
  the prior transient-reset versus final-shutdown lifetime. File-size limits,
  `PackedScene` probe instantiation, WMOBuilder metadata validation and probe-node
  destruction remain loader-owned before state accepts a scene.
  ADT water requests retain FIFO order and tile-key deduplication; tile release
  removes pending requests without cancelling active work, task completion and
  result publication order are unchanged, and the mutex remains limited to the
  worker/main-thread mailbox. The loader still owns ADT parsing, concurrency and
  profile limits, stale tile/path/root rejection, `WATER_FINALIZE` permits,
  tile subtree lifetime and `water_loaded` timing.
  Both raw-tile and delayed cached-tile water paths now call the same stateless
  finalizer. It invokes the unchanged `ADTBuilder.build_tile_water_scene`,
  attaches the returned root once and applies the existing optional recursive
  Editor ownership; tile subtree lifetime and dry-root cleanup are unchanged.
  M2 stale-cache rebuild selection retains the same positive billboard flag/
  vertex-count tests, referenced non-identity UV rotation, exclusive
  `0.000001` speed threshold, four-stage cap and first-decision-per-path cache
  lifetime. Raw loading, material refresh version, M2Builder rebuild/fallback and
  Mesh adoption remain loader-owned.
  Static M2 mesh pending requests preserve normalized-path dedupe and Dictionary
  insertion polling order; loaded/failed transitions preserve completion-order
  finalization FIFO and opaque statuses. All three pending-plus-finalize metrics,
  both clear sites and shutdown ResourceLoader drain order are unchanged; cache
  path selection, I/O, permits and adoption decisions remain loader-owned;
  missing outcomes now belong to the prototype cache state.
  Animated M2 pending requests preserve normalized-path dedupe and Dictionary
  insertion polling order; loaded/failed transitions preserve completion-order
  finalization FIFO and opaque statuses. All three pending-plus-finalize metrics,
  both clear sites and shutdown ResourceLoader drain order are unchanged. GLB
  eligibility/cache selection, I/O, permits, instantiation, material repair and
  prototype/static-fallback decisions remain loader-owned.
  Animated scene candidates retain PackedScene-only/Node3D-root admission,
  depth-first positional material mapping, source-index clamp, per-surface
  override priority, first-material fallback and at-least-one-AnimationPlayer
  acceptance. Accepted exact roots/player counts return to loader adoption/logs;
  rejected roots are synchronously freed, including the previously leaked
  non-Node3D imported-root edge case. I/O, permits, material-source selection,
  prototype/static outcome and playback policy remain loader-owned.
  Animated instance playback retains the exact path/index hash phase, ordinary/
  fish/bird priority lists, case-insensitive substring and first-name fallbacks,
  linear looping of every imported animation, selected play and positive-length
  phase seek. Native animators retain exact-script depth-first pairing, five
  reference/value assignments, optional prepare, phase and debug sampling.
  Instance duplication/attachment, visibility, shadows, Editor ownership and
  diagnostic log formatting remain loader-owned.
  Prepared static M2 Mesh lookups retain exact Resource identity, same-path
  replacement and map-refresh lifetime; the only clear remains final shutdown
  after asynchronous drain. Shared missing/static/animated prototype state now
  belongs to `M2PrototypeCacheState`; materialization remains loader-owned.
  Direct Mesh Resources, temporary PackedScene instances and prototype/rebuild
  subtrees retain the same depth-first first-Mesh rule. PackedScene still
  instantiates once and frees its temporary root synchronously before return;
  the extractor retains no state or Resource reference.
  Runtime material refresh remains version `2`; current Meshes skip raw loading,
  empty/ordinary data marks and reuses the original, billboard/UV-rotation data
  attempts the same M2Builder rebuild, and failure marks/reuses the original.
  Raw FileAccess/ClassDB M2Loader I/O now belongs to the stateless repository;
  exact path resolution and `load_m2`/`load_m2_animated` names are unchanged.
  Loader-owned normalization, fallback order, builders and result adoption remain
  unchanged; the same prototype/negative transitions now use cache-state methods.
  No new build-12340 parity claim is made; asset-backed visual/p95/p99 comparison remains pending.
- Changed files: scene-free scheduler and verifier; streamer budget composition/
  permit delegation; scheduler module spec; world renderer/module registry/RENDER notes;
  renderer-owned ground sample, facade/loader ground query, migrated terrain probe,
  immutable environment snapshot, facade/sky adapter, migrated checkpoint time input,
  contract-v1 entity snapshot, renderer-owned entity presenter, runtime composition,
  scene-free terrain quality Mesh cache and loader store/restore/clear adapters,
  immutable terrain chunk LOD policy, pure planner and both loader plan adapters,
  pure terrain chunk geometry queue planner and loader queue-adoption adapter,
  stateful M2 unique placement registry, loader reserve/release/clear adapters and
  migrated historical dedupe smoke, stateless M2 placement transform resolver and
  three transform consumers, stateless M2 placement grouper and worker adapter,
  stateless M2 build batch planner and loader cursor adapter,
  stateless WMO placement resolver and seven cache/identity/transform adapters,
  stateful WMO placement registry and global/tile add/release/clear adapters,
  stateless WMO render build step planner and loader cursor-adoption adapter,
  typed WMO render build job/queue and loader enqueue/drain/cancel/clear adapters,
  lightweight WMO render Resource/missing/request state and loader I/O/validation/
  reset adapters,
  cached WMO PackedScene/missing/request state and loader file-size/I/O/probe/
  validation/reset adapters,
  ADT water pending/task/result pipeline state and loader enqueue/start/publish/
  drain/release/reset/shutdown/metrics adapters,
  stateless ADT water scene finalizer and both loader build/attach adapters,
  memoized M2 runtime mesh rebuild classifier and loader query/clear adapters,
  M2 mesh load pipeline state and loader request/poll/finalize/metric/clear adapters,
  prepared M2 Mesh resource cache state and loader lookup/store/shutdown adapters,
  stateless M2 Mesh resource extractor and three loader traversal adapters,
  M2 runtime Mesh finalizer and loader raw-data/finalize/clear adapters,
  stateless M2 raw model repository and three native-load adapters,
  shutdown-lifetime M2 prototype cache state and all positive/negative adapters,
  M2 animation load pipeline state and loader request/poll/finalize/metric/clear adapters,
  M2 animated scene finalizer and loader candidate/material/player traversal adapters,
  M2 animation playback controller and loader native/imported playback adapters,
  M2 animated instance materializer and loader log/Editor-owner adapter,
  M2 static batch materializer and loader readiness/cursor/Editor-owner adapter,
  typed M2 build job/queue and loader enqueue/drain/progress/cancel/clear adapters,
  stateless M2 build dispatch planner and loader resource-observation/action adapter,
  typed M2 build resource snapshot and loader/dispatch/materializer adapters,
  static M2 build resource observer and loader/cache/pipeline/snapshot adapters,
  cached M2 animation resource observer and loader/prototype/pipeline/snapshot
  adapters plus generated GLB metadata regression fixtures,
  native M2 animation resource observer and loader/raw-repository/prototype-cache
  adapters plus synthetic lifecycle and exact-dependency regression fixtures,
  cached M2 animation resource finalizer and loader/pipeline/scene-finalizer/
  prototype-cache adapters plus synthetic terminal-I/O regression fixtures,
  expanded facade/internal-access/coordinate verifiers; work-package claims and this evidence.
- Remaining risks: worker concurrency and stale-result validation remain
  streamer-owned; cancellation stops new permits but does not interrupt
  in-flight work; the environment snapshot currently covers world time but not weather
  or indoor state; entity PackedScene loading is synchronous and not accepted for
  network-scale hot paths; terrain cache is entry-count bounded without Mesh-byte
  metrics and the remaining terrain build/tasks/state/finalization stay monolithic;
  chunk LOD asset-backed p95/p99 and visual acceptance remain pending;
  chunk queue planning adds a second tile-state pass whose asset-backed p95/p99
  still needs acceptance, while queue drains and geometry finalization remain monolithic;
  private Azeroth data was absent for the asset-backed ADT placement probe; M2
  asset-backed visual transform recheck, grouping/build/tasks/caches/finalization
  and boundary traversal p95/p99 remain pending; path grouping is not yet
  culling-driven spatial-cell grouping; M2 rebuild classification and static
  request/finalize bookkeeping, prepared Mesh cache ownership and first-Mesh
  traversal plus refresh/rebuild/fallback, raw native M2 I/O and prototype/
  negative cache state are separated, but synchronous native parsing/build and
  Mesh adoption remain in the loader call path; cached animation eligibility/
  request admission is extracted while terminal ResourceLoader polling remains;
  raw
  animated-instance materialization is now separated but remains synchronous
  main-thread work; asset-backed traversal/visual/leak/p95/p99 evidence is pending;
  native parsing/build also remains synchronous and the historically unfreed
  childless builder result remains a documented leak edge;
  static MultiMesh materialization is also separated but remains synchronous;
  headless timing does not measure transform upload GPU cost and spatial-cell
  batching still needs culling/performance evidence; typed M2 pending state is
  separated and dispatch decisions are explicit; static and cached-animation
  observers produce typed per-operation state, including native observation;
  animation terminal ResourceLoader drain is extracted, while action execution,
  material-prototype lookup, root cleanup and static Mesh finalize drain remain loader-owned;
  WMO ResourceLoader/FileAccess I/O, live fallback and group materialization
  remain in the loader;
  asset-backed WMO placement/portal/material/leak/p95/p99 evidence remains pending;
  ADT water parsing and active worker interruption remain loader-owned;
  materialization is separated but remains synchronous main-thread work behind
  the existing permit, and asset-backed MH2O/MCLQ traversal/leak/p95/p99/
  original-client evidence is pending; M03 still needs further terrain/M2/WMO/
  liquid service extraction and dependency/performance acceptance.
