## Context StudyDeck PC↔iPad today uses unauthenticated cleartext LAN HTTP for course packs only. There is no AI integration, Keychain usage, or API-key storage. Adding AI assist requires a separate config channel that can carry API keys without putting secrets in course zips or plaintext JSON. ## Goals / Non-Goals **Goals:** - Unified `AiRuntimeConfig` schema shared by PC, iPad, and future Server - PC configures vendor/model/key/prompts/`baseUrl`; secure OS storage - LAN pairing + ECDH + AES-GCM sync; session tokens revocable - iPad version compare via `updatedAt`; offline cache; clear unavailable states - Client direct-connect to `baseUrl` (vendor or future proxy) - Phase B study UI: PDF rect ask + AV in/out ask - Phase C hooks for server subscription / dual mode without full cloud auth yet **Non-Goals:** - Putting API keys in course packs or publish catalog - Requiring auth on existing `/api/courses*` publish endpoints - Full cloud account, billing, or production subscription backend in this change - Waveform/doodle mask polish (reserved; rect + in/out first) - PC-as-AI-proxy mode (client direct-connect only) ## Decisions ### D1: Separate AI paths on the same LAN server process When AI share is enabled, expose `/ai/pair`, `/ai/config`, `/ai/config/meta`, `/ai/revoke` alongside publish (same or dedicated listener). Course APIs stay unauthenticated; AI APIs require pairing token. **Why:** Reuse LAN discovery/QR UX; avoid mixing secrets into course download surface. ### D2: Pairing + ECDH + AES-GCM (not raw HTTPS dependency) QR carries `baseUrl`, `pairId`, PC ephemeral public key. iPad completes ECDH, receives `sessionToken`. Config responses are AES-GCM ciphertext. Keys never appear in QR/URL. **Alternatives:** Cleartext over trusted LAN (rejected); self-signed HTTPS pin (optional later). ### D3: Sync by `updatedAt`, prefer newest When PC reachable: fetch meta/config, compare timestamps, keep newer locally. When unreachable: use Keychain cache if present. Future Server: three-way max `updatedAt` with `source` retained. ### D4: Storage - iPad: Key + sessionToken in Keychain (`WhenUnlockedThisDeviceOnly`); metadata in UserDefaults/SwiftData - PC: Key in OS keyring (macOS Keychain / Windows Credential Manager) or encrypted file fallback; UI shows last 4 chars only ### D5: Server subscription (Phase C stub) Config `source: "pc" | "server"`. Provide merge helpers and a disabled-by-default `serverBaseUrl` setting. Prefer future short-lived proxy tokens over long-lived raw keys from server. No live billing in this change. ### D6: Study AI context - PDF: cropped page region image + question + `prompts.pdfAsk` - AV: `startMs`/`endMs` (+ optional note) + `prompts.audioAsk` / `prompts.videoAsk` - Calls go from device → `baseUrl` with configured key ## Risks / Trade-offs - **[Risk] Same-WiFi attacker** → Mitigation: pairing code, encrypted payload, revocable tokens; AI share default off - **[Risk] Stale cached key after rotation** → Mitigation: mark cache stale on revoke/401; prompt re-pair - **[Risk] Child accidental AI use** → Mitigation: AI entry behind parent menu / explicit affordance - **[Trade-off] ECDH on LAN vs HTTPS** → ECDH works offline without CA; HTTPS pin can be added later - **[Trade-off] Client holds raw key** → Required for direct-connect MVP; server proxy later reduces exposure ## Migration Plan 1. Ship PC AI settings + share endpoints (default off) 2. Ship iPad pair/sync + Keychain 3. Ship study AI panels gated by `features` 4. Later enable server source without schema break Rollback: disable AI share; clients keep offline cache until cleared. ## Open Questions - None blocking MVP; vendor list can start with `openai` + `custom`.