fix: AutistMask does not run in Firefox private windows (closes #646)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

Firefox gives an extension page in a private window locks of its own. A
popup there could save between the background's read and its write of the
stored record, and undo a network switch the background had saved.

manifest/firefox.json now sets "incognito": "not_allowed", so Firefox never
runs AutistMask in a private window. tests/manifest.test.js pins the key.
The README and five code comments no longer describe a private-window
exception to the lock.

Model: opus-5-5
This commit is contained in:
2026-10-26 21:38:59 +00:00
parent 387f40689e
commit cb44e9903d
8 changed files with 30 additions and 27 deletions
+10 -9
View File
@@ -1494,15 +1494,16 @@ wrote last, the record says which build's shape it is in.
Each write reads the record, changes it and writes it back, holding a lock from
the read to the write: the browser's own (`navigator.locks`), taken through
`withLock()` in `src/shared/browserApi.js`. Every page of the extension and its
background share it, except a page in a Firefox private window, which Firefox
gives locks of its own (see https://git.eeqj.de/sneak/AutistMask/issues/646).
The popup's `saveState()`, the background's `updateState()` and the
StateRecovery reset all take it, so among the pages and the background that
share it, no write lands between another write's read and its write, where it
would be lost. Chrome has it from version 69, older than any Chrome that runs a
Manifest V3 extension, in pages and in the service worker; Firefox from version
96, older than the 115 `manifest/firefox.json` declares. Where it is missing, a
write fails rather than going ahead without it.
background share it. `manifest/firefox.json` sets `"incognito": "not_allowed"`,
so no page runs in a Firefox private window. Firefox would give a page there
locks of its own. In Chrome, a page opened from an incognito window still runs
outside incognito and shares the lock. The popup's `saveState()`, the
background's `updateState()` and the StateRecovery reset all take it, so no
write lands between another write's read and its write, where it would be lost.
Chrome has it from version 69, older than any Chrome that runs a Manifest V3
extension, in pages and in the service worker; Firefox from version 96, older
than the 115 `manifest/firefox.json` declares. Where it is missing, a write
fails rather than going ahead without it.
Version 1 is the shape that shipped before versions existed, so a stored record
with no `schemaVersion` is version 1 rather than a defect: it loads normally and