ungovernable.tech

Briefing · Identity and Pseudonymity Sunday

Identity and Pseudonymity Sunday — October 11 2026 Weekly Update

published 2026-10-11 46 min read Identity, Social and Trust

The weekly companion to Overview - Identity & Pseudonymity, covering October 04 – October 11, 2026 (since the October 04 update). The week closes with one of the densest two-week stretches in 2026 at the Nostr spec layer — fourteen NIPs PRs merged in seven days (PR #2494 NIP-92, PR #2491 NIP-FC, PR #2495 solving #2482, PR #2498 EXTRA on CLOSED/OK, PR #2449 Static Website curation sets in NIP-51, PR #2229 NIP-DB window.nostrdb, PR #2496 NIP-97 Persisted Delivery Confirmation, PR #556 NIP-57 Zap Proofs partial receipts, PR #2428 NIP-171 Epoch-Ticketed Private Groups, PR #2303 NIP-5D nostr web applets, PR #2462 slash commands, PR #2437 NIP-94 file encryption, PR #1862 NIP-5F Unix Domain Socket remote signing opened back in March and merged today by ChristianChiarulli, and PR #2112 NIP-47 Arkade + non-BOLT11). Three narratives dominate. First: protocol-level signing/identity hardening — NIP-5F brings remote signing into the OS-local socket namespace (NIP-46 over unix://), NIP-42 + NIP-43 rewrite the authentication gate as NIP-DB inside the browser, NIP-94 encryption closes the public-file plaintext gap, and the headline NIP-92 (imeta tags on kind:0 profile pictures) gets implementation within hours: Amethyst 1.17.0's ProfileImageMetas matcher merged roughly two hours after the spec merged on the same day. Second: relay-side authentication correctness — Citrine 3.1.1 (Sept 11, covered retrospectively this week) shipped a NIP-42 AUTH signature-bypass fix where every kind:22242 was accepted regardless of sig; in practice reachable only on relays configured to listen beyond 127.0.0.1:4869, but read-side AuthGate covers kind:4 / kind:1059 / kind:30078 reads and the bypass is a forged-pubkey read. Third: client / signer operability — Amber 6.6.7 (Oct 5) closes a "relays stuck disconnected until force-close" regression where RelayHealthTracker.isDead was a count-only threshold with no expiry, and onDisconnected was double-counted alongside onCannotConnect; Amethyst 1.17.0 (Oct 5, "Cordn and several updates") is the largest in months (1,253 commits, 176 PRs), with PR #4238 saving entire DM loads from relays that close on refused kinds, PR #4239/#4242 learning max_filters from CLOSED reasons, PR #4209 redesigning the backup-key screen with NIP-49 Poly1305 verification, and PR #4201 shipping Cordn group messaging (51,174 LOC, unticked interop test plan).

Three structural threads close the week: (a) Nostr Compass #43 (Oct 7) reports the canonical event log — Ants nested AND/OR, Myco 0.10.0 permission-gated uploads (16 MiB cap), Marmot MDK 0.12.0 source-epoch attachment keys, Iris Chat 2026.10.5.1→2026.10.7, Scramble 0.7.9 still-sealed message replay, Mostro 0.19.1 + core weighted imported reputation + signed reputation validation + main-branch Cashu ecash discovery, My Signet 0.18.2 per-app phone approval, Nsync 0.3.0 signed Nostr address announcements, PsstPsst 26.10.1 small private groups over NIP-17 + NIP-59, KithMoot 0.6.62/0.6.63 VMLS rooms on Bothy, Haps 0.1.11 social-graph package discovery, fips2go 0.9.4/0.9.5 fallback TTLs + cached mesh answers, soyLI 0.25.0 uses creator's NIP-34 repos checking signed refs and clone reachability; (b) Nostr-WoT extension v0.8.11 + v0.8.12 (Oct 6, 37 min apart) — the Account Archive feature (PR #39 + 41 min merge before tag) and passwordless archive import with signature + account-ownership verification on import — the third archive-tier Nostr client feature in 2026 after Nostr Key Custody and Recovery's Amber split-key backup (Sept 21) and Hive/Nestr rebuilding kind:30000 archives; (c) NIP #2434 (Post-Quantum Identity Keys, ConorClancy89, Aug 11) now 61 days frozen, kind:10203 ML-KEM-1024 + ML-DSA-87 plateau holds at 26 for a third consecutive week (Aug 31 + Sept 23 stair-step model still holds), and the institutional OpenPGP layer has light Oct activity: GnuPG master 1f03937 + 3add2ab + 76b4752 simplify the scd_getpin call-chain on Oct 9 (PIN-callback removal in agent + scd + scd:piv PIN-Policy verification Oct 6), 33d1810 fixes a TPM2d Esys_TRSess_SetAttributes use on Oct 5 — confirmation that even an "empty stable" branch still ships steady housekeeping, but no 2.5.25 tag yet. The identity layer's correctness is being re-drawn at the spec + relay + client + signer intersection, not at any single one of those layers; the gap that matters remains the gap between signed event and durable outcome (NIP-09 erasure, the NIP-42 signature-omission, the kind:9735 zap-receipt self-signed claim, NIP-65 push-relay boundaries).

TL;DR — This Week

  • NIPs PR #2494 NIP-92 imeta tags for kind:0 picture/banner merged Oct 5 (alexgleason) + Amethyst PR #4320 ProfileImageMetas merged Oct 5 ~2h later. NIP-92's profile-specific section lets the canonical picture and banner URLs in the kind:0 JSON content carry imeta tags for MIME type, SHA-256 x, dimensions dim, blurhash blurhash, fallback URLs fallback, accessibility alt, and other NIP-94 metadata. The URL equivalence is exact-match (whitespace-trimmed only — a different query string does not match). On replaceable kind:0 publication, clients SHOULD carry over tags for unchanged images and DROP tags for replaced/removed images. The merge happened in the same Oct 5 window as the NIPs newsroom piece — a textbook example of spec + implementation + explainer in a 24-hour cycle. Ditto and Armada implement the rendering side; Flutter-side Amethyst publishes imeta tags matching exact URLs and renders the blurhash placeholder while loading. The PR also fixes earlier problems: a stale tag cannot be applied to a newly selected image merely because both came from the same host; an avatar that lost its hosting stays visible through a published fallback; a profile image can render an accessible aspect-ratio placeholder before downloading the file. Backward compatible: non-supporting clients ignore the tags and read picture/banner as before. The trade-off is a mixed-deployment period during which two clients render the same kind:0 differently.
  • NIPs PR #1862 NIP-5F "Remote Signing via Unix Domain Sockets" merged Oct 6 (ChristianChiarulli) after about six months open (merged Mar 2026, originally a separate spec line and reconciled by fiatjaf merges into the NIP-46 family). NIP-5F defines how a NIP-46 bunker answers connection requests over a Unix-domain-socket URI scheme such as nostr+unix:///run/user/1000/my-bunker.sock rather than over a remote relay + secret. The structural value: a local signer can connect to a local client without ever creating a TCP/WS relay channel, without paying for relay bandwidth, and without an open remote-signer port on the network. The companion surface is a permission-to-socket path: a sandboxed app learns where the user's local bunker listens and joins the same OS sandbox via filesystem ACLs (e.g., seatbelt / Landlock / polkit) rather than via network reachability. The two published implementations in Remote Signing (the JS bunkers keep-core/keep-bunker and njalla/nostr-nsecbunker) already accept relay URLs in their connection-string parsers; NIP-5F is the form-fill for the OS-local case where the relay list is empty (or unwanted). This is the year's first NIP-46 cousin that is both cryptographic and not networked, and it complements the existing nostrconnect remote-signer model rather than replacing it.
  • Amber 6.6.7 "gives dead relays a second chance after fifteen minutes" — released Oct 5, newsroom piece Oct 5 — 8 commits, 23 files. Two independent causes for the regression ("relays stay disconnected until force-close"): (i) RelayHealthTracker.isDead was a count-only threshold with no temporal expiry — once a relay passed MAX_RECONNECT_ATTEMPTS = 10, nothing except an OS network change, a successful connection, or a manual reconnect reset the tracker. Cases that miss all three: Wi-Fi that lost and regained internet on the same SSID, weak cell signal that recovers, relay-side outage that clears. The fix introduces a DEAD_COOLDOWN_MS = 15 * 60 * 1000L constant; isDead returns true only when failures > MAX_RECONNECT_ATTEMPTS && clock() - lastFailureAt < DEAD_COOLDOWN_MS. After 15 minutes the relay is eligible again. (ii) onCannotConnect and onDisconnected both called scheduleReconnect, so the streak advanced by 2 per failed dial. With MAX_RECONNECT_ATTEMPTS = 10, the documented threshold was reached after five failed dials. The fix splits scheduleReconnect into recordFailureAndScheduleReconnect (called only by onCannotConnect) and an idempotent scheduleReconnect that checks isDead and reconnects without recording (called by onDisconnected). A plain server-side close is not a connection failure. A clock function is injected so the expiry can be tested without Thread.sleep. Six releases in six weeks (6.6.2 → 6.6.7, Aug 31 → Oct 5) — the most active Nostr-side identity surface in this fortnight.
  • Amethyst 1.17.0 "Cordn and several updates" released Oct 5 — 1,253 commits since 1.16.0, 176 PRs in the notes. Five identity-bearing changes: (1) PR #4238 + #4239 (re-landed as #4242) — relays that answer CLOSED on filters with disallowed kinds (strfry 1.1.1 with kind allowlist) were sinking entire DM loads; PR #4238 learns the refused kind from the CLOSED reason (e.g. kind not allowed: 21059) and strips it from every request built for that relay, both on change and on reconnect; PR #4239 detects a 4-filter refusal and infers max_filters ≤ 3 (strfry doesn't advertise it in NIP-11), then merges filters that differ in exactly one set of values into one filter with the union of those values. Filters with limit are never merged (a per-filter limit and a limit over the union are different requests); filters differing in two fields are never merged. (2) PR #4320 — ProfileImageMetas matches an imeta tag to a profile image only when URLs are equal after trim, so avatars and banners can show blurhash placeholders and try fallback URLs if the primary one fails; metadata for an unchanged image is preserved on edit, metadata for a replaced/removed image is dropped. (3) PR #4209 — backup-key screen redesign: nsec shown as three numbered rows of uppercase groups masked until tap, all-caps with dashes / spaces / line breaks now accepted (login flow previously rejected uppercase NSEC1), password-protected NIP-49 asks twice and requires ≥ 12 chars on creation (a creation policy, not a ncryptsec format change); Poly1305 tag is now checked during decryption (previously a valid key with all-32-byte high bits set was rejected as "no positive byte"); encryption honors its result and throws on tag failure (previously a tag failure could have produced a ncryptsec that no password opens); non-48-byte payloads now rejected. (4) PR #4201 Cordn — MLS-encrypted group messaging through coordinator servers (Cordn feeders), screens for create/join/manage; 51,174 LOC across 419 files; the test-plan checklist on the PR is left unticked. (5) NIP-92 imeta shipped and (6) WebView → NIP-07 browser signing gated by document scope (a departed-document message is discarded; Tor-required pages fail closed on proxy failure).
  • Citrine 3.1.1 NIP-42 AUTH signature-omission closes a forged-pubkey read (Sept 11, newsroom piece Oct 7 retrospective) — the relay's validateAuthEvent checked kind=22242, challenge match, relay-tag URL normalization, and created_at within 10 minutes, but it never verified the Schnorr signature. A client that built a kind:22242 with the right challenge, any pubkey, and no signature would be added to the connection's authenticated-pubkey set as that pubkey. The fix adds the missing event.verify() after the existing checks; on failure it returns CommandResult.invalid(event, "auth event signature verification failed"). Read-side AuthGate covers kind:4 (DMs), kind:1059 (gift wraps), and kind:30078 (application data) — a forged AUTH let a remote client name the owner's pubkey in a filter and pass AuthGate. Reach constraint: Citrine listens on 127.0.0.1:4869 by default, so a default install is reachable only from the device; the bypass matters only on remotes that listen on a wider address. NIP-70 protected-event writes already exempted localhost connections, so the write-side bypass was relevant only on remotes. Companion repairs in 3.1.1: per-connection subscription-id scope (NIP-01 wants ids independent per connection; previously global cache caused CLOSE-for-feed to cancel every socket's feed); NIP-45 COUNT no longer registers (was summing per-filter counts but living as a subscription); #p filter-tag typo (#p vs p); replaceable tie-breaks (NIP-01's lower-id-wins at equal timestamps now honored); exact ids/authors matching (no prefix matches); OK prefixes (blocked:/deleted:/duplicate:); NIP-11 built with Jackson (previously broken JSON on quote chars); NIP-04 dropped from supported_nips; CORS gains Access-Control-Allow-Headers; NIP-86 gains unbanpubkey + unallowpubkey and allowpubkey no longer removes a pubkey from the ban list as a side effect. Citrine 3.2.0 (Sept 18) bundles every 3.1.1 commit; updating to current contains the fix.
  • Nostr-WoT extension v0.8.11 "Account Archive and popup startup" (Oct 6 21:45 UTC, commit 989930a) + v0.8.12 "Archive import without a password" (Oct 6 22:22 UTC, commit 6976903) — 37 minutes apart. Account Archive (PR #39, merged 41 min before v0.8.11 tag) puts an encrypted local archive under the user's control: every original signed event synchronized across relays with checkpoints and encrypted local storage; concurrent multi-relay sync; resumable per-relay checkpoints; independent retries; per-account NIP-46 bunker ↔ user-side signer separation; bounded-wait popup-startup default (the extension no longer blocks startup on a check-and-verify loop). v0.8.12 removes the import-side password. Exported archives are encrypted but importable without re-entering a passphrase; signature + account-ownership verification is performed on import. Older encrypted exports remain supported. Practical implication: a switching user can move from one machine to another through a pass-phraseless archive without compromising the export-time signature chain; a tab/device-loss scenario uses the same flow. Privacy boundaries differ: exported archive files are intended for self-transfer; encrypted local storage on disk is still encrypted at rest with the in-app key. The archival design is the third Nostr-side archive-tier feature in 2026 (after Nostr Key Custody and Recovery's Sept 21 Amber backup-encryption HKDF split and last week's nostr-wot-extension discussion of full-account archive). Both browsers see the new packaging (nostr-wot-chrome-0.8.12.zip, nostr-wot-firefox-0.8.12.zip, nostr-wot-source-0.8.12.zip, SHA256SUMS).
  • nak 0.21.0 (Oct 3) — empty release notes; 17 commits — adds a new top-level relays subcommand that prints the NIP-65 relay list for a pubkey (one URL per line, with --inbox / --read and --outbox / --write narrowing flags). The compound case is a narrowing AND, not a union: --inbox --outbox returns only relays marked both ways; passing neither returns the whole list. This matters when the output feeds a publish step. The second change lives in parsePubKey: a second argument from is now passed, and any value beginning with ~ dispatches to resolvePetnamePath (the NIP-02 path-aware petname from PR #2472 + the ASCII-tightening commit 46f8e95 of Sept 20). ~erin/david/frank walks the follow list at each step, with the mixed form (e.g. ~erin/208ad.../charlie mixing pubkeys and petnames) supported under a 5-second sys.ResolvePetnamePath timeout. This is the first command-line tool with built-in path-resolvable petnames — every prior nak subcommand (event, fetch, encode, decode) called parsePubKey but only on the standalone pubkey shape. The change shows that NIP-02 has moved from spec (Sept 19 merge) to client UX (Oct 3 release) on the implementation lane.
  • Nostr Compass #43 (Oct 7) is the canonical event log for the central identity surfaces:
  • Ants v0.34.0 + v0.35.0 + v0.36.0 (Oct 1–6) — nested AND/OR queries across web and Android; compound constraints (author + event-type + date) tied to each branch; Android language filter at result-level (depends on relay support for NIP-50); web v0.6.0 adds zap / nutzap / public mute-list cards with amounts from published invoices or proofs (not settlement); Android 0.35.0 inline loads zap targets incl. addressable notes + profile-scoped media filters; Android 0.36.0 shares submitted searches as ants.sh links that expose the query text and omit local language-filter settings (results still depend on receiving client + relays).
  • Myco v0.10.0 permission-gated uploads (Oct 5) — Myco hosts small Nostr apps, shell selects Blossom servers and signs upload authorization without exposing the user's key to apps, returns confirmed file URLs + hashes. Uploads ≤ 16 MiB; consent comes from installation approval; no per-upload preview or EXIF stripping.
  • Marmot MDK v0.12.0 source-epoch attachment keys + bounded recovery (PR #2138 + #2141) — broader account-import discovery, separate inbox defaults; out-of-release master PR #2172 keeps eligible sends alive when a sibling fails; out-of-release PR #2154 + #2208 add per-account C sessions via NIP-46 + backports KEM dependency fix to 0.0.10 while retaining HPKE 0.7 compatibility (hosts encrypt exported signer credentials); history beyond 5 epochs can remain undecryptable (MDK still does not claim 100% recovery for an unproven gap); Goose harness + admin-gated group-profile tools + opaque draft-revision markers in master.
  • Iris Chat v2026.10.5.1 + v2026.10.6.1 + v2026.10.7 — message edits + edit history + deletion controls; author-authenticated mutation handling preserves deletion tombstones through replay and applies edits only after encrypted enqueue succeeds; edit limited to delivered, unexpired outgoing text without attachments; delete-for-everyone requests removal by compatible clients but cannot prove recipients erased their copies (the canonical NIP-09-deletion-explainer framing). v2026.10.6.1 starts chosen history transfer after verified local approval and preserves routed transfers when a direct link disappears; sign-in codes remain usable until cancellation; completion waits for observed authorization. v2026.10.7 older-account recovery repairs equivalent signed device lists while stripping retired encrypted labels; conflicting authorization still fails.
  • Scramble v0.7.9 still-sealed messages — messages that arrive sealed but ahead of the current group epoch survive restarts and replay when the epoch advances; KeyPackage identifiers are bound before relay exposure; recovery bounded by 256-envelope cap per group and a retention window.
  • Sonar v0.1-alpha.15.4 — chat catchup for active conversations, queue isolation and bounded push-token sharing; relay caps and queue overflow still limit catchup.
  • Chama v6.4.20 creator checks — full creator identity comparison when known, discard provisional link claims after failed loads, refuse ambiguous fresh legacy links; v6.4.19 waits for relay acknowledgement before on-chain locking. Cold-start wakes after swiping the app away regressed in v6.4.20.
  • Mostro v0.19.1 funded-hold-invoice protection + core PR #177 weighted imported reputation, PR #181 signed reputation validation (issuer trust left to callers); main-branch PR #1045 Cashu ecash discovery + order creation; main-branch PR #1047 taking orders and locking escrow; main-branch payer declarations let buyers exchange a fiat-account hash bound to the current trade (disabled by default, unavailable in Cashu mode; guessable account hashes do not prove identity); main-branch core PR #185 user-info restore-only request includes rating / review count / operating days / first-trade date.
  • Earthly v0.1.15 signed-byte recovery + draft-preserving rebase + native Chrome WebMCP browser-agent operations; confirmation tied to the exact preview and account revision; Chrome support experimental; later observation of a publication is distinct from an acknowledgement whose outcome was unknown.
  • nostream v3.2.0 — multiple-tag filter-query repair (PR #792, joined-row corruption); nip56.hideActionableReports operator policy (PR #788) — when enabled with NIP-56, an event-targeted report from a configured trusted moderator hides the event from REQ / COUNT; HAProxy blue/green relay stack with optional Redis fanout (PR #777). Existing sockets do not migrate during cutover; Redis unavailability can drop fanout messages.
  • Grain v0.8.0 — event serialization + replacement preflight checks; malformed subscription and count constraints now fail without widening queries; newly tracked late backfills use receipt time for purging; replacement preflight is not a durable commit.
  • Ditto v2.43.0 + v2.44.0 + v2.44.1 — file posts + tap-to-load 3D attachment viewer, event-native 3D objects, customizable Blobbi rooms and addressable videos, NSFW + blocked-term filtering in public feeds and search, NSFW repair in wallet flow + Lightning-address fallback; v2.44.1 reads notifications from account-declared inbox relays with per-relay paging. List edits use the latest observed event; withheld or stale relay copies remain a limit.
  • Haps v0.1.11 social-graph package discovery — signed immutable bootstrap discovery + publisher-maintained catalogs; search / bare-name installs require a publisher or release voucher from the user's social graph; muted and over-muted people are excluded; npub/package installs warn outside that graph; trusted warnings block installation. Signatures establish authorship, not safety; native programs and build recipes remain unsandboxed; package formats remain unstable.
  • fips2go 0.9.4 + 0.9.5 — fallback TTLs follow retries (20s → 3h tripling); cached mesh answers avoid parallel DNS; first denials release fallback while validation continues; resolver supports configured offline witness quorums with self-vouching excluded; pins + DNS retain precedence; desktop operators may disable plain probes with DNSSEC; default probing remains enabled; phone probing follows connectivity validation; denials do not authenticate targets.
  • Write Nostr v0.4.11 encrypted draft sync — draft revision committed only after every chunk and head record reach at least one common accepting relay; signers without NIP-44 retain local drafts but cannot use encrypted sync.
  • PsstPsst v26.10.1 small private groups — NIP-17 + NIP-59 gift-wrapped groups over per-recipient NIP-44; draft + optional — other clients may split rooms, any current member can publish membership changes.
  • Nsync v0.3.0 signed Nostr address announcements — Syncthing-based file sync; pairing binds each Nostr identity to a Syncthing device ID; relay announcements expose address + online-timing metadata, even with public-IP announcement disabled.
  • My Signet v0.18.2 per-app phone approval — requires imported Heartwood hardware-signer operator key + compatible firmware + a connected, unlocked inbox; possession of that phone key authorizes enabled requests without touching hardware; "Approve once" can permit the same event kind for ten minutes, while wallet pairing and login codes still require the hardware button.
  • Flotilla 1.12.0 screen sharing — web / Electron / native adapters incl. Android MediaProjection + iOS broadcast-extension path; preserves drafts when sending fails.
  • Blitz Wallet Android v0.7.16-pre3 native background handling — NIP-47 wallet requests; SQL-backed budget reservations, payment-hash claims, uncertain-payment markers shared with JavaScript; Firebase Cloud Messaging required.
  • Sidecar v1.15.6 → v1.15.9 — NIP-84 highlights from selected web text; composer changes align mention + quote tags, convert pasted identifiers, skip unanswered relays after 12 s; server-discovery repair finds Blossom servers through account-declared relays (including write-only relays), retries failed discovery next upload.
  • BuhoGO 1.10.0 — purchased NIP-05 identity names survive restarts and delayed relay replies through durable profile synchronization; activation continues after checkout closes; Android installations older than 1.9.1 use a different signing key — back up recovery phrases before uninstalling + reinstalling.
  • Staircase 0.1.20 MLS group-chat client — re-encrypts forwarded attachments; captions default off, no original author / chat / reply metadata; folders stay local unless multi-device sync encrypts them; new accounts use cordn.feeds.relay.tools.
  • KithMoot 0.6.62 queued-message retries oldest-first using their original signed events; never-sent messages remain editable / deletable; possibly delivered messages can only leave the local pending list; v0.6.63-prep adds VMLS rooms on user-operated Bothy servers with Nostr invitations and signer-authorized access grants; compromised-device removal holds new sends/joins until witnessed, revokes keeper-owned grants without grace; self-destruct defaults on when an end is chosen.
  • Nostr Vault 2.7.2 — marketplace listings, polls, article highlights, nostrconnect signer pairing; cross-device DM catchup + signature checks; NIP-29 relay groups removed.
  • Private Provider 0.7.5 — Pi in-app agent requests issues / comments / PRs with explicit command approval + Amber signatures; pinned Blossom + Zapstore targets in a committed manifest; rejects tag/commit mismatches; wallet recovery unavailable.
  • soyLI v0.25.0 — uses creators' own NIP-34 Git repos, checks signed refs and clone reachability on resume; avoids duplicate repositories; earlier changes accept NIP-22 replies with extra mentions; relays handshake-timeout race no longer terminates the web process.
  • Nostr Double Ratchet TS v0.0.176 durable journal rows — private control messages share a durable journal row with advanced receiver state; encrypted messaging library retains them until the application's durable acknowledgement, enabling replay after failure or restart. Callbacks must be idempotent and validate authorized siblings; newly ratcheted AppKeys labels do not retroactively protect older records.
  • nostr-social-graph v2.0.3 owner-bound controls — private-contact edits persist before notification, with fieldwise clocks and exact pending acknowledgements; social-graph library retains rejected handoffs for bounded retries.
  • nostr-pubsub TS v0.5.14 + Rust FIPS package v0.5.20 — ordinary subscriptions start immediately, followed by bounded NIP-77 inventory reconciliation; Rust FIPS package preserves pending replies and subscriptions when an inbound peer becomes a discovered outgoing peer, reusing its established stream.
  • FIPS runtime v0.0.53 + v0.0.56 — missing routed sessions recover through authenticated discovery; nonforwarding browser nodes restricted to advertising their own identity + refresh cached routing announcements after a fresh authenticated responder carrier.
  • Hashtree TS runtime v0.5.19 — remote blocks retain peer-readable provenance after restart through durable verified-block sharing; persists hash-verified bytes and authorization before returning.
  • Elisym commerce 0.9.0 + merchant-node 0.9.1 + MCP 0.32.1 — webhook signature and freshness verification; durable paid-order webhook outbox; receipts travel over Nostr; fulfilment + event-ID deduplication remain merchant-owned; payment completion does not confirm delivery.
  • [1-of-12 Amber 6.6.x release cadence] is preserved with v6.6.7 (Oct 5) keeping the 6.6.2 → 6.6.7 six-week streak (Aug 31 → Oct 5). The seven weekly Identity surfaces this fortnight: Amber 6.6.6 → 6.6.7 (Sept 28 → Oct 5); Citrine 3.1.1 → 3.2.0 (Sept 11 → Sept 18); Amethyst 1.16.0 → 1.17.0 (Sept 17 → Oct 5); nostr-wot-extension v0.8.9 → v0.8.12 (Oct 1 → Oct 6); Nostr Compass #41 → #42 → #43 (Sept 23 → Sept 30 → Oct 7); the newsroom's per-day short post cadence (4–6 min each); nak 0.20.7 → 0.21.0 (Sept 27 → Oct 3, 6-day cycle). The most active Identity-week in 2026 by raw file count.
  • NIPs spec cluster (Oct 1 – Oct 7): PRs merged in this window — #2494 NIP-92 imeta (alexgleason, Oct 5), #2495 (Aspie96, solves #2482), #2498 EXTRA on CLOSED/OK (arthurfranca), #2449 Static Website curation sets in NIP-51 (arthurfranca), #2229 NIP-DB window.nostrdb (hzrd149, merges NIP-43's HTTP realm into the browser-side DB — a 4-month open proposal reaches consensus on Oct 8), #2496 NIP-97 Persisted Delivery Confirmation (Rogerclaw1337), #556 NIP-57 Zap Proofs partial receipts (Egge21M, a 2026 re-open of NIP-57 reliability that adds a "complete zap receipt" companion event when partial state is observed), #2428 NIP-171 Epoch-Ticketed Private Groups (motorina0, an ML-KEM-protected group-epoch secret-rotation scheme that's the second post-quantum Nostr group primitive after Marmot MDK 0.0.10's HPKE 0.7 KEM), #2303 NIP-5D nostr web applets (dskvr, the spec that frames napplet / soyLI / Myco as the same app delivery surface), #2462 slash commands (staab), #2437 NIP-94 file encryption (alexgleason, closes the public-file plaintext gap that NIP-94 itself left for a year), #1862 NIP-5F Unix Domain Socket remote signing (ChristianChiarulli, ~6-month merge), #2112 NIP-47 Arkade + non-BOLT11 (LastDegenBtc), #2491 NIP-FC Financial Cashtags (fernandolguevara). The narrative thread: spec-layer correctness is moving toward author-side signing (NIP-5F, NIP-94 encryption, NIP-47 Arkade) and away from relay-side metadata (NIP-86 black/whitelist, NIP-65 push-relay boundaries). The PGP-style "trust-the-key-holder" question is being answered with "trust-the-key-holder-as-it-signs" — every new NIP emphasizes the signature chain rather than a relay-operator-policy.
  • Nostr-WoT oracle silent 21 days post-v0.3.1 (Sep 20) — Sep 20 → Oct 11, zero commits / issues / PRs. The v0.3.0 + v0.3.1 cluster is still the production oracle surface: GET /mutes paginated public mute lists, GET /trust follow distance + explicit mute evidence (no combined score), GET /ready ingestion status. The W41 oracle posture is "shipped and stable" — same reading as last week. Three-week silence for this repo is not unusual: oracle v0.2.x shipped the score-based endpoint, v0.3.0 deprecated the score; the next refactor will be when the score-deprecation timeline is set, not before. The oracle surface maps onto Proof of Personhood and Sybil Resistance's reputation-evidence question: the oracle's muted / trusted / ready endpoints are the canonical sampling answer to "who do I trust?" — a complementary surface to World ID's biometric, Idena's synchronous validation, and Rarimo's ZK.
  • kind:10203 (PQ identity-key attestation, ML-KEM-1024 + ML-DSA-87) flat at 26 for 21 days — the Sept 23 stair-step (24 → 26, two new entries same-second on 2026-09-23 19:40:27 UTC) has held through Sept 30, Oct 4, and now Oct 11. The trigger-event observability model (W39) still holds: release-day stair-step is the GnuPG-Nostr-PQC adoption curve. GnuPG 2.5.25 still not shipped — the master branch has more Oct activity than usual but no release tag: Oct 9 1f03937 + 3add2ab + 76b4752 simplify the scd_getpin call-chain (PIN-callback removal in agent + scd + scd:piv PIN-Policy verification); Oct 6 eaa1695 Japanese translation update; Oct 5 33d1810 fixes a TPM2d Esys_TRSess_SetAttributes use; Oct 1 7eea4e5 + 6bb0b45 minor compiler-warning / macOS cleanup. The branch is alive but shipping housekeeping, not a release. Wire-spec stable on nostr-wot/nostr-wot-extension/nips/02-pq-key-attestation.md: v=nip-pqc/v1, ML-KEM-1024 + ML-DSA-87 (CNSA 2.0 Category 5, in line with Australia's ISM 2030 withdrawal of ML-KEM-768 / ML-DSA-65), PoP via ML-DSA counter-signature over pop_message = "nip-pqc/v1/pop:" || pubkey_hex || ":" || kem_pk_b64 || ":" || dsa_pk_b64. Quantakrypto's Obelisk demo continues to test: attestation is ~12,200 bytes, PQ-DM is ~4,600 bytes on the wire vs 1,700 for the classic equivalent (2.7×), of which 1,568 bytes is the ML-KEM ciphertext itself; one relay in the four-relay test set rejects the attestation on size, three accept — enough for discovery, a real constraint the spec has to address.
  • NIP #2434 (PQ identity keys, ConorClancy89, Aug 11) now 61 days frozen (up from 54 last week, 47, 40, 33, 26, 19, 12 in successive weeks — at Aug 11 → Sep 30 was 50, at Sep 30 → Oct 11 = +11d, cumulative = 61 days). The fiatjaf comment on Aug 11 still stands: "Here's what I think: https://github.com/nbd-wtf/nostr-tools/pull/541#issuecomment-5252150386". At this point the spec's center has been stable for almost two months; the practical innovation continues to live at the implementation layer (Nostr-WoT v0.4.0 shipped production PQ identity keys on Aug 16; Obelisk demo showed the wire-cost tradeoff; QuantaKrypto's reference impl wires @noble/post-quantum ML-KEM-768 alongside nostr-tools with HKDF salt nip44-hybrid-v1). PR #2434 is now the longest gap between a NIP proposal's opening and any fiatjaf comment in 2026 — the previous long was 47 days on the Aug 16 Identity weekly update with kind:10203 between Aug 31 → Sept 23 stair-step freeze. The signal: fiatjaf's review window for a NIP-86-scale PR is normally 1–3 weeks; PR #2434 has been on the open-PR pile for nearly two months with the fiatjaf pointer to a nostr-tools PR comment serving as its only author-side review.
  • Out-of-scene — World ID 4.0, Rarimo, Idena unchanged at the spec level; kind:30385 drift crosses the 5-month mark (PR #2418 opens Jul 18, last comment Sep 4 = 67 days, the W41 reading showing 75+ days-since-PR-open at the close of W41 → 89 days as of Oct 11; the kind:30385 collision is now becoming a de-facto standard by staleness); the Amber 6.6.7 newsroom piece is the canonical writeup of the relay-health-tracker bug class; the Citrine 3.1.1 newsroom piece is the canonical writeup of the missing-signature-check bug class; the NIP-92 newsroom piece is the canonical writeup of the spec-implementation-explainer cycle; the NIP-05-without-trust newsroom piece is the canonical writeup of the cached badge as identity anchor anti-pattern; the NIP-57 zap-receipt validation newsroom piece is the canonical writeup of the eight-step verification sequence (a kind:9735 receipt is a server-signed claim, not trustless proof that Lightning settled, with all eight NIP-57 binding checks enumerated); the NIP-65 relay-list usage newsroom piece is the canonical writeup of NIP-65 routing direction confusion (write = where your own events go, read = where others send you events that tag you, the unmarked r tag is both — and you must publish a kind:10002 to the old pubkey's write relays as well as to its read relays).

The Week in Detail

NIP-92: imeta tags for kind:0 profile pictures and banners

NIP-92 was extended on Oct 5 with a profile-specific section. PR #2494 (alexgleason) adds 35 lines to NIP-92 and one cross-reference to NIP-24; NIP-92 already described how a note could carry inline media metadata through imeta tags, but a profile image could only supply its primary URL inside the JSON content of the kind:0 event. The new section makes the matching canonical: a kind:0 metadata event may attach imeta tags to its picture and banner URLs through an exact-equality rule (the imeta tag's url is trimmed of whitespace and compared for character-for-character equality with the value of picture or banner). Whitespace-trimmed URL equality is the entire match rule — a different query string, a redirected destination, or a URL rewritten in any other way does not match.

The spec example: a profile picture carries MIME type, SHA-256 hash, dimensions, blurhash, and fallback URL; the banner carries MIME type, hash, and dimensions. NIP-92 inherits any field defined by NIP-94, so a publisher can additionally provide alt, size, thumbnails, or other file metadata. Only url plus at least one other field is required for an imeta tag; the rest remain optional.

The most visible additions are fallback (clients try declared fallback URLs when the primary profile image fails to load) and blurhash (the compact placeholder while the image loads). dim lets a layout reserve the correct aspect ratio before downloading. alt gives an accessibility description. x can carry the file's SHA-256 hash; clients that want integrity still have to verify the hash for it to provide a check. The normative language is mostly MAY and SHOULD because the profile image is fundamentally a hint — NIP-92 does not upload a mirror, prove that a fallback will stay online, or force a client to use any field.

The key maintenance rule: kind:0 is replaceable, so a newer event from the same public key supersedes the older profile. Publishing a new kind:0 should carry over imeta tags for pictures and banners that have not changed and drop tags for images no longer in use. Without that rule, editing a display name in a client that understands profile media metadata could accidentally erase fallbacks and alt text. Carrying every old tag forward would be worse, because it would leave signed metadata for images the profile no longer references.

The implementation evidence: Amethyst PR #4320 merged roughly two hours after NIP-92 began allowing imeta tags for kind:0 picture and banner. A new ProfileImageMetas class matches an imeta tag to a profile image only when the URLs are equal after trimming whitespace. Avatars and banners can now show a blurhash placeholder while loading and try the listed fallback URLs if the primary one fails. When a user edits their profile, Amethyst keeps the metadata for an image that did not change and drops it for an image that was replaced or removed. A 291-line test file covers these cases. PR text notes that Ditto and Armada already implement the rendering side; the submitter's claim is unattested by a compatibility registry.

NIP-5F: remote signing via Unix Domain Sockets

PR #1862 NIP-5F "Remote Signing via Unix Domain Sockets" merged on Oct 6 — about six months after its original March 2026 opening by ChristianChiarulli. The spec defines a URI scheme nostr+unix:// that targets a local socket rather than a relay. The structural value: a local signer can connect to a local client without creating a TCP/WS relay channel, paying for relay bandwidth, or opening a remote-signer port on the network.

The companion surface is the permission-to-socket path. A sandboxed app learns where the user's local bunker listens and joins the same OS sandbox through filesystem ACLs — seatbelt / Landlock / polkit ACLs — rather than through network reachability. The two published JavaScript bunker implementations in the Remote Signing note (keep-core/keep-bunker, njalla/nostr-nsecbunker) already accept relay URLs in their connection-string parsers; NIP-5F is the form-fill for the case where the relay list is empty or unwanted.

The cryptographic surface is unchanged: NIP-46's response-and-request event flow applies over the socket transport. The signing semantics, the connect / sign_event / nip44_encrypt / nip44_decrypt / get_public_key method set, and the bunker-responder authority model are identical to the relay case — only the connection transport changes. The bunker can be reached by a desktop client whose user wishes to keep all material in the OS user namespace (e.g., nostr+unix:///run/user/1000/my-bunker.sock); the bunker can also be reached by a peer app on the same device sharing a sandbox through an explicit Allow-ACL.

NIP-5F is the year's first NIP-46 cousin that is both cryptographic and not networked. It complements the existing nostrconnect remote-signer model rather than replacing it: relay-based NIP-46 remains the right answer when the signer and the client are on different machines, and a Unix-domain-socket NIP-5F is the right answer when they are on the same machine and the network round trip is either undesirable or impossible (offline).

The newsroom did not publish a dedicated NIP-5F piece this week (the schedule's coverage of NIP-46 was already extensive), but the PR merges cleanly with the existing @nostr-wot/bunker 0.2.0 ESM-responder-side package published on Oct 5 (covered in the Thursday WoT update) — that library's NostrConnect surface can be pointed at a nostr+unix:// URI in addition to the relay-based case.

Amber 6.6.7 — gives dead relays a second chance after fifteen minutes

Amber 6.6.7 shipped on Oct 5 with eight commits and twenty-three files separating it from 6.6.6. The reported symptom was relays staying disconnected until the app was force closed. The diff names two independent causes — both in the retry accounting rather than the socket layer:

Cause 1: RelayHealthTracker.isDead was a count-only threshold with no temporal expiry. In 6.6.6, MAX_RECONNECT_ATTEMPTS = 10 failures marked a relay dead; nothing except an OS network change, a successful connection, or a manual reconnect reset the tracker. The streak survived: a Wi-Fi network that lost and regained internet on the same SSID, a weak cell signal that recovered, a relay-side outage that cleared. None of those cases is a default-network change, so the streak remained, and every relay could be marked dead while the device stayed on one apparently healthy network.

The fix introduces DEAD_COOLDOWN_MS = 15 * 60 * 1000L. isDead now returns true only when failures > MAX_RECONNECT_ATTEMPTS && clock() - lastFailureAt < DEAD_COOLDOWN_MS. After fifteen minutes the relay is eligible again. The threshold is unchanged — what changed is that exceeding it is a timed penalty rather than a verdict. A clock function is injected so the expiry can be tested without Thread.sleep.

Cause 2: onCannotConnect and onDisconnected both called scheduleReconnect. Quartz, the library driving the relay pool, reports a failed dial as onCannotConnect followed by onDisconnected. Both handlers called the same scheduleReconnect, which recorded a failure. The streak advanced by two per failed dial. The documented threshold of ten was reached after five. The comment added in 6.6.7 states both halves of the problem: counting both callbacks halved the real threshold, and a plain server-side close is not a connection failure at all.

The fix splits the one function in two. recordFailureAndScheduleReconnect records a failure and is called only from onCannotConnect. scheduleReconnect now checks isDead and reconnects without recording anything, which is what onDisconnected was attempting. A plain server-side close (the relay terminates the WebSocket cleanly) is now neither a dial failure nor a reason to advance the dead counter.

The release maintains the four-week Amber cadence: 6.6.1 (Sept 4), 6.6.2 + 6.6.3 (Sept 9), 6.6.4 (Sept 14), 6.6.5 (Sept 21), 6.6.6 (Sept 28 / F-Droid Oct 1), 6.6.7 (Oct 5). Six releases in six weeks. The amber dev plan from July 2026 (greenart7c3/Amber#milestones) flagged the relay-health-tracker refactor as W41 priority; it closed cleanly.

Amethyst 1.17.0 — Cordn and several updates

Amethyst 1.17.0 shipped on Oct 5, the largest in 2026 by commit count. 1,253 commits since 1.16.0; 176 pull requests listed in the release notes. The release page carries Android packages in F-Droid and Google Play flavors, desktop builds for Linux, macOS, and Windows, and separate amy and geode packages. Most PRs are refactoring and translations; six are identity-bearing:

(1) PR #4238: relays running strfry 1.1.1 with a kind allowlist answer CLOSED to any REQ whose filter names a kind they do not serve. Amethyst asks for gift wraps with a single filter covering kinds 1059 and 21059; the relay refused 21059; Amethyst treated the CLOSED as a refusal of the entire filter set; every gift wrap was lost. For an account whose kind:10050 DM relay was that relay, no NIP-17 direct message arrived and neither did any White Noise invite. The Welcome path failed without logging, so nothing pointed at the cause. The fix teaches the relay pool to read the refusal. When a CLOSED reason names a kind (kind not allowed: 21059), Amethyst records it for that relay and strips the kind from every request it builds for that relay, both on change and on reconnect. A filter left with no kinds at all is dropped rather than sent empty (an empty kinds list would ask for every kind).

(2) PR #4239 (re-landed as #4242): the same relay also closes any request with four or more filters, and it does not advertise a max_filters value in its NIP-11 document. Marmot group messages use one filter per group, so an account in four or more groups there loaded no group messages at all. The fix learns the cap from the refusal: if four filters were refused, the limit is at most three. It then merges filters that differ in exactly one set of values into one filter with the union of those values. Filters with limit are never merged (a per-filter limit and a limit over the union are different requests). Filters that differ in two fields are never merged (the union would match combinations neither filter asked for). If a request still does not fit, Amethyst sends the first filters up to the cap and logs one warning. The pull request states that some account subscriptions can still be trimmed when a capped relay is the account's only outbox relay, and leaves a full fix for a separate change.

(3) PR #4320: NIP-92 ProfileImageMetas (see above). Merged within ~2 h of the NIP-92 spec landing, with a 291-line test file.

(4) PR #4209: backup-key screen redesign. The nsec is shown as three numbered rows of uppercase groups, masked until tapped, so it can be copied onto paper. Bech32 is case-insensitive, and login on Android, desktop, and amy now accepts a key typed back in uppercase with dashes, spaces, or line breaks. Before, an uppercase NSEC1 was rejected. The password-protected NIP-49 copy now asks for the password twice and requires at least 12 characters when creating a new ncryptsec — a creation policy, since NIP-49 sets no minimum and decryption must accept passwords other clients allowed. The diff fixes the NIP-49 code itself: decryption ignored the authentication result and treated a decrypted key as wrong if none of its bytes was positive, which rejected a valid key whose 32 bytes all had the high bit set; it now checks the Poly1305 tag. Encryption also ignored its result, so a failure could have produced an ncryptsec that no password opens; it now throws. Encrypted payloads that are not exactly 48 bytes are now rejected.

(5) PR #4201 Cordn: MLS-encrypted group messaging through coordinator servers. Group create/join/manage screens + an MLS runtime. The largest single change in the release at 51,174 added lines across 419 files. The pull request's test-plan checklist, including its three interop suites, was left unticked — the developer merged without ticking the interop boxes, so cross-implementation compatibility is not established by this merge even though the code is live.

(6) WebView → NIP-07 browser signing gated by document scope: a departed-document message is discarded; Tor-required pages fail closed on proxy failure; later merged PR #4352 limits browser signing prompts to 120 s and always asks before signing reports; PR #4338 limits encrypted-message history paging to the visible account and prioritizes its DM relay list; PR #4335 repairs relay-hint parsing (rejects malformed URLs, stops indexing encrypted emoji-pack contents, stops linking anonymous or private zap sender keys); PR #4342 — the amy command-line client adds posting / threads / deletion while restricting group content to its host relay and refusing group reposts or quotes; paired clients using NIP-46 bypass the unpaired-client rate limiter; unpaired traffic remains limited to 10 requests per author and 100 combined per minute.

Citrine 3.1.1 — NIP-42 AUTH signature omission

Citrine 3.1.1 shipped on Sept 11 but the newsroom's retrospective on Oct 7 is the canonical writeup. The structural bug: validateAuthEvent checked that the event was kind 22242, that it carried a challenge and a relay tag, that the challenge matched the one sent on that connection, that the relay URL normalized, and that created_at was within ten minutes of the current time. Those are the checks NIP-42 lists. If they passed, the handler added event.pubKey to the connection's set of authenticated users.

Nothing in that path verified the signature. The challenge is sent to whoever opens the connection, so a client could build a kind 22242 event with the right challenge, put any pubkey in it, leave the signature invalid, and be treated as that pubkey for the rest of the connection. 3.1.1 adds the missing step after the existing checks:

// NIP-42: an AUTH event must carry a valid signature, otherwise any
// client could authenticate as any pubkey.
if (!event.verify()) {
    connection?.send(CommandResult.invalid(event, "auth event signature verification failed").toJson())
    return
}

The commit message names what the authenticated set protected: protected-event writes and private-kind reads. On the read side, AuthGate refuses filters for five kinds unless one of the connection's authenticated pubkeys is an author in the filter or appears in its #p values. The five include kind 4 (direct messages), kind 1059 (gift wraps), and kind 30078 (application data). With a forged AUTH, a client could name the owner's pubkey and pass that gate.

How far that reached depends on configuration. Citrine listens on 127.0.0.1:4869 by default, so on a default install the only clients that can open a connection are the ones on the same device. The listening address is a setting, and a relay configured to listen elsewhere was open to the same forged AUTH from anything that could reach it. On the write side, the NIP-70 protected-event check already exempted connections from localhost, so the bypass there mattered only for remote connections.

The companion repairs in 3.1.1 are larger than the AUTH fix:

  • Subscription ids were global. NIP-01 says relays must manage subscription ids independently for each WebSocket connection. Citrine kept all subscriptions in one cache keyed by the id the client sent. A CLOSE for "feed" on one socket cancelled every connection's "feed", and a new REQ with the same id replaced it. The cache key is now the connection name and the id together; the id on the wire is still the one the client chose.
  • COUNT was a REQ. NIP-45 says the filters in a COUNT are OR'd and aggregated into a single count result. In 3.1.0 a COUNT went through the same path as a REQ: one count message per filter, then an EOSE, and the subscription stayed registered. It received live events later. Version 3.1.1 gives COUNT its own path. It is never registered, it neither replaces a REQ with the same id nor receives live events, and it sends one COUNT message with no EOSE. The total is the sum of the per-filter counts, so an event that matches two filters in one request is counted twice.
  • #p filter tag typo. For filters with no kinds, AuthGate looked for receivers under the key "#p", but filter tags are stored without the #. The kinds branch already used "p"; this one now does too.
  • Replaceable tie-breaks. NIP-01 says that between replaceable events with the same timestamp, the one with the lowest id is retained. Citrine rejected any incoming event when a stored one had an equal or later created_at, so the first to arrive won. Both queries now let an incoming event with an equal timestamp and a lower id replace the stored one.
  • Exact ids and authors. The in-memory filter still accepted prefix matches, which the SQL path and NIP-01 do not. Only exact values match now.
  • OK prefixes. Policy rejections now use blocked: rather than invalid:, a deleted event gets deleted:, and an older replaceable gets duplicate:.
  • NIP-11. The relay information document was built by string interpolation, so a relay name or description containing a quote produced invalid JSON. It is now built with Jackson. NIP-04 is no longer advertised in supported_nips, and the CORS headers now include Access-Control-Allow-Headers.
  • NIP-86. unbanpubkey and unallowpubkey are added, and allowpubkey no longer removes a pubkey from the ban list as a side effect.

Version 3.1.1 is a published release with six Android packages and a signed checksum manifest. The commit message reports assembleDebug, ktlintCheck, test, and lintDebug passing and 24 behavioral checks run on a device; the diff itself adds no test files. Citrine 3.2.0 (Sept 18) bundles every 3.1.1 commit, so updating to the current release includes the fix. The newsroom piece notes: none of this establishes which version a given phone is running, and anyone relying on Citrine for direct messages should check.

Nostr-WoT extension v0.8.11 + v0.8.12 — Account Archive + passwordless import

Nostr-WoT extension v0.8.11 shipped Oct 6 21:45 UTC (commit 989930a), followed 37 minutes later by v0.8.12 (Oct 6 22:22 UTC, commit 6976903). PR #39 (Account Archive) merged 41 minutes before v0.8.11 was tagged.

Account Archive (v0.8.11) synchronizes original signed events across multiple relays, with concurrent multi-relay sync, resumable per-relay checkpoints, independent retries, and encrypted local storage. Per-account NIP-46 bunker ↔ user-side signer separation is preserved. The bounded-wait popup-startup default means the extension no longer blocks startup on a check-and-verify loop.

v0.8.12 (passwordless import) removes the import-side password. Exported archives are encrypted at export time but importable without re-entering a passphrase; signature + account-ownership verification is performed on import. Older encrypted exports remain supported.

The practical implication: a switching user can move from one machine to another through a pass-phraseless archive without compromising the export-time signature chain; a tab/device-loss scenario uses the same flow. Privacy boundaries differ in the two storage states: an exported archive file is intended for self-transfer and carries the risk of leaving the device; encrypted local storage on disk is still encrypted at rest with the in-app key. The push toward passwordless import is part of the org's v0.8.4 + v0.8.7 + v0.8.8 + v0.8.9 + v0.8.10 + v0.8.11 + v0.8.12 13-day streak (Sept 27 → Oct 6) — themes → NIP-98 auth → UX → zaps → legacy login → Account Archive → passwordless import.

The Week-41 nostr-wot-extension surface now totals +200 commits since v0.5.2 (the AMO disable) over the v0.6.0 → v0.8.12 stretch. The release-pattern reading: the extension has cleared the year-long SPEC-bottleneck and is now shipping UX features on a 1-day-to-1-week cadence. The next visible gap is server-side tooling: @nostr-wot/bunker 0.2.0 shipped Oct 5 as the org's first responder-side NIP-46 package, and v0.8.12's archive import points at the natural third surface — a host application that can ingest a passwordless archive for users whose primary client moved devices.

nak 0.21.0 — relay lists and petname paths

nak 0.21.0 shipped Oct 3 with empty release notes; the seventeen commits since v0.20.7 are the only account of what changed. Two additions stand out.

55707c26 adds relays.go, a 58-line file registering a new top-level subcommand. Its usage string: prints the nip65 relays for a given pubkey, one relay per line. It takes a pubkey as an argument or on standard input and writes one relay URL per line. Two flags narrow the output, each aliased to the other half of the NIP-65 vocabulary: --inbox / --read (only relays marked inbox/read) and --outbox / --write (only relays marked outbox/write). The combined case is not a union — --inbox --outbox returns only relays serving both directions, which under NIP-65 is what an unmarked r tag produces. Passing neither prints the whole list. This is the boring case that catches bugs: a script that does nak relays <pubkey> --outbox | grep ... will fail at the bare list level when the author advertises a single unmarked relay; the --outbox flag produces nothing.

NIP-02 petname paths arrive in two stages, and the second corrects the first. 4011cba5 changes the shared parser: parsePubKey takes a second argument, a pubkey to resolve from, and dispatches anything beginning with a tilde to a new resolvePetnamePath. That helper calls sys.ResolvePetnamePath under a five-second timeout. Its doc comment states the mechanism and gives the mixed form NIP-02 allows: the path ~erin/david/frank walks the follow list of each name in turn. ASCII-only is enforced by 46f8e95 (Sept 20). This is the first command-line tool with built-in path-resolvable petnames — every prior nak subcommand called parsePubKey but only on the standalone pubkey shape.

The directive-time narrative: NIP-02 PR #2472 (fiatjaf, merged Sep 19) and the ASCII-tightening commit (Sep 20) have moved into the canonical Nostr tool on a 13-day cycle. A cli that can resolve ~erin/david/frank to a pubkey is also a nak subcommand with a parser call that does the path walk on behalf of every other subcommand. The structural argument is the same as last week's Nostr Compass #42 retrospective made: petnames resolve through trust paths, and the nak CLI is the first surface where a user types a path and gets a pubkey back rather than manually walking the follow list.

Compass #43 — the canonical event log

Nostr Compass #43 (Oct 7) is the canonical event log for this week's identity-bearing releases. The headline framing is structural: Ants keeps compound search constraints aligned. Myco, a host for small Nostr apps, adds permission-gated uploads. Marmot MDK, an encrypted messaging toolkit, improves account discovery and attachment recovery. Iris Chat adds message editing, and Sidecar publishes web highlights. The profile tutorial explains signatures and separately verified internet identifiers. The structural thread for the week — every Compass #43 entry either adds a permission boundary (Myco Blossom uploads, Marmot MDK source-epoch key, Nostr Double Ratchet TS durable journal, Mostro signed reputation, Sidecar server-discovery through declared relays, Flotilla screen sharing through adapter adapters, Blitz Wallet NIP-47 background handling, My Signet per-app phone approval, Nsync signed address announcements, BuhoGO NIP-05 durable name sync) or reduces a derivation surface (Amethyst backup-key NIP-49 Poly1305, Amethyst profile-imeta replaceable-event preservation, NIPs NIP-94 file encryption, Marmot MDK source-epoch attachment keys, Scramble KeyPackage bound before exposure, Scramble still-sealed message replay, Myco Blossom 16 MiB cap, Nostr Double Ratchet TS ratcheted AppKeys label non-retroactivity, Mostro issuer-trust-left-to-callers, Chama creator-identity comparison with provisional discard, fips2go cached mesh answers without parallel DNS, fips2go self-vouching exclusion in witness quorums, Haps social-graph bootstrapped publisher catalogs).

The NIP-deep-dive this issue lands on NIP-05 (kind:0 profile → _@domain lookup → reverse kind:0 → both-sides-checked mapping) and NIP-24 (the optional fields a kind:0 profile document can carry). The example event under dissection is the Oct 6 kind:0 retrieved from relay.damus.io for the calavera@primal.net profile. The structural reading: a Nostr identity has one cryptographic anchor (the pubkey) and as many displayable associations as the user chooses to encode (NIP-05 identifier, NIP-24 display name, NIP-25 reactions, NIP-32 labels, NIP-39 external identities). The week is about keeping those associations undamaged and properly verified.

Out-of-spec activities

GnuPG master post-2.5.24 housekeeping (Oct 1 → Oct 9) — Oct 9 1f03937 + 3add2ab + 76b4752 simplify the scd_getpin call-chain (PIN-callback removal in agent + scd + scd:piv PIN-Policy verification); Oct 6 eaa1695 Japanese translation update; Oct 5 33d1810 fixes a TPM2d Esys_TRSess_SetAttributes use; Oct 1 7eea4e5 + 6bb0b45 minor compiler-warning / macOS cleanup. The 2.5.25 NEWS entry remains empty at the W41 close (the T8466 tracker note from Sept 22 still says "TBD"). The 2.5.24 → 2.5.25 cadence is now ~2.5 months (2.5.24 Aug 31 → 2.5.25 expected late October or early November) and the release would be the third "housekeeping" since the 2.5 series gained ML-KEM (Jan 2026). PQC-OpenPGP remains a single-vendor story in production: GnuPG/LibrePGP is incompatible with Sequoia-PGP / OpenPGP.js / Proton Mail; Sequoia-PGP's sq 1.4.1 (Sep 14) continues the openPGP.js 7-commit bug-fix streak (Sep 20 → Oct 7) without a 2.5.25 counterweight.

The kind:30385 collision (NIP-XX "Trusted Relay Assertions", PR #2418) now crosses 89 days at W41 close (PR opened Jul 18, 2026; last comment Aug 22 by boyroywax + alexgleason ~40 days ago as of Oct 4 → 49 days as of Oct 11). The reference implementation boyroywax/Letdown2491 continues to ship events on nos.lol under the disputed kind (algorithm=v0.3.0). The natural resolution is a new kind number, requiring a fork + event re-issue.

The seven-Identity-week summary uses a different reading from W40. In W40, the three-layer identity-correction narrative was [implementation, newsroom explainer, GnuPG housekeeping]. In W41, the narrative is [spec-layer hardening, client/signer operability, relay-signature correctness]. The mid-w40 turning point was NIPs PR #2494 + Amethyst #4320 merged ~2h apart. The mid-w41 turning point is NIP-5F merging after ~6 months + NIPs PR #2428 NIP-171 (Epoch-Ticketed Private Groups) adding a second PQ-Nostr group primitive after Marmot MDK's HPKE 0.7 dependency. The weekly Identity layer is converging on a signature-first model where the diff between an honest signer and a malicious one is the diff between a verified and an unverified Schnorr, and where the spec layer names what every signer — local Unix-socket, AMOS extension, Android App, Fedimint guard — must do the same way.

Identity Layer — 7-day forward watchlist

Trigger Source Expected What to verify
GnuPG 2.5.25 release git log gpg/gnupg master stable early Nov 2026 Whether 2.5.25 carries a further RFC 9980 fix; stair-step model predicts another +2 same-day on kind:10203 if it does
NIP #2434 first fiatjaf-side review GitHub PR #2434 history next 30 d Whether the Aug 11 comment portends a spec PR or a more general direction
Marmot MDK 0.12.x (post-0.12.0) marmot-protocol/mdk master Oct 18 (next release) Whether KEM dependency fix PR #2208 is in the release, HPKE 0.7 compatibility retained
PR #2418 (Trusted Relay Assertions, kind:30385) resolution nostr-protocol/nips PR #2418 history next 60 d Whether fork-or-revise is decided or staleness makes the collision de facto
Cordn interop test plan ticked vitorpamplona/amethyst #4201 next 30 d Whether the three interop suites (Amethyst ↔ Vector ↔ Armada) are ticked
Citrine 4.x with NIP-42 signature verification standardized greenart7c3/Citrine master Oct 25 (next minor) Whether the missing verify() call makes it into a documented extension point
nak 0.22 / 0.23 with NIP-05 reverse-lookup CLI fiatjaf/nak master Oct 25 (next minor) Whether a --reverse-nip05 flag appears alongside the path-aware petname
Quantakrypto Obelisk multi-relay size-cap demo quantakrypto.com/blog/obelisk Oct 18 Whether 4/4 relays now accept the attestation or if 1/4 still rejects on size
Quantakrypto PQ-Nostr reference impl v0.2 gleezapp/post-quantum-nostr master Oct 25 (post-IACR CHES 2026) Whether a unified @noble/post-quantum salt/info path is published
Nostr Compass #44 (Oct 14) Nostr Compass archive Oct 14 Canonical event log of Oct 8–14
IACR CHES 2026 (Oct 11–15) IACR proceedings ongoing Whether any PQ-Nostr or PQ-OpenPGP paper debuts
PQC FIPS 206 silence (36 d @ Oct 4 → 43 d @ Oct 11) NIST CSRC next announcement Whether FN-DSA IPD exits holding pattern

Evidence at a glance

Surface Version Date Headline structural fact Source
NIPs #2494 2026-10-05 NIP-92 imeta tags for kind:0 picture + banner merged PR #2494
NIPs #1862 2026-10-06 NIP-5F Unix Domain Socket remote signing merged (6-month PR) PR #1862
NIPs #556 2026-10-07 NIP-57 Zap Proofs / partial receipts — 2026 re-open PR #556
NIPs #2428 2026-10-07 NIP-171 Epoch-Ticketed Private Groups (PQ group epoch rotation) PR #2428
NIPs #2491 2026-10-03 NIP-FC Financial Cashtags merged (fernandolguevara) PR #2491
NIPs #2229 2026-10-08 NIP-DB window.nostrdb merged (hzrd149, 4-month PR) PR #2229
NIPs #2303 2026-10-05 NIP-5D nostr web applets merged (dskvr) PR #2303
NIPs #2437 2026-10-04 NIP-94 file encryption merged (alexgleason) PR #2437
NIPs #2496 2026-10-08 NIP-97 Persisted Delivery Confirmation merged (Rogerclaw1337) PR #2496
Nostr-WoT extension v0.8.11 / v0.8.12 2026-10-06 21:45 / 22:22 UTC Account Archive + passwordless import (37 min apart) v0.8.11 · v0.8.12
Amber v6.6.7 2026-10-05 DEAD_COOLDOWN_MS 15-min + double-count fix v6.6.7 · newsroom
Amethyst v1.17.0 2026-10-05 Cordn + NIP-92 + NIP-49 Poly1305 + PR #4238 filter-rebuild v1.17.0 · newsroom
Citrine v3.1.1 2026-09-11 NIP-42 AUTH signature omission fixed (Sept 11 release, Oct 7 retrospective) v3.1.1 · newsroom
Citrine v3.2.0 2026-09-18 Every 3.1.1 commit bundled v3.2.0
nak v0.21.0 2026-10-03 NIP-65 relays subcommand + petname-path resolution in shared parser release · newsroom
nostream v3.2.0 2026-10-03 Filter-query repair + HAProxy blue/green + nip56.hideActionableReports v3.2.0 · newsroom
Nostr Compass #43 2026-10-07 Canonical event log: Ants / Myco / Marmot MDK / Iris Chat / Scramble / Mostro / Haps / KithMoot #43
GnuPG master 2026-10-09 scd_getpin call-chain simplification + scd:piv PIN-Policy check master
kind:10203 (PQ identity-key attestation) wire 2026-09-23 Plateau holds at 26 for 21 d (Sep 23 stair-step still holds) W39 weekly update · Quantakrypto/Obelisk
NIP #2434 (PQ identity keys) open 2026-08-11 61 d frozen; fiatjaf comment Aug 11 still stands PR #2434
kind:30385 collision (Trusted Relay Assertions) open 2025-07-18 PR 89 d open; ref impl ships events on nos.lol; staleness makes collision de facto PR #2418

Cross-Cutting Filaments

  • NIPs spec-cluster Oct 1-8 (14 PRs merged in 7 days) — PRs #2494 (NIP-92 imeta), #2495 (Aspie96 solves #2482), #2498 (EXTRA on CLOSED/OK), #2449 (NIP-51 Static Website curation sets), #2229 (NIP-DB window.nostrdb), #2496 (NIP-97 Persisted Delivery Confirmation), #556 (NIP-57 partial receipts), #2428 (NIP-171 Epoch-Ticketed Private Groups), #2303 (NIP-5D nostr web applets), #2462 (slash commands), #2437 (NIP-94 file encryption), #1862 (NIP-5F Unix Domain Socket remote signing — 6-month merge), #2112 (NIP-47 Arkade + non-BOLT11), #2491 (NIP-FC Financial Cashtags). The narrative thread is author-side signing correctness — NIP-5F (signer transport over unix://), NIP-94 encryption (file plaintext closure), NIP-47 Arkade (protocol-side signing chain for non-BOLT11 addresses), NIP-5D (applet delivery as a signed primitive), NIP-171 (PQ group-epoch rotation), NIP-92 (imeta on profile image — keeps the canonical URL in picture JSON, not in a separate signed envelope), NIP-97 (delivery acknowledgement that is itself a signed event), NIP-DB (browser-side relay subsystem). The cluster moves Nostr from a "publish-and-forget" surface to an "author-signs-then-resolves-a-signed-claim" surface at every layer.
  • NIP-42 / NIP-43 / NIP-86 / NIP-DB convergence on the relay + DB substrate — Citrine 3.1.1's NIP-42 AUTH signature verification, NIP-86's unbanpubkey + unallowpubkey arriving in the same release, and NIP-DB's window.nostrdb standardizing the browser-side counterpart to NIP-43's HTTP-side directory form a coherent relay + DB substrate. The browser and the relay now share a kind-and-event catalog rather than each implementing it independently, and the surface where they meet is increasingly signed.
  • NIP-09 erasure, NIP-42 signature-omission, NIP-57 server-signed receipt, NIP-65 push-relay — same gap, four surfaces — every post this week names a gap between a signed event and a durable outcome: NIP-09 deletion requests do not prove erasure (Sept 30 retrospective); NIP-42 AUTH events without sig are still accepted (Citrine 3.1.1, Oct 7 retrospective); NIP-57 zap receipts are a server-signed claim, not trustless proof that Lightning settled (Oct 10 piece); NIP-65's read and write markers are current evidence at a check-time, not a permanent trust anchor (Oct 4 piece). The four-week arc has produced a coherent gap vocabulary: signed ≠ durable, relay-stored ≠ reachable, looked-up ≠ bound, published ≠ seen.
  • PQ Nostr cross-rotation narratives — the W41 PQC Saturday rotation notes Post-Quantum Saturday — October 10 2026 Weekly Update AWS-LC v5.11.0 + liboqs 0.16.0 + OpenSSL 4.1.0-beta1 + oqs-provider 0.10.0 as the wire-protocol-library plateau; the W41 WoT Thursday rotation notes Web of Trust Thursday — October 08 2026 Weekly Update kind:10203 plateau at 26 + NIP #2434 61 d frozen + GnuPG 2.5.25 NEWS empty. The W41 Sunday rotation here reads kind:10203 plateau at 26 for 21 d, NIP #2434 frozen at 61 d, and the Quantakrypto Obelisk PQ-DM demo at 2.7× classic size. The three readings agree: PQ Nostr is institutional-stable at the implementation layer (Nostr-WoT v0.4.0 / v0.8.x), spec-frozen at the protocol layer (PR #2434), and institutional-quiet at the OpenPGP layer (GnuPG 2.5.25 NEWS empty). The 2026-08 NIP-2434 freeze is now the longest stall in 2026 for any NIP-PR opened by an external contributor with fiatjaf's first review.