diff --git a/plans/phase1-plan.md b/plans/phase1-plan.md new file mode 100644 index 0000000..55b03e2 --- /dev/null +++ b/plans/phase1-plan.md @@ -0,0 +1,39 @@ +# Phase 1 — per-file asset hashes and server manifest + +1. Add tests first in `server/asset-manifest.test.js`, deliberately extend + `server/static-delivery.test.js` and `frontend/shell-consistency.test.js`. +2. Describe the existing shell in `frontend/assets.json`: ordered file groups, + contract 1, eager core/settings/playlist/service-mode/lyrics-editor. Preserve + index script order and both service-worker sources byte-for-byte. +3. Add importable `server/asset-manifest.js`; integrate boot-time recursive + hashing, stamped index, manifest endpoint, per-file headers and rollback into + `server/server.js`. Register module tests in `server/package.json`. +4. Stamp safe HTML resource URLs (CSS/JS, font preloads, webmanifest). Retain + plain JS-created worker/import URLs: introducing a new helper would require + modifying the unchanged worker's shell or frontend callers. Inventory these + exceptions explicitly in the report. Hash every recursively served file, + including files outside the shell, so the banner never misses a change. +5. Extract `b77938a` using `perf/make-shell-fixture.sh` with an explicitly + computed expected tag (never query production). Add `perf/migration.mjs` + and instructions to `perf/README.md`; test old-client Refresh UI, a single + banner, complete new cache, no loop, offline reload, and legacy URL bodies + on Chromium and WebKit. Run reduced LTE cold/warm/offline baselines. +6. Review against master plan §3.1/§6b; commit `plans/phase1-report.md` (≤350 + words) with commit IDs, measurements, exceptions and iPhone checks; write + DONE01 to the queue signal only after verification succeeds. + +Hash self-reference: stamp resource URLs first; hash a canonical index with its +build-meta placeholder intact to derive the manifest build tag. Stamp that tag +and expose the actual final index byte hash. Canonical tag computation normalizes +only this derived index field, avoiding a cryptographic fixed-point requirement. +SW response hashing must likewise describe injected bytes rather than raw source. + +Rollback: `ASSET_HASHING=0` restores the existing recursive build tag and legacy +single-tag CSS/JS stamping/header behavior. Default ON; test both modes. +Risks: old-worker ignoreSearch, stalled installation, mutable stale URLs, +recursive paths, derived HTML/SW hashes, shared iOS cache/audio quota. + +Acceptance: both unit suites green after each implementation commit; no weakened +characterization tests; migration passes in both browsers; reduced baseline cold, +warm and offline boot succeeds with no first-paint regression. Phase 1 still +fetches the whole shell on update; <30 KB CSS-only updates belong to Phase 2.