Verify staged lazy loading and record Phase 3 measurements
This commit is contained in:
@@ -1,43 +1,29 @@
|
||||
# Phase 3 — decision required before live module replacement
|
||||
# Phase 3 staged apply — accepted owner decision
|
||||
|
||||
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.
|
||||
The owner accepted this decision on 2026-10-08. It refines master §2c.5:
|
||||
background downloading never implies that an executing classic script can be
|
||||
safely replaced.
|
||||
|
||||
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.
|
||||
1. Already executing groups stay pinned until the session ends or the next
|
||||
user-initiated, playback-guarded reload. P2P/direct and every stateful instance
|
||||
are never re-evaluated live. Phase 4 must provide disposal and state handoff
|
||||
before live replacement is allowed.
|
||||
2. A group that has not executed can immediately use newer verified cached URLs
|
||||
only when its contract and dependency contracts equal those expected by the
|
||||
running core's embedded manifest. For a different contract, keep the running
|
||||
build's N-1 URLs, set `Lazy.reloadRequired`, and request the existing Refresh UI
|
||||
banner through the unchanged meta-build versus `/api/version` comparison.
|
||||
3. New core boot may receive a verified N-1 response for an uncached new URL only
|
||||
when group contracts match. The response retains its actual hash; it is never
|
||||
stored under the new hash. Contract changes join the blocking download set.
|
||||
|
||||
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.
|
||||
Reason: direct-media.js owns private room, pending transfer and waiting maps;
|
||||
WebRTC callbacks retain these closures. Re-evaluating the singleton redirects
|
||||
messages away from those transfers. P2P sockets/timers and piano/MIDI/floating
|
||||
windows have similar state. Contract equality alone does not migrate it.
|
||||
|
||||
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.
|
||||
Implemented in 4853c2c and 5d6a154. Node loader tests cover pinned execution,
|
||||
compatible unexecuted selection, incompatible N-1 plus reload-required, and
|
||||
incompatible dependencies. Worker tests cover same-contract fallback without
|
||||
cache poisoning and changed-contract readiness before commit. `perf/lazy.mjs`
|
||||
checks these decisions with real workers on Chromium and WebKit.
|
||||
|
||||
Reference in New Issue
Block a user