No way to sign yourself out #171

Closed
opened 2026-10-11 17:02:24 +00:00 by kayg · 6 comments
Owner

Owner, 2026-10-11: there is no way to sign yourself out (Settings → Devices only signs out other devices). Add "Sign out" for this device: profile pill menu, Settings → Account, ⌘K; compact confirmation; lands on sign-in with no stale state. Uses the existing logout endpoint (apps/tracer/src/auth.ts). Branch signout from release-prod-2; goes into the night production batch.

Owner, 2026-10-11: there is no way to sign yourself out (Settings → Devices only signs out *other* devices). Add "Sign out" for this device: profile pill menu, Settings → Account, ⌘K; compact confirmation; lands on sign-in with no stale state. Uses the existing logout endpoint (apps/tracer/src/auth.ts). Branch `signout` from release-prod-2; goes into the night production batch.
Author
Owner

Start: branch signout, base 382d59ce (release-prod-2 + taste 382d59ce). Plan: shared signOut() (sign-out.ts) + logout in auth.ts; profile-pill menu (shared window menu, extended to open above), palette 'Sign out', Settings -> Account row; compact confirm; mock double keeps a signed-out preview signed out across reload; Playwright spec on port 4911.

Start: branch signout, base 382d59ce (release-prod-2 + taste 382d59ce). Plan: shared signOut() (sign-out.ts) + logout in auth.ts; profile-pill menu (shared window menu, extended to open above), palette 'Sign out', Settings -> Account row; compact confirm; mock double keeps a signed-out preview signed out across reload; Playwright spec on port 4911.
Author
Owner

Finish: head b4ae9e2289 on signout (pushed). Entry points: profile pill menu, palette "Sign out", Settings -> Account; one signOut() (logout first, then teardown, sign-in screen). Gates on the production build: tsc clean; bun test src 150 pass; transfer-budget exit 0: critical gzip 293456/307200 brotli 243965/256000; deferred gzip 48880/51200 brotli 43161/45056; onDemand largest chunk gzip 15015/20480 brotli 13339/18432. sign-out.spec.ts 12/12 on port 4911; inbox.spec 9/9; onboarding, sidebar-polish, focus-ring, phone-polish pass (two flaky in a long combined run, green alone). clusters-grid has 6 failures in "split right in a stacked column" that fail identically on base 382d59ce (pre-existing). Captures: apps/tracer/captures/signout/.

Finish: head b4ae9e2289f005b746188761c2f7d2502f3a8306 on signout (pushed). Entry points: profile pill menu, palette "Sign out", Settings -> Account; one signOut() (logout first, then teardown, sign-in screen). Gates on the production build: tsc clean; bun test src 150 pass; transfer-budget exit 0: critical gzip 293456/307200 brotli 243965/256000; deferred gzip 48880/51200 brotli 43161/45056; onDemand largest chunk gzip 15015/20480 brotli 13339/18432. sign-out.spec.ts 12/12 on port 4911; inbox.spec 9/9; onboarding, sidebar-polish, focus-ring, phone-polish pass (two flaky in a long combined run, green alone). clusters-grid has 6 failures in "split right in a stacked column" that fail identically on base 382d59ce (pre-existing). Captures: apps/tracer/captures/signout/.
Author
Owner

Orchestrator: deployed web-only b4ae9e22 to production (no server restart, MainPID unchanged); release-prod-2 → b4ae9e22. check pass, transfer budget exit 0 on the production build; spec 12/12 per the author.

Orchestrator: deployed web-only b4ae9e22 to production (no server restart, MainPID unchanged); release-prod-2 → b4ae9e22. check pass, transfer budget exit 0 on the production build; spec 12/12 per the author.
Author
Owner

D245 implemented on branch signout-clear (base 1f77a449 = release-prod-3), commits d8fb45c8 (clear + guards + unit test) and d472ee3a (e2e test). Not deployed.

Storage inventory (tracer app; no Cache Storage, IndexedDB, service worker or JS cookies are used):

Key Area Holds On sign-out
infraternal.canvas. localStorage canvas document: windows, columns, views (about 260-420 bytes for a few windows, roughly 100 bytes per window) cleared (this account only)
tracer.sessions. localStorage session names, pins, recency per host (about 100 bytes per session) cleared
tracer.session. sessionStorage public id of the terminal this tab had open cleared
tracer.user-id localStorage public id of the last account to sign in (written, never read back) cleared if it names this account
tracer.theme, tracer.card, tracer.windows, tracer.background, tracer.font, tracer.ui-font localStorage look preferences kept: device-level, no account data
tracer.window-size.phone/desktop, tracer.extended-info, tracer.fps-hud-open localStorage window sizes, info toggle, frame meter toggle kept: device-level
tracer.toolbar localStorage toolbar order (device override; the account copy is on the server) kept: device-level
tracer.device-name localStorage label for the device in onboarding (read only here) kept: names the device, not the account
mock-ca-unlocked sessionStorage test-double only (mock add-host) not in product; gone with the tab
in-memory page canvas, inventory, sessions, connections disposed by the teardown; the session also dies with the page

Scoping: every account key ends in the account id and is built in one module (apps/tracer/src/account-storage.ts) that also does the clearing, so another account on the same browser is untouched. If the id is unknown the sweep clears every account's keys.

Order: logout, teardown (its last flush writes the layout), then the clear. The document sync and the live inventory are inert once disposed, so no timer, pagehide flush or late socket message writes after the clear.

Copy: the confirmation says "You will need your passkey to sign in again." and never promised the layout was kept, so no copy or visual change.

Tests: bun run check clean; bun test src 153 pass; build + transfer-budget.ts exit 0 (budgets untouched). Playwright (port 4961, CPUWeight=10000): all 13 sign-out specs pass including the new D245 spec (storage areas empty after sign-out, other account and theme survive, reload clean). sessions-canvas: 19 of 21 pass; "the empty, loading and error states" fails on the base commit too; the others that failed in some runs passed on re-run (host load average was about 90).

D245 implemented on branch `signout-clear` (base 1f77a449 = release-prod-3), commits d8fb45c8 (clear + guards + unit test) and d472ee3a (e2e test). Not deployed. Storage inventory (tracer app; no Cache Storage, IndexedDB, service worker or JS cookies are used): | Key | Area | Holds | On sign-out | |---|---|---|---| | infraternal.canvas.<account> | localStorage | canvas document: windows, columns, views (about 260-420 bytes for a few windows, roughly 100 bytes per window) | cleared (this account only) | | tracer.sessions.<account> | localStorage | session names, pins, recency per host (about 100 bytes per session) | cleared | | tracer.session.<account> | sessionStorage | public id of the terminal this tab had open | cleared | | tracer.user-id | localStorage | public id of the last account to sign in (written, never read back) | cleared if it names this account | | tracer.theme, tracer.card, tracer.windows, tracer.background, tracer.font, tracer.ui-font | localStorage | look preferences | kept: device-level, no account data | | tracer.window-size.phone/desktop, tracer.extended-info, tracer.fps-hud-open | localStorage | window sizes, info toggle, frame meter toggle | kept: device-level | | tracer.toolbar | localStorage | toolbar order (device override; the account copy is on the server) | kept: device-level | | tracer.device-name | localStorage | label for the device in onboarding (read only here) | kept: names the device, not the account | | mock-ca-unlocked | sessionStorage | test-double only (mock add-host) | not in product; gone with the tab | | in-memory | page | canvas, inventory, sessions, connections | disposed by the teardown; the session also dies with the page | Scoping: every account key ends in the account id and is built in one module (apps/tracer/src/account-storage.ts) that also does the clearing, so another account on the same browser is untouched. If the id is unknown the sweep clears every account's keys. Order: logout, teardown (its last flush writes the layout), then the clear. The document sync and the live inventory are inert once disposed, so no timer, pagehide flush or late socket message writes after the clear. Copy: the confirmation says "You will need your passkey to sign in again." and never promised the layout was kept, so no copy or visual change. Tests: bun run check clean; bun test src 153 pass; build + transfer-budget.ts exit 0 (budgets untouched). Playwright (port 4961, CPUWeight=10000): all 13 sign-out specs pass including the new D245 spec (storage areas empty after sign-out, other account and theme survive, reload clean). sessions-canvas: 19 of 21 pass; "the empty, loading and error states" fails on the base commit too; the others that failed in some runs passed on re-run (host load average was about 90).
Author
Owner

Orchestrator: DEPLOYED to production as a web-only change (no server restart; ActiveEnterTimestamp unchanged 03:17:48 UTC, CA stays unlocked) at release-prod-3w 4855e033 = 1f77a449 + signout-clear (D245) + phone-width (TASTE full width / edge to edge, lone window full width) + cursor-blink (D249). Gates on the merged head: tsc clean, bun test src 154 pass, transfer budget pass, sign-out + phone-window-width + phone-polish + cursor-blink specs 34/35 (DPR-2 alignment timed out at 29.2 s under load 61, passed on rerun in 37 s). Owner to test on iPhone.

Orchestrator: DEPLOYED to production as a web-only change (no server restart; ActiveEnterTimestamp unchanged 03:17:48 UTC, CA stays unlocked) at release-prod-3w 4855e033 = 1f77a449 + signout-clear (D245) + phone-width (TASTE full width / edge to edge, lone window full width) + cursor-blink (D249). Gates on the merged head: tsc clean, bun test src 154 pass, transfer budget pass, sign-out + phone-window-width + phone-polish + cursor-blink specs 34/35 (DPR-2 alignment timed out at 29.2 s under load 61, passed on rerun in 37 s). Owner to test on iPhone.
Author
Owner

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Sign-out clear (d8fb45c8, d472ee3a) is in dev and release-prod-live; deployed web-only in 4855e033. Reopen if anything is still missing.

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Sign-out clear (d8fb45c8, d472ee3a) is in dev and release-prod-live; deployed web-only in 4855e033. Reopen if anything is still missing.
kayg closed this issue 2026-10-28 17:53:01 +00:00
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#171
No description provided.