Commit Graph
6914 Commits
Author SHA1 Message Date
thePR0M3TH3AN 6cd77767e1 dispatch-2 client-reliability-3: verify normal landing and refresh owner preview 2026-10-19 22:59:33 -04:00
thePR0M3TH3AN c206e0a3c0 fleet init 2026-10-19 22:58:13 -04:00
thePR0M3TH3AN 6d4ed9200c fleet init 2026-10-19 22:57:58 -04:00
thePR0M3TH3AN 7fde734d87 land: area/client-reliability 1c49eb3b2c (client-reliability) 2026-10-19 18:14:58 -04:00
thePR0M3TH3AN 1c49eb3b2c Merge branch 'unstable' into area/client-reliability 2026-10-19 18:14:56 -04:00
thePR0M3TH3AN b815446a52 client-reliability-3: close verified landed lifecycle fix and record dispatch handoff 2026-10-19 18:14:53 -04:00
thePR0M3TH3AN 7d20a509ca land: area/client-reliability e522efc191 (client-reliability) 2026-10-19 18:08:52 -04:00
thePR0M3TH3AN e522efc191 client-reliability-3: record full 426-file and native browser validation 2026-10-19 18:08:49 -04:00
thePR0M3TH3AN 607d5ce1a1 client-reliability-3: preserve shared badge callbacks and guard reentrant disposal 2026-10-19 18:02:46 -04:00
thePR0M3TH3AN 712b05cf87 client-reliability-3: cancel queued torrent probes after last card owner disposes 2026-10-19 17:56:25 -04:00
thePR0M3TH3AN 66832dc3a9 land: area/dispatch 03766d39ef (dispatch) 2026-10-19 17:47:52 -04:00
thePR0M3TH3AN 03766d39ef dispatch-2 client-reliability-3: verify landings and route reproduced obsolete probe bug 2026-10-19 17:47:47 -04:00
thePR0M3TH3AN f9adfc8f53 land: area/client-reliability af16ee1d09 (client-reliability) 2026-10-19 16:35:24 -04:00
thePR0M3TH3AN af16ee1d09 Merge branch 'unstable' into area/client-reliability 2026-10-19 16:35:22 -04:00
thePR0M3TH3AN cee4962166 client-reliability-1 client-reliability-2: close verified landed items 2026-10-19 16:35:21 -04:00
thePR0M3TH3AN de6918cee8 land: area/client-reliability 683cedf0bf (client-reliability) 2026-10-19 16:29:12 -04:00
thePR0M3TH3AN 683cedf0bf client-reliability-1 client-reliability-2: record full 425-file validation and unblock landing 2026-10-19 16:29:08 -04:00
thePR0M3TH3AN 181eae95d9 client-reliability-2: make concurrent-init test hermetic and close feed transport 2026-10-19 16:22:57 -04:00
thePR0M3TH3AN 3968a97922 Merge branch 'unstable' into area/client-reliability 2026-10-19 16:20:34 -04:00
thePR0M3TH3AN 3770eb4186 land: area/dispatch 4a6978ebc4 (dispatch) 2026-10-19 16:20:13 -04:00
thePR0M3TH3AN 4a6978ebc4 Merge branch 'unstable' into area/dispatch 2026-10-19 16:20:12 -04:00
thePR0M3TH3AN 16f6dca41e dispatch-2 client-reliability-2: route retained relay cleanup to existing worker 2026-10-19 16:20:10 -04:00
thePR0M3TH3AN 6da037f59b client-reliability-1: record checked fix and newly exposed full-gate blocker 2026-10-19 16:13:49 -04:00
thePR0M3TH3AN dbdac18df1 client-reliability-1: preserve native hidden-attribute behavior in style fixture 2026-10-19 16:09:26 -04:00
thePR0M3TH3AN d02240786d Merge branch 'unstable' into area/client-reliability 2026-10-19 16:07:49 -04:00
thePR0M3TH3AN be6058b0af client-reliability-1: preserve prior integrity notes alongside modal entry 2026-10-19 16:07:46 -04:00
thePR0M3TH3AN c3fee19059 client-reliability-1: bound modal fixture style work with native focus contract 2026-10-19 16:07:36 -04:00
thePR0M3TH3AN e106a15ea5 land: area/dispatch f303ab0e72 (dispatch) 2026-10-19 16:03:01 -04:00
thePR0M3TH3AN f303ab0e72 dispatch-2: record verified worker launch and preserved local preview 2026-10-19 16:03:01 -04:00
thePR0M3TH3AN 9e6c310d80 land: area/dispatch c312399117 (dispatch) 2026-10-19 16:01:33 -04:00
thePR0M3TH3AN c312399117 Merge branch 'unstable' into area/dispatch 2026-10-19 16:01:11 -04:00
thePR0M3TH3AN 3514c0570d dispatch-2: register approved client-reliability worker and scoped bootstrap gate decision 2026-10-19 16:01:10 -04:00
thePR0M3TH3AN 3e451aac0b land: area/dispatch 8b204687d2 (dispatch) 2026-10-19 15:52:32 -04:00
thePR0M3TH3AN 8b204687d2 dispatch-1: record verified startup landing and close preparation 2026-10-19 15:52:32 -04:00
thePR0M3TH3AN fa538097bd land: area/dispatch 386cf14bbe (dispatch) 2026-10-19 15:52:15 -04:00
thePR0M3TH3AN 386cf14bbe dispatch-1: record fleet goal, baseline, and first worker proposal 2026-10-19 15:52:05 -04:00
thePR0M3TH3AN d90591163f chore: initialize Codex agent fleet on unstable 2026-10-19 15:41:55 -04:00
thePR0M3TH3AN 5fdf53deb8 chore: pause Bitvid automated design audit 2026-09-14 18:54:18 -04:00
thePR0M3TH3ANandClaude Fable 5 4dd3eb0330 Add repo memory layer and agent governance
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-12 20:57:52 -04:00
thePR0M3TH3ANandClaude Fable 5 911afb1c05 Split AGENTS.md reference sections into docs/; keep thin agent constitution
Extracts Playwright harness tables and Dark Factory testing standard to
docs/testing/, and dated incident writeups to docs/lessons/, bringing
AGENTS.md under the 32KiB context budget agent harnesses eagerly load.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-12 15:20:08 -04:00
thePR0M3TH3ANandClaude Fable 5 6eb89afcec Dedupe CLAUDE.md testing rules into AGENTS.md pointer; untrack agent memory scratch
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-12 15:15:08 -04:00
thePR0M3TH3ANandClaude Fable 5 c098612c94 Make 'npm test' run the real unit suite
package.json had no "test" script, so `npm test` failed with
"Missing script" and the obvious fallback -- `node --test tests/*.test.mjs`
-- reports ~10 bogus failures. Those files are not broken: the runner
sets NODE_ENV=test (so nostrToolsBootstrap uses the mock toolkit) and
imports tests/test-helpers/setup-localstorage.mjs, and without that
harness they fail on missing globals. tests/modal-accessibility.test.mjs,
for example, is 8/8 under the runner and 0/1 under a bare node --test.

Aliasing test -> run-unit-tests.mjs means the obvious command is also the
correct one, so nobody re-derives that false failure list. CI is
unaffected (it calls test:unit and the shards, which are unchanged).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-04 16:44:47 -04:00
thePR0M3TH3AN 1ddfa95a84 [auth] Vendor BitLogin 30b4f34 and allow WASM in the app CSP
Picks up BitLogin's login-surface expansion (NIP-07 extension, NIP-46
remote signer with nostrconnect QR, passkey sign-in), three rounds of
adversarial-audit fixes, and the mandatory recovery-phrase ceremony for
passkey-created accounts. Vendored via scripts/build-bitlogin-widget.mjs,
which pins the source commit in vendor/bitlogin.integrity.json; the
shared-chunk hashes changed, so three old chunks are removed and three
new ones added.

CSP fix, required for sign-in to work at all: BitLogin's crypto worker
compiles an Argon2id WASM module, and index.html's script-src had no
'wasm-unsafe-eval', so WebAssembly.compile would be blocked and every
BitLogin password flow would fail -- silently, because the page still
loads. This exact omission broke sign-in on bitlogin.network for four
days. The keyword permits WASM compilation only; JS eval stays blocked,
and the CSP comment's stale "no bundle uses wasm" claim is corrected.

tests/csp-policy.test.mjs now pins the keyword for index.html so it
cannot be dropped again. Baseline verified unchanged: npm run test:unit
green, npm run lint clean, and the raw tests/*.test.mjs glob fails the
same 10 pre-existing files before and after this change.

test_integrity_note:
  change_type: ["new_tests"]
  scenarios:
    - id: SCN-csp-allows-wasm-for-bitlogin
      given: "index.html mounts <bitlogin-auth>, whose worker compiles an Argon2id WASM module"
      when: "the page's Content-Security-Policy script-src is evaluated"
      then: "'wasm-unsafe-eval' is present, so WebAssembly.compile is permitted while 'unsafe-eval' remains absent"
  observable_outcomes:
    - "script-src directive parsed from the index.html CSP meta tag contains 'wasm-unsafe-eval'"
    - "existing assertions still forbid 'unsafe-inline' and 'unsafe-eval'"
  determinism_controls:
    - "pure static parse of a committed HTML file; no clock, network, or browser"
  anti_cheat_rationale:
    prevents:
      - "silently relaxing script-src to make sign-in work"
      - "dropping the keyword and shipping a login page that cannot run Argon2id"
  relaxation:
    did_relax_any_assertion: false
    if_true_explain_spec_basis: ""
2026-08-04 16:13:09 -04:00
thePR0M3TH3ANandClaude Opus 5 fbac54dd48 Re-vendor BitLogin at 205b067, and record its provenance
Updates the vendored widget to BitLogin 205b067, which includes the
second-audit hardening the previous bytes predated -- phrase-gated sudo key,
deterministic migration, the pinned derivation chain -- plus the entropy
work: the closed nonce/IV surface, fail-closed RNG tests, and the
package-wide Math.random ban.

Also ports the provenance recording from BitUnlock's vendoring script. The
manifest now carries repository, commit, commit date and toolchain, and the
script refuses to vendor from a BitLogin checkout with uncommitted changes,
resolved before vendorDir is deleted so the refusal leaves the committed
files intact. Hashes prove the bytes have not changed since they were
committed; only the commit says which BitLogin produced them, and version
"0.1.0" has covered many substantive changes.

EXISTING SIGN-INS ARE UNAFFECTED, which matters most here since this is the
one consumer with real users. normalize.ts, argon2id.ts, hkdf.ts and
scalarExpand.ts are byte-identical between the previously vendored build and
205b067, so login name + password derive the same locator, signing scalar
and capsule key as before. Accounts created with a hand-typed password still
sign in: the manual-password removal took away the creation, recovery and
rotation CONTROLS, not the acceptance, and nothing on the login path
inspects the password's shape. BitLogin's legacyPassword.e2e.test.ts pins
that, including the migration path of signing in with an old typed password
and rotating onto a generated one.

What does change for users: creating a new account, recovering, or rotating
now hands out a generated six-word passphrase instead of accepting a typed
one.

2354 unit tests pass, including the 10 bitlogin-specific ones in
auth-providers-bitlogin and bitlogin-modal-integration.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01HtNMsKzzFTPURemX7tT19u
2026-07-31 22:17:08 -04:00
thePR0M3TH3ANandClaude Fable 5 58922e55c3 Record the caching decision: content-hash filenames, then immutable
Option A chosen. Noting explicitly that Option B should not ship as an interim
step -- the two are not stackable, and a bounded max-age shipped now is the
thing that never gets revisited.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1
2026-07-31 14:53:07 -04:00
thePR0M3TH3ANandClaude Fable 5 5e69fa4a7d Todo: static asset caching, and why "just add immutable" would break it
/css/* and /js/* have no header rule at all, so every stylesheet and script
revalidates on every page load. The obvious fix is a trap: asset URLs are not
content-hashed, so a long max-age with immutable would pin returning users to
stale CSS/JS after each deploy with no way to bust it. Records both real
options and the measured live headers.

Also corrects an earlier hand-off note claiming ~10 failing tests here; all
three suites pass on unstable as of today.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1
2026-07-31 12:31:36 -04:00
thePR0M3TH3ANandClaude Fable 5 8d40d85079 Delete netlify.toml; the site deploys on Vercel
Vestigial. Verified dead before removing: the live headers on
bitvid.network come from vercel.json, not from this file -- /js/* is
served with Vercel's default `max-age=0, must-revalidate` rather than
the `immutable, max-age=31536000` netlify.toml asks for, which is proof
the file is not consulted by anything deploying this site. It cost real
time today by making the deploy target look like Netlify.

Two rules it carried that vercel.json does NOT, both deliberately left
out rather than silently dropped:
- `Content-Security-Policy: frame-ancestors *` on /*. No behaviour
  change: absence is equally permissive, and the embed page relies on
  being framable, not on the header.
- Long-lived immutable caching for /css/* and /js/*. This one is a real
  (small) performance regression that predates this commit -- the live
  site has been serving those with max-age=0 for as long as it has been
  on Vercel. Worth porting into vercel.json separately; deleting a file
  nothing reads is not the change that should carry it.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1
2026-07-31 10:14:43 -04:00
thePR0M3TH3ANandClaude Fable 5 847a855ec8 Update the vendored BitLogin widget to the security-audit build
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
2026-07-31 10:02:48 -04:00
thePR0M3TH3ANandClaude Fable 5 5cce3b726a docs: close stale innerHTML TODO — ShareNostrModal has no innerHTML left
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LHH3wPBsoruwCaJo8Rpf6a
2026-07-30 11:45:23 -04:00
thePR0M3TH3ANandClaude Fable 5 975b996f4c [nostr-core] Pin the NIP-46 multi-account lifecycle contract (TODO #33)
The 2026-06-25 audit blamed "logout logs out everyone" / broken profile
switching / unknown-user-after-refresh on the single shared nip46Client and
single-slot session storage. Re-auditing the current code shows every named
suspect has since been fixed piecemeal: per-account v2 session map with v1
last-connected default, keepStored logout, scoped no-arg clear (v1 slot only),
reuseStored+expectPubkey switch wired end-to-end into
useStoredRemoteSigner({pubkey}), and a validator-enforced boot restore.

None of that was pinned at the manager level, so any layer could regress
silently. tests/nip46-signer-lifecycle.test.mjs now exercises the real
SignerManager against the real signer registry and real (polyfilled) storage:

- logging out the active NIP-46 account destroys its live client exactly once
  while BOTH accounts' stored sessions and the other account's registry signer
  survive
- a failed targeted restore (passphrase-locked or missing session) fails typed
  and deletes nothing
- disconnectRemoteSigner with and without keepStored never touches the
  per-account map

Mutation-checked: reinjecting the historical bugs (logout without keepStored;
no-arg clear wiping the v2 map) fails 2/6; real code passes 6/6.

TODO #33 updated: remaining work is the on-phone Amber verification the item
already gates on — and if that still misbehaves, the failure is now known to
live ABOVE this contract (UI/state reconciliation on restore failure), which
narrows the search considerably.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LHH3wPBsoruwCaJo8Rpf6a
2026-07-30 11:33:26 -04:00