PR #169 made DEBUG a build-time flag defaulting off, but nothing guarded the wiring. The tests load src/shared/constants.js outside a bundle and take the jest fallback branch, so deleting the __BUILD_DEBUG__ define from build.js left all tests passing and make check green while silently restoring the drainable-wallet vulnerability in every shipped artifact. The property only exists in the emitted output, so it is now asserted against the emitted output. script/verify-build reads two independent facts per bundle. Which bundles must be inspected comes from esbuild's metafile: build.js writes dist/constants-bundles.txt naming every emitted JS output whose input set includes constants.js, so the set is derived from the real dependency graph rather than a hardcoded count or filenames. What each bundle's DEBUG state is comes from BUILD_DEBUG_MARKER, a new constant derived from DEBUG itself that the bundler folds to exactly one of two string literals. Deriving the bundle set from the marker would be the silent-pass hole: a bundle with no marker would be indistinguishable from content/index.js, which legitimately contains none. The marker is a plain string rather than a match on minified `DEBUG:!1`, because minifier output is not a contract across esbuild versions. When DEBUG is not known at build time the fold cannot happen and both literals survive, which is exactly the shape of the regression this guards against. Every way of failing to determine a bundle's state is a hard failure: missing manifest, empty manifest, a listed file that does not exist, both markers, neither marker, the wrong marker, or a bundle carrying a marker while absent from the manifest. There is no path on which the script exits 0 without positively identifying the expected marker in at least one bundle. It runs on the build path only. make build and make build-debug both invoke it, the latter asserting the inverse, and Dockerfile:17 runs a bare make build, so CI fails on a release build with a live debug branch. It is deliberately not in script/check: that would make check depend on dist/ existing and pull a full build into its time budget, and the obvious workaround -- skip when dist/ is absent -- is precisely the silently-green behaviour this exists to prevent.
5.5 KiB
Workflow
- branch (from
main) - do the work in Next Step
- move Next Step to the top of Completed Steps
- move the top item of Future Steps into Next Step
- commit (
TODO.mdchanges in the same commit as the work) - merge to
mainif the branch is not protected, otherwise open a PR - push
Status
pre-1.0, working towards the 1.0.0 milestone. Tagged v0.1.0 on 2026-02-27. No
other branch is in flight: the settings About well landed as #145 on 2026-07-26
and scripts-to-rule-them-all landed as #148, so the scripts/ directory
question is resolved. Full policy file set present. make check verified
passing on main at 23aeae4 on 2026-08-09. The 1.0.0 backlog is filed as
#149-#168. A real-browser end-to-end suite (make test-e2e) now sits alongside
make check, which cannot see a runtime ReferenceError in a popup view.
Next Step
Land #149: make DEBUG a build-time constant that defaults to off, injected as
the __BUILD_DEBUG__ esbuild define from AUTISTMASK_DEBUG=1, so a plain
make build stops handing every newly created wallet the publicly committed
test recovery phrase. Branch fix/issue-149-debug-build-flag; PR open, awaiting
review.
Completed Steps
- 2026-08-09: Post-build assertion that every emitted bundle containing
constants.jshasDEBUGcompiled off, viascript/verify-buildon themake buildpath (#170). - 2026-08-09: Containerized Chrome end-to-end harness (
make test-e2e/script/test-e2e) driving the real popup with all network intercepted, plus the two used-but-not-imported crashes it caught: AddToken unreachable (#150) and TransactionDetail broken for every ERC-20 transfer (#151). Harness demonstrated failing before the fixes and passing after (#181). Interception covers the MV3 background service worker, not just the popup page, and a launch-time canary aborts the suite if worker traffic starts escaping. - 2026-08-09: Reviewed the repo end to end and filed the 1.0.0 backlog (#149-#168).
- 2026-08-09: Test coverage for the address-poisoning defense in
src/shared/transactions.js(#160) - 2026-07-26: About well in settings with build info, repo link and the version click easter egg (#145); proper view navigation stack (#146).
- 2026-07-07 Adopted scripts-to-rule-them-all:
script/entrypoints, Makefile shims, README Entrypoints section (#148) - 2026-03-01: USD display suppressed on testnets (#142); estimated USD for ETH in approve-tx view (#141).
- Sepolia testnet support (#137); etherscan links go to token-specific URLs (#136).
- Transaction detail improvements: Type field and on-chain details (#130), txid-first reordering (#133), swap display corrections (#128), expanded confirm-tx warnings (#118).
- Dark mode theme setting (Light/Dark/System) with contrast fixes (#126); timestamps include timezone offset (#120); layout shift audit, reserved space for error messages (#124).
- Copy-flash visual feedback with timing tune (#113, #121); cross-wallet-type duplicate detection (#115).
- 2026-02-27: v0.1.0 tagged.
- 2026-02-24: Initial scaffolding: popup UI, BIP-39 wallet creation via ethers.js, wallet persistence, real ETH balances over RPC, ENS forward and reverse resolution.
Future Steps
- Add ESLint to
script/lint(#152).make checkisprettier --checkonly and cannot catch undefined identifiers, which is how #150 and #151 shipped. - Decide the libsodium backend that actually ships (#182) and delete the single
allowlist entry it owns in
tests/e2e/harness.js. - Extend the end-to-end suite to the dApp approval signing path (EIP-1193
through the real content script, background worker and approval popup). That
path needs a CDP-based route to background-worker console output first:
Playwright exposes no error event for service workers, so an uncaught
exception in the worker cannot fail the run today (worker network traffic is
already covered). Decide separately whether docker-in-docker makes
make test-e2erunnable in the Gitea workflow. - Make the Firefox target functional: Chrome callback APIs are used against the
promise-only
browsernamespace (#153). - Send and transaction-flow correctness: gas fee excluded from the insufficient-balance check (#154), WaitTx 60s timeout overwriting a rendered success screen (#155), last-wallet deletion leaving inconsistent state (#156).
- Security: plaintext password crossing the extension messaging boundary during dApp approvals (#157); MV3 service worker termination killing the background refresh and the 24h phishing list update (#158).
- Test the crypto core —
wallet.jsderivation andvault.jsencryption (#159) — and the address-poisoning defense intransactions.js(#160). - Wallet features for 1.0: show a wallet's recovery phrase behind the password (#161), delete an address from an HD wallet (#162).
- Docs:
docs/README.mdcontradicts the code on external services and names competitors (#163); README Screen Map omits three shipped screens (#164). - Owner decisions: Sepolia support versus "Non-Goals for 1.0", and
isMetaMasknaming a competitor in shipped code (#165). - Repo policy compliance sweep: test rerun pattern,
yarn/npx, frozen lockfile, undocumented Makefile targets (#166). - Prune the 24 stale remote feature branches (#167).
- Remove dead exports and de-duplicate copy-pasted view helpers (#168).
- Pre-1.0 security review of the extension (key handling, DEBUG mode policy, RPC input validation) before any 1.0rc tag; #149 and #157 are parts of it, but the review is broader than either.
- Cut 1.0.0 once the milestone is empty, then continue tagging as milestones land.