# M03-RND-SCHEDULER-001 — Bounded render budget scheduler

<!-- OPENWC_CLAIM:M03-RND-SCHEDULER-001:sindo-main-codex:2026-07-18 -->

## Ownership

- Target: M03
- Program: RND
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m03-render-budget-scheduler`
- Lease expires UTC: 2026-07-18
- Integrator: M03 milestone integrator

## Outcome

Extract the streamer's per-frame main-thread operation quotas into a scene-free
`RenderBudgetScheduler`, preserving existing queue priority and quota values and
stopping permit issuance after renderer teardown cancellation.

## Non-goals

- Move queue, worker-task, cache, Node, Resource or RID ownership out of the streamer.
- Change queue ordering, concurrency limits, exported defaults or visual behavior.
- Add a generic job framework, priority graph, time-based adaptive budgeting or dependency.
- Change cache formats, renderer profiles or target milestone status.

## Paths

- Exclusive: `src/render/streaming/render_budget_scheduler.gd`,
  `src/tools/verify_render_budget_scheduler.gd`,
  `docs/modules/render-budget-scheduler.md`, this claim
- Shared/hotspots: `src/scenes/streaming/streaming_world_loader.gd`,
  `docs/modules/world-renderer.md`, `docs/modules/README.md`, `RENDER.md`,
  `targets/03-renderer-facade.md`
- Generated/ignored: `.godot`, native DLL, generated cache resources and
  proprietary renderer corpus

## Contracts and data

- Input: immutable per-frame map from documented operation lane IDs to
  non-negative operation limits
- Output: boolean permits and remaining/consumed diagnostic snapshots
- Lifecycle: `begin_frame` resets permits; `cancel` permanently rejects permits
  for the current scheduler instance
- Queue contents, ordering, task concurrency and schema/cache versions: unchanged
- Consumer: `StreamingWorldLoader` main-thread queue/finalize drains

## Dependencies

- Requires: integrated M03 facade and streaming planner on master `650d584`
- Blocks: renderer performance regression gate and per-service extraction
- External state: none; tests use synthetic lane limits and no world assets

## Verification

- Commands: dedicated scheduler verifier, facade/planner/focus/coordinate
  regressions, renderer manifest/dry-run and repository gates
- Fixtures: shared lane priority, independent lanes, zero/negative limits,
  frame reset, unknown lane and cancellation
- Fidelity evidence: operation defaults and loop order are captured before
  migration; all seven renderer checkpoint plans remain valid
- Performance budget: permit checks are constant-time dictionary operations and
  create no Node, Resource, worker task, cache entry or RID

## Documentation deliverables

- Inline API docs for scheduler lifecycle, permits and diagnostics
- New module specification with input/output table, data-flow, sequence and
  lifecycle diagrams
- Updated world-renderer flow/ownership/source map, module registry and renderer notes

## Simplicity and naming

- Important name: `RenderBudgetScheduler`
- Simplest approach: one small main-thread service with named quota lanes
- Rejected complexity: generic job graph, callbacks, queue ownership, adaptive
  timing controller, service container or third-party dependency
- Unavoidable complexity: chunk removal and creation intentionally share one
  lane so removal retains priority while consuming the same historical budget
- Measured optimization evidence: no optimization claim; exact bounded extraction

## Status

- State: ready-for-review
- Done: extracted all 16 historical operation quotas, migrated ordered drains,
  added terminal teardown cancellation, asset-free verification and module docs
- Next: M03 integrator reviews and merges `e52f703`
- Blocked by:

<!-- OPENWC_HANDOFF:READY:M03-RND-SCHEDULER-001:e52f703 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M03-RND-SCHEDULER-001:7ece2ab -->

## Handoff

- Commit: `e52f703`
- Results: `RenderBudgetScheduler` owns only per-frame lane counters and terminal
  cancellation; `StreamingWorldLoader` retains queue order, task/cache/node/RID
  ownership and operation execution. Chunk removal/create share one historical budget.
- Verification: scheduler `cases=6 iterations=20000 elapsed_ms=7.495`; planner
  `cases=5 average_ms=1.879`; facade/focus contracts passed; coordinate boundary
  `files=111 consumers=6`; renderer manifest `checkpoints=7 coverage=7 caches=7`;
  shutdown ownership, documentation, coordination and diff gates passed.
- Fidelity: exported defaults, quality presets, queue order, operation sites,
  cache versions and visible rendering rules are unchanged. Seven checkpoint
  plans remain valid. No build-12340 parity claim is added.
- External/local inputs: ignored native DLL and two generated ADT resource scripts
  were copied from master only for the worktree parse/smoke and then removed.
  Proprietary extracted ADT data was unavailable, producing expected degraded-data diagnostics.
- Remaining risks: queue storage length and worker concurrency remain streamer-owned;
  cancellation stops permit issuance but does not interrupt in-flight work; exact
  p95/p99 impact still requires an asset-backed baseline.
- Documentation: new scheduler module spec with API, input/output, data-flow,
  sequence, lifecycle, ownership, cancellation, performance and source-map sections;
  world renderer, module registry and renderer implementation notes updated.
- Integration: accepted in master merge `7ece2ab`; post-merge scheduler timing
  `cases=6 iterations=20000 elapsed_ms=10.216`, all listed regressions and gates passed.
