Skip to content

fix: tab-close cold-start wipes lastRealHost session store#14

Merged
Babyhamsta merged 1 commit into
mainfrom
fix/last-real-host-clobber
Jun 13, 2026
Merged

fix: tab-close cold-start wipes lastRealHost session store#14
Babyhamsta merged 1 commit into
mainfrom
fix/last-real-host-clobber

Conversation

@Babyhamsta

Copy link
Copy Markdown
Owner

Bug (found by Fable 5)

P0.3 persisted lastRealHost to survive SW suspension, but the onRemoved handler mutated + persisted without hydrating first. Sequence: SW asleep → student closes any tab → SW cold-starts with an empty Map → handler deletes nothing → the debounced persist writes {} over chrome.storage.session, wiping all about:blank in-page-proxy attribution. The exact failure P0.3 exists to prevent, now triggerable by closing a tab.

Fix

Extract the logic into extension/lib/last-real-host.js (mirrors createPinStore) whose set()/remove() hydrate before mutating, so no call site can clobber the store. sw.js uses it for all reads, the nav write, and tab close.

Test

test/detect.mjs gains a last-real-host section with faked session storage + injected timer: a cold-start remove() must preserve stored attribution (fails against the old non-hydrating handler), the closed tab is still removed, and set() hydrates+merges+persists.

Verified: full node suite, parity, pytest, eslint, prettier all green.

The onRemoved handler deleted from the in-memory Map and scheduled a persist
WITHOUT hydrating first. A tab close wakes a suspended SW: it cold-starts with
an empty Map, the handler deletes nothing, then the debounced persist writes {}
over chrome.storage.session — wiping all about:blank in-page-proxy attribution.
That is the exact failure P0.3 added persistence to prevent, now triggerable by
closing any tab instead of suspension alone.

Extract the logic into lib/last-real-host.js (mirrors the pin store) whose set()
and remove() hydrate before mutating, so no call site can clobber the store.
sw.js uses it for all reads, the nav write, and tab close. Add a regression test
in detect.mjs (faked session storage + injected timer) covering the cold-start
no-clobber invariant.
@Babyhamsta Babyhamsta merged commit 239ff90 into main Jun 13, 2026
3 checks passed
@Babyhamsta Babyhamsta deleted the fix/last-real-host-clobber branch June 13, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant