# M03-RND-M2-CACHED-ANIMATION-RESOURCE-OBSERVER-001

<!-- OPENWC_CLAIM:M03-RND-M2-CACHED-ANIMATION-RESOURCE-OBSERVER-001:sindo-main-codex:2026-07-20 -->

## Owner

- Agent ID: `sindo-main-codex`
- Target: M03 Renderer Facade and Safe Extraction
- Branch: `work/sindo-main-codex/m03-m2-cached-animation-resource-observer`
- Worktree: `C:\Users\sindo\open-wc-worktrees\m03-m2-cached-animation-resource-observer`

## Outcome

Move cached-GLB animated M2 lookup, allow/deny and primitive/schema safety
selection, threaded request admission and static-only transition from the loader
into a service that produces `M2BuildResourceSnapshot`.

## Non-goals

- Move native GryphonRoost raw-data build, debug logging or finalize drains.
- Own/free prototype Nodes or change cache/pipeline ownership.
- Change allow/deny defaults, primitive limits, candidate order or GLB rules.
- Change batching, permits, cache formats, profiles or visible output.

## Paths

- Exclusive: `src/render/m2/m2_cached_animation_resource_observer.gd`,
  `src/tools/verify_m2_cached_animation_resource_observer.gd`,
  `docs/modules/m2-cached-animation-resource-observer.md`, this claim
- Shared: loader, M2 snapshot/animation pipeline/prototype specs and verifiers,
  world renderer, module registry, `RENDER.md` and M03 Evidence

## Contracts and data

- Cached animated prototype wins; static-only and pending states do not request.
- Empty allowlist rejects; denylist wins; matching is stripped/case-insensitive.
- Historical nested/lowercase/basename `.glb` order remains exact.
- Candidate requires animations, primitive limit and accepted empty or
  `pivot_prefix_v1` schema; other schemas are rejected.
- Successful/`ERR_BUSY` request is remembered and reported pending; no usable
  candidate or request failure marks animation static.
- Service produces a snapshot borrowing the exact prototype and frees nothing.

## Dependencies

- Requires: accepted static observer `5ebf4de`, snapshot and animation pipeline
- Blocks: native animation observation and remaining finalize extraction

## Verification

- Synthetic cache/pipeline/snapshot lifecycle, policy/path/GLB metadata fixtures,
  source boundaries and timing; adjacent M2/renderer gates; full headless suite
  and checkpoint dry-run.

## Documentation deliverables

- Inline API docs; module API/I/O/ownership; data-flow/state/sequence/dependency
  diagrams; adjacent renderer docs and M03 Evidence.

## Status

- State: accepted
- Done: implementation, integration and post-merge acceptance
- Next: native M2 animation observation extraction
- Blocked by:

## Handoff

- Commit: `df87619` (`render: extract cached M2 animation resource observer`)
- Results: observer PASS (`33` cases, `20,000` iterations, `61.745ms`);
  full autonomous suite PASS (`56/56`); renderer checkpoint dry-run PASS (`7/7`);
  internal-access PASS (`30` private symbols); documentation PASS (`43` module
  specs); coordination PASS with `34` historical warnings.
- Remaining risks: successful asynchronous admission is covered by source and
  existing pipeline regressions because an undrained unit request leaks; generated
  GLB metadata does not prove Godot import fidelity; private traversal, p95/p99,
  leak and paired visual evidence remain unavailable; native observation and
  terminal ResourceLoader polling/finalize remain loader-owned.
- Documentation updated: new cached observer API/I/O/data-flow/state/sequence/
  dependency/ownership specification; M2 snapshot, batch/dispatch, animation
  pipeline/prototype, world-renderer, module registry, `RENDER.md` and M03 Evidence.

## Integration

- Merge: `f79e064` (`merge: cached M2 animation resource observer`)
- Post-merge: observer `33` cases / `20,000` iterations / `61.514ms`;
  animation pipeline `11` / `66.049ms`; snapshot `12` / `39.947ms`;
  dispatch `10` / `17.915ms`; prototype cache `16` / `35.053ms`; shutdown,
  facade, internal-access `30`, manifest `7/7`, documentation `43` and
  coordination passed. Checkpoint dry-run completed `7/7`; expected private
  Azeroth/character assets remained unavailable.
