Releases: tigercraft4/goose
v12.0
- style: cargo fmt bridge and openwhoop_reference files
- fix: add packet_type_debug_name for unknown packet type visibility
- seeds: v13.0 hardware bands (Puffin/Monument/Symphony) and Rust arch refactor
- fix: correct BLE command opcodes for high-freq sync, extended battery, IMU historical mode
- feat(91-02): add ALGO: bibliographic comments to Rust algorithm constants
- feat(91-01): add THREADING: invariant comments to Swift bridge and queue types
- feat(90-04): update all view files to read from domain objects; build succeeds
- wip(90-04): partial view migration — save before merge
- feat(90-04): inject domain objects at scene root and redirect sync view
- refactor(90-03): redirect all migrated property writes through domain objects in GooseAppModel extensions
- wip: partial 90-03 changes before rebase
- refactor(90-02): update init() callbacks to write through domain objects
- refactor(90-02): remove migrated var properties from GooseAppModel; add domain lets
- feat(90-01): add HealthState @observable domain object and register all 3 in Xcode project
- feat(90-01): add SyncState @observable domain object
- feat(90-01): add BLEState @observable domain object
- feat(89-02): update GooseAppModel.ble to any BLETransport via BLESessionCoordinator
- feat(89-03): replace scattered capability guards with DeviceCatalog queries
- feat(89-03): add DeviceCatalog struct centralising Gen4/Gen5 capability branching
- feat(89-02): create BLESessionCoordinator actor
v11.0
- chore(v11.0): remove REQUIREMENTS.md — archived to milestones/v11.0-REQUIREMENTS.md
- docs(v11.0): archive milestone — ROADMAP, REQUIREMENTS, AUDIT committed to milestones/
- docs(v11.0): milestone audit passed — 23/23 requirements satisfied
- docs: plant seed SEED-003 — Gen4/Gen5 protocol architecture refactor (deferred from Phase 83)
- docs(v11.0): phases 80-82 complete — roadmap and state updated
- feat(phase-82): persist HealthKit import to metric_series SQLite table
- fix(phase-81): expose R22 battery_pct in compact summary; reject invalid 2A19 reads
- fix(phase-80): tighten resting HR floor from 25 to 30 bpm in metric_features.rs
- feat(v11.0): add phases 80-82 from issue backlog (resting HR, battery, HealthKit persistence)
- chore: mark SEED-001 resolved (implemented in Phase 78 BLE-REL-01)
- docs(v11.0): milestone audit passed — 20/20 requirements satisfied
- docs(v11.0): Phase 79 complete — all 6 phases done, milestone ready for audit
- docs(79): complete polish and deferred features plan summary
- feat(79): rename Support to Logs & Export, reorganise More nav (POL-02)
- feat(79): split More > Debug into Status/Capture/Research tabs (POL-01)
- docs: plant seed SEED-002 — battery level Gen4+Gen5 protocol offsets
- docs(v11.0): Phase 78 complete — perf + BLE reliability done
- docs(78-01): complete performance and BLE reliability plan summary
- feat(78): BLE auth retry on insufficientAuthentication with 2.5s delay (BLE-REL-01)
- perf(78): defer GooseBLEClient/bridge init for faster first frame (PERF-02)
- perf(78): add covering indexes on schema v20 tables (PERF-01)
- docs(78): context (PERF-01/02 + BLE-REL-01)
- docs(v11.0): Phase 77 complete — codebase audit done
- docs(77): AUDIT-03 verification — 6 CRITICAL fixed, build passed
- fix(73): gate alarmIsArmed and buzz on canWriteAlarm guard (CR-01, CR-02)
- fix(71): add 90-day retention limit to DailyJournalStore (CR-02)
- fix(71): use async notificationSettings to preserve actor isolation (CR-01)
- fix(70): correct haptic command sequence rollover to 0 (CR-01)
- fix(67): validate calendar date bounds in parse_rfc3339_utc_unix_ms (CR-01)
- docs(77): AUDIT-02 code review phases 67-73 (6 CRITICAL, 15 WARNING)
v10.0
No changes listed.
v9.0
- chore: archive v9.0 milestone — BLE Reliability & Protocol Parity (5/6 phases shipped)
- feat(about): add License section with GPL v3, copyright, source link; rename Model → Device
- docs(v9.0): milestone audit — passed (5/6 phases, Phase 66 hardware-gated)
- seed: release-version-bump — align MARKETING_VERSION with milestone number per release
- docs(66): Ghidra investigation — cap sense UUID blocked, 11500X series candidates documented
- seeds: smart-alarm-strap-haptic, journal-behaviour-tracking, coach-vow-messages (Ghidra-verified)
- docs(65): verification passed — generic BLE state machine complete
- docs(65): add code review fix report
- fix(65): revert static let bleLogger to static var in generic struct (Swift limitation)
- fix(65): WR-01 change bleLogger from computed var to static let in StateMachine
- fix(65): CR-01 CR-02 add NSLock to GooseBLEBondingManager and check transition result
- docs(65): add code review report
- docs(65-01): complete generic-ble-state-machine plan — SUMMARY, STATE, ROADMAP updated
- feat(65-01): wire GooseStateMachine.swift into pbxproj and migrate GooseBLEBondingManager onto StateMachine
- feat(65-01): add generic StateMachine struct and GooseBLEBondingEvent transition table
- chore(github): migrate issue templates to yml with required fields
- docs(65): create phase plan
- docs(65): auto-generated context (infrastructure phase)
- docs(64): verification passed — HR data sanitizer complete
- fix(64): replace (20...240) literals with GooseHRSanitizer thresholds; validRange as static let
- docs(64): add code review report
- docs(64-02): human verification passed — HR sanitizer visible in More > Debug
- seeds: align all trigger_conditions to v10.0 milestone scope
- seeds: ble-data-validator, realtime-strain, hr-decimation, service-layer-di, ble-historical-manager
- docs(64-01): complete HR Data Sanitizer plan
- feat(64-01): wire hrSpikeCount observable and display in More > Debug
- feat(64-01): gate recordLiveHeartRate through GooseHRSanitizer
- feat(64-01): add GooseHRSanitizer value type with static thresholds
- docs(64): create phase plan for HR data sanitizer
- docs(64): auto-generated context (infrastructure phase)
v8.0
- chore: remove REQUIREMENTS.md for v8.0 milestone
- chore: archive v8.0 milestone files
- docs(61): add pattern map
- docs(61): resolve open questions in research
- docs(61): create phase plan for BLE bonding state machine
- chore: replace tigercraft4 bundle IDs with com.goose.app
- docs(phase-61): add validation strategy
- docs(61): research phase BLE bonding state machine
- docs(planning): mark milestone v8.0 complete, backfill v6.0 entry
- fix(ble): guard peripheral.state == .connected in refreshBatteryLevel
- feat(nav): move HR Monitor from Device tab to More > Device section
- fix(i18n): add missing en overrides and pt-PT translations
- fix(device): use openSettingsURLString for BT Settings button
- chore: move REVIEWS-06-08.md to milestones archive
- feat(coach): sign-in card button opens settings instead of inline OAuth
- test(60): complete UAT — 4 passed, 2 blocked (physical-device)
- docs(phase-60): add/update validation strategy
- docs(phase-60): add/update security threat verification
- fix(60): guard BGTask handler against nil sharedModel and force cast (CR-01, CR-02)
- docs(60): add phase verification report
- docs(60): add phase verification report
- docs(60): add code review report
- docs(60-03): complete band-first sync integration plan — all tasks done and human-verified
- docs(60-03): complete plan 03 tasks 1-3; checkpoint at task 4 human-verify
- fix(60-03): add BandFirstSync to Xcode project; remove residual overnight call sites
- feat(60-03): remove overnight UI, context refs, residual call sites; repo sweep clean
- feat(60-03): remove overnightGuardActive from NotificationPipeline and ActivityTimeline
- feat(60-03): rewrite Lifecycle handlers; add D-03 on-disk purge
- docs(60-02): complete band-first sync BGAppRefreshTask wiring plan
- feat(60-02): register BGAppRefreshTask in GooseSwiftApp and add Info.plist keys
v7.0
v7.0 — Sync Correctness, Async & Sleep Sync
Shipped: 2026-06-10 | Phases: 5 (46–50) | Plans: 18 | Requirements: 8/12
What's New
Upload round-trip complete; upload-sync race eliminated; HealthDataStore fully async; morning band sleep sync wired end-to-end.
Upload route pair (Phase 46)
POST /v1/ingest-frames— raw BLE frame ingest with Bearer authGET /v1/export/frames/{device_id}— cursor-paginated export; bidirectional UUID ↔ device_model lookup
device_uuid end-to-end (Phase 47)
- CoreBluetooth UUID captured at BLE connect; stored in
raw_evidence+decoded_framesSQLite columns; propagated to server on every upload
Upload sync race fix (Phase 48)
captureAllPendingRowIDspre-HTTP;markStreamsSyncedonly after2xx— eliminates blind-marking bug where interrupted uploads left rows permanently "synced" without server confirmation
HealthDataStore async migration (Phase 49)
- 60+
bridge.requestcalls converted from synchronous GCD.asynctoasync/await - All GCD dispatch queues removed from HealthDataStore scope; zero blocking calls on
@MainActor
Morning band sleep sync (Phase 50)
gravity_x/y/zextracted from V24History K18/K24 frames at BLE connect (morning, hour ≥ 4)- Cole-Kripke staging →
external_sleep_sessionsimport - Sleep V2 shows "A aguardar sincronização" / "Sincronizado da pulseira" state labels
Algorithm defaults — sleep v1, strain v1, recovery v1, readiness v1 promoted to defaults
Deferred (Phase 51 — hardware gate)
VAL-HRV-01/VAL-SLP-01: physical WHOOP device + ≥5 overnight captures required- K24 gravity offset confirmation (K33–K44 vs actual WHOOP sensor)
MoreDataStoreasync migration (18+ callers) — explicitly scoped out of Phase 49
v6.0
v6.0 — UI Wiring, Algorithm Alignment & Parity Validation
Shipped: 2026-06-09 | Phases: 9 (36–45) | Files changed: 31 | Lines added: +2910
What's New
All v5.0 Rust algorithms wired into SwiftUI dashboards; three algorithm divergences corrected; pt-PT localisation at 0 untranslated strings.
Dashboard wiring
- Recovery: daily readiness level (rundown / strained / balanced / primed); ACWR 7d/28d; Foster monotony
- Sleep V2: 4-class hypnogram (wake / light / deep / REM); AASM metrics — REM latency, TST, efficiency, SOL, WASO per stage
- V24 Biometrics: SpO₂, respiratory rate, wrist temperature with "Não calibrado" badge
- Strain: detected activities list with start time, duration, calories, strain score
- IMU: steps card ("via acelerómetro") in Strain tab
Algorithm alignment (Phase 42) — fixed 3 divergences: Recovery Z-score + logistic, EWMA α = 0.0483, Cole-Kripke 30 s epochs
Synthetic validation fixtures — HRV and sleep-staging fixtures for hardware-gated tests
Raw BLE frame import — importHistoricalDataFromServer button wired; trust-chain rebuilt without BLE reconnection; fallback to rr_intervals when decoded_frames unavailable
Upload Sync UI — pending badge; manual Backfill button; Test Connection with inline /healthz result
Localisation — 775 pt-PT strings; 0 untranslated (was 49)
Deferred
ALG-HRV-04/ALG-SLP-04: real overnight validation gates — synthetic fixtures ready, hardware required- V24 biometric live decode (SpO₂/skin_temp/resp show "--" pending K24 offset confirmation)
v5.0
v5.0 — Metrics Accuracy, IMU & Upstream Fixes
Shipped: 2026-06-08 | Phases: 16 (20–35) | Plans: 28 | Requirements: 22/26 | Rust tests: 128 | Schema: v19
What's New
All core biometric algorithms ported from Python reference into Rust and validated against WHOOP 5.37.0 IPA via Ghidra disassembly.
HRV pipeline — BLE-gap segmentation; Lipponen-Tarvainen ectopic filter; tiered SWS window selection
Recovery v1 — Z-score + logistic squash; EWMA baseline (14-night α = 0.0483); cold-start gate; Vermelho / Amarelo / Verde scoring
Strain & Calories — Tanaka HRmax; Banister TRIMP; Keytel + Harris-Benedict coefficients (Ghidra-confirmed from WHOOP binary)
4-class Sleep Staging — Cole-Kripke + cardiorespiratory features + AASM physiological constraints
V24 Biometric Decode — SpO₂, skin temperature, respiratory rate, gravity2; 4 new SQLite tables; uncalibrated flag
Exercise Detection — retroactive from HR + gravity; Karvonen heart-rate zones; exercise_sessions table
Upload Sync — synced flag on 8 stream tables; two-namespace cursors; raw outbox prune invariant
Readiness Engine — ACWR (7d/28d) + Foster monotony; 5-class synthesis (rundown → primed)
IMU foundation — I16SeriesSummary full_samples; gravity schema v15; feature-flagged
Code quality — 9 HIGH findings from codebase audit identified and fixed; upstream Gen4 historical sync corrected
Deferred (hardware gates)
ALG-HRV-04: RMSSD real-device validation (≥5 overnight sessions) → Phase 51ALG-SLP-04: 4-class staging concordance ≥70% (real overnight data) → Phase 51
v4.0
v4.0 — Security, Performance & Coach Expansion
Shipped: 2026-06-06 | Phases: 4 | Plans: 12 | Requirements: 8/10
What's New
Deep-link security guard, full @Observable migration, four-provider AI Coach, and complete pt-PT translations.
Security
allowsRemoteInvocationguard blocks state-changing BLE commands from externalgooseswift://deep links (SEC-01; upstream PR #15)
Performance — @Observable migration
- 68
@Publishedproperties removed acrossGooseAppModel,HealthDataStore,GooseBLEClient NavigationRequestObserverwarning eliminated; proper@Environmentconsumption in all views
AI Coach (multi-provider)
CoachProviderprotocol +CoachProviderRegistry- Four backends: ChatGPT, Claude, Custom endpoint, Gemini (OAuth PKCE)
- Provider picker UI in Coach Settings; isolated per-provider Keychain storage
Localisation — 128 new pt-PT strings for all Coach UI; 0 untranslated after gap-closure commit
Limitations
- Gemini OAuth, provider switching, and credential isolation require live API keys for human verification
v3.0
v3.0 — Wearable UX, CI Hardening & RTC Sync
Shipped: 2026-06-05 | Phases: 9 | Plans: 17 | Commits: 163 | Files changed: 83
What's New
HR monitor scan/connect UI, BLE stack hardening, WHOOP 4.0 RTC sync, Recovery V2 dashboard, and full pt-PT localisation.
BLE stability
catch_unwindFFI boundary; 24 MB storage cap; exponential reconnect backoff (1s → 60s) for both WHOOP and HR devices- Per-row
device_idcapture tracking
HR Monitor UI (Phase 10.1)
- Live
CBCentralManagerscan list with RSSI; connect sheet; connected status panel - Independent HR capture mode (
startHRMonitorCapture/stopHRMonitorCapture) ungated from WHOOP session
RTC sync — silent clock-drift correction via BLE after WHOOP 4.0 connection
Recovery V2 dashboard — hero readiness score; HRV/RHR metrics; 7-day trend cards
Localisation — Localizable.xcstrings; 650+ pt-PT strings; LocalizedStatusStrings.swift for dynamic status
HRV accuracy — rmssd_segment_aware; baseline normalisation; hkHRVSDNNMs rename