2.7 KiB
Phase 3 — decision required before live module replacement
COMMON.md says: "If you hit a decision that changes user-visible behaviour or risks data loss that the documents do not answer, write QUESTION ... and end your turn instead." This concerns §2c.5's instruction to switch stale modules when new bytes arrive, after a new build has booted using a same-contract fallback.
Concrete finding: direct-media.js creates private rooms, pending, transfers and waiting maps at module evaluation (lines 4–6). Its public API has no busy, dispose or state handoff method. Re-evaluation replaces window.DirectMedia, while WebRTC callbacks/workers still close over the old maps. Later messages routed by app.js through the new DirectMedia.handle can no longer find those in-flight transfers. p2p-client.js similarly replaces its public singleton but retains old sockets, timers and its visibility listener; P2PTransfer exposes start/download without disposal. Matching contract numbers do not establish safe runtime state migration. Piano/MIDI/floating-window UI also retains closures.
Recommended owner decision: background-download and verify the new URLs immediately, but pin an already-executing stale module until its feature session closes and can be safely recreated. Keep P2P/direct instances until the next explicit user-initiated, playback-guarded page reload. Groups never executed use the newest cached version immediately. In Phase 4, introduce explicit teardown and state handoff seams before enabling live replacement of these instances. This narrows "switch when the new one arrives" for stateful modules; it requires owner approval rather than silently claiming that caching new bytes replaces running code.
Completed safe prerequisites: plan commit 895f20a; pure contract fallback and background-group synchronization commit f804a23; ordered build-local loader with unit tests (not yet wired into index.html). No layout or feature was removed from the current eager path. Full browser/layout/performance acceptance remains outstanding. This is a QUESTION checkpoint, not a completed phase report.
Accepted owner decision
The owner accepted pinning on 2026-10-08. Already executing stale groups remain pinned until their session ends or the next explicit playback-guarded reload. P2P/direct and other stateful instances are never re-evaluated live; Phase 4 must add disposal/state handoff before permitting replacement. An unexecuted group may use newly cached URLs only when its contract equals the running core's embedded contract. A different contract keeps the running build's N-1 URLs, marks reload required and prompts the existing build-tag-based Refresh UI banner. Unit tests cover all three cases. Continue Phase 3 under these rules.