docs(12): capture phase context
Restored onto phase-12 branch — discuss-phase originally committed the context (dc41073) on the phase-18 branch by mistake. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
79111232b6
commit
3ed9a42845
@@ -0,0 +1,122 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user