diff --git a/.planning/phases/01-foundation-broker-spike/01-CONTEXT.md b/.planning/phases/01-foundation-broker-spike/01-CONTEXT.md
new file mode 100644
index 0000000..4c35696
--- /dev/null
+++ b/.planning/phases/01-foundation-broker-spike/01-CONTEXT.md
@@ -0,0 +1,108 @@
+# Phase 1: Foundation + Broker Spike - Context
+
+**Gathered:** 2026-06-04
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+Stand up the FamilySync stack (Docker Compose + MariaDB, deployed through the real Pangolin tunnel) and deliver: Authelia OIDC login with persistent sessions, stable per-member identity, and an auto-assigned per-member color; a CalDAV broker that reads and caches at least one real event from a Fastmail calendar via a per-member app password; and a documented go/no-go on the personal-calendar overlay (CAL-08).
+
+**In scope:** AUTH-01/02/03, CAL-01, CAL-08 (spike + decision), infra scaffold, Pangolin deployment, SSE pass-through smoke test.
+**Out of scope (later phases):** calendar UI/views (Phase 2), event write-back (Phase 3), lists + live sync feature (Phase 4), push (Phase 5). No single-occurrence recurring edits ever in v1.
+
+
+
+## Implementation Decisions
+
+### Personal-Calendar Access & Spike (CAL-08 gate)
+- **D-01:** The wife's personal calendar lives on **Fastmail** (confirmed by user). It is a Fastmail-hosted calendar collection, so the broker can reach it via CalDAV. This removes the iCloud "unreachable" risk entirely.
+- **D-02:** Broker access model = **per-member app passwords**, NOT single-token cross-account share+accept. Each member generates their own Fastmail app password; the broker holds N credentials and reads each account directly. This eliminates the unconfirmed cross-account CalDAV ACL discovery risk — the original highest project risk. The CAL-08 spike therefore simplifies to: confirm an app password reads its own account's shared + personal calendars via PROPFIND/REPORT.
+- **D-03:** Phase 1 proceeds with **only the primary user's (Lucas) app password**. Success criterion #4 (read+cache a real event) is proven against Lucas's personal + the shared family calendar. The wife's app password is added in Phase 2 — Phase 1 is NOT blocked on coordinating with her. CAL-08 is structurally proven (N-credential broker) without her credential present.
+- **D-04:** App passwords are stored in an **encrypted-at-rest DB table**, keyed by user `oidc_sub`, with the encryption key supplied from env. This supports adding the wife later via an onboarding/settings flow with no redeploy, and scales to the N-credential broker. App passwords are backend-only — never exposed to the frontend (locked, security).
+- **D-05:** Go/no-go record: since access is per-member app passwords and her calendar is on Fastmail, the expected outcome is GO. The documented fallback (only relevant if a Fastmail app password unexpectedly cannot read a personal calendar) is shared-family-only for v1, moving CAL-08 to v1.x.
+
+### Member Color Assignment (AUTH-03)
+- **D-06:** Each member's color is **auto-assigned from a curated palette on first login** and persisted on the user row (keyed by `oidc_iss + oidc_sub`). Stable across sessions, no settings UI in Phase 1, works for both current members and any future member. Not user-pickable in v1 (a settings color-picker is a deferred idea).
+
+### Infrastructure & Deployment Scope
+- **D-07:** Phase 1 **deploys through the real Pangolin tunnel + Authelia**, not local-only. OIDC redirect URIs, HTTPS, and session cookies are validated in the real topology from day one to avoid a "worked locally, broke in prod" OIDC failure. Ensure FamilySync and Authelia share the same parent domain so Authelia session cookies are same-site (Pitfall 17).
+- **D-08:** Phase 1 **folds in the Pangolin SSE pass-through smoke test** (a trivial long-lived SSE endpoint confirmed over the public URL). De-risks Phase 4 transport choice early (issue #1034). A failure here changes the Phase 4 real-time transport decision; it does NOT block Phase 1's auth/broker success criteria.
+
+### Locked Upstream (carried forward — do NOT re-litigate)
+- **D-09:** CalDAV-only via `tsdav`; broker auth = Fastmail **app password**, never JMAP/API token. Principal URL form `https://caldav.fastmail.com/dav/principals/user/{email}/` (Pitfall 1).
+- **D-10:** Identity = `oidc_iss + oidc_sub` composite key, never email (AUTH-03).
+- **D-11:** **Skip the Authelia `groups` claim** — two equal members; authentication not authorization (Pitfall 16).
+- **D-12:** **Backend confidential client holds the refresh token**; no iframe silent renewal (Pitfall 17). Persistent session (AUTH-02) via backend-managed refresh, not browser iframe.
+- **D-13:** Calendar cache: store raw VEVENT blob + `dtstart_utc`; all-day events as `DATE` / `{date, allDay}` struct, never coerced to DATETIME/UTC (Pitfall 3). Write-through cache invalidation; only cache server-returned objects (Pitfall 14). Use sync-token (WebDAV-Sync) with ctag-poll fallback from day one (Pitfall 4).
+
+### Claude's Discretion
+- **Phase 1 landing page:** a thin authenticated shell that ALSO displays the one cached event as broker proof (not a bare health page, not a real calendar UI). Confirms end-to-end auth + broker in one screen.
+- **Color palette:** a small set of visually-distinct, accessible hues assigned round-robin by join order. Exact values are Claude's choice.
+- **Broker internals:** sync-token vs ctag detection, poll interval (research suggests conservative 5-min / 60s acceptable for v1), Drizzle schema specifics, OIDC middleware wiring, encryption helper implementation.
+- **Stack libraries/versions:** per locked research stack (Hono + Drizzle/mysql2 + tsdav + ical.js + rrule + @hono/oidc-auth).
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Phase definition & requirements
+- `.planning/ROADMAP.md` § "Phase 1: Foundation + Broker Spike" — goal + 5 success criteria (the scope anchor)
+- `.planning/REQUIREMENTS.md` — AUTH-01, AUTH-02, AUTH-03, CAL-01, CAL-08 (full requirement text + traceability)
+- `.planning/PROJECT.md` — constraints, key decisions, household context
+
+### Research (read before planning — flagged NEEDS research-phase by SUMMARY)
+- `.planning/research/SUMMARY.md` — cross-cutting findings; Phase 1 section + confidence assessment
+- `.planning/research/PITFALLS.md` — Phase-1-relevant pitfalls: #1 (CalDAV-only), #3 (all-day DATE), #4 (ETag/sync-token), #7 (personal-cal sharing), #14 (cache double-write), #16 (Authelia groups), #17 (Authelia silent renewal/cookies), #18 (Pangolin WS/SSE)
+- `.planning/research/STACK.md` — locked library versions + import paths
+- `.planning/research/ARCHITECTURE.md` — broker-cache pattern, component layout, MariaDB schema guidance
+
+### External docs (authoritative)
+- Fastmail CalDAV principal URL + app passwords (see SUMMARY/PITFALLS Sources)
+- Authelia OIDC client config — PKCE S256, `client_secret_basic`, response_type `code`, grant types `authorization_code`+`refresh_token` (see CLAUDE.md "Authelia OIDC Integration")
+- Pangolin WebSocket/SSE issue #1034 (referenced in PITFALLS #18)
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- None — greenfield repo. Only `.planning/`, generated `CLAUDE.md`, and an empty `README` exist. No source tree yet.
+
+### Established Patterns
+- None established yet. Phase 1 sets the foundational patterns (Docker Compose layout, Drizzle schema/migrations, broker module boundary, OIDC session middleware) that later phases inherit.
+
+### Integration Points
+- Authelia (already deployed, both members have accounts) — register FamilySync as an OIDC confidential client; no Authelia deploy/provisioning.
+- Pangolin/Newt tunnel (already running) — FamilySync gets a public hostname under the same parent domain as Authelia.
+- MariaDB + Redis available in the Unraid stack; no PostgreSQL.
+
+
+
+
+## Specific Ideas
+
+- The broker module must be a hard boundary: all Fastmail I/O isolated in `broker/`; nothing else imports Fastmail credentials or tsdav directly (architecture note).
+- "No per-member credential juggling" is a core-value phrase, but the user explicitly accepted per-member app passwords as the access model — the juggling avoided is calendar-credential *login* friction for members (they still log in only via Authelia SSO), not broker-side secrets.
+
+
+
+
+## Deferred Ideas
+
+- **User-pickable member color** (settings color-picker) — deferred; v1 auto-assigns. Could land in a later settings/profile phase.
+- **Single-token broker via Fastmail share+accept** — not chosen; per-member app passwords selected instead. Kept on record only as an alternative if credential management ever becomes painful.
+- **Wife's app password onboarding flow** — the encrypted-credential DB table is built in Phase 1 to support it, but the actual onboarding UX/endpoint is Phase 2 work.
+
+### Reviewed Todos (not folded)
+- "Kick off FamilySync with /gsd:new-project" — stale project-kickoff todo, already completed during initialization; not relevant to Phase 1 scope.
+
+
+
+---
+
+*Phase: 1-Foundation + Broker Spike*
+*Context gathered: 2026-06-04*
diff --git a/.planning/phases/01-foundation-broker-spike/01-DISCUSSION-LOG.md b/.planning/phases/01-foundation-broker-spike/01-DISCUSSION-LOG.md
new file mode 100644
index 0000000..67d434c
--- /dev/null
+++ b/.planning/phases/01-foundation-broker-spike/01-DISCUSSION-LOG.md
@@ -0,0 +1,112 @@
+# Phase 1: Foundation + Broker Spike - 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-04
+**Phase:** 1-Foundation + Broker Spike
+**Areas discussed:** Personal-cal spike & fallback, Member color assignment, Infra validation scope
+
+---
+
+## Area Selection
+
+| Option | Selected |
+|--------|----------|
+| Personal-cal spike & fallback | ✓ |
+| Member color assignment | ✓ |
+| Phase 1 landing scope | (skipped → Claude's discretion) |
+| Infra validation scope | ✓ |
+
+---
+
+## Personal-cal spike & fallback
+
+### Where the wife's personal calendar lives
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fastmail | Fastmail-hosted collection; broker can reach it | ✓ |
+| iCloud / Apple Calendar | Broker cannot read; CAL-08 degrades | |
+| Not sure yet | Confirm before spike | |
+| Both / mixed | Define overlay target | |
+
+**User's choice:** Fastmail
+**Notes:** Removes the iCloud "unreachable" risk; CAL-08 is technically achievable.
+
+### Broker access model
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Single broker token + share | One token; share+accept per member | |
+| Per-member app passwords | Each member's own app password; broker holds N creds | ✓ |
+| Prove single-token, keep per-member ready | Hybrid | |
+
+**User's choice:** Per-member app passwords
+**Notes:** Eliminates the unconfirmed cross-account CalDAV ACL discovery risk (the project's original highest risk). Spike simplifies to confirming an app password reads its own account.
+
+### Spike credential sequencing
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Just mine now | Prove broker with Lucas's app password; wife's added Phase 2 | ✓ |
+| Both before Phase 1 done | Get wife's password too; fully close CAL-08 now | |
+
+**User's choice:** Just mine now
+**Notes:** Phase 1 not blocked on coordinating with wife. CAL-08 structurally proven via N-credential broker.
+
+### Credential storage
+| Option | Description | Selected |
+|--------|-------------|----------|
+| DB table, encrypted at rest | Keyed by oidc_sub, key from env; supports later onboarding | ✓ |
+| Env vars / secrets file | Simple, but redeploy to add/rotate | |
+
+**User's choice:** DB table, encrypted at rest
+**Notes:** Supports adding wife later with no redeploy; backend-only, never exposed to frontend.
+
+---
+
+## Member color assignment
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Auto-assign from palette | Assign on first login, persist on user row | ✓ |
+| User-pickable in settings | Default + settings color-picker | |
+| Hardcoded per account | Fixed color in config per oidc_sub | |
+
+**User's choice:** Auto-assign from palette
+**Notes:** No settings UI in Phase 1; stable across sessions; works for future members. Pickable color deferred.
+
+---
+
+## Infra validation scope
+
+### Deployment scope
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Deploy through Pangolin | Real tunnel + Authelia; validate OIDC topology day one | ✓ |
+| Local docker-compose only | Localhost; defer tunnel validation | |
+
+**User's choice:** Deploy through Pangolin
+**Notes:** Avoids "worked locally, broke in prod" OIDC failure; same-parent-domain cookies (Pitfall 17).
+
+### Pangolin SSE smoke test
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fold it in now | Trivial SSE endpoint over public URL; de-risk Phase 4 | ✓ |
+| Defer to Phase 4 | Keep Phase 1 strict to its 5 criteria | |
+
+**User's choice:** Fold it in now
+**Notes:** Cheap while stack+tunnel are up; a failure changes Phase 4 transport but does not block Phase 1.
+
+---
+
+## Claude's Discretion
+
+- Phase 1 landing page: thin authenticated shell that also displays the one cached event as broker proof.
+- Color palette: small set of visually-distinct, accessible hues, round-robin by join order.
+- Broker internals (sync-token vs ctag, poll interval), Drizzle schema, OIDC middleware wiring, encryption helper.
+- Stack libraries/versions per locked research stack.
+
+## Deferred Ideas
+
+- User-pickable member color (settings color-picker) — future settings/profile phase.
+- Single-token broker via share+accept — not chosen; alternative on record only.
+- Wife's app-password onboarding UX/endpoint — Phase 2 (the encrypted credential table is built in Phase 1 to support it).