Absorb single-user mode into multi-user (phases 1-3)#380
Open
chadbyte wants to merge 4 commits into
Open
Conversation
…e 1) Groundwork for folding single-user mode into multi-user. When a multi-user instance has exactly one user with no PIN, authenticate them automatically instead of showing a login wall, preserving the frictionless single-user onramp. Central change: getMultiUserFromReq() falls back to users.getSoloNoPinUser() when there's no valid token, so every HTTP and WS auth gate (all route through this) is covered by one path. Disabled the moment a PIN is set or a second user is added. Inert today: only triggers when multiUser is true (single-user deploys are unaffected until the later migration phase flips them).
…ase 2) On daemon boot, detect a legacy single-user deploy and fold it into the multi-user model with zero manual steps: - provision one "admin" user that inherits the single-user PIN hash (same PIN still logs in), profile.json, and settings (chatLayout, autoContinue, matesEnabled, terminalFont, deletedBuiltinKeys, mateOnboardingShown) - move legacy flat mates into the per-user mates dir - backfill ownerId onto legacy sessions so they belong to the user - flip multiUser = true Runs before projects/mates/sessions load. Heavily guarded: backs up users.json/daemon.json/profile.json first, is idempotent (config marker), tolerates partial failure per step, and is a no-op on fresh installs and already-multi-user deploys. Combined with the phase-1 solo auto-login, a no-PIN single-user deploy upgrades with no login wall.
…(phase 3) There is no separate single-user runtime anymore. Every deploy runs in the (general) multi-user model: - Remove the "Just me (single user) / Multiple users" setup question. Fresh installs go straight to multi-user; OS-user isolation stays an opt-in (offered on Linux at setup, toggleable later). - daemon boot calls ensureMultiUser(): migrate a legacy single-user deploy, or provision a default no-PIN "admin" on a fresh one. With phase-1 solo auto-login, a solo user gets in with no account creation and no login wall. - Flip every mode fallback from "single" to "multi". Solo onramp is unchanged in feel (npx clay-server -> just works); it's now a one-user multi-user deploy under the hood.
Capture the plan, what's done (phases 1-3 + verification), and the remaining cleanup (phase 4 settings dual-path, phase 5 !isMultiUser branch removal, phase 6 flag/dead-code removal) with file:line targets and watch-outs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the separate single-user runtime: every deploy now runs in the (general) multi-user model. A solo user is just a one-user multi-user deploy with an auto-provisioned default admin and no login wall. OS-user isolation is orthogonal and untouched.
Principle: migrate-then-flip — safety nets and data migration land before the default flips, so existing deploys upgrade with zero manual steps.
Phases in this PR
getMultiUserFromReq()falls back tousers.getSoloNoPinUser()(exactly one user, no PIN), so every HTTP/WS auth gate is satisfied with no login wall. Inert until multi-user.lib/migrate-single-user.js, at daemon boot): carry the PIN hash (same PIN still logs in),profile.json, settings (chatLayout, autoContinueOnRateLimit, matesEnabled, terminalFont, deletedBuiltinKeys, mateOnboardingShown), move flat mates →mates/<userId>/, backfillownerIdon legacy sessions, flipmultiUser=true. Backups + idempotent (config marker) + best-effort per step; no-op on fresh / already-multi.ensureMultiUser()(migrate legacy, or provision a default no-PIN admin on fresh installs); allmodefallbacks flipped"single"→"multi".Net:
isMultiUser()is effectively always true and there's always ≥1 user; single-user code paths are now dead (removed in follow-up phases 4-6).Verification (isolated
CLAY_HOMEharness — real~/.clayuntouched)Static checks:
node --checkon all touched files.Follow-up (handoff)
docs/ongoing/SINGLE-USER-ABSORPTION.mddocuments the remaining cleanup — phase 4 (settingsdc→user-record dual-path, with an avatar-logic caveat), phase 5 (!isMultiUserbranch removal across ~27 files), phase 6 (flag/dead-code removal) — plus a watch-out: transitioning a solo (no-PIN) deploy to real multi-user must force the admin to set a PIN first (not yet handled).🤖 Generated with Claude Code