Brings 14 commits to the production branch, including the BitLogin widget
re-vendored at 205b067 with recorded provenance.
main and unstable had diverged: both independently committed a "security-
audit build" widget update (0592c0ee here, 847a855e there), so the merge
conflicted on six vendor/bitlogin files, including a rename/rename on the
shared chunk -- Vite content-hashes those filenames, so two builds of the
same source produce different names.
Every conflict resolved by taking unstable's side wholesale. Vendored files
are build output, not authored source; a hand-merged bundle would correspond
to no build and no commit. The result was then verified against a clean
rebuild of BitLogin at 205b067 rather than trusted: vendor/bitlogin is
byte-identical to packages/widget/dist from a from-scratch build, the file
set matches origin/unstable exactly, and the manifest reads
provenance=attributed at 205b0678cc67.
main's widget was the OLDER build (0d118d59), predating BitLogin's
second-audit hardening, so this moves production forward rather than back.
Existing sign-ins are unaffected. normalize.ts, argon2id.ts, hkdf.ts and
scalarExpand.ts are byte-identical across this range, so login name plus
password derive the same locator, signing scalar and capsule key. Accounts
created with a hand-typed password still work -- the manual-password removal
took away the creation, recovery and rotation controls, not the acceptance.
What changes: creating, recovering or rotating now issues a generated
six-word passphrase.
Full suite green on the merged tree: 2354 passed, 0 failed.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01HtNMsKzzFTPURemX7tT19u
Was on the 2026-07-25 build. Carries an adversarial audit's fixes, the
ones that matter most for a site that hands the widget real identities:
- Origin binding is enforced INSIDE the crypto worker and derived from
self.location instead of a caller-supplied field, so a page cannot
read or adopt a wallet connection bound to a different site.
- Phrase recovery no longer trips the rollback alarm on every later
login (the mark is keyed by the everyday pubkey, which recovery
preserves, while the recovered capsule restarts at generation 0) --
users who had ever rotated a password previously saw "possibly
revoked credentials" forever, with no way to clear it.
- quorumMet counts relays that ANSWERED rather than ones that merely
accepted a socket, and relay responses are now checked against the
address requested, so a single junk event can no longer block
registration, rotation, and recovery.
- Password rotation checks the new capsule reached quorum BEFORE
publishing the tombstone that destroys the old one; a failed rotation
used to be able to leave neither password working.
- Derived secrets (Argon2id output, both PRKs, the BIP-39 seed) are now
wiped at their derivation site, as the spec always claimed.
- The worker RPC validates message shapes, times out, and rejects
pending calls when the worker dies, so a torn-down worker surfaces as
an error instead of a permanent hang.
- Synthetic (script-dispatched) clicks no longer drive consent UI.
Verified: the 10 pre-existing test failures in this suite are unchanged
by this update (checked by stashing the vendor directory and re-running
-- 1330 pass / 10 fail either way), and the BitLogin auth-provider
tests pass. dist/ is gitignored build output and regenerates.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1