release: there is no packaging, no artifact and no signing — the extension cannot be installed durably on either browser #310

Open
opened 2026-08-20 11:59:45 +02:00 by clawbot · 0 comments
Collaborator

Found by the pre-1.0 deployability audit (#303). Blocker: there is no path by which the owner installs this once and keeps using it.

Checked exhaustively, all negative:

  • .gitea/workflows/ holds only check.yml and e2e.yml; neither uploads an artifact.
  • No zip/crx/xpi/pack target in Makefile, script/, package.json or Dockerfile.
  • git grep -niE '(web-ext|xpi|crx|\.pem|amo|addons\.mozilla|chrome web store|update_url|code.?sign)' returns exactly one hit: a comment at tests/e2e/firefox/driver.js:166 saying no XPI and no signing are involved.
  • manifest/chrome.json has no key and no update_url.
  • One tag exists, v0.1.0, and it is not an ancestor of HEAD — 246 commits back; git describe --tags fails outright.

Chrome

README.md:44-45 documents Load unpacked from dist/chrome/. With no key in the manifest, the extension ID is derived from the absolute directory path, so moving or re-cloning the checkout yields a different ID and therefore a different chrome.storage.local partition — the wallet silently reads as empty. No update channel, and a Developer-mode nag on every browser start. (Absence of key verified directly; the ID-derivation consequence is documented Chrome behaviour, not tested here — see the DoD.)

Firefox

README.md:46-47 documents Load Temporary Add-on as the only route. Release Firefox and ESR enforce signing with no working override, and this repo produces no XPI and has no signing key or AMO tooling, so on release Firefox this cannot be permanently installed at all. A temporary add-on is unloaded when Firefox exits — the repo says so itself at tests/e2e/firefox/driver.js:167 ("the add-on dies with the profile"). Daily use means re-adding it by hand from about:debugging on every browser start.

manifest/firefox.json:22-26 does carry a stable gecko.id, which is the right shape for storage to survive a re-add, but no test asserts that the vault survives an add-on removal and re-add — and that is exactly the property that must hold before real money goes in.

Related: dist/constants-bundles.txt and dist/styles.css sit at dist/ root, outside both browser directories, so a naive zip of dist/chrome/ would miss them. Version is triplicated and unwired — manifest/chrome.json:4 and manifest/firefox.json:4 (both hardcoded 0.1.0, copied verbatim by build.js:198-205) and package.json:3 (a separate source feeding the About screen); nothing checks they agree. BUILD_COMMIT (build.js:63,71) has no dirty check, so a build from a modified tree stamps a clean hash.

Definition of done

  • A release entrypoint produces a versioned, self-contained artifact per browser, with everything the browser needs inside the archive.
  • manifest/chrome.json carries a fixed key, so the extension ID and its storage partition are stable across checkout moves and re-clones.
  • Firefox ships a signed XPI (AMO self-distribution is sufficient), or the README states plainly that Firefox requires Developer Edition or Unbranded and that a temporary add-on does not survive a restart.
  • One version source of truth; the build fails if the manifests and package.json disagree. BUILD_COMMIT marks a dirty tree as dirty.
  • Test on the pinned Firefox harness: install, create a wallet, uninstall, re-install, assert the vault is still there.
  • Test: two unpacked Chrome loads from different paths in one profile, asserting whether storage is shared — documenting the real behaviour either way.
  • make check green.

Note: tagging a release and publishing to AMO are outward-facing acts and are sneak's call, not the implementer's. This issue covers producing and verifying the artifact, not publishing it.

Found by the pre-1.0 deployability audit (https://git.eeqj.de/sneak/AutistMask/issues/303). **Blocker: there is no path by which the owner installs this once and keeps using it.** Checked exhaustively, all negative: - `.gitea/workflows/` holds only `check.yml` and `e2e.yml`; neither uploads an artifact. - No zip/crx/xpi/pack target in `Makefile`, `script/`, `package.json` or `Dockerfile`. - `git grep -niE '(web-ext|xpi|crx|\.pem|amo|addons\.mozilla|chrome web store|update_url|code.?sign)'` returns exactly one hit: a comment at `tests/e2e/firefox/driver.js:166` saying no XPI and no signing are involved. - `manifest/chrome.json` has **no `key`** and no `update_url`. - One tag exists, `v0.1.0`, and it is **not an ancestor of HEAD** — 246 commits back; `git describe --tags` fails outright. ## Chrome `README.md:44-45` documents Load unpacked from `dist/chrome/`. With no `key` in the manifest, the extension ID is derived from the absolute directory path, so **moving or re-cloning the checkout yields a different ID and therefore a different `chrome.storage.local` partition — the wallet silently reads as empty.** No update channel, and a Developer-mode nag on every browser start. (Absence of `key` verified directly; the ID-derivation consequence is documented Chrome behaviour, not tested here — see the DoD.) ## Firefox `README.md:46-47` documents **Load Temporary Add-on** as the only route. Release Firefox and ESR enforce signing with no working override, and this repo produces no XPI and has no signing key or AMO tooling, so **on release Firefox this cannot be permanently installed at all.** A temporary add-on is unloaded when Firefox exits — the repo says so itself at `tests/e2e/firefox/driver.js:167` ("the add-on dies with the profile"). Daily use means re-adding it by hand from `about:debugging` on every browser start. `manifest/firefox.json:22-26` does carry a stable `gecko.id`, which is the right shape for storage to survive a re-add, but **no test asserts that the vault survives an add-on removal and re-add** — and that is exactly the property that must hold before real money goes in. Related: `dist/constants-bundles.txt` and `dist/styles.css` sit at `dist/` root, outside both browser directories, so a naive zip of `dist/chrome/` would miss them. Version is triplicated and unwired — `manifest/chrome.json:4` and `manifest/firefox.json:4` (both hardcoded `0.1.0`, copied verbatim by `build.js:198-205`) and `package.json:3` (a separate source feeding the About screen); nothing checks they agree. `BUILD_COMMIT` (`build.js:63,71`) has no dirty check, so a build from a modified tree stamps a clean hash. ## Definition of done - [ ] A release entrypoint produces a versioned, self-contained artifact per browser, with everything the browser needs inside the archive. - [ ] `manifest/chrome.json` carries a fixed `key`, so the extension ID and its storage partition are stable across checkout moves and re-clones. - [ ] Firefox ships a signed XPI (AMO self-distribution is sufficient), **or** the README states plainly that Firefox requires Developer Edition or Unbranded and that a temporary add-on does not survive a restart. - [ ] One version source of truth; the build fails if the manifests and `package.json` disagree. `BUILD_COMMIT` marks a dirty tree as dirty. - [ ] Test on the pinned Firefox harness: install, create a wallet, uninstall, re-install, assert the vault is still there. - [ ] Test: two unpacked Chrome loads from different paths in one profile, asserting whether storage is shared — documenting the real behaviour either way. - [ ] `make check` green. Note: tagging a release and publishing to AMO are outward-facing acts and are sneak's call, not the implementer's. This issue covers producing and verifying the artifact, not publishing it.
clawbot added this to the 1.0.0 milestone 2026-08-20 11:59:45 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#310