# M02-GMP-SANDBOX-CAPABILITIES-001 — Debug movement capability gate

<!-- OPENWC_CLAIM:M02-GMP-SANDBOX-CAPABILITIES-001:sindo-main-codex:2026-07-16 -->

## Ownership

- Target: M02
- Program: GMP/FND
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m02-sandbox-capabilities`
- Lease expires UTC: 2026-07-16
- Integrator: M02 milestone integrator

## Outcome

Introduce an immutable local-player movement capability contract and require it
at the movement boundary so debug sprint and free flight execute only in the
explicit `RenderSandbox` profile and are rejected by `Blizzlike335`.

## Non-goals

- Claim that current movement values or `Blizzlike335` locomotion are 1:1.
- Build a global application/profile framework before the application shell exists.
- Remove debug Input Map actions or change their current sandbox bindings.
- Implement jump, fall, swim, collision, server authority or reconciliation.
- Mark M02 complete or edit its checklist/Evidence.

## Paths

- Exclusive: `src/gameplay/movement/player_movement_capabilities.gd`,
  `src/tools/verify_player_movement_capabilities.gd`, this claim
- Shared/hotspots: `src/gameplay/movement/local_player_movement_controller.gd`,
  `src/scenes/player/third_person_wow_controller.gd`, movement/input verifiers,
  player regression scene, `docs/modules/local-player-movement.md`,
  `docs/modules/player-input.md`
- Generated/ignored: local `.godot`, native DLL, generated resources and renderer corpus

## Contracts and data

- `PlayerMovementCapabilities` owns immutable profile ID plus explicit debug
  sprint/flight booleans and safe named factories.
- `LocalPlayerMovementController` requires the capability value; missing input
  falls back to `Blizzlike335`, never sandbox.
- Player scene maps its exported profile selection once at the composition boundary.
- Input actions and `MoveIntent` remain unchanged; rejected debug requests have no effect.

## Dependencies

- Requires: merged character presentation package on master `8c71e46`.
- Blocks: final M02 integration audit and milestone closeout.
- External state: none; verification is asset-free.

## Verification

- Pure profile factory/default and immutability regression.
- Sprint accepted in RenderSandbox and ignored in Blizzlike335.
- Flight toggle/vertical basis accepted in RenderSandbox and rejected in Blizzlike335.
- Real regression scene verifies both profile compositions.
- Existing input/movement/terrain/camera/presentation and renderer gates remain required.
- Fidelity evidence: negative proof that debug capabilities cannot affect the
  compatibility profile; no positive movement parity claim.

## Documentation deliverables

- Inline public API and profile semantics on the capability/controller boundary.
- Updated movement and input specs: API, inputs/outputs, data flow, lifecycle,
  failure/recovery, capability matrix and source map.

## Simplicity and naming

- Important name: `PlayerMovementCapabilities`.
- Simplest approach: one immutable value injected into the existing controller.
- Rejected complexity: autoload singleton, generic feature-flag service and global profile registry.
- Unavoidable complexity: one profile-to-capability mapping at scene composition.
- Measured optimization evidence: not applicable.

## Status

- State: ready-for-review
- Done: added immutable capability contract, gated sprint/free-flight, covered
  pure and real-scene profiles and updated movement/input specifications
- Next: milestone integrator reviews and merges `742c415`
- Blocked by:

<!-- OPENWC_HANDOFF:READY:M02-GMP-SANDBOX-CAPABILITIES-001:742c415 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M02-GMP-SANDBOX-CAPABILITIES-001:c3094c9 -->

## Handoff

- Branch/commit: `work/sindo-main-codex/m02-sandbox-capabilities` at `742c415`.
- Outcome: debug sprint and free flight now require explicit
  `PlayerMovementCapabilities.render_sandbox()`; `Blizzlike335`, unknown and
  null capability inputs reject both effects.
- Public contract: immutable profile ID plus `allows_debug_sprint` and
  `allows_debug_free_flight`; named factories map configuration once at the
  composition boundary. The movement controller exposes its effective profile ID.
- Runtime composition: `ThirdPersonWowController.movement_profile_id` defaults
  to `RenderSandbox`, preserving renderer-scene behavior. Selecting
  `Blizzlike335` keeps ordinary movement while ignoring Shift/Space/E/Q effects.
- Verification: capability `profiles=3 sprint=2 flight=2 scenes=2 boundary=1`,
  movement `cases=12 state_transitions=2`, input `actions=12 intent_cases=6`,
  terrain `contract=4 interpolation=1 cache=1 failures=2`, camera
  `state_cases=12 policy_cases=3`, presentation
  `appearance_cases=9 animation_cases=10`, coordinate boundaries
  `files=101 consumers=5`, and StreamingFocus `runtime_scenes=2 capture_tools=3` passed.
- Renderer: dry-run passed project/material/dedupe/cache/manifest/calibration/
  coordinate/server-spawn gates and planned all seven checkpoints; the combined
  run reported coordinate `files=103`. Missing proprietary GLB/DBC/ADT inputs
  produced the expected diagnostics only.
- Repository gates: documentation `module_specs=8`, coordination
  `fallback_claims=30`; five unrelated expired M00 claim warnings remain.
- Fidelity: this package provides negative evidence that sandbox-only debug
  movement cannot alter the `Blizzlike335` profile. It does not prove ordinary
  movement, bindings, flight or timing match build 12340.
- Migration: direct `LocalPlayerMovementController.new(...)` callers that need
  debug behavior must now pass `render_sandbox()`; omitted/null capability is
  intentionally compatibility-safe. Existing repository scenes require no edit.
- Cache/persistence: no schema, cache, binding or stored-profile migration.
- Local ignored inputs: native extension DLL, UID cache and generated ADT
  resource scripts supported renderer verification and are not committed.
- Risks: runtime renderer scenes still default to `RenderSandbox`; the future
  application shell must explicitly choose its profile. `Blizzlike335` currently
  guarantees only debug exclusion, not complete movement fidelity.
- Recommended merge order: merge after presentation (already on master), then
  perform the final M02 integration/evidence audit before any target closeout.
- Documentation: updated movement/input API, inputs/outputs, data flow, state,
  sequence, ownership, failure/recovery, capabilities, verification and source maps.
