Files
familysync/.planning/milestones/v1.1-phases/12-initial-setup-wizard/12-DISCUSSION-LOG.md
T
2026-06-18 22:21:38 -04:00

5.8 KiB

Phase 12: Initial Setup Wizard - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-06-15 Phase: 12-initial-setup-wizard Areas discussed: Wizard nature, Restart & resume, Credential + admin, Guard


Wizard nature

Q1 — Does the wizard write config, or validate-only?

Option Description Selected
Validate-only (UI-SPEC) Wizard never writes config; checks env, generates secrets to paste, validates, flips setup_complete
Collect-and-write some Wizard accepts some config via fields and persists it; contradicts the no-input UI-SPEC

User's choice: Collect-and-write some — "I'm okay to migrate away from a .env file entirely if that helps. The wizard could supersede it and config values live in the DB."

Q2 — Which config to collect-and-write?

Option Description Selected
App / external URL Non-secret runtime URL → app_config (folded into D-02)
OIDC client_id + issuer Non-secret OIDC identifiers (caveat: boot-time read) (folded into D-02)
VAPID public key Non-secret half of keypair → app_config (folded into D-02)
Nothing — reconsider Keep validate-only after all

User's choice (free text): "I want the env variables to come through from docker or fall back to that .env file" + (Q3) "minimal kernel + db config."

Q3 — How far to push config-into-DB?

Option Description Selected
Minimal kernel + DB config Env keeps bootstrap kernel only; wizard writes non-secret config to app_config
Wizard validates env, writes only credential Smallest, matches UI-SPEC
Full DB-config migration Move everything + refactor all consumers; scope risk

User's choice: Minimal kernel + DB config; env from Docker, .env fallback. Notes: Hard floor surfaced and accepted: DB connection + ENCRYPTION_KEY + VAPID_PRIVATE_KEY + SESSION_SECRET + OIDC client_secret cannot leave env (chicken-and-egg / key-beside-ciphertext / SC-3).


Restart & resume

Q1 — How to handle re-entry after the post-secrets restart?

Option Description Selected
Live re-detection, world is the state No cursor; each step re-checks live env/DB; skip satisfied steps
Persisted step cursor in app_config Store setup_step; can drift from reality
Always restart from Step 1 Simplest but breaks the un-re-showable secrets step

User's choice (free text / reframe): "No, I'm envisioning an Unraid template or clear instructions to bootstrap the image and all of those variables should be defined before first boot." Notes: This designs OUT the mid-wizard restart entirely — kernel is complete at first boot; the generate-secrets step leaves the wizard.

Q2 — Where do the secret values come from before first boot?

Option Description Selected
Documented commands in template/README openssl + npx web-push generate-vapid-keys
Helper script in the repo npm run generate-secrets prints all four, VAPID via web-push lib
Pre-boot generator endpoint/mode App boots unconfigured to generate; reintroduces complexity

User's choice: Helper script in the repo.


Credential + admin

Q1 — How is the first Fastmail credential handled with no user row?

Option Description Selected
Validate in wizard, store post-login via self-service CalDAV-validate only; store later via SetupBanner; double-entry
Store against a pending/first user row Wizard reserves a user row + credential, reconcile at login ✓ (refined)
No credential in wizard at all Drops the CalDAV step; fails SC-2

User's choice (free text): "When we switch from Fastmail to generic provider, the first user who gets provisioned will need to enter this. … we need a local user who will get merged into an OIDC user once that's set up." Notes: Refined into the local-user → claim-at-first-login model (D-07/D-08); provider-agnostic framing.

Q2 — How is the first OIDC login matched to the pending local user?

Option Description Selected
First-login-claims First OIDC login after setup_complete adopts the local user
Match by email claim Couples identity to email (fights D-10)
Explicit claim code One-time code; strongest but extra friction

User's choice: First-login-claims. Notes: User added a deferred capability — a fully local (no-OIDC) operating mode, wiring OIDC in later — to be captured as its own future phase.


Guard

Q1 — What does the 423 guard trust per invocation?

Option Description Selected
Flag OR live-config (defense in depth) Lock if setup_complete OR (creds row + VAPID env), re-evaluated every call
Flag only, read fresh each call Single setup_complete flag, re-read per call
Live-computed only (no flag) No persisted flag; risks premature mid-flow lock

User's choice: Flag OR live-config (defense in depth).


Claude's Discretion

  • Exact reworked step list and per-step field grouping (consistent with the revised UI-SPEC).
  • Exact /api/setup/* route paths and new app_config key names.
  • Migration packaging for the nullable-OIDC-identity + claimed-marker schema change.
  • Whether app_config runtime reads are per-process cached or per-request.

Deferred Ideas

  • Local-auth / no-OIDC operating mode — run entirely on local DB users, wire OIDC in later; its own future phase, built atop Phase 12's local-user foundation (D-07).