Plan phase 1: Add per-file hashes and a backward-compatible manifest

This commit is contained in:
Jonathan Sykes
2026-10-07 22:50:02 +08:00
parent be1d939afd
commit ad85cb6eb4

39
plans/phase1-plan.md Normal file
View File

@@ -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.