docs(auth): reading the full reading's fixes (ADR 0017)

ADR 0017 gets "Reading the fixes (21 Oct 2026)": each finding and what
was done, and "The rules as they stand" brought up to date (resets take
effect once 72 hours outside hold-outs passed and lapse 30 days after
they were asked; GitHub-only accounts go 30 days after the end; a member
takes the register's moment by its own clock; nothing secret copied on
the device). The module README and Learn's AGENTS.md say the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-21 16:49:57 +02:00
commit 8d6c54ef22
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -292,12 +292,15 @@ Built on the three parts above, on the register (members forward every step thro
account's signing key, which every signed-in device keeps) and a code set a new
password, the keys staying. A lost password without it: a mailed code asks, 72 hours
pass (a mail at the start, a sign-in calls it off), a new code carries it out: new
password, new keys, no authenticators. While the owner is held out of signing in (codes
waiting, the address's ceiling of proofs filled), every reset not carried out is pushed
to 72 hours after the hold-out ends (`pushOutResets`, `account_resets.dart`); a reset
that took effect and wasn't carried out lapses a week later (`resetLapsesAfter`,
pruned by `forgetLapsedResets`); `SignInWays` tells signed-in devices when each waiting
reset takes effect, and `password.callOffResets` calls them off for the owner's proof.
password, new keys, no authenticators. A reset takes effect once the owner had 72 hours
outside hold-outs (codes waiting, the address's ceiling of proofs filled): each
hold-out that begins before it takes effect moves it on by the time it holds the owner
out and no hold-out counted before did (`pushOutResets`, `account_resets.dart`, the
row's `heldOutUntil`); a reset that took effect and wasn't carried out lapses a week
later (`resetLapsesAfter`), and every reset not carried out 30 days after it was asked
(`resetLivesAtMost`), both pruned by `forgetLapsedResets`; `SignInWays` tells
signed-in devices when each waiting reset takes effect, and `password.callOffResets`
calls them off for the owner's proof.
- **Changing while signed in:** `password.change` takes the owner's proof (the old
password's SRP proof for a `password.beginChange` challenge, and a TOTP or recovery
code) and the same keys wrapped under the new password; `password.setRecoveryKeys`
@ -318,11 +321,11 @@ Built on the three parts above, on the register (members forward every step thro
all. The register ends its own and keeps a `sessions_ended_notice` per member (told at
once in the background, and hourly until it confirms, `deliverSessionNotices`, as deletions are told): it names a moment, so a
session made since stays, and the session that asked for a change. A member answering
one (`/halkyon-base/member/sessions-ended`) ends its sessions made before the moment;
a member signing someone in after a reset ends its own first and makes the new session
only once its clock is past the moment (`issueSessionAfter`), refusing with
`passwordChanged` (sign in again with the new password) when its clock is more than
`maxClockSkew` behind or ahead. The owner's warning of a session ended for its proofs is
one (`/halkyon-base/member/sessions-ended`) ends its sessions made before the moment,
taken by its own clock (the notice carries the register's, `sentAt`, so the clocks'
offset drops out); a member signing someone in after a reset ends every session of the
account it holds made before the register's moment or before now, whichever is later,
then makes the new one (`issueSessionAfter`), waiting for nothing. The owner's warning of a session ended for its proofs is
dismissed only by a session made since (`signedInBefore`). A refusal for a reset not due says when it takes effect
(`takesEffectAt`).
- **Older ways:** an account that signs in with a password (it had a confirmed