W-033: ecs-schedule per-world state and isolation (SCH-F05)¶
Type: feature · Size: M · Epic: E-schedule-v0 · Target: packages/ecs-schedule · Breaking: no Depends: W-030, W-031 Refs: spec SCH-060, SCH-061, SCH-062, SCH-063, SCH-064, SCH-065, SCH-113, SCH-117, SCH-125, SCH-151
Goal¶
Complete the per-world state trait that W-030 started: name, disabled, and onStartDone with lazy add, the readonly schedule.state property, and the reset behaviour. Enforce isolation between worlds and between schedules, and check that importing the package has no side effects. Unknown names in disabled are ignored.
Steps¶
- S1 (SCH-063, SCH-151): state trait fields exactly
name,disabled(factory default),onStartDone;schedule.stateis readonly with stable identity; added lazily, soworld.hasisfalseuntil first use;nameequalsschedule.name; files: packages/ecs-schedule/src/state.ts, packages/ecs-schedule/src/schedule.ts, packages/ecs-schedule/tests/state-shape.test.ts - S2 (SCH-060, SCH-061): one schedule on two worlds keeps enabled and
OnStartstate separately; files: packages/ecs-schedule/tests/state-worlds.test.ts - S3 (SCH-062, SCH-064): two schedules on one world do not share state; importing the package has no side effects and no module-level mutable state; files: packages/ecs-schedule/tests/state-schedules.test.ts, packages/ecs-schedule/tests/import-side-effects.test.ts
- S4 (SCH-065, SCH-125): after
world.reset()all systems are enabled andOnStartruns again, with the trait re-added under the samename; names indisabledthat match no system are ignored silently; files: packages/ecs-schedule/tests/state-reset.test.ts - S4a (SCH-113): empty and fully skipped OnStart leave
schedule.state.onStartDonetrue after the call; files: packages/ecs-schedule/tests/state-on-start-done.test.ts - S5a (SCH-117): remove the per-call allocation in beginOnStart (src/on-start.ts: koota world.get on the state trait allocates ~25 B/call); use a per-schedule WeakSet
as the hot-path started check while keeping the state trait observable; re-run packages/ecs-schedule/bench/run-alloc.bench.ts and confirm ~0 B/call; files: packages/ecs-schedule/src/on-start.ts, packages/ecs-schedule/bench/run-alloc.bench.ts - S5 (changeset): add
.changeset/w-033-ecs-schedule-state.md(patch,@workspace/ecs-schedule)
Log¶
- 2026-11-01 created from the approved spec split of W-004 (Triage)
- 2026-11-02 S4a added for SCH-113 (empty and fully skipped OnStart state), taken from the deferred W-030 S2 cases (Triage)
- 2026-11-02 S5a added for SCH-117 (per-call allocation in beginOnStart), moved from W-030 S5 follow-up (Triage)