Skip to content

fix(sw): scope every fetch-handler caches.match() to its owned cache (#514) - #612

Merged
qnbs merged 4 commits into
mainfrom
fix/514-sw-cache-match-scoping
Sep 5, 2026
Merged

qnbs merged 4 commits into
mainfrom
fix/514-sw-cache-match-scoping

Conversation

@qnbs

@qnbs qnbs commented Sep 5, 2026

Copy link
Copy Markdown
Owner

User description

Fixes #514.

Problem

CacheStorage is origin-scoped, not path-scoped. qnbs.github.io hosts multiple independent GitHub Pages projects on different paths, so a bare caches.match(request) in public/sw.js's fetch handler searches every cache on the origin, not just this app's own CACHE_STATIC/CACHE_DYNAMIC/CACHE_IMAGES. In principle a different project's cached Response for a request whose full URL happens to coincide with one WorldScript Studio fetches could be served here.

Root cause

Four caches.match() call sites never passed an explicit cacheName:

  1. JS/CSS Cache-First strategy β€” caches.match(request)
  2. Navigation fallback β€” caches.match(request) and caches.match(${BASE}index.html)
  3. offlineFallback()'s document branch β€” caches.match(${BASE}offline.html) (reachable from every fetch-handler catch path; not explicitly named in public/sw.js fetch handler: caches.match() reads are not scoped to owned cachesΒ #514 but the identical gap, so fixed alongside it)

This is the read-path counterpart to DA-03 (#513), which fixed the same shared-origin invariant for cache deletion. Practical exploitability is low (per #514's own analysis β€” collision requires another origin-sibling app fetching/caching the exact same full URL), which is why this was correctly deferred rather than treated as a release blocker.

Scope

public/sw.js fetch handler and the offlineFallback helper it calls, only. No behavior change for any request whose URL doesn't collide with a foreign cache entry β€” every scoped lookup targets exactly the cache each value is actually written to.

Non-goals

Fix

Scoped all 4 call sites to the cache each one's value is actually written to, via the standard { cacheName } match option β€” the same pattern already used elsewhere in this file for reads via an opened cache handle (e.g. the image Cache-First branch).

Regression coverage

tests/unit/swCacheMatchScoping.test.ts β€” mirrors the existing source-contract test style for this classic (non-importable, self-using) worker script (see swLocaleStrategy.test.ts). Asserts every caches.match() call in the fetch handler and in offlineFallback carries an explicit cacheName. Verified via a manual negative-control: stashed the fix, confirmed 2 of 3 assertions fail against the original unscoped code, restored the fix, confirmed all 3 pass.

Validation

  • pnpm exec vitest run tests/unit/swCacheMatchScoping.test.ts β€” 3/3 pass.
  • pnpm exec biome check --error-on-warnings public/sw.js tests/unit/swCacheMatchScoping.test.ts β€” clean.
  • node scripts/check-doc-metrics.mjs β€” clean after syncing README's test-count metrics (598 files/7436 tests) for the new test file.
  • Full CI is the authoritative gate for typecheck/build/E2E; not rerun locally per this repo's low-end-hardware guidance.

Summary by Sourcery

Restrict service-worker cache reads to their owning caches and add regression coverage for shared-origin isolation.

Bug Fixes:

  • Scope service-worker cache lookups to this application’s owned caches, preventing cached responses from other projects on the shared origin from being served.

Documentation:

  • Update documented test metrics to include the new regression test file and test cases.

Tests:

  • Add regression coverage verifying all fetch-handler and offline-fallback caches.match() calls specify an owned cache.

CodeAnt-AI Description

Prevent offline pages and cached assets from being served from other apps on the same domain

What Changed

  • Service worker cache lookups now only use this app’s own caches for scripts, styles, navigation requests, the offline page, and the SPA fallback
  • Added regression tests covering all service-worker cache lookups to prevent unscoped matches from returning another app’s cached response
  • Updated documented test totals to include the new coverage

Impact

βœ… Prevents cross-app cached content
βœ… Keeps offline navigation within this app
βœ… Protects service-worker cache behavior from regressions

πŸ’‘ Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.


Summary by cubic

Scopes service worker cache reads to their owning caches so a request on the shared qnbs.github.io origin can't be served a response from another project's cache.

  • Four caches.match() calls in the fetch handler and offlineFallback now pass an explicit cacheName.
  • Adds a regression test that pins each call site to its exact expected cache and the total call count.
  • No behavior change for requests that don't collide with a foreign cache entry.
  • Updates README test metrics for the new test file.

Written for commit 1db048d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Improved offline and navigation fallback behavior by limiting service-worker cache lookups to the app’s designated static and dynamic caches.
    • Helps prevent unrelated cached content from being returned during offline use.
  • Documentation

    • Updated documented test metrics to reflect the latest test count and file count.

qnbs added 2 commits September 5, 2026 06:48
…514)

CacheStorage is origin-scoped, not path-scoped. On a shared origin like
qnbs.github.io (hosting multiple independent GitHub Pages projects), a bare
caches.match(request) searches every cache on the origin, not just this
app's own CACHE_STATIC/CACHE_DYNAMIC/CACHE_IMAGES β€” in principle a different
project's cached response for a coincidentally-identical full URL could be
served here. This is the read-path counterpart to DA-03 (#513), which fixed
the same shared-origin invariant for cache deletion.

Scopes all 4 unscoped caches.match() call sites (JS/CSS Cache-First,
navigation fallback's two lookups, and the offlineFallback helper reachable
from every fetch-handler catch path) to the explicit cache each one's value
actually lives in, via the standard { cacheName } match option β€” the same
pattern already used elsewhere in this file for reads via an opened cache
handle.

Regression test mirrors the existing source-contract style for this
classic (non-importable) worker script: asserts every caches.match() call
in the fetch handler and in offlineFallback carries an explicit cacheName,
and is confirmed to fail against the pre-fix source.
…ression test

check-doc-metrics.mjs computes its expected count from the actual Vitest
source set β€” adding tests/unit/swCacheMatchScoping.test.ts (3 tests) shifted
597β†’598 files and 7433β†’7436 tests.
@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

πŸ€– CodeAnt AI β€” Review Status

Status Commit Started (UTC) Finished (UTC)
βœ… Reviewed your PR 1bc0275 Sep 05, 2026 Β· 04:52 04:53

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @qnbs, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days and 9 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
worldscript-studio Ready Ready Preview Sep 5, 2026 5:12am UTC

@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! πŸŽ‰

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X Β·
Reddit Β·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR fixes shared-origin cache leakage risk by adding explicit cacheName scoping to all four relevant caches.match() reads in the service worker, adds source-based regression coverage for the fetch and offline fallback paths, and updates README test metrics.

Sequence diagram for scoped service worker cache reads

sequenceDiagram
    participant Browser
    participant ServiceWorker
    participant CacheStorage
    participant Network

    Browser->>ServiceWorker: fetch(request)
    alt script or style
        ServiceWorker->>CacheStorage: match(request, { cacheName: CACHE_STATIC })
        alt cache miss
            ServiceWorker->>Network: fetch(request)
            ServiceWorker->>CacheStorage: put(request, response) in CACHE_STATIC
        end
    else navigation
        ServiceWorker->>CacheStorage: match(request, { cacheName: CACHE_DYNAMIC })
        alt navigation cache miss
            ServiceWorker->>Network: fetch(request)
            ServiceWorker->>CacheStorage: match(BASE + index.html, { cacheName: CACHE_STATIC })
            alt fallback cache miss
                ServiceWorker->>CacheStorage: match(BASE + offline.html, { cacheName: CACHE_STATIC })
            end
        end
    end
    CacheStorage-->>ServiceWorker: response or cache miss
    ServiceWorker-->>Browser: response
Loading

File-Level Changes

Change Details Files
Scoped all service-worker cache reads to the cache that owns the requested resource.
  • Added explicit cacheName options to the offline document fallback, static script/style cache-first lookup, dynamic navigation lookup, and static SPA-shell fallback.
  • Preserved existing cache write and fallback behavior while preventing reads from sibling applications’ origin-shared caches.
public/sw.js
Added source-contract regression tests for cache-match scoping.
  • Extracted the fetch handler and offlineFallback source blocks from the classic service worker.
  • Asserted that every top-level caches.match() call includes an allowed explicit cacheName.
  • Used comment-stripping and call-site checks to guard the four affected lookups.
tests/unit/swCacheMatchScoping.test.ts
Synchronized documented test metrics with the added regression test file.
  • Updated the test count and file count in the badges, testing overview, repository tree, and current metrics section.
README.md

Assessment against linked issues

Issue Objective Addressed Explanation
#514 Scope every caches.match() read in the public/sw.js fetch handler to an explicitly owned cache, preventing reads from other applications' origin-shared caches. βœ…
#514 Ensure navigation fallback lookups use the cache corresponding to where the requested document and SPA shell are stored. βœ…
#514 Add regression coverage documenting and enforcing that fetch-handler cache reads, including the offline fallback path, always specify an owned cacheName. βœ…

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Sep 5, 2026
@deepsource-io

deepsource-io Bot commented Sep 5, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 2847305...1db048d on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSourceΒ β†—

PR Report Card

Overall GradeΒ Β  SecurityΒ Β 

ReliabilityΒ Β 

ComplexityΒ Β 

HygieneΒ Β 

Code Review Summary

Analyzer Status Updated (UTC) Details
Docker Sep 5, 2026 5:11a.m. ReviewΒ β†—
Python Sep 5, 2026 5:11a.m. ReviewΒ β†—
Rust Sep 5, 2026 5:11a.m. ReviewΒ β†—
Shell Sep 5, 2026 5:11a.m. ReviewΒ β†—

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The service worker cache scoping fix is correctly implemented and addresses the shared-origin security concern described in #514. All four caches.match() call sites now explicitly specify cacheName, preventing cross-app cache pollution on shared origins like qnbs.github.io. The contract-based test coverage is appropriate for a classic service worker. README metric updates reflect the new test file. No defects found - ready to merge.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

codescene-access[bot]

This comment was marked as outdated.

@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 1db048de
Scan Time: 2026-09-05 05:12:03 UTC

βœ… Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets βœ… PASSED 0 secrets found
Duplicate Code βœ… PASSED 0.0% duplicated
SAST βœ… PASSED No security issues
Bugs βœ… PASSED Rating S: No bugs
IAC βœ… PASSED No IAC issues

View Full Results

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 40 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 76 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Essentials

Run ID: 6ac2be77-f6df-4f8e-9cea-d6194949b739

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 1bc0275 and 1db048d.

πŸ“’ Files selected for processing (2)
  • README.md
  • tests/unit/swCacheMatchScoping.test.ts

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Essentials

Run ID: fe8f9795-2b09-4054-8cb4-ff45d0798d6f

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 2847305 and 1bc0275.

πŸ“’ Files selected for processing (3)
  • README.md
  • public/sw.js
  • tests/unit/swCacheMatchScoping.test.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


πŸ“ Walkthrough

Walkthrough

The service worker now scopes cache reads to owned caches. A regression test validates the source contract. README test metrics were updated to 7,436+ tests across 598 files.

Changes

Service-worker cache read scoping

Layer / File(s) Summary
Scope service-worker cache lookups
public/sw.js, tests/unit/swCacheMatchScoping.test.ts
Offline, asset, and navigation lookups now specify owned caches. Tests verify the scoped caches.match() calls.

README test metrics

Layer / File(s) Summary
Update README test metrics
README.md
README badges and project metrics now report 7,436+ tests across 598 files.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: βšͺ Minimal Β· up to 1bc02

Service-worker cache reads are now restricted to the application’s owned caches, preventing same-origin cache results from other projects while preserving the existing asset, navigation, and offline fallback behavior. No merge-blocking risk remains.

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly identifies the service-worker fix and the specific change: scoping fetch-handler caches.match() calls to owned caches.
Linked Issues check βœ… Passed The pull request scopes the relevant caches.match() lookups in public/sw.js to explicit owned caches, including static, dynamic, and offline document lookups. The regression test verifies the required…
Out of Scope Changes check βœ… Passed The changes remain within the issue objectives. The service-worker edits implement cache scoping, the test covers the regression, and the README updates document the added tests.
Docstring Coverage βœ… Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. (1 skipped: 1 …
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/514-sw-cache-match-scoping

Comment @coderabbitai help to get the list of available commands.

@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

CodeAnt Nitpicks

2 code suggestions

1. The fetch-handler test requires only two calls, although the handler currently has three, so one lookup could disappear without the regression test failing.

Incomplete implementation Β· tests/unit/swCacheMatchScoping.test.ts:52


2. The assertion accepts any owned cache name, so a lookup in the wrong cache can pass even though it misses the response written or precached elsewhere.

Incomplete implementation Β· tests/unit/swCacheMatchScoping.test.ts:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1bc0275698

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/unit/swCacheMatchScoping.test.ts
@codecov

codecov Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codecov Report

βœ… All modified and coverable lines are covered by tests.
βœ… All tests successful. No failed tests found.

πŸ“’ Thoughts on this report? Let us know!

qnbs added 2 commits September 5, 2026 07:09
Two real gaps: (1) the fetch-handler call-count assertion used a lower
bound, so a call site could silently disappear without failing; (2) the
cacheName assertion accepted any of the three owned caches, so a lookup
scoped to the wrong cache (e.g. reading CACHE_IMAGES for a value written to
CACHE_STATIC) would still pass. Verified the fix by injecting a wrong-cache
mistake locally and confirming it now fails, then reverting.

Each call site is now checked against its exact expected cache name;
the ${BASE} interpolation is normalized to a plain placeholder in the
extracted call text so the expected-value strings don't need to embed a
real template-literal placeholder (avoids fighting biome's
noTemplateCurlyInString on a literal string, without a suppression).
…ng test

The review-driven tightening split one assertion into two, adding a 4th
test (7436β†’7437) without changing the file count.

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@qnbs
qnbs merged commit 69b5db1 into main Sep 5, 2026
40 checks passed
@qnbs
qnbs deleted the fix/514-sw-cache-match-scoping branch September 5, 2026 05:37
qnbs added a commit that referenced this pull request Sep 5, 2026
* chore(release): bump version to v1.28.4

Patch release reconciling release-truth documentation with everything
merged to main since v1.28.3 (62 commits / ~40 PRs, audited against
live GitHub state, not assumed from commit subjects):

- fix: PWA first-install unprompted reload (#585, PR #613)
- fix: shared-origin service-worker cache-read isolation (#514, PR #612)
- fix: Factory Reset could reboot into Settings instead of Welcome
  Portal (PR #592)
- fix: preserve-first desktop corruption recovery (PR #542) and a
  distinct filesystem-I/O recovery action (PR #545)
- fix: intentionally cleared project metadata no longer reappears
  (PR #546)
- a11y: Welcome/Home dashboard WCAG AA contrast + reduced-motion
  cascade fix + default appearance preset change (#565, PR #609);
  ManuscriptEditor contrast (PR #560)
- security: fflate ZIP64-parsing DoS override (PR #595); routine
  dependency floor bumps (PR #587, #561, #562, #594)
- docs: R-15 secure desktop storage design contract admitted (PRs
  #564, #580, #581, #582, #584) β€” design only, no implementation yet
- tests: visual regression testing repaired β€” baselines were directory
  listings, not the application (PR #610); IDB reset-quiescence
  hardening (PR #596); WelcomePortal E2E navigation made
  locale-independent (PR #590)

Everything classified as pure internal/CI-governance churn (PR-size
exception plumbing, dual-graph tooling, toolchain pins) is omitted from
CHANGELOG.md as non-user-facing.

Version bumped via the existing sync scripts (sync-tauri-version.mjs,
sync-sw-version.mjs) across package.json, src-tauri/Cargo.toml,
src-tauri/tauri.conf.json, src-tauri/Cargo.lock, AGENTS.md, and
public/sw.js's APP_VERSION.

CHANGELOG.md and README.md use the established release-candidate
marker convention (<!-- release-candidate: v1.28.4 -->) so the dated
entry and version badge are truthful before the v1.28.4 tag exists;
both markers are removed in a follow-up post-release truth-sync once
the tag and GitHub Release are published, matching the v1.28.2/v1.28.3
precedent.

TODO.md's Current Sprint section was archived (its final "release cut
remains open" bullet is now resolved β€” v1.28.2 and v1.28.3 both
shipped) and replaced with the actual current sprint: this release cut
followed by the R-15 desktop at-rest encryption priority program.

AUDIT.md is intentionally not touched here β€” its release-gate entry
requires real post-merge CI/CodeQL run evidence that doesn't exist
until after this PR merges and the tag is cut, matching how every
prior release's AUDIT.md entry was written (a follow-up commit, not
part of the release-prep PR itself).

* docs(release): correct premature done-marker on the v1.28.4 TODO item

TODO.md's Current Sprint marked the release cut as done (checked
'v1.28.4' release cut, reconciling ... AUDIT.md truth ...) while this
same PR's own Non-goals section correctly states AUDIT.md is not
touched here, and while no tag, GitHub Release, or release artifacts
exist yet. Corrected to in-progress language naming PR #615 directly
and listing what actually remains pending (tag, release, artifacts,
post-release AUDIT.md evidence).

* docs(release): correct R-15 gate language and credit PR #596's real fix

Two corrections from review, verified against live evidence before
fixing:

1. TODO.md's Current Sprint claimed R-15 desktop at-rest encryption
   implementation was being prioritized now. docs/native/DESKTOP-
   MIGRATION-ROADMAP-REV3.md explicitly forbids pulling Wave 3/4 R-15
   implementation ahead of unresolved Wave 2 authority prerequisites,
   and CORE-MIGRATION-LEDGER.md row 10 records
   S5_IMPLEMENTATION_READY=NO. Corrected to state R-15 design is
   complete but implementation stays gated behind the still-open Wave
   2 prerequisite (ledger row 9: the project state-shape compatibility
   adapter), which is what this sprint's desktop-storage work actually
   is.

2. CHANGELOG.md listed PR #596 only as generic IDB test hardening
   under Tests. Verified against its actual diff: deleteDatabase()
   previously resolved on a genuine onerror or an onblocked event as
   if deletion succeeded, so wipeAllAppData() could report Factory
   Reset complete while a database was never actually deleted. onerror
   now rejects; onblocked waits for the connection to close before
   giving up. This is a real production data-integrity fix, not test
   hardening, and now has its own Fixed entry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

public/sw.js fetch handler: caches.match() reads are not scoped to owned caches

1 participant