feat(pwa): retirement kill-switch, offline-version binding guard, and dev teardown flag#826
Conversation
…rd, and dev teardown flag Close the three open findings from the 2026-07-17 PWA setup review with zero cache-semantics change (CACHE_VERSION untouched): - public/sw-kill-switch.js: the retirement worker docs/pwa.md rule 6 requires — skipWaiting on install, deletes all clinical-kb-pwa-* caches including unknown future versions, unregisters, no fetch listener. Locked by tests/pwa-kill-switch.test.ts (prefix parity with the live worker, foreign-cache preservation, caches-unavailable resilience). - tests/pwa-manifest.test.ts: bind the offline.html sha256 to the sw.js CACHE_VERSION pairing so an offline-document edit cannot ship without a fresh, never-reused version bump. - pwa-lifecycle: ?pwa-dev=0 on local hosts unregisters the dev-session worker and deletes owned caches; production and non-local hosts ignore the flag. Dom test proves foreign workers and caches stay untouched. - docs/pwa.md: rules 1 and 6 now reference the committed guards; the local-dev cleanup step documents the opt-out flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR adds a PWA retirement service worker, local ChangesPWA hardening
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Browser
participant PwaLifecycle
participant ServiceWorker
participant CacheStorage
Browser->>PwaLifecycle: load PWA lifecycle
PwaLifecycle->>ServiceWorker: register or tear down based on environment and query flag
ServiceWorker->>CacheStorage: delete owned caches during retirement
ServiceWorker-->>PwaLifecycle: unregister and claim clients
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/pwa-lifecycle.tsx`:
- Around line 72-77: Update the service-worker filtering in the registration
cleanup flow to compare each worker’s scriptURL exactly against the absolute URL
produced by new URL(SERVICE_WORKER_URL, window.location.origin).href, rather
than using endsWith. Also update the foreign-worker test fixture to use a nested
/.../sw.js URL so it verifies unrelated workers are preserved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1fb8e633-480f-4921-a037-47d93ab9ac58
📒 Files selected for processing (7)
docs/branch-review-ledger.mddocs/pwa.mdpublic/sw-kill-switch.jssrc/components/pwa-lifecycle.tsxtests/pwa-kill-switch.test.tstests/pwa-lifecycle.dom.test.tsxtests/pwa-manifest.test.ts
A suffix check would also unregister an unrelated same-origin worker at a nested path like /other-app/sw.js. Addresses the CodeRabbit review finding on PR #826; the foreign-worker fixture now uses a nested /sw.js path to lock the exact-match behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
Summary
CACHE_VERSIONbump;public/sw.jsuntouched):docs/pwa.mdrule 6 (public/sw-kill-switch.js): skipWaiting on install (the documented retirement exception), deletes everyclinical-kb-pwa-*cache including unknown future versions, unregisters itself, registers no fetch listener. Locked by 5 new tests intests/pwa-kill-switch.test.ts, including prefix-parity with the live worker.tests/pwa-manifest.test.tsnow binds thepublic/offline.htmlsha256 to the sw.jsCACHE_VERSIONpairing, so an offline-document edit cannot ship without a fresh, never-reused version bump.?pwa-dev=1cleanup friction:?pwa-dev=0on local hosts unregisters the dev-session worker and deletes owned caches (production and non-local hosts ignore the flag); a new dom test proves foreign workers and caches are untouched.docs/pwa.mdupdated: rules 1 and 6 now point at the committed guards; the local-dev cleanup step documents the opt-out flag.Verification
npm run test -- tests/pwa-service-worker.test.ts tests/pwa-manifest.test.ts tests/pwa-lifecycle.dom.test.tsx tests/pwa-kill-switch.test.ts) — 53/53 passed on the rebased branch.npm run verify:cheap— green except one pre-existing failure unrelated to this diff:tests/pdf-extraction-budget.test.tsfails identically on a clean checkout of main in this remote container (child-process SIGKILL semantics); baselined by clean re-run.npm run ensure+npm run test:e2e:pwa— the offline-fallback/CacheStorage-privacy journey passes; the installability test fails only in this container with Chromium's sole complaint"in-incognito", reproduced identically from a detached clean-main worktree with its own server — an environment artifact of the preinstalled Chromium, not this diff. Hosted CI Chromium (which runs this spec in the Production UI job) is authoritative.npm run verify:ui— 218 passed (7.7m); 2 failures, both reproduced identically on a clean-main (54229f0) detached worktree, i.e. pre-existing and container-local: theui-pwainstallability test above, and theui-smoke"document viewer puts the PDF preview first…" mobile test (flagged separately as a possible upstream regression — not introduced here).npm run verify:pr-local— unit stage: 2764 passed / 1 failed, the same twice-baselined container-onlypdf-extraction-budgetfailure, which stops the local chain; the conditional production-build/client-bundle stages are covered authoritatively by this PR's blocking hosted CI Build job (bundle budget enforced).npm run format:checkclean for repo files.Clinical Governance Preflight
Not applicable — no ingestion, answer generation, search/ranking, source rendering, document access, privacy-boundary, production env, or clinical output behavior changes. The service-worker privacy contract is unchanged (no new cached content classes; the existing CacheStorage-inventory e2e and worker policy suite prove it).
Risk and rollout
/sw.js; the lifecycle change adds a localhost-only opt-out branch ahead of an otherwise unchanged registration path; remaining changes are tests and docs.Notes
2b1c365on this branch.🤖 Generated with Claude Code
https://claude.ai/code/session_01EXsJcLrbZUXwnBeG91cVo9
Summary by CodeRabbit
?pwa-dev=0, automatically unregistering the worker and removing owned caches.