The audit's most important finding was not a doc issue at all. In
vaultSetBinding the identifier `origin` resolved to the WORKER GLOBAL
self.origin rather than the intended value, so the dashboard's "Revoke
app access" REBOUND the record to the calling page instead of clearing
it -- the precise cross-origin adoption the binding guard exists to
prevent, wearing the label of the button meant to prevent it. It
typechecked because the DOM lib declares that global. I introduced this
hours ago: a string replace intended for one call site silently matched
two. Fixed, with the reasoning written where the next reader will hit it.
Relay/account audit fixes:
- Phrase recovery permanently tripped the rollback alarm. The mark is
keyed by the everyday pubkey (unchanged by recovery) while recovery
legitimately restarts at generation 0, and raiseHighWaterMark keeps
the maximum -- so anyone who had ever rotated a password met "possibly
revoked credentials" on EVERY later login, forever, with no way to
clear it. The phrase is the master authority; it now resets the mark.
- quorumMet counted TCP connections, not answers: a query timeout
RESOLVED, so a connectable-but-silent relay counted as responding and
every "not enough relays answered" guard was near-vacuous. Only EOSE
is an answer now.
- Relay responses were never checked against the address requested, so
one junk event from one relay blocked registration, rotation, and
recovery for every login name and password a user tried. Events must
now match author, kind, and d-tag.
Website honesty (the surface a stranger reads first, and the one that
had drifted furthest from the spec):
- docs.html and llms.txt still carried "private keys never leave the
worker" -- false on its face, since the widget ships a reveal-nsec
button. Both now state the same limit the README does.
- "you revoke" became honest everywhere: removing a connection deletes
the stored copy; spending authority is revoked at the wallet.
- index.html dropped a pre-softening recovery claim, now says an account
lives only while relays retain its capsule, and says "independently
unaudited" out loud.
- llms.txt gains the two warnings that were missing entirely: losing
BOTH password and phrase is permanent, and removal is not revocation.
- Stale headers: nwc-connections.md no longer claims "Not implemented",
docs/README no longer says the authorization layer is unbuilt, the
test count and spec version are current, and the demo domain points
at bitlogin.network.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1