M-2: Settings surface (canonical config writer; F-001/UQ-4) #6

Open
opened 2026-05-12 19:01:59 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-05-12 19:01:59 +00:00 (Migrated from github.com)

Goal

Land Settings as the single canonical writer for configuration mutation (F-001 / UQ-4). Foundation for all subsequent commands that flip config; Voice surface will lose configuration setters in M-6 once Settings is canonical.

Scope — surfaces in this phase

  • JarvisAPI.Settings with getSettings query + settingsChanged event
  • Commands: setProvider, setTTSTier, setSTTBackend, setFeatureFlag, setHotkey, storeAPIKey
  • Per UQ-4: Settings also owns setWakeWordMuted, setVoiceRunning, setLaunchAtLogin (replaces Voice's muteWakeWord/unmuteWakeWord/startVoice/shutdownVoice)
  • Hotkey collision detector (G-005 harness-injectable trigger for bindFailed)
  • getSettings.confirmationTimeoutSeconds field (foreshadows R-008 / M-7 ConfirmationBroker fix)

Files (created/modified)

  • packages/JarvisAPI/Sources/JarvisAPI/Surfaces/Settings+Adapter.swift (new) — wraps ConfigStore
  • App/AppDelegate.swift — wire Settings conformer
  • Settings window (legacy AppKit) — keeps working in dual-writer mode (both paths converge on ConfigStore)
  • packages/Harness/Tests/HarnessTests/SettingsScenarioTests.swift (new)

Test contract

Scenarios S-SET-001..S-SET-008 — all run in BOTH transport modes per UQ-5:

  • Round-trip per-field setters (provider, TTS tier, STT backend, feature flag, hotkey, API key, wake-word mute, voice running, launch-at-login)
  • Hotkey collision detector emits bindFailed
  • API-key validate via mock provider (UQ-1 gate)
  • getSettings.confirmationTimeoutSeconds round-trips against ConfigStore.perTurn().confirmationPolicy.timeoutSeconds

Acceptance criteria

  • All Settings scenarios green via .inProcessActor runner
  • All Settings scenarios green via .jsonRoundTripWebView runner
  • bash scripts/check-bus-harness-parity.sh green
  • getSettings.confirmationTimeoutSeconds round-trip matches ConfigStore.perTurn().confirmationPolicy.timeoutSeconds
  • Settings window (legacy AppKit) still works during dual-writer window
  • bash scripts/check-app-builds.sh green
  • PR merged to develop

Carry-forward closures

None — substrate for downstream surfaces.

Dependencies

  • Blocked by: #5 (M-1)
  • Blocks: #7 (M-3 Diagnostics)

Sub-issues

  • #105 — M-2: define JarvisAPI.Settings protocol + adapter wrapping ConfigStore
  • #106 — M-2: Settings commands — setProvider/setTTSTier/setSTTBackend/setFeatureFlag/setHotkey/storeAPIKey
  • #107 — M-2: Settings.setWakeWordMuted/setVoiceRunning/setLaunchAtLogin (UQ-4 slim Voice prep)
  • #108 — M-2: harness scenarios S-SET-001..008 in both transport modes (UQ-5)

Estimate

1.5–2.0 engineer-days

Source

  • .planning/architecture/JARVIS-API-MIGRATION-PLAN.md §2.3
  • .planning/architecture/JARVIS-API-DESIGN-v0.1.md — Settings surface
  • .planning/architecture/JARVIS-API-DESIGN-v0.2.md §5 — UQ-4 (Settings is sole config writer)
  • .planning/architecture/REVIEW-MIGRATION-RISK.md R-008
  • Parent epic: v1.0 API Migration — UI/Backend separation (M-0..M-7) (#76)
## Goal Land Settings as the single canonical writer for configuration mutation (F-001 / UQ-4). Foundation for all subsequent commands that flip config; Voice surface will lose configuration setters in M-6 once Settings is canonical. ## Scope — surfaces in this phase - **`JarvisAPI.Settings`** with `getSettings` query + `settingsChanged` event - Commands: `setProvider`, `setTTSTier`, `setSTTBackend`, `setFeatureFlag`, `setHotkey`, `storeAPIKey` - Per UQ-4: Settings also owns `setWakeWordMuted`, `setVoiceRunning`, `setLaunchAtLogin` (replaces Voice's `muteWakeWord`/`unmuteWakeWord`/`startVoice`/`shutdownVoice`) - Hotkey collision detector (G-005 `harness-injectable` trigger for `bindFailed`) - `getSettings.confirmationTimeoutSeconds` field (foreshadows R-008 / M-7 ConfirmationBroker fix) ## Files (created/modified) - `packages/JarvisAPI/Sources/JarvisAPI/Surfaces/Settings+Adapter.swift` (new) — wraps `ConfigStore` - `App/AppDelegate.swift` — wire Settings conformer - Settings window (legacy AppKit) — keeps working in dual-writer mode (both paths converge on `ConfigStore`) - `packages/Harness/Tests/HarnessTests/SettingsScenarioTests.swift` (new) ## Test contract Scenarios `S-SET-001..S-SET-008` — all run in BOTH transport modes per UQ-5: - Round-trip per-field setters (provider, TTS tier, STT backend, feature flag, hotkey, API key, wake-word mute, voice running, launch-at-login) - Hotkey collision detector emits `bindFailed` - API-key validate via mock provider (UQ-1 gate) - `getSettings.confirmationTimeoutSeconds` round-trips against `ConfigStore.perTurn().confirmationPolicy.timeoutSeconds` ## Acceptance criteria - [ ] All Settings scenarios green via `.inProcessActor` runner - [ ] All Settings scenarios green via `.jsonRoundTripWebView` runner - [ ] `bash scripts/check-bus-harness-parity.sh` green - [ ] `getSettings.confirmationTimeoutSeconds` round-trip matches `ConfigStore.perTurn().confirmationPolicy.timeoutSeconds` - [ ] Settings window (legacy AppKit) still works during dual-writer window - [ ] `bash scripts/check-app-builds.sh` green - [ ] PR merged to develop ## Carry-forward closures None — substrate for downstream surfaces. ## Dependencies - Blocked by: #5 (M-1) - Blocks: #7 (M-3 Diagnostics) ## Sub-issues - #105 — M-2: define JarvisAPI.Settings protocol + adapter wrapping ConfigStore - #106 — M-2: Settings commands — setProvider/setTTSTier/setSTTBackend/setFeatureFlag/setHotkey/storeAPIKey - #107 — M-2: Settings.setWakeWordMuted/setVoiceRunning/setLaunchAtLogin (UQ-4 slim Voice prep) - #108 — M-2: harness scenarios S-SET-001..008 in both transport modes (UQ-5) ## Estimate 1.5–2.0 engineer-days ## Source - `.planning/architecture/JARVIS-API-MIGRATION-PLAN.md` §2.3 - `.planning/architecture/JARVIS-API-DESIGN-v0.1.md` — `Settings` surface - `.planning/architecture/JARVIS-API-DESIGN-v0.2.md` §5 — UQ-4 (Settings is sole config writer) - `.planning/architecture/REVIEW-MIGRATION-RISK.md` R-008 - Parent epic: #76
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#6