From d03e977360e9794f7fb500c82e7db5b64298446f Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 12 Mar 2026 15:50:39 -0500 Subject: [PATCH 001/133] Update submodule URLs to loopkitdev forks; add sync doc - Point all 18 submodule URLs to https://github.com/loopkitdev/* forks - Minizip and TrueTime.swift retain LoopKit origin (no forks) - Add docs/tidepool-sync-2026-03-10.md (Tidepool sync documentation) --- .gitmodules | 36 +- AmplitudeService | 2 +- CGMBLEKit | 2 +- G7SensorKit | 2 +- LibreTransmitter | 2 +- LogglyService | 2 +- Loop | 2 +- LoopKit | 2 +- LoopOnboarding | 2 +- LoopSupport | 2 +- .../xcshareddata/swiftpm/Package.resolved | 12 +- MinimedKit | 2 +- NightscoutRemoteCGM | 2 +- NightscoutService | 2 +- OmniBLE | 2 +- OmniKit | 2 +- RileyLinkKit | 2 +- TidepoolService | 2 +- dexcom-share-client-swift | 2 +- docs/tidepool-sync-2026-03-10.md | 669 ++++++++++++++++++ 20 files changed, 714 insertions(+), 37 deletions(-) create mode 100644 docs/tidepool-sync-2026-03-10.md diff --git a/.gitmodules b/.gitmodules index 1308e60c03..3637ab97e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,21 +1,21 @@ [submodule "Loop"] path = Loop - url = https://github.com/LoopKit/Loop.git + url = https://github.com/loopkitdev/Loop.git [submodule "LoopKit"] path = LoopKit - url = https://github.com/LoopKit/LoopKit.git + url = https://github.com/loopkitdev/LoopKit.git [submodule "CGMBLEKit"] path = CGMBLEKit - url = https://github.com/LoopKit/CGMBLEKit.git + url = https://github.com/loopkitdev/CGMBLEKit.git [submodule "dexcom-share-client-swift"] path = dexcom-share-client-swift - url = https://github.com/LoopKit/dexcom-share-client-swift.git + url = https://github.com/loopkitdev/dexcom-share-client-swift.git [submodule "RileyLinkKit"] path = RileyLinkKit - url = https://github.com/LoopKit/RileyLinkKit + url = https://github.com/loopkitdev/RileyLinkKit [submodule "NightscoutService"] path = NightscoutService - url = https://github.com/LoopKit/NightscoutService.git + url = https://github.com/loopkitdev/NightscoutService.git [submodule "Minizip"] path = Minizip url = https://github.com/LoopKit/Minizip.git @@ -24,37 +24,37 @@ url = https://github.com/LoopKit/TrueTime.swift.git [submodule "LoopOnboarding"] path = LoopOnboarding - url = https://github.com/LoopKit/LoopOnboarding.git + url = https://github.com/loopkitdev/LoopOnboarding.git [submodule "AmplitudeService"] path = AmplitudeService - url = https://github.com/LoopKit/AmplitudeService.git + url = https://github.com/loopkitdev/AmplitudeService.git [submodule "LogglyService"] path = LogglyService - url = https://github.com/LoopKit/LogglyService.git + url = https://github.com/loopkitdev/LogglyService.git [submodule "OmniBLE"] path = OmniBLE - url = https://github.com/LoopKit/OmniBLE.git + url = https://github.com/loopkitdev/OmniBLE.git [submodule "NightscoutRemoteCGM"] path = NightscoutRemoteCGM - url = https://github.com/LoopKit/NightscoutRemoteCGM.git + url = https://github.com/loopkitdev/NightscoutRemoteCGM.git [submodule "LoopSupport"] path = LoopSupport - url = https://github.com/LoopKit/LoopSupport + url = https://github.com/loopkitdev/LoopSupport [submodule "G7SensorKit"] path = G7SensorKit - url = https://github.com/LoopKit/G7SensorKit.git + url = https://github.com/loopkitdev/G7SensorKit.git [submodule "TidepoolService"] path = TidepoolService - url = https://github.com/LoopKit/TidepoolService.git + url = https://github.com/loopkitdev/TidepoolService.git [submodule "OmniKit"] path = OmniKit - url = https://github.com/LoopKit/OmniKit.git + url = https://github.com/loopkitdev/OmniKit.git [submodule "MinimedKit"] path = MinimedKit - url = https://github.com/LoopKit/MinimedKit.git + url = https://github.com/loopkitdev/MinimedKit.git [submodule "MixpanelService"] path = MixpanelService - url = https://github.com/LoopKit/MixpanelService + url = https://github.com/loopkitdev/MixpanelService [submodule "LibreTransmitter"] path = LibreTransmitter - url = https://github.com/LoopKit/LibreTransmitter.git + url = https://github.com/loopkitdev/LibreTransmitter.git diff --git a/AmplitudeService b/AmplitudeService index 5a7e8c69f5..f094a60c2d 160000 --- a/AmplitudeService +++ b/AmplitudeService @@ -1 +1 @@ -Subproject commit 5a7e8c69f545bd8a2347dd35f68c7ac95ec4492b +Subproject commit f094a60c2d223601d36be077387591d21c53b2a8 diff --git a/CGMBLEKit b/CGMBLEKit index 134396b961..c8dbdd4aab 160000 --- a/CGMBLEKit +++ b/CGMBLEKit @@ -1 +1 @@ -Subproject commit 134396b96170d410b18f9699b92409bc6d35aedb +Subproject commit c8dbdd4aab35427dc8b7807b6e6f7ad9b856f4fd diff --git a/G7SensorKit b/G7SensorKit index 0c09305008..c86b4d4195 160000 --- a/G7SensorKit +++ b/G7SensorKit @@ -1 +1 @@ -Subproject commit 0c093050084b63d7af0dc99307dba09239eb3180 +Subproject commit c86b4d4195fcb045f06e3082e5cf00cded81f70e diff --git a/LibreTransmitter b/LibreTransmitter index 12dec3ce19..6c0e4aa667 160000 --- a/LibreTransmitter +++ b/LibreTransmitter @@ -1 +1 @@ -Subproject commit 12dec3ce191afe761fd68a70172ef75638319e20 +Subproject commit 6c0e4aa66758decbe6a2537164cd2e3d36de70a5 diff --git a/LogglyService b/LogglyService index 8a7691cd74..eb04e1b7be 160000 --- a/LogglyService +++ b/LogglyService @@ -1 +1 @@ -Subproject commit 8a7691cd7497ffacf4fd8caa4a174fb860e42297 +Subproject commit eb04e1b7be192753e9f37b790b9159f8174cbc3e diff --git a/Loop b/Loop index c044b52fb3..79eee6d5cb 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit c044b52fb30f3986a7b55c6d5cb1c587c5f9a4ee +Subproject commit 79eee6d5cbb24915b6101fac476df4b4e0d7a40a diff --git a/LoopKit b/LoopKit index 58cd228556..e003e6b69e 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 58cd22855637a86fd1776d1735fec4cb2b92a460 +Subproject commit e003e6b69e61d8ba73be3e19b564c1f655fb29c9 diff --git a/LoopOnboarding b/LoopOnboarding index 60f57a77c9..7bfc5fdf8c 160000 --- a/LoopOnboarding +++ b/LoopOnboarding @@ -1 +1 @@ -Subproject commit 60f57a77c9450df17c39f475542795e72f261136 +Subproject commit 7bfc5fdf8c323fce9c1fedcf52ecbd19afea137d diff --git a/LoopSupport b/LoopSupport index 6d7d3e293e..4538579519 160000 --- a/LoopSupport +++ b/LoopSupport @@ -1 +1 @@ -Subproject commit 6d7d3e293ebc5f8b7d9f9e6b0326bf6641da8680 +Subproject commit 4538579519b80a33422097ee7d3425130be49ead diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 85b387d04a..5d6f9b843a 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "7645108625333b4ec60e0e439db0c0dc8a91ad0942d36797c6b66208a9082ea2", + "originHash" : "9fa433ef5fce7eff885b44f4dea36e033d61f148853051ee0494bf4e79200676", "pins" : [ { "identity" : "amplitude-ios", @@ -82,6 +82,15 @@ "version" : "2.0.0" } }, + { + "identity" : "loopalgorithm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tidepool-org/LoopAlgorithm", + "state" : { + "branch" : "main", + "revision" : "13cb4b45258cee5be1eb2ad941b374dde53de551" + } + }, { "identity" : "mixpanel-swift", "kind" : "remoteSourceControl", @@ -167,7 +176,6 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/LoopKit/ZIPFoundation.git", "state" : { - "branch" : "stream-entry", "revision" : "c67b7509ec82ee2b4b0ab3f97742b94ed9692494" } } diff --git a/MinimedKit b/MinimedKit index 942996e3f5..c13c039344 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit 942996e3f53c4875553c9827aeee1799a8dbf434 +Subproject commit c13c039344decf762b988062af9f2a7c8ec752eb diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 512c9dc6d8..87e3898b01 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 512c9dc6d81b54ea9cc9a3a6681a888ea5ac91dc +Subproject commit 87e3898b01d84e0ad7f42dc6d4dc23b3f377c4d2 diff --git a/NightscoutService b/NightscoutService index d21abadedf..1ea3e43b4e 160000 --- a/NightscoutService +++ b/NightscoutService @@ -1 +1 @@ -Subproject commit d21abadedf3cb25fa4732223f3954a22050ee532 +Subproject commit 1ea3e43b4e93926f8d5670c17b2541ace65e53a8 diff --git a/OmniBLE b/OmniBLE index 3782c584fe..536efd9244 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit 3782c584fe800116b6e60754e3be3cd818e033ee +Subproject commit 536efd9244d894bb67a552168fe6243dcdf124fd diff --git a/OmniKit b/OmniKit index 1446be89bf..0e3cf2e0c8 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit 1446be89bfab23ac021d3e22f03b34bda8ce30cf +Subproject commit 0e3cf2e0c89b27db466da4bc43087e9be82c2f5d diff --git a/RileyLinkKit b/RileyLinkKit index 8dad76d152..b9a52dccc2 160000 --- a/RileyLinkKit +++ b/RileyLinkKit @@ -1 +1 @@ -Subproject commit 8dad76d15295e13e091be74f6f47dbca5f0eb022 +Subproject commit b9a52dccc2b5f7c69b344770b5c65da4862f907c diff --git a/TidepoolService b/TidepoolService index a10f9d3ba0..08b57560b6 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit a10f9d3ba097daae85de61d4a5bca063f34d64dc +Subproject commit 08b57560b6585fdb04d3e245d00899a0d50ff45e diff --git a/dexcom-share-client-swift b/dexcom-share-client-swift index 8c4f0edfe9..29409f34c6 160000 --- a/dexcom-share-client-swift +++ b/dexcom-share-client-swift @@ -1 +1 @@ -Subproject commit 8c4f0edfe9356463c66a2e5dff9d00794291ebfd +Subproject commit 29409f34c6fb127eec683e9133975c9fde0e015c diff --git a/docs/tidepool-sync-2026-03-10.md b/docs/tidepool-sync-2026-03-10.md new file mode 100644 index 0000000000..2569b7f625 --- /dev/null +++ b/docs/tidepool-sync-2026-03-10.md @@ -0,0 +1,669 @@ +# Tidepool → LoopKit DIY Sync — 2026-03-10 + +**Branch:** `tidepool-sync/2026-03-10` (all 18 repos) +**Build status:** ✅ Compiles clean (verified 2026-03-12) + +This document describes the changes introduced by syncing the Tidepool fork of Loop +back into DIY, the conflicts encountered during that merge, and the +decisions made to resolve them. + +--- + +## Table of Contents + +1. [New Features from Tidepool](#1-new-features-from-tidepool) +2. [Conflicts Encountered](#2-conflicts-encountered) +3. [Conflict Resolution Decisions](#3-conflict-resolution-decisions) +4. [DIY Features Preserved](#4-diy-features-preserved) +5. [Post-Merge Fixes](#5-post-merge-fixes) +6. [Testing Notes](#6-testing-notes) + +--- + +## 1. New Features from Tidepool + +### LoopAlgorithm — A New Architecture for DIY + +#### Background: What Changed and Why + +DIY Loop previously embedded algorithm logic directly +inside `LoopKit` as an inline copy (`LoopKit/LoopKit/LoopAlgorithm/`), and effects +calculations were distributed across the data store layer — `CarbStore` computed carb +effects, `DoseStore` computed insulin effects, and `GlucoseStore` computed glucose momentum +and retrospective correction. `LoopDataManager` orchestrated these by calling each store +asynchronously and stitching the results together. The central `LoopAlgorithm` type was +a Swift `actor` — a stateful, async object. + +This sync introduces the **LoopAlgorithm Swift Package** as an actual dependency, replacing +that architecture with something fundamentally different. + +#### The New Design: Functional and Stateless + +The package reconceives the algorithm as a **pure function**: given a complete snapshot of +the user's current state, produce a complete output. No stores, no CoreData, no HealthKit, +no async, no side effects. + +``` +AlgorithmOutput = LoopAlgorithm.run(input: AlgorithmInput) +``` + +`LoopAlgorithm` is now declared as a `caseless enum` — it cannot be instantiated. All +methods are static. There is no mutable state. The same input will always produce the +same output. + +**Input (`AlgorithmInput` protocol)** is a value-type snapshot containing everything the +algorithm needs: + +| Field | Description | +|-------|-------------| +| `glucoseHistory` | Recent CGM readings | +| `doses` | Insulin delivery history (basal + boluses) | +| `carbEntries` | Active carb entries | +| `basal` | Scheduled basal rate timeline | +| `sensitivity` | ISF timeline | +| `carbRatio` | ICR timeline | +| `target` | Glucose target range timeline | +| `suspendThreshold` | Low glucose suspend threshold | +| `maxBolus` | Safety limit | +| `maxBasalRate` | Safety limit | +| `maxActiveInsulinMultiplier` | Max IOB cap as multiple of maxBolus (default 2×) | +| `carbAbsorptionModel` | Parabolic, linear, or piecewise linear | +| `recommendationType` | Temp basal, automatic bolus, or manual | +| `useIntegralRetrospectiveCorrection` | IRC vs standard RC | +| `gradualTransitionsThreshold` | Threshold for gradual effect ramping | + +**Output (`AlgorithmOutput`)** is a complete value type containing everything produced: + +| Field | Description | +|-------|-------------| +| `recommendationResult` | `Result` — temp basal and/or bolus | +| `predictedGlucose` | Full glucose prediction curve | +| `effects` | Broken-out insulin, carb, momentum, RC, counteraction effects | +| `dosesRelativeToBasal` | Each dose expressed relative to scheduled basal | +| `activeInsulin` | Current IOB | +| `activeCarbs` | Current COB | + +The `effects` field (`LoopAlgorithmEffects`) exposes every intermediate calculation — +insulin effect curve, carb effect curve, carb absorption status per entry, retrospective +correction, glucose momentum, insulin counteraction velocities, and retrospective glucose +discrepancies. Previously these intermediate values were scattered across store callbacks +and ephemeral local variables inside `LoopDataManager`. + +#### Why This Matters for DIY + +**Testability.** Because the algorithm is a pure function over value types, tests require +no mocks, no CoreData stack, no async machinery. A test is just: + +```swift +let input = AlgorithmInputFixture(...) // or decoded from JSON +let output = LoopAlgorithm.run(input: input) +XCTAssertEqual(output.predictedGlucose, expected) +``` + +Fixtures can be serialized to and from JSON, making it trivial to capture a real-world +scenario and turn it into a regression test. The package ships with JSON fixture files +for glucose math, carb math, and dosing scenarios. + +**Portability.** Removing HealthKit and CoreData as dependencies means the algorithm can +run anywhere Swift runs — on a server, in a command-line tool, in a simulation, or in +tests — without needing a full iOS stack underneath it. + +**Clarity.** Previously, understanding what went into a dosing decision required tracing +through multiple async callbacks across multiple store classes. Now the entire decision +lives in one call with explicit inputs and outputs. + +#### What the Package Replaced vs. What Was Already There + +| Aspect | Before (DIY inline) | After (LoopAlgorithm package) | +|--------|--------------------|-----------------------------| +| `LoopAlgorithm` type | `public actor` (stateful, async) | `public enum` (no state, static methods only) | +| Entry point | `generatePrediction(input:startDate:) throws` | `run(input:) -> AlgorithmOutput` (non-throwing; errors in Result) | +| Effects calculation | Distributed across `CarbStore`, `DoseStore`, `GlucoseStore` | All in `LoopAlgorithm.generatePrediction(...)` static methods | +| Error handling | `throws` propagated through async chain | `Result<_, Error>` in output struct | +| Effects exposed | 5 fields (insulin, carbs, RC, momentum, counteraction) | 8 fields (adds carbStatus, retrospective discrepancies, total RC magnitude) | +| Error cases | 2 (`missingGlucose`, `incompleteSchedules`) | 7 (granular: glucose too old, incomplete timeline, sensitivity window, etc.) | +| Unit types | `HKUnit` / `HKQuantity` (HealthKit) | `LoopUnit` / `LoopQuantity` (custom, no HealthKit import) | +| Dependencies | HealthKit, CoreData | None (pure Swift) | +| Testability | Required mocked async stores | Pure value types; JSON fixture files included | + +#### Specific Changes in This Sync's LoopAlgorithm Version + +On top of the architectural shift, the version of LoopAlgorithm synced here includes +several algorithmic and API improvements made by Tidepool since the package was established: + +| Change | Details | +|--------|---------| +| **Gradual effect transitions** | Insulin and carb effects ramp up gradually at the start of absorption rather than stepping immediately to full effect, producing smoother prediction curves (PR #23) | +| **Configurable max active insulin multiplier** | `maxActiveInsulinMultiplier` on `AlgorithmInput` caps max IOB as a multiple of `maxBolus`; defaults to 2× (LOOP-5502, PR #22) | +| **Carb absorption model selection** | `carbAbsorptionModel` field on input allows runtime selection of parabolic, linear, or piecewise-linear absorption modeling (PR #21) | +| **AutomaticDoseRecommendation backward decode fix** | Decoding old stored recommendations without `basalAdjustment` field no longer crashes (PR #20) | +| **ISF fix during mid-absorption** | Corrects which ISF value is used during active carb absorption for more accurate corrections (PR #19) | +| **TempBasalRecommendation direction** | `.direction` field (increase / decrease / unchanged) added to `TempBasalRecommendation`; enables directional UI feedback (LOOP-5295, PR #18) | +| **Swift 6 Sendable conformances** | `AbsoluteScheduleValue` and other types marked `Sendable` throughout (PR #14) | +| **Glucose math tests moved here** | `GlucoseMathTests.swift` and JSON fixtures moved from LoopKit into this package where they belong (PR #24) | + +### Loop (App) — Presets Overhaul + +Presets have been substantially redesigned. The changes span the data model, safety +guardrails, manager architecture, UI, and Watch app. This is the most user-visible +change in this sync. + +#### Before: Override Presets in DIY Loop + +In prior DIY Loop, override presets were simple `TemporaryScheduleOverridePreset` objects +stored in `LoopSettings.overridePresets`. Each preset had a name, symbol, correction range, +insulin sensitivity multiplier, and duration. There was no preset type system — all presets +were generic overrides. Users could set a target range and/or an ISF multiplier, activate +a preset from the toolbar, and it would run until it expired or was manually cancelled. +There were no guardrails specific to presets, no required training, no scheduling, and no +safety mitigations for extreme settings. + +#### After: SelectablePreset Type System + +Presets are now modeled as a typed enum, `SelectablePreset`, with three distinct cases: + +```swift +enum SelectablePreset { + case preMeal(range: ClosedRange) + case activity(ActivityPreset) + case custom(TemporaryPreset) +} +``` + +Each case has different capabilities enforced at the type level: + +| Capability | Pre-Meal | Activity | Custom | +|-----------|---------|----------|--------| +| Adjust correction range | ✅ | ✅ | ✅ | +| Adjust insulin needs (ISF multiplier) | ❌ | ✅ | ✅ | +| Set duration | ❌ (ends when carbs entered) | ✅ | ✅ | +| Indefinite duration | ❌ | ❌ | ✅ | +| Rename | ❌ | ❌ | ✅ | +| Schedule (day/time) | ❌ | ✅ | ✅ | +| Delete | ❌ | ❌ | ✅ | + +#### Activity Presets — Evidence-Based Defaults + +A new `.activity` case provides four pre-defined activity presets with evidence-based +default insulin reduction values. These appear in the Presets list for all users and +can be customized but not deleted: + +| Activity | Default Target Range | Default Insulin Needs | +|----------|--------------------|-----------------------| +| Jogging | 150–170 mg/dL | 21% of normal | +| Biking | 150–170 mg/dL | 23% of normal | +| Walking | 150–170 mg/dL | 23% of normal | +| Strength Training | 150–170 mg/dL | 37% of normal | + +The `insulinNeedsScaleFactor` (e.g. 0.21 for jogging) scales all three delivery parameters +simultaneously — basal rate, carb ratio, and ISF — so that "need 21% of normal insulin" +is expressed as a single unified control rather than three separate adjustments. + +When a user modifies an activity preset from its defaults, a "modified" indicator is shown +in the UI (`isModifiedFromDefault`). + +#### New Safety Feature: High Insulin Needs Mitigation (LOOP-5439) + +When a preset's `insulinNeedsScaleFactor` exceeds 165% (the upper recommended guardrail +bound), a safety mitigation is automatically applied: the effective correction range is +clamped to a minimum of **110 mg/dL**, regardless of what the user set. + +```swift +// TemporaryScheduleOverride.effectiveCorrectionRangeDuring(scheduledRange:) +if veryHighInsulinNeeds { + return range.clampedTo(atLeast: highInsulinNeedsMitigationCorrectionRangeLimit) // 110 mg/dL +} +``` + +This prevents the dangerous combination of very high insulin delivery AND a very low +correction target. Even if a user sets a correction range of 80 mg/dL while also +setting insulin needs to 180%, the system will use 110 mg/dL as the effective floor. +The UI makes this behavior visible to the user. + +#### Preset Guardrails + +| Setting | Absolute Bounds | Warning | Recommended | +|---------|----------------|---------|-------------| +| Insulin Needs | 15%–200% | 15%–190% | 15%–165% | +| Custom preset correction range | Suspend threshold–250 mg/dL | Suspend threshold–180 mg/dL | — | +| Pre-meal correction range | Suspend threshold–130 mg/dL | Dynamic (based on scheduled range) | — | + +The pre-meal guardrail is dynamic: the recommended upper bound is capped at the lower +bound of the user's current correction range schedule, encouraging a pre-meal target +that is meaningfully lower than their normal target. Pre-meal maximum is hard-capped +at 130 mg/dL absolute. + +Guardrail violations are surfaced inline during editing with color-coded warnings +(yellow = outside recommended, red = outside absolute) and a `GuardrailWarning` view +shown before saving. + +#### TemporaryPresetsManager — Separated from LoopDataManager + +Preset lifecycle management has been extracted from `LoopDataManager` into a dedicated +`TemporaryPresetsManager` (`@MainActor @Observable`). It owns: + +- The active `scheduleOverride` (with `didSet` observers for activation/deactivation events) +- `presetHistory` (a `TemporaryScheduleOverrideHistory` for IOB/ISF history reconstruction) +- Override intent observer (Siri shortcut handling) +- Preset scheduling and reminder alerts +- `basalRateScheduleApplyingOverrideHistory`, `insulinSensitivityScheduleApplyingOverrideHistory`, + `carbRatioScheduleApplyingOverrideHistory` — used by the algorithm to reconstruct what + the effective schedules were over the past few hours, accounting for any presets that were + active during that window + +#### Safety Alert: Indefinite Preset Reminder + +When a custom preset is started with indefinite duration, a repeating alert fires every +24 hours reminding the user it is still active: + +> *"[Preset Name] has been active for more than 24 hours. Make sure you still want it +> enabled, or turn it off."* + +This alert is time-sensitive (interrupts Focus modes) and repeats until the preset is +deactivated. When the preset is deactivated, the alert is retracted. + +#### Preset Scheduling + +Presets can now be scheduled to start at a specific time, optionally repeating on +selected days of the week (`PresetScheduleRepeatOptions`: Sunday through Saturday as +an `OptionSet`). When a scheduled preset's start time approaches, a time-sensitive +alert fires asking the user whether to start it: + +> *"Would you like to start your [Preset Name] preset? This will end any active preset."* + +The alert offers "Don't Start" (dismiss) and "Yes, Start Now" (activates the preset). + +#### Required Training Before Creating Presets + +New users must complete a required in-app training sequence (`PresetsTraining`) before +they can create custom presets. The training is gated by `PresetsTrainingCompletion`, +which tracks progress through 5 chapters persisted in `UserDefaults`: + +1. **Customizing Presets** — How overall insulin %, correction range, and duration work +2. **Illness** — How to use presets when sick (illness typically increases insulin needs) +3. **Daily Activities** — How to use presets for non-exercise activities +4. **Exercise** — How to use presets for exercise (aerobic vs. anaerobic differences) +5. **Training Complete** — Summary + +If a user attempts to create a new preset without completing training, an alert blocks +the action and offers to start the training flow. The training can be reviewed at any +time from the Presets screen. (Debug builds allow skipping chapters via `allowDebugFeatures`.) + +#### Presets UI + +The Presets screen (`PresetsView`) is now a dedicated full-screen view accessible from +Settings, with: + +- **Active preset card** — shown at the top when a preset is running, with expected end + time and tap-to-manage +- **All Presets list** — sortable by name, last used, or date created (ascending/descending) +- **Training card** — shown until training is complete; blocks the "+" create button +- **Presets Performance History** — a history view showing past preset activations +- **Review Training** option in the Support section + +Individual preset cards (`PresetCard`) display the preset's icon, name, duration, insulin +needs, and correction range, with guardrail-aware color coding. + +#### Other Loop (App) Changes + +| Feature | Details | +|---------|---------| +| **Active Preset Banner on CarbEntryView** | Shows the active override preset while entering carbs (LOOP-5432) | +| **DeeplinkView widget component** | Replaces `SystemActionLink.swift`; cleaner implementation of widget deep-link action buttons | +| **roundBasalRate utility** | `DeviceDataManager.roundBasalRate(unitsPerHour:)` added for consistent basal rate rounding (LOOP-5558) | +| **schedulePresets storage** | `NSUserDefaults` now persists schedule presets (LOOP-4754) | +| **defaultEnvironment key** | New `NSUserDefaults` key for Tidepool service environment selection (LOOP-5153) | +| **iOS 17+ onChange API** | `onChange(of:)` calls updated to the two-parameter form throughout views | +| **XCTest environment guard** | `AppDelegate` skips full initialization when running under XCTest | +| **Async/await in RemoteDataServicesManager** | `uploadCgmEventData` migrated from callback-based to `async/await Task` pattern | +| **"Save as Favorite" conditional display** | CarbEntryView only shows "Save as favorite" when no existing favorite food is selected | +| **GeometryReader removed from BolusEntryView** | Cleaner layout; fixes safe area issues | + +### Pump Drivers (OmniKit / OmniBLE / MinimedKit) + +| Feature | Details | +|---------|---------| +| **Decision ID on pump events** | `decisionId: UUID?` added to dose entries and pump events across OmniKit, OmniBLE, and MinimedKit — links pump commands to the algorithm decision that triggered them (LOOP-5295) | +| **Pump inoperable state** | `inSignalLoss` and `isInoperable` properties added to LibreTransmitter, OmniBLE, and OmniKit for consistent inoperable-device reporting (LOOP-4801) | +| **acknowledgeAlert async migration** | OmniBLE and OmniKit: `acknowledgeAlert` migrated from completion-handler to `async throws` | + +### Services + +| Feature | Details | +|---------|---------| +| **TidepoolService: decisionId** | `DoseEntry` now carries `decisionId` for Tidepool upload correlation | +| **NightscoutService: decisionId** | Same `decisionId` support added for Nightscout upload | + +--- + +## 2. Conflicts Encountered + +### LoopAlgorithm +**No conflicts.** Because DIY Loop had never incorporated this package before, there were +no diverging commits on the DIY side — the repo had been tracking `LoopKit/LoopAlgorithm` +main without any local modifications. The merge was a clean fast-forward: Tidepool was +29 commits ahead, all of which applied without conflict. + +--- + +### LoopKit +**16 conflicts** across Swift source and project files. + +| File | Conflict Type | +|------|--------------| +| `LoopKit.xcodeproj/project.pbxproj` | File references, deployment target, `.strings` vs `.xcstrings` | +| Multiple algorithm files in `LoopKit/LoopAlgorithm/` | HealthKit → LoopUnit type migration | +| Various type definition files | API additions on both sides | + +--- + +### Loop (App) +**33 conflicts** across 30+ files — the most complex repo in the sync. + +| Category | Count | Files | +|----------|-------|-------| +| Modify/delete | 3 | `SystemActionLink.swift`, `FavoriteFoodDetailView.swift`, `Main.strings` | +| Swift source | 22 | Managers, ViewControllers, ViewModels, Views, Core/Tests | +| xcschemes | 7 | All scheme files | +| project.pbxproj | 1 | Build settings, file references | + +**Deepest conflict: `LoopDataManager.swift`** — 7 conflict hunks due to a fundamental architectural divergence: +- Tidepool migrated to Swift Concurrency (`@MainActor async/await`, `Task {}`) +- DIY added Live Activity support and retained `dataAccessQueue`-based threading + +--- + +### Peripheral Repos (9 repos) +**pbxproj-only conflicts** — no Swift source conflicts. + +| Repo | Conflict | +|------|----------| +| CGMBLEKit | project.pbxproj | +| G7SensorKit | project.pbxproj | +| dexcom-share-client-swift | project.pbxproj | +| NightscoutRemoteCGM | project.pbxproj | +| RileyLinkKit | project.pbxproj | +| LoopSupport | project.pbxproj | +| LoopOnboarding | project.pbxproj | +| AmplitudeService | project.pbxproj | +| LogglyService | project.pbxproj | + +**Swift source conflicts in plugin repos:** + +| Repo | Files | Conflict | +|------|-------|---------| +| OmniKit | `OmnipodPumpManager.swift`, `PodCommsSessionTests.swift` | decisionId, async acknowledgeAlert | +| OmniBLE | `OmniBLEPumpManager.swift`, `PodState.swift` | decisionId, slot6SuspendTimeExpired guard, async acknowledgeAlert | +| MinimedKit | `MinimedPumpManager.swift` | decisionId, async Task, updateLastEventDates | +| LibreTransmitter | `LibreTransmitterManagerV3.swift` | inSignalLoss/isInoperable properties | +| TidepoolService | `DoseEntry+Tidepool.swift` | decisionId, import LoopAlgorithm | +| NightscoutService | `NightscoutService.swift` | decisionId, RemoteNotificationResponseManager | + +--- + +## 3. Conflict Resolution Decisions + +### LoopAlgorithm: HealthKit → LoopUnit Migration + +**Conflict:** Tidepool replaced `HKUnit`/`HKQuantity` HealthKit types throughout the algorithm +with custom `LoopUnit`/`LoopQuantity` types. LoopKit DIY's inline algorithm copy still used +HealthKit types. + +**Decision:** Accept Tidepool's type migration in full. `LoopUnit` and `LoopQuantity` are +functionally equivalent and improve portability. The inline LoopKit algorithm code was updated +to match. The `HKUnit.swift` and `HKQuantity.swift` extensions were removed. + +--- + +### Loop: `LoopDataManager.swift` — Concurrency Migration + +**Conflict:** The deepest conflict in the sync. Tidepool restructured `LoopDataManager` around +Swift Concurrency — replacing `dataAccessQueue.async` blocks with `Task { @MainActor in }` and +`await`-based calls. DIY had added `LiveActivityManager` integration woven into the same +`dataAccessQueue` paths, and retained `lockedSettings`/`mutateSettings()`/`loop()`/`loopInternal()`/`finishLoop()`. + +**Decision:** +- Adopt Tidepool's `Task { @MainActor in await updateDisplayState() }` pattern as the new + threading model throughout +- Remove DIY's `dataAccessQueue`, `lockedSettings`, `mutateSettings()`, `loop()`, + `loopInternal()`, and `finishLoop()` chain — Tidepool's async pattern replaces this +- Inject DIY's Live Activity calls into Tidepool's new `updateDisplayState()` call sites + (hunks 3, 4, 5), so live activity updates fire from the same points the old queue callbacks did +- Adopt Tidepool's new init parameters (`analyticsServicesManager`, `carbAbsorptionModel`, + `usePositiveMomentumAndRCForManualBoluses`, `dosingStrategySelectionEnabled`) and move + all stored property assignments before the `overrideIntentObserver` closure to satisfy + Swift's init-before-capture requirement + +--- + +### Loop: `SystemActionLink.swift` — Deleted (replaced by DeeplinkView) + +**Conflict:** Tidepool deleted `SystemActionLink.swift` and replaced it with `DeeplinkView.swift`. +DIY had made improvements to `SystemActionLink` (widget rendering mode, active preset colors). + +**Decision:** Accept the deletion and take `DeeplinkView.swift`. It provides equivalent +deeplink functionality. DIY's widget tinting improvements should be ported to `DeeplinkView` +if verified missing. + +--- + +### Loop: `FavoriteFoodDetailView.swift` — Deleted (moved) + +**Conflict:** Tidepool moved the file to `Loop/Views/Favorite Foods/FavoriteFoodDetailView.swift`. +DIY had added `String(localized:)` annotations to the original location. + +**Decision:** Accept the move. The `Favorite Foods/` subfolder version already exists in DIY's +tree. DIY's localization annotations should be verified against the new location. + +--- + +### Loop: `Main.strings` — Keep Deleted + +**Conflict:** DIY deleted `Main.strings` when migrating to `.xcstrings` string catalogs. +Tidepool modified `Main.strings` (never migrated). + +**Decision:** Keep the deletion. DIY's `.xcstrings` format is the forward path. + +--- + +### Loop: `AppDelegate.swift` — Keep Both + +**Conflict:** DIY added diagnostic logging setup; Tidepool added an XCTest environment guard +(skips full initialization during unit tests). + +**Decision:** Keep both — they are independent and complementary additions. + +--- + +### Loop: `DeviceDataManager.swift` — Keep Both + +**Conflict:** DIY added a diagnostic report function with submodule SHAs (`b6e88416`); Tidepool +added `roundBasalRate(unitsPerHour:)` (`184ea75a`). Both additions were at adjacent but +non-overlapping locations. + +**Decision:** Keep both — distinct features, no overlap. + +--- + +### Loop: `SettingsView.swift` — Keep Both + +**Conflict:** DIY had a Favorite Foods sheet; Tidepool added a Presets sheet. + +**Decision:** Keep both sheets — separate features serving different user needs. + +--- + +### Loop: `NSUserDefaults.swift` — Keep Both + +**Conflict:** DIY added `liveActivity` key (`LiveActivitySettings`); Tidepool added +`defaultEnvironment` key. + +**Decision:** Keep both — entirely separate features (Live Activity vs Tidepool service config). + +--- + +### Loop: `WidgetBackground.swift` — Take Tidepool's + +**Conflict:** Tidepool uses `Color.widgetBackground` extension; DIY used `Color("WidgetBackground")` +string-based lookup. + +**Decision:** Take Tidepool's — the extension is safer (compile-time vs. runtime string lookup). + +--- + +### Loop: `ContentMargin.swift` — Keep DIY's + +**Conflict:** Both sides had identical implementation; only the copyright year differed. + +**Decision:** Keep DIY's copyright date. + +--- + +### OmniBLE: `slot6SuspendTimeExpired` Guard — Keep DIY's + +**Conflict:** Tidepool's version of OmniBLE removed the `slot6SuspendTimeExpired` safety check +that prevents acknowledging a pod alert when the pod is suspended. + +**Decision:** Preserve DIY's guard. This is a safety-critical check: if the pod is suspended, +the pod should continue beeping until the user resumes it. Silently acknowledging in this state +could mask a dangerous condition. + +--- + +### MinimedKit: `updateLastEventDates` — Keep DIY's + +**Conflict:** Tidepool's MinimedKit removed `updateLastEventDates()`, a function DIY uses to +track cannula age and insulin age for display in the UI. + +**Decision:** Preserve DIY's implementation. Cannula/insulin age tracking is a meaningful DIY +feature with no equivalent in Tidepool's version. + +--- + +### NightscoutService: `RemoteNotificationResponseManager` — Keep DIY's + +**Conflict:** Tidepool's NightscoutService version removed `RemoteNotificationResponseManager`, +which handles feedback notifications for remote commands sent via Nightscout. + +**Decision:** Preserve DIY's implementation. Remote command feedback is a core DIY feature +(remote bolus, temp basal, etc.) that has no Tidepool equivalent. + +--- + +### TidepoolService: `import LoopAlgorithm` — Removed + +**Conflict:** Tidepool's `TidepoolService` imports `LoopAlgorithm` as a Swift package. DIY does +not include the `LoopAlgorithm` package in the workspace — the algorithm is embedded inline +inside `LoopKit`. + +**Decision:** Remove `import LoopAlgorithm` from `TidepoolService`. In DIY, the types it +provided come from `LoopKit` which is already imported. + +--- + +### All Repos: project.pbxproj + +Applied consistent rules across all 18 repos: + +| Setting | Decision | Rationale | +|---------|----------|-----------| +| `IPHONEOS_DEPLOYMENT_TARGET` | Take higher value (17.0) | Both sides are raising it; take the further-along value | +| `LOCALIZATION_PREFERS_STRING_CATALOGS` | Keep `YES` | DIY's xcstrings migration | +| `.strings` file references | Drop Tidepool's | DIY deleted these files; re-adding references causes build errors | +| `.xcstrings` references | Keep DIY's | Current localization format | +| `XCRemoteSwiftPackageReference "LoopAlgorithm"` | Omit | DIY embeds algorithm inline in LoopKit | +| New Swift file references | Keep both sides' additively | Both sides added files; all should be included | +| PBXGroup `children`/`files` duplicates | Deduplicate after merge | "Keep both" strategy on adjacent group entries can produce duplicates | +| Bundle IDs (`com.loopkit.*` / `com.tidepool.*`) | Keep both | Apply to different build targets | + +--- + +## 4. DIY Features Preserved + +| Feature | Repo | Notes | +|---------|------|-------| +| **Live Activity** (`LiveActivityManager`) | Loop | Woven into Tidepool's new `updateDisplayState()` async calls | +| **Diagnostic report with submodule SHAs** | Loop | Kept alongside Tidepool's `roundBasalRate` addition | +| **Favorite Foods sheet** | Loop | Kept alongside Tidepool's new Presets sheet | +| **liveActivity NSUserDefaults key** | Loop | Kept alongside Tidepool's `defaultEnvironment` key | +| **slot6SuspendTimeExpired safety guard** | OmniBLE | Safety-critical; not present in OmniKit (different pod hardware) | +| **updateLastEventDates** | MinimedKit | Cannula/insulin age tracking | +| **RemoteNotificationResponseManager** | NightscoutService | Remote command feedback | +| **`.xcstrings` localization** | All repos | DIY's Xcode 15+ string catalog format | +| **Community CGM integrations** | CGMBLEKit, LibreTransmitter, etc. | Open-source CGM drivers not in Tidepool | +| **Open-source pump drivers** | OmniKit, OmniBLE, MinimedKit, RileyLinkKit | All preserved | + +--- + +## 5. Post-Merge Fixes + +After the mechanical merge, the following additional fixes were required to achieve a +clean build: + +### `LoopDataManager.swift` — Init Property Ordering (Loop) + +**Problem:** Swift requires all stored properties to be initialized before `self` can be +captured in a closure. The `overrideIntentObserver` closure captured `self`, but several +stored properties (`analyticsServicesManager`, `carbAbsorptionModel`, +`usePositiveMomentumAndRCForManualBoluses`, `automationHistory`, +`publishedMostRecentGlucoseDataDate`, `dosingStrategySelectionEnabled`, +`publishedMostRecentPumpDataDate`) were assigned *after* the closure in the init. + +**Fix:** Moved all stored property assignments before the `overrideIntentObserver` closure. + +--- + +### `NSUserDefaults.swift` — Missing Closing Braces (Loop) + +**Problem:** The merge introduced a structural artifact in the `liveActivity` computed property +— the closing `}}` for the `set {` block was missing. + +**Fix:** Restored the two missing closing braces manually. + +--- + +### `Loop.xcodeproj/project.pbxproj` — Structural Corruption (Loop) + +**Problem:** The pbxproj resolver's "keep both" strategy on a `PBXVariantGroup` conflict +(conflict 36) produced a combined brace depth of +2 instead of 0, making the file +unparseable by Xcode. + +**Root cause:** Both sides of the conflict had `brace_balance = +1`. Naively keeping both +produced `+2`, breaking the file's structure. + +**Fix:** +1. Re-ran `git merge-file` on origin/dev vs merge-base vs tidepool/dev to get clean + conflict markers +2. Applied improved resolver: checks `brace_count(ours) + brace_count(theirs)` before + keeping both; takes OURS when the combined balance would be non-zero +3. Deduplicated 7 duplicate lines in PBXGroup `children`/`files` lists (artifact of + "keep both" on adjacent group entries) +4. Validated with `xcodebuild -project Loop.xcodeproj -list` ✅ + +--- + +## 6. Testing Notes + +### Critical paths to verify + +- [ ] **Live Activity** — glucose, dosing, and carb update notifications all trigger live activity updates +- [ ] **Widget action buttons** — carbs, bolus, pre-meal, preset deeplinks work; colors correct in tinted/accented mode (DeeplinkView replaced SystemActionLink) +- [ ] **Favorite Foods** — detail view labels localized; "Save as favorite" only shown when no food selected +- [ ] **Settings** — both Favorite Foods and Presets sheets accessible +- [ ] **Bolus entry** — safe area layout correct (GeometryReader removed) +- [ ] **Presets training** — training flow completes; "+" button blocked until training done +- [ ] **Activity presets** — all 4 activity types appear; defaults are correct; "modified" indicator shows when changed +- [ ] **High insulin needs mitigation** — correction range clamped to ≥ 110 mg/dL when insulin needs > 165% +- [ ] **Indefinite preset reminder** — 24-hour alert fires when indefinite preset is active; retracts on deactivation +- [ ] **Preset scheduling** — scheduled presets alert at the correct time; "Yes, Start Now" activates correctly +- [ ] **Pre-meal guardrail** — max 130 mg/dL hard cap; recommended upper bound matches correction range lower bound +- [ ] **Active preset banner** — displays correctly on CarbEntryView when override active +- [ ] **Algorithm** — glucose predictions, ISF during carb absorption, max IOB multiplier +- [ ] **TempBasalRecommendation direction** — direction field populated in recommendations +- [ ] **Pump decision IDs** — OmniKit, OmniBLE, Minimed dose entries carry decisionId +- [ ] **Remote commands** — Nightscout remote bolus/basal feedback notifications work +- [ ] **Cannula/insulin age** — displays correctly for Minimed users (updateLastEventDates) +- [ ] **OmniBLE pod suspend safety** — suspended pod continues beeping; alert not silently acked +- [ ] **Diagnostic report** — support report includes submodule SHAs +- [ ] **App expiry alerts** — TestFlight and provisioning profile expiry handled correctly +- [ ] **Unit tests** — `LoopAlgorithmTests`, `LoopKitTests`, `LoopTests` suites pass From 24f9d53336c6833d078827f3db5a65f700ad70e2 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 12 Mar 2026 16:24:20 -0500 Subject: [PATCH 002/133] Update sync doc: preset scheduling history, alert permissions accuracy --- docs/tidepool-sync-2026-03-10.md | 39 ++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/docs/tidepool-sync-2026-03-10.md b/docs/tidepool-sync-2026-03-10.md index 2569b7f625..bbfd35fe17 100644 --- a/docs/tidepool-sync-2026-03-10.md +++ b/docs/tidepool-sync-2026-03-10.md @@ -155,8 +155,17 @@ stored in `LoopSettings.overridePresets`. Each preset had a name, symbol, correc insulin sensitivity multiplier, and duration. There was no preset type system — all presets were generic overrides. Users could set a target range and/or an ISF multiplier, activate a preset from the toolbar, and it would run until it expired or was manually cancelled. -There were no guardrails specific to presets, no required training, no scheduling, and no -safety mitigations for extreme settings. + +DIY did have a limited scheduling concept: the UIKit `AddEditOverrideTableViewController` +exposed a **Start Time** row that allowed setting a future start time for an override. +If `startDate > Date()`, the override was queued as a one-shot future event and shown in +a "SCHEDULED PRESET" section in `OverrideSelectionViewController`. There was no +day-of-week recurrence, no system alert to prompt the user at the scheduled time, and +no persistence of the schedule on the preset definition itself — the delay was set +per-activation, not stored on the preset. + +There were no guardrails specific to presets, no required training, and no safety +mitigations for extreme settings. #### After: SelectablePreset Type System @@ -262,16 +271,31 @@ When a custom preset is started with indefinite duration, a repeating alert fire This alert is time-sensitive (interrupts Focus modes) and repeats until the preset is deactivated. When the preset is deactivated, the alert is retracted. -#### Preset Scheduling +#### Preset Scheduling — Significantly Expanded -Presets can now be scheduled to start at a specific time, optionally repeating on -selected days of the week (`PresetScheduleRepeatOptions`: Sunday through Saturday as -an `OptionSet`). When a scheduled preset's start time approaches, a time-sensitive -alert fires asking the user whether to start it: +DIY Loop already had a basic scheduling concept: a **one-shot future start time** +that could be set per-activation in the old UIKit override editor. That delayed the +activation of an override to a future time, but the schedule was not stored on the +preset, could not repeat, and generated no alert to remind the user. + +The new scheduling system stores the schedule on the preset definition itself and adds +full day-of-week recurrence. Presets can now be scheduled to start at a specific time, +optionally repeating on selected days of the week (`PresetScheduleRepeatOptions`: +Sunday through Saturday as an `OptionSet`). When a scheduled preset's start time +approaches, a time-sensitive system alert fires asking the user whether to start it: > *"Would you like to start your [Preset Name] preset? This will end any active preset."* The alert offers "Don't Start" (dismiss) and "Yes, Start Now" (activates the preset). +The schedule is re-armed after each activation to fire again at the next scheduled time. + +| Aspect | Old DIY | New (Tidepool) | +|--------|---------|----------------| +| Schedule stored on preset | ❌ (set per-activation) | ✅ | +| One-shot future start | ✅ | ✅ | +| Day-of-week recurrence | ❌ | ✅ (any combination of days) | +| System alert at scheduled time | ❌ | ✅ (time-sensitive) | +| User confirm/dismiss in alert | ❌ | ✅ | #### Required Training Before Creating Presets @@ -313,6 +337,7 @@ needs, and correction range, with guardrail-aware color coding. | **roundBasalRate utility** | `DeviceDataManager.roundBasalRate(unitsPerHour:)` added for consistent basal rate rounding (LOOP-5558) | | **schedulePresets storage** | `NSUserDefaults` now persists schedule presets (LOOP-4754) | | **defaultEnvironment key** | New `NSUserDefaults` key for Tidepool service environment selection (LOOP-5153) | +| **Granular alert permission warnings** | `AlertPermissionsChecker` (existing since 2021) updated: single "safety notifications off" alert replaced with 5 granular cases distinguishing `notificationsDisabled`, `criticalAlertsDisabled`, `timeSensitiveDisabled`, and combinations thereof — each with tailored messaging | | **iOS 17+ onChange API** | `onChange(of:)` calls updated to the two-parameter form throughout views | | **XCTest environment guard** | `AppDelegate` skips full initialization when running under XCTest | | **Async/await in RemoteDataServicesManager** | `uploadCgmEventData` migrated from callback-based to `async/await Task` pattern | From 5e98b2205f87cbe5ab5a72b1aa1c86d530800e4d Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 12 Mar 2026 17:21:29 -0500 Subject: [PATCH 003/133] Update submodule refs after filter-branch author rewrite; add workspace docs - Update all 17 submodule commit pointers to reflect rewritten history (filter-branch changed SHAs when fixing author to LoopKit Developer) - Add Loop build fix commit (LoopDataManager init ordering) - Add LOOPKIT_SYNC_PROCESS.md, SYNC_PROGRESS.md, sync-docs/ --- AmplitudeService | 2 +- CGMBLEKit | 2 +- G7SensorKit | 2 +- LOOPKIT_SYNC_PROCESS.md | 440 +++++++++++++++++++++++++++++++++++++ LibreTransmitter | 2 +- LogglyService | 2 +- Loop | 2 +- LoopKit | 2 +- LoopOnboarding | 2 +- LoopSupport | 2 +- MinimedKit | 2 +- NightscoutRemoteCGM | 2 +- NightscoutService | 2 +- OmniBLE | 2 +- OmniKit | 2 +- RileyLinkKit | 2 +- SYNC_PROGRESS.md | 71 ++++++ TidepoolService | 2 +- dexcom-share-client-swift | 2 +- sync-docs/Loop.md | 158 +++++++++++++ sync-docs/LoopAlgorithm.md | 143 ++++++++++++ 21 files changed, 829 insertions(+), 17 deletions(-) create mode 100644 LOOPKIT_SYNC_PROCESS.md create mode 100644 SYNC_PROGRESS.md create mode 100644 sync-docs/Loop.md create mode 100644 sync-docs/LoopAlgorithm.md diff --git a/AmplitudeService b/AmplitudeService index f094a60c2d..ac96a29fb4 160000 --- a/AmplitudeService +++ b/AmplitudeService @@ -1 +1 @@ -Subproject commit f094a60c2d223601d36be077387591d21c53b2a8 +Subproject commit ac96a29fb464de334b0b94e8b6dcb15578ba8e9e diff --git a/CGMBLEKit b/CGMBLEKit index c8dbdd4aab..6b702067d4 160000 --- a/CGMBLEKit +++ b/CGMBLEKit @@ -1 +1 @@ -Subproject commit c8dbdd4aab35427dc8b7807b6e6f7ad9b856f4fd +Subproject commit 6b702067d40394bc39c9b0874cb2e9189e7ff69c diff --git a/G7SensorKit b/G7SensorKit index c86b4d4195..4b850b09e1 160000 --- a/G7SensorKit +++ b/G7SensorKit @@ -1 +1 @@ -Subproject commit c86b4d4195fcb045f06e3082e5cf00cded81f70e +Subproject commit 4b850b09e192df7bc3fd94317ebfe7935ccbe929 diff --git a/LOOPKIT_SYNC_PROCESS.md b/LOOPKIT_SYNC_PROCESS.md new file mode 100644 index 0000000000..e671d54f1e --- /dev/null +++ b/LOOPKIT_SYNC_PROCESS.md @@ -0,0 +1,440 @@ +# LoopKit ↔ Tidepool Sync Process + +**Purpose:** A repeatable process an developer can follow to merge changes from Tidepool's fork of the Loop +ecosystem back into the LoopKit DIY repos, resolving conflicts with full contextual understanding. + +**Last updated:** 2026-03-10 (added Golden Rule; clarified .strings vs .xcstrings handling) + +--- + +## Background & Architecture + +The Loop ecosystem consists of two parallel development streams: + +- **LoopKit (DIY/open source):** The community-maintained fork at `github.com/LoopKit/*`. + Organized as a set of git submodules in `LoopWorkspace`. +- **Tidepool:** A company building a supported version of Loop at `github.com/tidepool-org/*`. + Tidepool's repos are **forks** of the LoopKit repos, with additional clinical/regulatory features. + +Changes flow in both directions over time, but syncing is typically done in the direction: +**tidepool-org → LoopKit**, bringing Tidepool's upstream improvements back to DIY, and then DIY -> Tidepool + +--- + +## ⭐ Golden Rule: Prefer Tidepool, Protect DIY + +**When in doubt about a conflict resolution, prefer Tidepool's version — but never at the cost of +breaking or removing DIY functionality.** + +More specifically: + +- **Tidepool changes win** for: algorithm improvements, bug fixes, new clinical features, API + changes, architecture decisions, test coverage, Swift version upgrades. +- **LoopKit DIY wins** for: anything that is *exclusively* a DIY capability — community + translations, open-source-only build paths, non-Tidepool signing/bundle IDs, features that + only exist in DIY and would be silently deleted by taking Tidepool's version. +- **Keep both** when a DIY feature and a Tidepool feature occupy the same code area but serve + different purposes and can coexist (e.g. an added Tidepool service upload alongside an existing + Nightscout upload). +- **Never silently drop** a DIY feature. If Tidepool's version removes something DIY users + depend on, document it explicitly in the per-repo sync log and flag it for human review (⚠️) + rather than quietly taking Tidepool's side. + +**Practical decision tree for any conflicting hunk:** + +1. Is this a pure algorithm/logic change? → Take Tidepool's. +2. Does Tidepool's version remove a capability DIY users have? → Keep both if possible; if not, + flag for human review. +3. Is this cosmetic (formatting, style, ordering)? → Take Tidepool's; not worth fighting over. +4. Is this a build/project setting (deployment target, signing, bundle ID)? → See the + "project.pbxproj" section below for specific rules. +5. Is this a Tidepool-only backend integration (e.g. Coastal, Tidepool upload)? → Keep it; + it doesn't harm DIY users and removing it creates future conflicts. + +--- + +### ⚠️ Key Architectural Divergence: LoopAlgorithm + +The most important structural difference between the two streams: + +- **Tidepool** extracted the core Loop algorithm into a standalone Swift Package: + `tidepool-org/LoopAlgorithm` (a fork of `LoopKit/LoopAlgorithm`). + Tidepool's `LoopKit` repo declares it as a SwiftPM dependency (in `Package.resolved`). +- **LoopKit DIY** still embeds the algorithm code inline inside `LoopKit/LoopKit/LoopAlgorithm/`. + +This means when syncing `LoopKit`: +- Algorithm changes Tidepool made via their `LoopAlgorithm` package need to be found by + looking at `tidepool-org/LoopAlgorithm` commits AND `tidepool-org/LoopKit` commits. +- Conflicts in `LoopAlgorithm.swift`, `LoopPredictionOutput.swift`, etc. inside LoopKit + may reflect changes that Tidepool now maintains in their separate package. +- **LoopAlgorithm must be synced first** (as a standalone package repo) before syncing LoopKit. + +--- + +## Repository Map + +All repos below are submodules of `LoopWorkspace`, except `LoopAlgorithm` which is standalone. + +| Repo | LoopKit branch | Tidepool fork | Notes | +|------|---------------|---------------|-------| +| **LoopAlgorithm** | `main` | `tidepool-org/LoopAlgorithm` | ⚠️ Standalone Swift Package. Sync FIRST. Not in sync.swift. | +| LoopKit | `dev` | `tidepool-org/LoopKit` | ⚠️ Complex. References LoopAlgorithm as package (Tidepool) vs inline (DIY). | +| Loop | `dev` | `tidepool-org/Loop` | Most complex. Many source conflicts. Sync LAST. | +| TidepoolService | `dev` | `tidepool-org/TidepoolService` | Tidepool-specific service; sync carefully | +| OmniBLE | `dev` | `tidepool-org/OmniBLE` | Pump driver; test after merge | +| OmniKit | `main` | `tidepool-org/OmniKit` | Pump driver; test after merge | +| MinimedKit | `main` | `tidepool-org/MinimedKit` | Pump driver; test after merge | +| NightscoutService | `dev` | `tidepool-org/NightscoutService` | Service layer | +| LibreTransmitter | `main` | `tidepool-org/LibreTransmitter` | CGM driver | +| G7SensorKit | `main` | `tidepool-org/G7SensorKit` | CGM driver | +| CGMBLEKit | `dev` | `tidepool-org/CGMBLEKit` | CGM driver | +| dexcom-share-client-swift | `dev` | `tidepool-org/dexcom-share-client-swift` | CGM client | +| RileyLinkKit | `dev` | `tidepool-org/RileyLinkKit` | Radio hardware | +| LoopOnboarding | `dev` | `tidepool-org/LoopOnboarding` | Onboarding UI | +| LoopSupport | `dev` | `tidepool-org/LoopSupport` | Support utilities | +| AmplitudeService | `dev` | `tidepool-org/AmplitudeService` | Analytics service | +| LogglyService | `dev` | `tidepool-org/LogglyService` | Logging service | +| NightscoutRemoteCGM | `dev` | `tidepool-org/NightscoutRemoteCGM` | CGM source | +| MixpanelService | `main` | `tidepool-org/MixpanelService` | Analytics service | + +**Not synced:** `Minizip`, `TrueTime.swift` (third-party libs, no Tidepool fork) + +--- + +## Recommended Sync Order + +**Core → App → Plugins (Peripheral)** + +The correct order is *not* simply "foundational to dependent" in a build-graph sense. +It is **core architectural decisions first**, so that by the time you reach the peripheral +plugins you already understand what the core changed — making those conflicts easier to +read and resolve coherently. + +In practice, a conflict in a pump driver that looks like "Tidepool changed the DoseEntry +type" only makes sense once you've already seen that LoopKit changed `DoseEntry` in the +core repo. If you do plugins first, you're resolving conflicts blind. + +### Tier 1 — Core (do these first) +1. **LoopAlgorithm** — standalone package; establishes the algorithm API everything else uses +2. **LoopKit** — foundational types (`DoseEntry`, `GlucoseValue`, `Guardrail`, etc.); all plugins depend on it + +### Tier 2 — App (do before plugins) +3. **Loop** — the top-level app; resolving this *before* plugins means you understand which + app-level API changes the plugins are expected to match, rather than discovering surprises later + +### Tier 3 — Plugins / Peripheral (do last, in any order) +4. **CGM drivers**: CGMBLEKit, G7SensorKit, dexcom-share-client-swift, NightscoutRemoteCGM, LibreTransmitter +5. **Pump drivers**: RileyLinkKit, OmniKit, OmniBLE, MinimedKit +6. **Services**: TidepoolService, NightscoutService, AmplitudeService, LogglyService, MixpanelService +7. **Support/Onboarding**: LoopSupport, LoopOnboarding + +> **Note:** pbxproj-only conflicts in peripheral repos can be batched and resolved +> mechanically at any point since they don't require architectural context. Swift source +> conflicts in peripheral repos should wait until Tier 1 + 2 are done. + +--- + +## Setup (One-Time Per Workspace Clone) + +For each repo in the sync list, add the Tidepool remote if not already present: + +```bash +cd LoopWorkspace/ +git remote add tidepool https://github.com/tidepool-org/.git +git fetch tidepool +``` + +For LoopAlgorithm (standalone — clone separately): +```bash +cd LoopWorkspace # or wherever you keep it +git clone https://github.com/LoopKit/LoopAlgorithm.git +cd LoopAlgorithm +git remote add tidepool https://github.com/tidepool-org/LoopAlgorithm.git +git fetch tidepool +``` + +--- + +## Per-Repo Sync Process + +Repeat these steps for each repo, in the order listed above. + +### Step 1 — Choose a sync branch name + +Use a consistent name across all repos for this sync run, e.g.: +``` +tidepool-sync/YYYY-MM-DD +``` + +### Step 2 — Create sync branch + +```bash +cd LoopWorkspace/ +git checkout origin/ # e.g. origin/dev or origin/main +git checkout -b tidepool-sync/YYYY-MM-DD +``` + +### Step 3 — Attempt merge + +```bash +git merge --no-edit tidepool/ +``` + +If the merge succeeds with no conflicts → commit and move to Step 9. +If there are conflicts → continue to Step 4. + +### Step 4 — Identify conflict files + +```bash +git diff --name-only --diff-filter=U +``` + +Categorize conflicts: +- **project.pbxproj** → See "Xcode Project File Conflicts" section below +- **Swift source files** → See "Source Code Conflicts" section below +- **Other** (yml, strings, etc.) → Research case by case + +### Step 5 — Research each conflict (Source Files) + +For each conflicting Swift file: + +**a) Understand what each side changed:** +```bash +MERGE_BASE=$(git merge-base HEAD tidepool/) + +# What did LoopKit change in this file since the merge base? +git log --oneline $MERGE_BASE..origin/ -- +git diff $MERGE_BASE..origin/ -- + +# What did Tidepool change? +git log --oneline $MERGE_BASE..tidepool/ -- +git diff $MERGE_BASE..tidepool/ -- +``` + +**b) Find related GitHub issues and PRs:** + +For each commit hash found above, search for it on GitHub: +- `https://github.com/LoopKit//commit/` +- Look at the PR that merged it (GitHub shows "merged via PR #NNN") +- Read the PR description and linked issues +- Also search for the LOOP-XXXX ticket numbers in commit messages at: + `https://github.com/LoopKit//issues` and + `https://github.com/tidepool-org//issues` + +**c) For LoopAlgorithm-related conflicts in LoopKit:** +- Check if the same change exists in `tidepool-org/LoopAlgorithm` +- The Tidepool version of a function in LoopKit may be forwarding to their package; + the DIY version keeps it inline. Preserve the inline version while incorporating + any algorithmic improvements from the package version. + +### Step 6 — Resolve conflicts + +**General principles:** Follow the ⭐ Golden Rule (see top of document) — prefer Tidepool's +version, but never silently remove DIY functionality. + +**For algorithm changes:** Take Tidepool's. Their test coverage is usually more thorough +and the algorithmic direction is the right one. Check the `LoopAlgorithm` sync doc to +understand if a conflict here is related to the HealthKit→LoopUnit migration. + +**For UI changes:** Take Tidepool's unless it removes a DIY-only UI path. Regulatory/clinical +UI additions from Tidepool are fine to include — they add capability without breaking DIY. + +**For Tidepool-specific features** (Tidepool Service uploads, Coastal integration, etc.): +Keep them — they don't break DIY users, and removing them creates future conflicts. + +**For DIY-only features** (e.g. community CGM integrations, Nightscout, open-source pump +drivers not supported by Tidepool): Protect these. They are the reason DIY exists. + +**Never silently drop** either side's work without a note in the sync doc. + +After resolving each file: +```bash +git add +``` + +### Step 7 — Resolve Xcode Project File Conflicts (project.pbxproj) + +The `.pbxproj` is a structured text file. Conflicts here are almost always about: +- **Object version** (LoopKit likely bumped for newer Xcode) +- **File references** (new Swift files added by either side) +- **Build settings** (deployment targets, signing, feature flags) +- **Localization** (LoopKit uses `.xcstrings`; Tidepool may still use `.strings`) + +**Approach:** +```bash +# See what LoopKit changed in the project file since merge base +git diff $MERGE_BASE..origin/ -- .xcodeproj/project.pbxproj + +# See what Tidepool changed +git diff $MERGE_BASE..tidepool/ -- .xcodeproj/project.pbxproj +``` + +Then look at the actual conflict markers in the file: +```bash +grep -n "<<<<<<\|=======\|>>>>>>>" .xcodeproj/project.pbxproj +``` + +**Common resolutions:** +- `objectVersion`: Keep LoopKit's (higher = newer Xcode format) +- `IPHONEOS_DEPLOYMENT_TARGET`: Take the *higher* of the two values (both are raising it) +- New file references added by LoopKit (e.g. `.xcstrings`): Keep them +- New file references added by Tidepool (new Swift files, mapping models, etc.): Keep them +- Tidepool's `.strings` localization file references: **Drop them** (DIY deleted these; see Pattern below) +- Tidepool's `XCRemoteSwiftPackageReference "LoopAlgorithm"`: **Omit from DIY** (DIY embeds it inline) +- LoopKit bundle IDs (`com.loopkit.*`): Keep LoopKit's +- Tidepool bundle IDs (`com.tidepool.*`): Keep Tidepool's (they're for different targets) +- Signing/provisioning settings: Keep LoopKit's for shared targets + +After resolving: +```bash +git add .xcodeproj/project.pbxproj +``` + +### Step 8 — Commit + +```bash +git commit -m "Merge tidepool/dev into tidepool-sync/YYYY-MM-DD + +Resolved conflicts: +- : +- : + +See sync-docs/.md for full context." +``` + +### Step 9 — Document in per-repo log + +Update `sync-docs/.md` with: +- Merge base commit hash +- LoopKit and Tidepool tip commit hashes +- For each resolved conflict: + - The file path + - Relevant commit hashes from each side + - Links to GitHub PRs/issues + - What each side was trying to do + - How it was resolved and why + - Any features that need testing as a result +- Any open questions or items requiring human review + +### Step 10 — Update SYNC_PROGRESS.md + +Mark the repo as done (✅) or blocked (❌) in the progress table. +Note any cross-repo dependencies discovered (e.g. "LoopKit change requires matching Loop change"). + +### Step 11 — Push and create PR (when ready) + +```bash +git push origin tidepool-sync/YYYY-MM-DD +# Then open a PR on GitHub: tidepool-sync/YYYY-MM-DD → +``` + +--- + +## Special Case: LoopAlgorithm + +LoopAlgorithm lives at `LoopKit/LoopAlgorithm` (not a submodule of LoopWorkspace) and +`tidepool-org/LoopAlgorithm` is a fork of it. + +**Key questions before syncing:** +1. Is the DIY `LoopAlgorithm` used as a package by Loop/LoopKit, or still embedded inline? + - If package: sync just like any other repo + - If inline (current DIY state): sync algorithm changes need to flow into LoopKit's + `LoopKit/LoopAlgorithm/` subdirectory AND the standalone LoopAlgorithm package + +2. What is the current pinned version of `tidepool-org/LoopAlgorithm` in Tidepool's LoopKit? + Check `LoopKit.xcodeproj/.../Package.resolved` on `tidepool/dev`. + +3. Clone LoopAlgorithm separately: + ```bash + git clone https://github.com/LoopKit/LoopAlgorithm.git + cd LoopAlgorithm + git remote add tidepool https://github.com/tidepool-org/LoopAlgorithm.git + git fetch tidepool + ``` + +4. Follow the same per-repo sync process above. +5. After resolving LoopAlgorithm, **also check** whether any of the same changes need to be + applied to the inline copy in `LoopKit/LoopKit/LoopAlgorithm/` (if DIY hasn't adopted the package yet). + +--- + +## Common Patterns to Watch For + +### Pattern: Tidepool adds LoopAlgorithm package dependency +In Tidepool's `LoopKit`, the `project.pbxproj` will have: +``` +XCRemoteSwiftPackageReference "LoopAlgorithm" +repositoryURL = "https://github.com/tidepool-org/LoopAlgorithm"; +``` +**Resolution for DIY:** Omit this package reference. Keep the inline `LoopAlgorithm/` code. +However, DO bring in any algorithmic logic changes from the inline vs. package versions. + +### Pattern: Deployment target bumps +Tidepool regularly bumps `IPHONEOS_DEPLOYMENT_TARGET`. DIY follows at its own pace. +**Resolution:** Take the higher value unless there's a specific reason not to. +Check LoopKit's own dev branch to see what they've already committed to. + +### Pattern: Localization format migration +LoopKit DIY migrated from `.strings` files to `.xcstrings` (Xcode 15+ string catalogs). +Tidepool does not maintain translations and remains on `.strings`. + +**Resolution:** Keep LoopKit's `.xcstrings` format. **Never re-add Tidepool's `.strings` +file references** — Tidepool's `.strings` references belong to files that DIY deliberately +deleted when migrating to string catalogs. Re-adding them would cause build errors +("file not found") because the actual `.strings` files no longer exist in DIY's tree. + +In practice, when resolving `project.pbxproj` conflicts: +- Drop any `PBXFileReference` entries for `*.strings` that came from Tidepool's side +- Drop any `PBXBuildFile` entries referencing those same `.strings` files +- Drop any group `children = (...)` entries pointing to `.strings` files from Tidepool +- Keep DIY's `*.xcstrings` references +- Keep all of Tidepool's non-translation additions (new Swift files, mapping models, etc.) + +### Pattern: Tidepool-specific regulatory features +Features like Coastal integration, FDA submission mode, specific clinical guardrails. +**Resolution:** Keep them. They add capability without breaking DIY. Only omit if they +require Tidepool backend infrastructure that simply won't exist in DIY. + +### Pattern: Bundle identifier differences +`com.loopkit.*` (LoopKit) vs `com.tidepool.*` (Tidepool). +**Resolution:** Keep both — they apply to different build targets/schemes. + +### Pattern: HKUnit.swift removal +Both sides removed the `HKUnit.swift` extension file (HealthKit unit helpers were moved). +This should auto-merge or be a trivially clean conflict. If not, take the removal. + +--- + +## Testing Checklist After Merge + +After completing all repos, test these critical paths before opening PRs: + +- [ ] **Glucose display:** CGM data flows and displays correctly +- [ ] **Insulin delivery:** Bolus and basal commands work (OmniBLE/OmniKit/Minimed) +- [ ] **Loop algorithm:** Closed loop prediction and dosing recommendations +- [ ] **Remote services:** Nightscout upload/download, Tidepool service +- [ ] **Onboarding:** Fresh install and therapy settings configuration +- [ ] **Watch app:** Complication and status display (if applicable) +- [ ] **Widgets:** Lock screen / home screen widgets (if applicable) +- [ ] **Build:** All targets compile cleanly with no warnings promoted to errors + +--- + +## Tracking Files + +| File | Purpose | +|------|---------| +| `SYNC_PROGRESS.md` | Master status table, notes on blocked items | +| `sync-docs/.md` | Per-repo conflict log with full context and links | +| `LOOPKIT_SYNC_PROCESS.md` | This file — the process itself | + +--- + +## Reference Links + +- LoopKit org: https://github.com/LoopKit +- Tidepool org: https://github.com/tidepool-org +- LoopAlgorithm (LoopKit): https://github.com/LoopKit/LoopAlgorithm +- LoopAlgorithm (Tidepool): https://github.com/tidepool-org/LoopAlgorithm +- LoopWorkspace: https://github.com/LoopKit/LoopWorkspace +- Original sync script: `LoopWorkspace/Scripts/sync.swift` diff --git a/LibreTransmitter b/LibreTransmitter index 6c0e4aa667..bc017fba25 160000 --- a/LibreTransmitter +++ b/LibreTransmitter @@ -1 +1 @@ -Subproject commit 6c0e4aa66758decbe6a2537164cd2e3d36de70a5 +Subproject commit bc017fba254e3e8e18efc7ddb326e951c7f246e1 diff --git a/LogglyService b/LogglyService index eb04e1b7be..86253bd32a 160000 --- a/LogglyService +++ b/LogglyService @@ -1 +1 @@ -Subproject commit eb04e1b7be192753e9f37b790b9159f8174cbc3e +Subproject commit 86253bd32a46b7257e7c671acb96aadc65f8722a diff --git a/Loop b/Loop index 79eee6d5cb..71e06d6ab8 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 79eee6d5cbb24915b6101fac476df4b4e0d7a40a +Subproject commit 71e06d6ab88396dd7e2d0f069d7bbf254130a583 diff --git a/LoopKit b/LoopKit index e003e6b69e..12ed30ae5b 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit e003e6b69e61d8ba73be3e19b564c1f655fb29c9 +Subproject commit 12ed30ae5ba993a78707e41089d05056e152e2ff diff --git a/LoopOnboarding b/LoopOnboarding index 7bfc5fdf8c..eece785c7b 160000 --- a/LoopOnboarding +++ b/LoopOnboarding @@ -1 +1 @@ -Subproject commit 7bfc5fdf8c323fce9c1fedcf52ecbd19afea137d +Subproject commit eece785c7b18d835e3da82f32776e385ac0f72ea diff --git a/LoopSupport b/LoopSupport index 4538579519..de1dae3aec 160000 --- a/LoopSupport +++ b/LoopSupport @@ -1 +1 @@ -Subproject commit 4538579519b80a33422097ee7d3425130be49ead +Subproject commit de1dae3aecada9dd8e2b48d2ee8a8df26939998e diff --git a/MinimedKit b/MinimedKit index c13c039344..fcba4a7d36 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit c13c039344decf762b988062af9f2a7c8ec752eb +Subproject commit fcba4a7d369f624748da201c80a231750b8a7f12 diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 87e3898b01..45a1782dc0 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 87e3898b01d84e0ad7f42dc6d4dc23b3f377c4d2 +Subproject commit 45a1782dc09c11c8f9b54a6eefc6ceb8f7b8abe6 diff --git a/NightscoutService b/NightscoutService index 1ea3e43b4e..5ba403c210 160000 --- a/NightscoutService +++ b/NightscoutService @@ -1 +1 @@ -Subproject commit 1ea3e43b4e93926f8d5670c17b2541ace65e53a8 +Subproject commit 5ba403c21072312f8cf4236f7fef3f6c011716dc diff --git a/OmniBLE b/OmniBLE index 536efd9244..d8b6b1560a 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit 536efd9244d894bb67a552168fe6243dcdf124fd +Subproject commit d8b6b1560af9c972dab885480b22f14205b1c376 diff --git a/OmniKit b/OmniKit index 0e3cf2e0c8..a5897b9c58 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit 0e3cf2e0c89b27db466da4bc43087e9be82c2f5d +Subproject commit a5897b9c58bfc70ab75734246946e795a5b1bd10 diff --git a/RileyLinkKit b/RileyLinkKit index b9a52dccc2..bc1f77b333 160000 --- a/RileyLinkKit +++ b/RileyLinkKit @@ -1 +1 @@ -Subproject commit b9a52dccc2b5f7c69b344770b5c65da4862f907c +Subproject commit bc1f77b333319d9c06aff47d89dd0d9feb765b50 diff --git a/SYNC_PROGRESS.md b/SYNC_PROGRESS.md new file mode 100644 index 0000000000..362551fe03 --- /dev/null +++ b/SYNC_PROGRESS.md @@ -0,0 +1,71 @@ +# Tidepool → LoopKit Sync Progress + +**Sync branch:** `tidepool-sync/2026-03-10` +**Source:** `tidepool-org//dev` (or `main`) +**Target:** `LoopKit//dev` (or `main`) +**Started:** 2026-03-10 +**Completed:** 2026-03-10 +**Last updated:** 2026-03-10 + +**Process doc:** [LOOPKIT_SYNC_PROCESS.md](LOOPKIT_SYNC_PROCESS.md) + +--- + +## Status: ✅ ALL REPOS COMPLETE + +18 repos synced, 0 conflicts remaining, ready for compile test & PR. + +--- + +## Full Repo Status + +Work proceeded in **Core → App → Plugins** order (see process doc for rationale). + +| # | Repo | Base | Key Conflicts | Status | Doc | +|---|------|------|---------------|--------|-----| +| 1 | **LoopAlgorithm** | `main` | none (fast-forward) | ✅ Done | [doc](sync-docs/LoopAlgorithm.md) | +| 2 | **LoopKit** | `dev` | 16 conflicts: HK→LoopUnit types, pbxproj, .strings cleanup | ✅ Done | [doc](sync-docs/LoopKit.md) | +| 3 | **Loop** | `dev` | 33 conflicts + Swift Concurrency migration | ✅ Done | [doc](sync-docs/Loop.md) | +| 4 | **TidepoolService** | `dev` | pbxproj + DoseEntry (`import LoopAlgorithm` removed, `decisionId`) | ✅ Done | — | +| 5 | **NightscoutService** | `dev` | pbxproj + NightscoutService (RemoteNotificationResponseManager preserved, `decisionId` added) | ✅ Done | — | +| 6 | **MinimedKit** | `main` | pbxproj + MinimedPumpManager (`decisionId`, async Task, `updateLastEventDates` preserved) | ✅ Done | — | +| 7 | **LibreTransmitter** | `main` | pbxproj + `inSignalLoss`/`isInoperable` properties added | ✅ Done | — | +| 8 | **OmniBLE** | `dev` | pbxproj + OmniBLEPumpManager (6 hunks) + PodState | ✅ Done | — | +| 9 | **OmniKit** | `main` | pbxproj + OmnipodPumpManager (4 hunks) + PodCommsSessionTests | ✅ Done | — | +| 10 | **CGMBLEKit** | `dev` | pbxproj only | ✅ Done | — | +| 11 | **G7SensorKit** | `main` | pbxproj only | ✅ Done | — | +| 12 | **dexcom-share-client-swift** | `dev` | pbxproj only | ✅ Done | — | +| 13 | **NightscoutRemoteCGM** | `dev` | pbxproj only | ✅ Done | — | +| 14 | **RileyLinkKit** | `dev` | pbxproj only | ✅ Done | — | +| 15 | **LoopSupport** | `dev` | pbxproj only | ✅ Done | — | +| 16 | **LoopOnboarding** | `dev` | pbxproj only | ✅ Done | — | +| 17 | **AmplitudeService** | `dev` | pbxproj only | ✅ Done | — | +| 18 | **LogglyService** | `dev` | pbxproj only | ✅ Done | — | +| — | **MixpanelService** | `main` | already in sync, noop | ✅ Noop | — | + +--- + +## Next Steps + +1. **Compile test** — open `LoopWorkspace.xcworkspace` in Xcode and build +2. **Fix any compile errors** that surface (type mismatches, missing parameters, etc.) +3. **Push branches** — requires `GH_TOKEN` with repo write access +4. **Open PRs** — one per repo, `tidepool-sync/2026-03-10` → `dev` (or `main`) + +--- + +## Key Architectural Decisions + +See [LOOPKIT_SYNC_PROCESS.md](LOOPKIT_SYNC_PROCESS.md) for the full Golden Rule and process. + +| Decision | Detail | +|---|---| +| No `import LoopAlgorithm` in TidepoolService | DIY gets types from LoopKit; LoopAlgorithm not in workspace | +| `decisionId: UUID?` added everywhere | LOOP-5295: pump events now carry a decision ID | +| `pumpInoperable` state | LOOP-4801: LibreTransmitter, OmniBLE, OmniKit all got `inSignalLoss`/`isInoperable` | +| `acknowledgeAlert` → `async throws` | OmniBLE + OmniKit: migrated from completion to async | +| OmniBLE `slot6SuspendTimeExpired` guard | DIY safety: don't ack if pod suspended; pod beeps until resumed | +| `updateLastEventDates` preserved in MinimedKit | DIY cannula/insulin age tracking | +| `RemoteNotificationResponseManager` preserved | DIY feature: remote command feedback notifications | +| Live Activity wired via `updateDisplayState()` | LoopDataManager Concurrency migration complete | +| `.strings` refs stripped from all pbxprojs | Tidepool doesn't maintain translations; DIY uses `.xcstrings` | diff --git a/TidepoolService b/TidepoolService index 08b57560b6..c3229fa940 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit 08b57560b6585fdb04d3e245d00899a0d50ff45e +Subproject commit c3229fa940303675a545d7acaef2f0519ae07dd1 diff --git a/dexcom-share-client-swift b/dexcom-share-client-swift index 29409f34c6..a4b6a4b9e6 160000 --- a/dexcom-share-client-swift +++ b/dexcom-share-client-swift @@ -1 +1 @@ -Subproject commit 29409f34c6fb127eec683e9133975c9fde0e015c +Subproject commit a4b6a4b9e6eb2446a5c6112f66c7d98919cbf9ef diff --git a/sync-docs/Loop.md b/sync-docs/Loop.md new file mode 100644 index 0000000000..57292038ca --- /dev/null +++ b/sync-docs/Loop.md @@ -0,0 +1,158 @@ +# Loop Sync Log + +**Repo:** https://github.com/LoopKit/Loop +**Tidepool fork:** https://github.com/tidepool-org/Loop +**Sync date:** 2026-03-10 +**Sync branch:** `tidepool-sync/2026-03-10` +**Base branch:** `dev` + +--- + +## Merge Summary + +- Merge base: `55cf35a9` +- 33 conflicts across 30+ files +- Categories: 3 modify/delete, 22 Swift source, 7 xcschemes, 1 pbxproj + +--- + +## Modify/Delete Resolutions + +### `Loop Widget Extension/Components/SystemActionLink.swift` — DELETED +- **Tidepool** deleted it in commit `c22b37f4` ("Code cleanup"), replacing with `DeeplinkView.swift` +- **DIY** had improved it: added `@available(iOS 16.1, *)`, `widgetRenderingMode`, fixed active preset colors +- **Resolution:** Take deletion. `DeeplinkView.swift` auto-merged cleanly and provides the same + deeplink functionality. DIY's widget tinting improvements should be ported to `DeeplinkView` + if they're missing. +- ⚠️ **Test:** Widget action buttons (carbs, bolus, pre-meal, preset) — verify colors in accented/tinted mode + +### `Loop/Views/FavoriteFoodDetailView.swift` — DELETED (moved) +- **Tidepool** moved it to `Loop/Views/Favorite Foods/FavoriteFoodDetailView.swift` in commit + `2c914f87` ("Renaming/organizing favorite foods") +- **DIY** had updated it with `String(localized:)` annotations on the same fields +- **Resolution:** Take deletion. The `Favorite Foods/` subfolder version already exists in DIY's + tree and `FavoriteFoodsView.swift` references it correctly. DIY's localization updates need + to be checked against the Favorite Foods subfolder version. +- ⚠️ **Test:** Favorite Foods detail view — verify all field labels are localized + +### `Loop/en.lproj/Main.strings` — KEPT DELETED +- DIY deleted it in `cfff59a5` (migrated to `.xcstrings` format) +- Tidepool modified it (never migrated to xcstrings) +- **Resolution:** Keep deleted per the standard .strings policy + +--- + +## Swift Source Resolutions + +### Widget Files + +| File | Resolution | Notes | +|------|-----------|-------| +| `ContentMargin.swift` | Kept DIY's copyright date | Same impl, only date differed | +| `WidgetBackground.swift` | Took Tidepool's | `Color.widgetBackground` extension cleaner than `Color("WidgetBackground")` | +| `SystemStatusWidget.swift` | Took Tidepool's | Uses `DeeplinkView` + `.containerRelativeBackground()`; removed `@available(iOS 16.1, *)` guard (no longer needed) | + +### Managers + +| File | Hunks | Resolution | Notes | +|------|-------|-----------|-------| +| `AppDelegate.swift` | 1 | Kept both | DIY: logging; Tidepool: XCTest environment guard (skip full init in unit tests) | +| `StoredAlert.swift` | 2 | Took Tidepool's | Whitespace/empty hunks only | +| `AppExpirationAlerter.swift` | 2 | Took Tidepool's | Indentation of `#if targetEnvironment(simulator)` only | +| `DeviceDataManager.swift` | 1 | Kept both | DIY: diagnostic report with submodule SHAs (`b6e88416`); Tidepool: `roundBasalRate(unitsPerHour:)` function (`184ea75a`) — different code at adjacent location | +| `RemoteDataServicesManager.swift` | 1 | Took Tidepool's | Migrated `uploadCgmEventData` from callback to `async/await Task` | + +### LoopDataManager ⚠️ NEEDS COMPILE TEST + +This file has the deepest architectural conflict. Tidepool migrated to Swift Concurrency +(`@MainActor async/await`) while DIY added Live Activity support and kept `dataAccessQueue`. + +| Hunk | DIY | Tidepool | Resolution | +|------|-----|---------|-----------| +| 1 | `liveActivityManager: LiveActivityManagerProxy?` property | `lastReservoirValue` computed property | **Kept both** | +| 2 | LiveActivityManager init + overrideIntentObserver setup | Different init params (`analyticsServicesManager`, `carbAbsorptionModel`, etc.) | **Kept both** — ⚠️ likely compile errors; needs human review | +| 3 | `dataAccessQueue.async` + cache invalidation + liveActivity update | `Task { @MainActor in await updateDisplayState() }` | **Tidepool's Task + liveActivity injected** | +| 4 | `dataAccessQueue.async` + glucose effect clear + liveActivity | `Task { @MainActor }` + `restartGlucoseValueStalenessTimer()` | **Tidepool's Task + liveActivity injected** | +| 5 | `dataAccessQueue.async` + insulin effect clear + liveActivity | `Task { @MainActor in await updateDisplayState() }` | **Tidepool's Task + liveActivity injected** | +| 6 | `lockedSettings`, `settings`, `mutateSettings()` + liveActivity calls | `Task { await updateDisplayState() }` | **Kept both** — ⚠️ structural divergence; needs human review | +| 7 | Complete `loop()`→`loopInternal()`→`finishLoop()`→`update()` chain | `await dosingDecisionStore.storeDosingDecision()` (async) | **Kept both** — ⚠️ DIY loop chain critical; Tidepool async store; needs human review | + +**Key questions for human review:** +- Did Tidepool replace `lockedSettings`/`mutateSettings()` with a different pattern? If so, all callers need updating. +- Does Tidepool's `updateDisplayState()` need to also call `liveActivityManager?.update()`? +- Is the DIY `loop()`/`loopInternal()` chain still intact or did Tidepool restructure it? + +### View Controllers + +| File | Resolution | Notes | +|------|-----------|-------| +| `CarbAbsorptionViewController.swift` | Took Tidepool's | Cleaner async do/catch pattern for carb review | +| `InsulinDeliveryTableViewController.swift` | Took Tidepool's | `pumpEvent.dose` + `String(describing:)` format | +| `StatusTableViewController.swift` | Took Tidepool's | More complete `.inProgress` switch handling | + +### View Models + +| File | Resolution | Notes | +|------|-----------|-------| +| `CarbEntryViewModel.swift` | Took Tidepool's | `CarbMath.dateAdjustmentPast` (from LoopAlgorithm pkg) vs `LoopConstants.maxCarbEntryPastTime` — same value, different source | +| `SimpleBolusViewModel.swift` | Took Tidepool's | Explicit `NSLocalizedString("–", comment:...)` | + +### Views + +| File | Resolution | Notes | +|------|-----------|-------| +| `BolusEntryView.swift` | Took Tidepool's | Removed `GeometryReader` wrapper; updated `onChange(of:)` to iOS 17+ two-param API | +| `CarbEntryView.swift` | Took Tidepool's | "Save as favorite" button only shown when `selectedFavoriteFood == nil` | +| `ManualEntryDoseView.swift` | Took Tidepool's | Minor indentation + iOS 17+ `onChange` API | +| `SettingsView.swift` | Kept both | DIY's `favoriteFoods` sheet + Tidepool's `presets` sheet added | + +### Core / Tests + +| File | Resolution | Notes | +|------|-----------|-------| +| `NSUserDefaults.swift` | Kept both | DIY: `liveActivity` key (`LiveActivitySettings`); Tidepool: `defaultEnvironment` key — separate features | +| `AlertStoreTests.swift` | Took Tidepool's | Updated JSON encoding assertions for new Alert format | +| `StoredAlertTests.swift` | Took Tidepool's | Updated JSON expectations | + +### xcschemes (all 7) + +Took Tidepool's — updated Xcode scheme versions. + +--- + +## project.pbxproj + +- Standard resolver applied: merged both sides' file references, dropped Tidepool's `.strings` refs, kept DIY's `.xcstrings`, took Tidepool's deployment target + +--- + +## Features Added by This Merge (Tidepool → DIY) + +- **Active Preset Banner** on CarbEntryView (LOOP-5432) +- **DeeplinkView** widget component (replaces SystemActionLink) +- **roundBasalRate** in DeviceDataManager (LOOP-5558) +- **schedulePresets** storage in NSUserDefaults (LOOP-4754) +- **defaultEnvironment** key for Tidepool service (LOOP-5153) +- **iOS 17+ onChange API** updates throughout views +- **XCTest environment guard** in AppDelegate (skip full init when testing) +- **Async Task pattern** in RemoteDataServicesManager + +## DIY Features Preserved + +- **Live Activity** (`LiveActivityManager`, `liveActivityManager?.update()` calls woven into Tidepool's Task blocks) +- **Diagnostic report with submodule SHAs** in DeviceDataManager +- **FavoriteFoods** sheet in SettingsView +- **liveActivity** NSUserDefaults key + `LiveActivitySettings` + +--- + +## Testing Notes + +- [ ] ⚠️ **Build** — `LoopDataManager.swift` hunks 2/6/7 kept both sides and will very likely need manual fixup to compile +- [ ] **Live Activity** — verify glucose, dosing, and carb notifications all trigger liveActivity updates (hunks 3/4/5) +- [ ] **Widget action buttons** — carbs, bolus, pre-meal, preset deeplinks work; colors correct in tinted mode +- [ ] **Favorite Foods** — detail view labels localized; "Save as favorite" only shown when no food selected +- [ ] **Settings** — both Favorite Foods and Presets sheets accessible +- [ ] **Bolus entry** — recommendation clears on edit; safe area layout correct (GeometryReader removed) +- [ ] **App expiry alerting** — TestFlight and profile expiry both handled independently +- [ ] **Diagnostic report** — includes submodule SHAs in support report diff --git a/sync-docs/LoopAlgorithm.md b/sync-docs/LoopAlgorithm.md new file mode 100644 index 0000000000..a5a98238ff --- /dev/null +++ b/sync-docs/LoopAlgorithm.md @@ -0,0 +1,143 @@ +# LoopAlgorithm Sync Log + +**Repo:** https://github.com/LoopKit/LoopAlgorithm +**Tidepool fork:** https://github.com/tidepool-org/LoopAlgorithm +**Sync date:** 2026-03-10 +**Sync branch:** `tidepool-sync/2026-03-10` +**Base branch:** `main` + +--- + +## Merge Summary + +**Type:** ✅ Clean fast-forward — no conflicts + +- Merge base (LoopKit/main tip): `9d24054` +- Tidepool/main tip: `13cb4b4` +- LoopKit has 0 commits not in Tidepool +- Tidepool has 29 commits not in LoopKit (across multiple PRs) + +``` +git checkout -b tidepool-sync/2026-03-10 +git merge --no-edit tidepool/main +# Result: Fast-forward, 67 files changed, 2237 insertions(+), 442 deletions(-) +``` + +--- + +## What Was Merged + +### PR #24 — Move glucose math tests from LoopKit to LoopAlgorithm +- Commit: `13cb4b4` +- https://github.com/tidepool-org/LoopAlgorithm/pull/24 +- Adds `GlucoseMathTests.swift` (435 lines) and associated fixtures +- Moves test coverage that was previously in LoopKit into this package +- **Testing impact:** Run `LoopAlgorithmTests` test suite + +### PR #23 — Gradual transitions support +- Commit: `8093b57` +- https://github.com/tidepool-org/LoopAlgorithm/pull/23 +- Adds support for gradual insulin/carb effect transitions in algorithm +- **Testing impact:** Verify glucose prediction curves match expected shapes + +### PR #22 — LOOP-5502: Allow setting of max active insulin multiplier +- Commit: `89dd58a` +- https://github.com/tidepool-org/LoopAlgorithm/pull/22 +- Adds configurable `maxActiveInsulinMultiplier` to algorithm input +- **Testing impact:** Verify max IOB calculations respect the multiplier + +### PR #21 — Carb absorption model selection updates +- Commit: `29c7b52` +- https://github.com/tidepool-org/LoopAlgorithm/pull/21 +- Updates how carb absorption model is selected/configured +- **Testing impact:** CarbMathTests; verify carb absorption curves + +### PR #20 — Fix decoding of old AutomaticDoseRecommendation structures +- Commit: `7ba61e1` +- https://github.com/tidepool-org/LoopAlgorithm/pull/20 +- Fixes backward compatibility for `AutomaticDoseRecommendation` without `basalAdjustment` +- **Testing impact:** Data migration; old stored recommendations should decode without crashing + +### PR #19 — Fix issue with mid-absorption ISF calculation +- Commit: `84a099f` +- https://github.com/tidepool-org/LoopAlgorithm/pull/19 +- Fixes insulin sensitivity factor calculation during active carb absorption +- **Testing impact:** CorrectionDosingTests; verify ISF used correctly during meal absorption + +### LOOP-5295 — Add directionality to TempBasalRecommendation +- PR: https://github.com/tidepool-org/LoopAlgorithm/pull/18 +- Adds `.direction` property to `TempBasalRecommendation` (increase/decrease/unchanged) +- Enables Loop UI to show directional feedback on temp basal changes +- **Testing impact:** Verify temp basal recommendations include direction field + +### LOOP-5280 — Display Glucose Preference by InternationalUnit +- Adds `LoopUnit` and `LoopQuantity` types to replace HealthKit dependency for glucose units +- **Testing impact:** New `LoopUnitTests.swift` added + +### Remove HealthKit Dependency & Upgrade to Swift 6 +- Removes `HKUnit.swift` and `HKQuantity.swift` extensions +- Replaces with `LoopUnit` and `LoopQuantity` (custom, no HealthKit import) +- Upgrades Swift concurrency to Swift 6 (`Sendable` annotations throughout) +- **Testing impact:** ⚠️ HIGH IMPACT — changes the unit/quantity types used in algorithm API. + Any caller of the algorithm API that used `HKUnit`/`HKQuantity` needs to be updated + to use `LoopUnit`/`LoopQuantity`. This is a breaking API change. + In LoopKit DIY: the inline `LoopKit/LoopAlgorithm/` code will need these types added, + OR LoopKit should adopt this package. + +### Remove CoreData Import +- Removed CoreData framework dependency from the package +- Package is now more portable and framework-independent + +### PR #14 — Mark AbsoluteScheduleValue as Sendable +- Adds Swift 6 `Sendable` conformance to `AbsoluteScheduleValue` + +--- + +## ⚠️ Breaking API Change: HealthKit Removal + +The most significant change is the replacement of `HKUnit`/`HKQuantity` with `LoopUnit`/`LoopQuantity`. + +**Impact on LoopKit DIY's inline algorithm code (`LoopKit/LoopKit/LoopAlgorithm/`):** +- The inline code still uses HealthKit types +- When syncing LoopKit, these new types need to either: + 1. Be introduced inline in `LoopKit/LoopAlgorithm/` as well, OR + 2. Prompt a decision to adopt the `LoopAlgorithm` package in LoopKit DIY + +This is a cross-repo dependency: **LoopAlgorithm sync must be reviewed before LoopKit sync**. +Specifically, any LoopKit conflict in `LoopAlgorithm/*.swift` files likely involves +these same HealthKit→LoopKit unit type changes. + +--- + +## Files Changed + +| Change | Files | +|--------|-------| +| Deleted | `Extensions/HKQuantity.swift`, `Extensions/HKUnit.swift` | +| Added | `LoopQuantity.swift`, `LoopUnit.swift`, `Tests/GlucoseMathTests.swift`, `Tests/LoopUnitTests.swift` | +| Added fixtures | 13 JSON test fixture files for glucose/carb math tests | +| Modified | `LoopAlgorithm.swift`, `DoseMath.swift`, `GlucoseMath.swift`, `CarbMath.swift`, `InsulinMath.swift`, `LoopPredictionInput.swift`, `AlgorithmInput.swift`, `TempBasalRecommendation.swift`, `AutomaticDoseRecommendation.swift`, and others | + +--- + +## Status + +✅ **Merged cleanly** — fast-forward, no conflicts. + +⚠️ **Action required before LoopKit sync:** +- Review the `LoopUnit`/`LoopQuantity` API change impact on LoopKit's inline algorithm code +- Decide: adopt LoopAlgorithm as a package in DIY, or update inline code to match? +- Consider whether PR needs to be opened on `LoopKit/LoopAlgorithm` → `main` + +--- + +## Testing Notes + +After this sync is pushed and integrated: +- [ ] Run full `LoopAlgorithmTests` test suite +- [ ] Verify glucose prediction accuracy (GlucoseMathTests) +- [ ] Verify ISF handling during carb absorption (CorrectionDosingTests) +- [ ] Verify carb absorption model selection +- [ ] Verify `AutomaticDoseRecommendation` backward decode compatibility +- [ ] Verify `TempBasalRecommendation` direction field populated +- [ ] Check for any callers of algorithm API still using `HKUnit`/`HKQuantity` From 1a0b850a3ef81949f1e3d190590703e36c192216 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 12 Mar 2026 19:45:57 -0500 Subject: [PATCH 004/133] Update TidepoolService submodule ref (restore LoopAlgorithm imports) --- TidepoolService | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TidepoolService b/TidepoolService index c3229fa940..7b6a704055 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit c3229fa940303675a545d7acaef2f0519ae07dd1 +Subproject commit 7b6a704055bbe0a99fd7c80d7f6c7127284e585b From c9608997c51f4f8bda898e27df39602ca8b3ce3e Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 12 Mar 2026 19:46:25 -0500 Subject: [PATCH 005/133] Update sync doc with TidepoolServiceKit import fix --- docs/tidepool-sync-2026-03-10.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/tidepool-sync-2026-03-10.md b/docs/tidepool-sync-2026-03-10.md index bbfd35fe17..5b4a8d5df0 100644 --- a/docs/tidepool-sync-2026-03-10.md +++ b/docs/tidepool-sync-2026-03-10.md @@ -647,6 +647,19 @@ stored properties (`analyticsServicesManager`, `carbAbsorptionModel`, --- +### `TidepoolServiceKit/Extensions/DoseEntry.swift` and `DeviceLogUploader.swift` — Missing `import LoopAlgorithm` + +**Problem:** Both files use `AbsoluteScheduleValue` (DoseEntry.swift) and `TDeviceLogEntry` +(DeviceLogUploader.swift) from the LoopAlgorithm package, but `import LoopAlgorithm` was +incorrectly removed from both files during conflict resolution. All other ~10 files in +TidepoolServiceKit correctly import LoopAlgorithm. The omission caused build failures in +Xcode (though command-line builds may succeed due to implicit module visibility from +LoopKit.xcodeproj's LoopAlgorithm SPM dependency). + +**Fix:** Restored `import LoopAlgorithm` in both files. + +--- + ### `Loop.xcodeproj/project.pbxproj` — Structural Corruption (Loop) **Problem:** The pbxproj resolver's "keep both" strategy on a `PBXVariantGroup` conflict From 530057f9de7d03ee328275ae515e905d4354479e Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 13:42:33 -0500 Subject: [PATCH 006/133] Update TidepoolKit to latest dev (4f4747ff) --- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- TidepoolService | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 5d6f9b843a..1e4885644b 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -168,7 +168,7 @@ "location" : "https://github.com/tidepool-org/TidepoolKit", "state" : { "branch" : "dev", - "revision" : "54045c2e7d720dcd8a0909037772dcd6f54f0158" + "revision" : "4f4747ff647d836c5a27cc1b9c275e5717901e83" } }, { diff --git a/TidepoolService b/TidepoolService index 7b6a704055..babbfa9e72 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit 7b6a704055bbe0a99fd7c80d7f6c7127284e585b +Subproject commit babbfa9e72c2588853b7ee8213edc538bb5483ce From 2498db2cce33312c632629cb8ab9ced07ecd8c82 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 13:55:07 -0500 Subject: [PATCH 007/133] Update mixpanel-swift to v6.0.0 (b4cb3f6e) --- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1e4885644b..373197533b 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -97,7 +97,7 @@ "location" : "https://github.com/mixpanel/mixpanel-swift.git", "state" : { "branch" : "master", - "revision" : "c676a9737c76e127e3ae5776247b226bc6d7652d" + "revision" : "b4cb3f6e3e3084e1637c4dfe06c2dcda169ff523" } }, { From 4e4ae7c4b4ef25b3c878cd908ee7c9c1e9392b88 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 13:58:24 -0500 Subject: [PATCH 008/133] MixpanelService: bump deployment target to iOS 17.0 --- MixpanelService | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MixpanelService b/MixpanelService index b33debdac3..6bf2787e83 160000 --- a/MixpanelService +++ b/MixpanelService @@ -1 +1 @@ -Subproject commit b33debdac37d6ef3be955eebb0c42495a1f19232 +Subproject commit 6bf2787e83ddd8e68686127c90a6a964ca29437c From 577beb97760af65fa4aeaf15fb49dbfa3a4130ac Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 14:05:33 -0500 Subject: [PATCH 009/133] MixpanelService: add instance pluginIdentifier for Pluggable conformance --- MixpanelService | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MixpanelService b/MixpanelService index 6bf2787e83..36c0b767b5 160000 --- a/MixpanelService +++ b/MixpanelService @@ -1 +1 @@ -Subproject commit 6bf2787e83ddd8e68686127c90a6a964ca29437c +Subproject commit 36c0b767b5e56be3b38ad86ba60a50f232f55138 From fa192ac23237aedc6ce6f5d83a74c3b7d0437d78 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 14:35:28 -0500 Subject: [PATCH 010/133] MixpanelService: update ServiceUI conformance for new LoopKitUI API --- MixpanelService | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MixpanelService b/MixpanelService index 36c0b767b5..4a4b433c71 160000 --- a/MixpanelService +++ b/MixpanelService @@ -1 +1 @@ -Subproject commit 36c0b767b5e56be3b38ad86ba60a50f232f55138 +Subproject commit 4a4b433c7181fd8d6fa7d22840fd8466a3f6101e From a11ce414b034a4063e6e705f006555452a646f7c Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 16:25:15 -0500 Subject: [PATCH 011/133] OmniBLE: fix private(set) whitespace for Swift 6 compatibility --- OmniBLE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OmniBLE b/OmniBLE index d8b6b1560a..d5fa71f7f0 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit d8b6b1560af9c972dab885480b22f14205b1c376 +Subproject commit d5fa71f7f055ddd48a5fd314234b7425f1465199 From 3ee6fe3f747dc5924beda297a9d3b589b961fd68 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 16:33:49 -0500 Subject: [PATCH 012/133] OmniBLE: fix Swift 6 compile errors --- OmniBLE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OmniBLE b/OmniBLE index d5fa71f7f0..db9d08a86a 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit d5fa71f7f055ddd48a5fd314234b7425f1465199 +Subproject commit db9d08a86a3fdbfd57bc78a9c52a3f32b162395a From b048699c031e6d6151894eb561db66e4ac55db77 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 17:02:54 -0500 Subject: [PATCH 013/133] Package.resolved: add json-logic-swift 1.2.4 (resolved by Xcode) --- .../xcshareddata/swiftpm/Package.resolved | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 373197533b..766968a3f1 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -64,6 +64,15 @@ "version" : "1.7.1" } }, + { + "identity" : "json-logic-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/advantagefse/json-logic-swift", + "state" : { + "revision" : "9088eed1b26937fe13d248aa24d7632a51be28e2", + "version" : "1.2.4" + } + }, { "identity" : "kituracontracts", "kind" : "remoteSourceControl", From e1c6955fb0bd1ed6a71d8c4b42a15506b2ad3eda Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Wed, 25 Mar 2026 17:11:35 -0500 Subject: [PATCH 014/133] OmniKit: fix Swift 6 compile errors --- OmniKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OmniKit b/OmniKit index a5897b9c58..aa07d3e95d 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit a5897b9c58bfc70ab75734246946e795a5b1bd10 +Subproject commit aa07d3e95ded3dcb70b125a52ad4fb524f98d478 From da186a3f64f1863e87e37fac9eb6bd292eed4bad Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 9 Apr 2026 19:01:02 -0500 Subject: [PATCH 015/133] Bump submodule pins to current tidepool-sync/2026-03-10 heads Catches the superproject up to all submodule work that has accumulated on tidepool-sync/2026-03-10 since the initial sync commit, including: - Loop: restore manual dose entry "+" button on insulin delivery screen - LoopKit, NightscoutService, TidepoolService, LibreTransmitter: string catalog updates from Xcode build - OmniKit: fix reentrant lock crash in isSignalLost - Various submodules: merge upstream/{dev,main} into tidepool-sync branch --- CGMBLEKit | 2 +- G7SensorKit | 2 +- LibreTransmitter | 2 +- LogglyService | 2 +- Loop | 2 +- LoopKit | 2 +- LoopOnboarding | 2 +- LoopSupport | 2 +- MinimedKit | 2 +- NightscoutRemoteCGM | 2 +- NightscoutService | 2 +- OmniBLE | 2 +- OmniKit | 2 +- TidepoolService | 2 +- dexcom-share-client-swift | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CGMBLEKit b/CGMBLEKit index 6b702067d4..6093b71458 160000 --- a/CGMBLEKit +++ b/CGMBLEKit @@ -1 +1 @@ -Subproject commit 6b702067d40394bc39c9b0874cb2e9189e7ff69c +Subproject commit 6093b71458a8b7331dfc49ddc0794243b8cb763d diff --git a/G7SensorKit b/G7SensorKit index 4b850b09e1..32e4b88f06 160000 --- a/G7SensorKit +++ b/G7SensorKit @@ -1 +1 @@ -Subproject commit 4b850b09e192df7bc3fd94317ebfe7935ccbe929 +Subproject commit 32e4b88f06182b661b9a6ef3ce39ee19eb2d09c9 diff --git a/LibreTransmitter b/LibreTransmitter index bc017fba25..2f485e22c6 160000 --- a/LibreTransmitter +++ b/LibreTransmitter @@ -1 +1 @@ -Subproject commit bc017fba254e3e8e18efc7ddb326e951c7f246e1 +Subproject commit 2f485e22c662b556aa943f08868cbe94e6be958d diff --git a/LogglyService b/LogglyService index 86253bd32a..ce3312ebc8 160000 --- a/LogglyService +++ b/LogglyService @@ -1 +1 @@ -Subproject commit 86253bd32a46b7257e7c671acb96aadc65f8722a +Subproject commit ce3312ebc80146b1ca803bdf41865d3622ebdff3 diff --git a/Loop b/Loop index 71e06d6ab8..07e729d30f 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 71e06d6ab88396dd7e2d0f069d7bbf254130a583 +Subproject commit 07e729d30fdc2516ea074dc022d5b011a2d12173 diff --git a/LoopKit b/LoopKit index 12ed30ae5b..775fcc5293 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 12ed30ae5ba993a78707e41089d05056e152e2ff +Subproject commit 775fcc529324d06fb5ef1b359884081c6654383d diff --git a/LoopOnboarding b/LoopOnboarding index eece785c7b..c80552cad3 160000 --- a/LoopOnboarding +++ b/LoopOnboarding @@ -1 +1 @@ -Subproject commit eece785c7b18d835e3da82f32776e385ac0f72ea +Subproject commit c80552cad38fccf8509082ff695329a10b8f7d8e diff --git a/LoopSupport b/LoopSupport index de1dae3aec..592f516190 160000 --- a/LoopSupport +++ b/LoopSupport @@ -1 +1 @@ -Subproject commit de1dae3aecada9dd8e2b48d2ee8a8df26939998e +Subproject commit 592f516190fdfce143a9067af10eddaaad98d8ac diff --git a/MinimedKit b/MinimedKit index fcba4a7d36..95fbc6e1d2 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit fcba4a7d369f624748da201c80a231750b8a7f12 +Subproject commit 95fbc6e1d2aca61d34af7e8e4d9fa5f0ca1626d3 diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 45a1782dc0..68f5c4bc7d 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 45a1782dc09c11c8f9b54a6eefc6ceb8f7b8abe6 +Subproject commit 68f5c4bc7dbdab04d0da40131b313895bd6b5abc diff --git a/NightscoutService b/NightscoutService index 5ba403c210..219314ae23 160000 --- a/NightscoutService +++ b/NightscoutService @@ -1 +1 @@ -Subproject commit 5ba403c21072312f8cf4236f7fef3f6c011716dc +Subproject commit 219314ae23b2193cef6ab48fce4be0a8a81744bc diff --git a/OmniBLE b/OmniBLE index db9d08a86a..a16d31d2af 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit db9d08a86a3fdbfd57bc78a9c52a3f32b162395a +Subproject commit a16d31d2aff5294d19f566f6b846a367800bf2ca diff --git a/OmniKit b/OmniKit index aa07d3e95d..fc0c5a5ad6 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit aa07d3e95ded3dcb70b125a52ad4fb524f98d478 +Subproject commit fc0c5a5ad69dd0c248e00a1e1a485c9b7dcfd80e diff --git a/TidepoolService b/TidepoolService index babbfa9e72..61c041726a 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit babbfa9e72c2588853b7ee8213edc538bb5483ce +Subproject commit 61c041726a9525d5d2aafbe27bc39153c12b1207 diff --git a/dexcom-share-client-swift b/dexcom-share-client-swift index a4b6a4b9e6..320cc673f4 160000 --- a/dexcom-share-client-swift +++ b/dexcom-share-client-swift @@ -1 +1 @@ -Subproject commit a4b6a4b9e6eb2446a5c6112f66c7d98919cbf9ef +Subproject commit 320cc673f49d7fef19f5bae089ae0a60c7f4cde6 From 71525a18f43192ea1c0505de306af3dc31282b36 Mon Sep 17 00:00:00 2001 From: LoopKit Developer Date: Thu, 23 Apr 2026 18:08:06 -0500 Subject: [PATCH 016/133] OmniBLE: bump to e9425ad (fix reentrant lock crash in isSignalLost) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parallel fix to OmniKit 924f10d — OmniBLE had the identical bug where isSignalLost() read state.lastPumpDataReportDate from inside a lockedState.mutate closure, causing recursive lock acquisition. --- OmniBLE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OmniBLE b/OmniBLE index a16d31d2af..e9425ad3bf 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit a16d31d2aff5294d19f566f6b846a367800bf2ca +Subproject commit e9425ad3bfc8a1cc9eb06224f831eb8300e5d6ec From 99c1e57c99f9440f5dedc33f4875022aef75c45d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 10:47:53 -0500 Subject: [PATCH 017/133] Bump submodule pins to tidepool-sync/2026-05-11 heads Tier 1 - LoopKit: bd30c463 (409 commits from tidepool/dev; 18 source conflicts + 19 pbxproj regions resolved; DIY divergence preserved at BasalRateScheduleEditor) - Loop: 76b6b1e3 (14 commits from tidepool/dev; 3 pbxproj regions) Tier 3 - CGM drivers - CGMBLEKit: 69562e7 - G7SensorKit: d024513 - dexcom-share-client-swift: 541de2f - NightscoutRemoteCGM: b1ea9ee - LibreTransmitter: c99daf1 Tier 3 - Pump drivers - RileyLinkKit: 19f5ae8 - OmniKit: b3b6080 (preserves reentrant lock fix; adopts mutateState) - OmniBLE: 645e0fc (preserves reentrant lock fix and Pod Keep Alive suspend special case; adopts mutateState) - MinimedKit: f994d6e (preserves CAGE/IAGE tracking) Tier 3 - Services - TidepoolService: 5f6a064 (incl. DoseEntry dedupe follow-up) - NightscoutService: 1b5cded (preserves APNS response feature) - AmplitudeService: 77dae3e - LogglyService: 8e18081 - MixpanelService: unchanged (already up to date with tidepool) Tier 3 - Support/Onboarding - LoopSupport: a312dfb - LoopOnboarding: fd7e410 Package.resolved - LoopAlgorithm: tidepool-org/LoopAlgorithm bd1a879 (4 test-only commits) --- AmplitudeService | 2 +- CGMBLEKit | 2 +- G7SensorKit | 2 +- LibreTransmitter | 2 +- LogglyService | 2 +- Loop | 2 +- LoopKit | 2 +- LoopOnboarding | 2 +- LoopSupport | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- MinimedKit | 2 +- NightscoutRemoteCGM | 2 +- NightscoutService | 2 +- OmniBLE | 2 +- OmniKit | 2 +- RileyLinkKit | 2 +- TidepoolService | 2 +- dexcom-share-client-swift | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/AmplitudeService b/AmplitudeService index ac96a29fb4..d73d20d3a9 160000 --- a/AmplitudeService +++ b/AmplitudeService @@ -1 +1 @@ -Subproject commit ac96a29fb464de334b0b94e8b6dcb15578ba8e9e +Subproject commit d73d20d3a9c27a200ca30f9672b6d165b2114dc9 diff --git a/CGMBLEKit b/CGMBLEKit index 6093b71458..69f3a85e33 160000 --- a/CGMBLEKit +++ b/CGMBLEKit @@ -1 +1 @@ -Subproject commit 6093b71458a8b7331dfc49ddc0794243b8cb763d +Subproject commit 69f3a85e3371ec7e550151fee67bc0166fe71f69 diff --git a/G7SensorKit b/G7SensorKit index 32e4b88f06..468eefc12c 160000 --- a/G7SensorKit +++ b/G7SensorKit @@ -1 +1 @@ -Subproject commit 32e4b88f06182b661b9a6ef3ce39ee19eb2d09c9 +Subproject commit 468eefc12c936e6d14e0582f9f3bf242b57f6096 diff --git a/LibreTransmitter b/LibreTransmitter index 2f485e22c6..356824bfd8 160000 --- a/LibreTransmitter +++ b/LibreTransmitter @@ -1 +1 @@ -Subproject commit 2f485e22c662b556aa943f08868cbe94e6be958d +Subproject commit 356824bfd8482dbd54e12a8553c459a698d48ede diff --git a/LogglyService b/LogglyService index ce3312ebc8..44f97c9977 160000 --- a/LogglyService +++ b/LogglyService @@ -1 +1 @@ -Subproject commit ce3312ebc80146b1ca803bdf41865d3622ebdff3 +Subproject commit 44f97c99779ba04154f541e4527e512f092f9120 diff --git a/Loop b/Loop index 07e729d30f..761eb48691 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 07e729d30fdc2516ea074dc022d5b011a2d12173 +Subproject commit 761eb48691c4f288b62525ea4609a924f01aff41 diff --git a/LoopKit b/LoopKit index 775fcc5293..c073eab151 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 775fcc529324d06fb5ef1b359884081c6654383d +Subproject commit c073eab151ac40f11898ae6bc10ff6e2980345cc diff --git a/LoopOnboarding b/LoopOnboarding index c80552cad3..da95d69d2c 160000 --- a/LoopOnboarding +++ b/LoopOnboarding @@ -1 +1 @@ -Subproject commit c80552cad38fccf8509082ff695329a10b8f7d8e +Subproject commit da95d69d2c3f35861066dbe704fadb4e4117e787 diff --git a/LoopSupport b/LoopSupport index 592f516190..b93873f4f4 160000 --- a/LoopSupport +++ b/LoopSupport @@ -1 +1 @@ -Subproject commit 592f516190fdfce143a9067af10eddaaad98d8ac +Subproject commit b93873f4f49458d5c23de6a0b98cb7893958d480 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 766968a3f1..181c9131fd 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -97,7 +97,7 @@ "location" : "https://github.com/tidepool-org/LoopAlgorithm", "state" : { "branch" : "main", - "revision" : "13cb4b45258cee5be1eb2ad941b374dde53de551" + "revision" : "bd1a879ef5942c18630429d25294a473c03b426c" } }, { diff --git a/MinimedKit b/MinimedKit index 95fbc6e1d2..a317b3e38e 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit 95fbc6e1d2aca61d34af7e8e4d9fa5f0ca1626d3 +Subproject commit a317b3e38e267297aae816ed47f657bc5c9c1077 diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 68f5c4bc7d..00eefaa056 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 68f5c4bc7dbdab04d0da40131b313895bd6b5abc +Subproject commit 00eefaa0561cee23ed56cb2585d8415b316ec5f1 diff --git a/NightscoutService b/NightscoutService index 219314ae23..09dc797b9a 160000 --- a/NightscoutService +++ b/NightscoutService @@ -1 +1 @@ -Subproject commit 219314ae23b2193cef6ab48fce4be0a8a81744bc +Subproject commit 09dc797b9a30682d02f20a985fec3efb79975e14 diff --git a/OmniBLE b/OmniBLE index e9425ad3bf..832b124e0d 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit e9425ad3bfc8a1cc9eb06224f831eb8300e5d6ec +Subproject commit 832b124e0d1cad4b44cfc758c689834e69d88d18 diff --git a/OmniKit b/OmniKit index fc0c5a5ad6..0d81565530 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit fc0c5a5ad69dd0c248e00a1e1a485c9b7dcfd80e +Subproject commit 0d81565530e02b9de63cdb4157e0b915a4c4e7c9 diff --git a/RileyLinkKit b/RileyLinkKit index bc1f77b333..8a3164bfef 160000 --- a/RileyLinkKit +++ b/RileyLinkKit @@ -1 +1 @@ -Subproject commit bc1f77b333319d9c06aff47d89dd0d9feb765b50 +Subproject commit 8a3164bfefeb749cff08acefb97e741467e566fe diff --git a/TidepoolService b/TidepoolService index 61c041726a..765bcb9b33 160000 --- a/TidepoolService +++ b/TidepoolService @@ -1 +1 @@ -Subproject commit 61c041726a9525d5d2aafbe27bc39153c12b1207 +Subproject commit 765bcb9b339a1c058428707d6dd8ddb0967e90a5 diff --git a/dexcom-share-client-swift b/dexcom-share-client-swift index 320cc673f4..e4c2796377 160000 --- a/dexcom-share-client-swift +++ b/dexcom-share-client-swift @@ -1 +1 @@ -Subproject commit 320cc673f49d7fef19f5bae089ae0a60c7f4cde6 +Subproject commit e4c2796377c7e32c8983006f95b23c3114e6a06f From 212bc27dc63aa6c20dd3459278fcf67cb942bfc8 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 10:48:18 -0500 Subject: [PATCH 018/133] Sync log + progress for 2026-05-11 docs/tidepool-sync-2026-05-11.md describes the merge, conflicts, and divergences. SYNC_PROGRESS.md updated to reflect the new branch and the divergences carried forward. --- SYNC_PROGRESS.md | 94 ++++++++------- docs/tidepool-sync-2026-05-11.md | 199 +++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+), 44 deletions(-) create mode 100644 docs/tidepool-sync-2026-05-11.md diff --git a/SYNC_PROGRESS.md b/SYNC_PROGRESS.md index 362551fe03..40b6adb132 100644 --- a/SYNC_PROGRESS.md +++ b/SYNC_PROGRESS.md @@ -1,71 +1,77 @@ # Tidepool → LoopKit Sync Progress -**Sync branch:** `tidepool-sync/2026-03-10` +**Sync branch:** `tidepool-sync/2026-05-11` **Source:** `tidepool-org//dev` (or `main`) **Target:** `LoopKit//dev` (or `main`) -**Started:** 2026-03-10 -**Completed:** 2026-03-10 -**Last updated:** 2026-03-10 +**Started:** 2026-05-11 +**Last updated:** 2026-05-11 **Process doc:** [LOOPKIT_SYNC_PROCESS.md](LOOPKIT_SYNC_PROCESS.md) +**Sync log:** [docs/tidepool-sync-2026-05-11.md](docs/tidepool-sync-2026-05-11.md) +**Previous sync:** [SYNC_PROGRESS history for 2026-03-10](#) — branch merged to dev across all 18 repos --- -## Status: ✅ ALL REPOS COMPLETE +## Status: ✅ ALL REPOS MERGED (build verification pending) -18 repos synced, 0 conflicts remaining, ready for compile test & PR. +17 repos merged, 1 noop (MixpanelService already current). All conflicts resolved; build verification in progress. --- ## Full Repo Status -Work proceeded in **Core → App → Plugins** order (see process doc for rationale). - -| # | Repo | Base | Key Conflicts | Status | Doc | -|---|------|------|---------------|--------|-----| -| 1 | **LoopAlgorithm** | `main` | none (fast-forward) | ✅ Done | [doc](sync-docs/LoopAlgorithm.md) | -| 2 | **LoopKit** | `dev` | 16 conflicts: HK→LoopUnit types, pbxproj, .strings cleanup | ✅ Done | [doc](sync-docs/LoopKit.md) | -| 3 | **Loop** | `dev` | 33 conflicts + Swift Concurrency migration | ✅ Done | [doc](sync-docs/Loop.md) | -| 4 | **TidepoolService** | `dev` | pbxproj + DoseEntry (`import LoopAlgorithm` removed, `decisionId`) | ✅ Done | — | -| 5 | **NightscoutService** | `dev` | pbxproj + NightscoutService (RemoteNotificationResponseManager preserved, `decisionId` added) | ✅ Done | — | -| 6 | **MinimedKit** | `main` | pbxproj + MinimedPumpManager (`decisionId`, async Task, `updateLastEventDates` preserved) | ✅ Done | — | -| 7 | **LibreTransmitter** | `main` | pbxproj + `inSignalLoss`/`isInoperable` properties added | ✅ Done | — | -| 8 | **OmniBLE** | `dev` | pbxproj + OmniBLEPumpManager (6 hunks) + PodState | ✅ Done | — | -| 9 | **OmniKit** | `main` | pbxproj + OmnipodPumpManager (4 hunks) + PodCommsSessionTests | ✅ Done | — | -| 10 | **CGMBLEKit** | `dev` | pbxproj only | ✅ Done | — | -| 11 | **G7SensorKit** | `main` | pbxproj only | ✅ Done | — | -| 12 | **dexcom-share-client-swift** | `dev` | pbxproj only | ✅ Done | — | -| 13 | **NightscoutRemoteCGM** | `dev` | pbxproj only | ✅ Done | — | -| 14 | **RileyLinkKit** | `dev` | pbxproj only | ✅ Done | — | -| 15 | **LoopSupport** | `dev` | pbxproj only | ✅ Done | — | -| 16 | **LoopOnboarding** | `dev` | pbxproj only | ✅ Done | — | -| 17 | **AmplitudeService** | `dev` | pbxproj only | ✅ Done | — | -| 18 | **LogglyService** | `dev` | pbxproj only | ✅ Done | — | -| — | **MixpanelService** | `main` | already in sync, noop | ✅ Noop | — | +| # | Repo | Base | Tidepool commits | Conflicts | Submodule commit | Status | +|---|------|------|------------------|-----------|------------------|--------| +| — | **LoopAlgorithm** | `main` | 4 (test-only) | — (pin bump) | pin → `bd1a879` | ✅ Done | +| 1 | **LoopKit** | `dev` | 409 | 18 source + 19 pbxproj | `bd30c463` | ✅ Done | +| 2 | **Loop** | `dev` | 14 | 0 source + 3 pbxproj | `76b6b1e3` | ✅ Done | +| 3 | **CGMBLEKit** | `dev` | 13 | pbxproj only (4) | `69562e7` | ✅ Done | +| 4 | **G7SensorKit** | `main` | 15 | pbxproj only (2) | `d024513` | ✅ Done | +| 5 | **dexcom-share-client-swift** | `dev` | 15 | pbxproj only (3, + orphan cleanup) | `541de2f` | ✅ Done | +| 6 | **NightscoutRemoteCGM** | `dev` | 13 | pbxproj only (2) | `b1ea9ee` | ✅ Done | +| 7 | **LibreTransmitter** | `main` | 14 | pbxproj only (3) | `c99daf1` | ✅ Done | +| 8 | **RileyLinkKit** | `dev` | 3 | pbxproj only (2) | `19f5ae8` | ✅ Done | +| 9 | **OmniKit** | `main` | 18 | OmnipodPumpManager (6 regions) + pbxproj | `b3b6080` | ✅ Done | +| 10 | **OmniBLE** | `dev` | 20 | OmniBLEPumpManager (8 regions) + pbxproj | `645e0fc` | ✅ Done | +| 11 | **MinimedKit** | `main` | 18 | MinimedPumpManager + 1 trivial + pbxproj | `f994d6e` | ✅ Done | +| 12 | **TidepoolService** | `dev` | 45 | DoseEntry + pbxproj | `5f6a064` | ✅ Done | +| 13 | **NightscoutService** | `dev` | 22 | NightscoutService + pbxproj | `1b5cded` | ✅ Done | +| 14 | **AmplitudeService** | `dev` | 6 | pbxproj only (2) | `77dae3e` | ✅ Done | +| 15 | **LogglyService** | `dev` | 6 | pbxproj only (2) | `8e18081` | ✅ Done | +| 16 | **LoopSupport** | `dev` | 11 | pbxproj only (2) | `a312dfb` | ✅ Done | +| 17 | **LoopOnboarding** | `dev` | 28 | pbxproj only (2) | `fd7e410` | ✅ Done | +| — | **MixpanelService** | `main` | 0 | — | unchanged | ✅ Noop | + +LoopWorkspace superproject commit: `3d4432c` ("Bump submodule pins to tidepool-sync/2026-05-11 heads"). --- ## Next Steps -1. **Compile test** — open `LoopWorkspace.xcworkspace` in Xcode and build -2. **Fix any compile errors** that surface (type mismatches, missing parameters, etc.) -3. **Push branches** — requires `GH_TOKEN` with repo write access -4. **Open PRs** — one per repo, `tidepool-sync/2026-03-10` → `dev` (or `main`) +1. **Compile test** — `xcodebuild build -workspace LoopWorkspace.xcworkspace -scheme Loop -destination 'platform=iOS Simulator,name=iPhone 17'` +2. **Fix any compile errors** that surface +3. **Push branches** to `loopkitdev/` +4. **Open PRs** — one per repo, `tidepool-sync/2026-05-11` → `dev` (or `main`) --- -## Key Architectural Decisions +## DIY Divergences Established This Sync -See [LOOPKIT_SYNC_PROCESS.md](LOOPKIT_SYNC_PROCESS.md) for the full Golden Rule and process. +| Decision | Detail | +|---|---| +| `BasalRateScheduleEditor` enforces max basal | DIY rejects tidepool/LoopKit PR #734 (LOOP-5767). Keep `maximumBasalRate: therapySettings.maximumBasalRatePerHour`, not `nil`. See [`memory/divergence_basal_max_filter.md`](../memory/divergence_basal_max_filter.md). The DIY user-reported bug (max basal not respected on OmniBLE/Dash) is what surfaced this. | +| OmniBLE/OmniKit reentrant-lock fix | DIY's `isSignalLost(at:lastPumpDataReportDate:)` signature is preserved over Tidepool's `isSignalLost(at: Date = Date())` to avoid reentrant lock crashes under rapid status polling. | +| OmniBLE Pod Keep Alive suspend special case | DIY's `slot6SuspendTimeExpired` skip-ack guard preserved during the migration to `mutateState`. | +| MinimedKit CAGE/IAGE | DIY's `updateLastEventDates(from:)` for cannula and insulin age tracking preserved; Tidepool has no equivalent. | +| NightscoutService APNS response feature | DIY's `RemoteNotificationResponseManager` + JWT-managed return notifications preserved; Tidepool's simpler version dropped. | +| OmniBLE temp basal error handling | Kept DIY's `completion(.communication(error))` style; did not adopt Tidepool's `do { ... } catch` refactor because it cannot be cleanly applied to the conflict region alone. decisionId tracking already present in DIY. | + +--- + +## Key Patterns Carried Forward from 2026-03-10 | Decision | Detail | |---|---| -| No `import LoopAlgorithm` in TidepoolService | DIY gets types from LoopKit; LoopAlgorithm not in workspace | -| `decisionId: UUID?` added everywhere | LOOP-5295: pump events now carry a decision ID | -| `pumpInoperable` state | LOOP-4801: LibreTransmitter, OmniBLE, OmniKit all got `inSignalLoss`/`isInoperable` | -| `acknowledgeAlert` → `async throws` | OmniBLE + OmniKit: migrated from completion to async | -| OmniBLE `slot6SuspendTimeExpired` guard | DIY safety: don't ack if pod suspended; pod beeps until resumed | -| `updateLastEventDates` preserved in MinimedKit | DIY cannula/insulin age tracking | -| `RemoteNotificationResponseManager` preserved | DIY feature: remote command feedback notifications | -| Live Activity wired via `updateDisplayState()` | LoopDataManager Concurrency migration complete | -| `.strings` refs stripped from all pbxprojs | Tidepool doesn't maintain translations; DIY uses `.xcstrings` | +| LoopAlgorithm as Swift Package | DIY pulls `tidepool-org/LoopAlgorithm` via workspace `Package.resolved`. Do not re-add `XCRemoteSwiftPackageReference "LoopAlgorithm"` to per-repo `.pbxproj` files. | +| `.xcstrings` over `.strings` | DIY uses Xcode 15+ string catalogs; always drop Tidepool's `.strings` PBXFileReferences and variant-group children during pbxproj conflict resolution. | +| Preserve `LOCALIZATION_PREFERS_STRING_CATALOGS = YES` | Always keep DIY side of this XCBuildConfiguration setting. | diff --git a/docs/tidepool-sync-2026-05-11.md b/docs/tidepool-sync-2026-05-11.md new file mode 100644 index 0000000000..cb24ee94ef --- /dev/null +++ b/docs/tidepool-sync-2026-05-11.md @@ -0,0 +1,199 @@ +# Tidepool → LoopKit DIY Sync — 2026-05-11 + +**Branch:** `tidepool-sync/2026-05-11` (17 repos merged + LoopAlgorithm pin bump) +**Build status:** pending verification (in progress at time of writing) +**Previous sync:** 2026-03-10 (see [`tidepool-sync-2026-03-10.md`](tidepool-sync-2026-03-10.md)) + +This is the smaller, follow-up sync after the large 2026-03-10 rebase. +Most of the heavy architectural integration (LoopAlgorithm package extraction, +Swift Concurrency migration, HK→LoopUnit migration) landed last time. This sync +absorbs roughly 2 months of incremental Tidepool development. + +--- + +## Headline numbers + +| Repo (Tier 1+2) | Tidepool commits absorbed | +|---|---| +| LoopKit | 409 | +| Loop | 14 | + +| Repo (Tier 3) | Tidepool commits absorbed | +|---|---| +| TidepoolService | 45 | +| LoopOnboarding | 28 | +| NightscoutService | 22 | +| OmniBLE | 20 | +| OmniKit / MinimedKit | 18 each | +| G7SensorKit / dexcom-share-client-swift | 15 each | +| LibreTransmitter | 14 | +| CGMBLEKit / NightscoutRemoteCGM | 13 each | +| LoopSupport | 11 | +| AmplitudeService / LogglyService | 6 each | +| RileyLinkKit | 3 | +| MixpanelService | 0 (already up to date) | +| LoopAlgorithm (package pin) | 4 (test-only) | + +Total: ~660 Tidepool commits across the ecosystem. + +--- + +## 1. New features from Tidepool + +Most of these are completed by Tidepool in the LoopKit/Loop repos themselves. +The plugins primarily got matching protocol/API updates. + +### LoopKit + +- **Required version-update flow** (LOOP-1114) — new `LoopNotificationCategory.requiredUpdate` + and a `SupportProviding` protocol with `MockSupport` UI. +- **`isMutable` dose detection** (LOOP-5843) — `DoseStore` now uses `isMutable` rather + than time-based heuristics to determine unfinished doses. +- **Activity preset insulin-scale tuning** (LOOP-5807) — biking 0.22→0.23, strength + training 0.39→0.37 in `TemporaryScheduleOverride.defaultInsulinNeedsScaleFactor`. +- **Correction range overrides guardrail** (LOOP-5878) — `CorrectionRangeOverridesEditor` + now actually passes `viewModel.guardrail` (was always `nil`). +- **New preset UI infrastructure** — `EditPresetView`, `ReviewNewPresetView`, + `InsulinNeedsAdjustmentPreview`, and supporting types. +- **Media/Transcript support** — 7 new files under `LoopKit/Media/` (captions, transcripts, + metadata) — likely for in-app support/training video infrastructure. +- **QuantityFormatter API simplification** — removed unused `rule:` parameter from + `doubleValue()`. + +### Loop + +- **Required version-update view** — `RequiredVersionUpdateView`, paired with the LoopKit + notification category above. +- **Preset performance history** — `PresetPerformanceHistoryView` and `PresetsPerformanceHistoryViewModel`. +- **Automation history tracking** — `AutomationHistoryEntry`, `AutomationHistoryEntryTests`. +- **Media/Transcript player infrastructure** — `AudioPlayer`, `CaptionsView`, `MediaPlayerView`, + `PlayerControls`, `TranscriptView`, `VideoView` under `Loop/Views/Presets/Media Player/`. + +### Plugins + +- **OmniBLE / OmniKit** — `mutateState` API migration (replacing `setState`); `decisionId` + carried through the temp-basal path; pod-inoperable refinements. +- **MinimedKit** — same `decisionId` + protocol updates as the other pump drivers. +- **TidepoolService / NightscoutService** — `decisionId` on `DoseEntry` and + `PersistedPumpEvent`; misc protocol updates. + +--- + +## 2. Conflicts encountered & resolutions + +### LoopKit — 18 source conflicts + 19 pbxproj regions + +**Mechanical "take Tidepool" (low risk):** +DoseStore, LoopNotificationCategory, QuantityFormatter, TemporaryScheduleOverride, +LoopKitUI/SupportUI, GlucoseTherapySettingInformationView, CorrectionRangeOverridesEditor, +InsulinType (loses Lokalise detailed insulin descriptions — translations will repopulate +on next Lokalise run). + +**Keep DIY (DIY-only debug features):** +`MockKitUI/Views/MockCGMManagerSettingsView.swift` and `MockPumpManagerSettingsView.swift` +— simulator settings gated by `allowDebugFeatures`. Tidepool doesn't have these. + +**Accept Tidepool deletions (LoopAlgorithm package extraction, LOOP-4781):** +- `LoopKit/InsulinKit/ExponentialInsulinModel.swift` +- `LoopKit/LoopAlgorithm/LoopAlgorithm.swift` +- `LoopKit/LoopAlgorithm/LoopPredictionOutput.swift` + +These types now live in `tidepool-org/LoopAlgorithm` (the Swift Package DIY already +pulls via workspace `Package.resolved`). Deleting the inline copies makes DIY match +Tidepool's architecture. + +**Accept Tidepool deletion (preset UI replaced):** +`LoopKitUI/View Controllers/OverrideSelectionViewController.swift` — superseded by +Tidepool's new SwiftUI `EditPresetView` / `ReviewNewPresetView`. DIY's crash-fix +commit `3ce43ded` does not apply to the new SwiftUI flow. + +**Add/add — both sides added the same files:** +Took Tidepool's content for the new preset infrastructure +(`InsulinNeedsAdjustmentPreview`, `EditPresetView`, `ReviewNewPresetView`). + +**DIY divergence — BasalRateScheduleEditor max-basal filtering (see Section 4):** +The auto-merge silently dropped this fix; restored manually with a comment pointing +at the divergence memory. + +**pbxproj (19 regions):** +- Dropped all Tidepool `.strings` PBXFileReferences and PBXBuildFiles +- Kept DIY's `.xcstrings` references and `LOCALIZATION_PREFERS_STRING_CATALOGS = YES` +- Kept Tidepool's new Media/Transcript and `TimeInterval+Timecode.swift` references +- Dropped references to the 4 source files deleted in this merge +- Pre-existing `XCRemoteSwiftPackageReference "LoopAlgorithm"` in HEAD was left alone + (not part of this merge; same as 2026-03-10) +- Final state: 1898 `{` / 1898 `}`, `xcodebuild -list` parses + +### Loop — 3 pbxproj regions only (no source conflicts) + +- Regions 1 + 2: both sides added a Swift file at the same insertion point — + kept both `ContentMargin.swift` (DIY) and `PresetPerformanceHistoryView.swift` (Tidepool). +- Region 3: dropped Tidepool's `.strings` refs (ru/de InfoPlist/Localizable/ckcomplication); + kept Tidepool's new Swift files (`RequiredVersionUpdateView`, `AutomationHistoryEntry`, + `AutomationHistoryEntryTests`, `LoopCircleView`). +- Cleaned up 3 orphaned variant-group children at lines ~4088, 4147, 4166 that + referenced the dropped `.strings` FileReferences. + +### Plugins (Tier 3) — pbxproj patterns + +For 11 of the 15 plugin merges, the *only* conflict was the standard +`LOCALIZATION_PREFERS_STRING_CATALOGS = YES` line in the Debug+Release +XCBuildConfiguration blocks. All resolved by keeping DIY's setting. + +Notable plugin-specific cleanup: +- **CGMBLEKit**: dropped a duplicate array-form `LD_RUNPATH_SEARCH_PATHS` entry + (string form remains below). +- **dexcom-share-client-swift**: cleaned up an orphaned `Localizable.strings` + children-reference in the `ShareClient` PBXGroup that had no PBXFileReference + declaration. +- **TidepoolService**: 4 conflict regions — kept DIY's `.xcstrings` PBXBuildFiles + and PBXFileReferences (the 4 IDs are properly wired into PBXGroup children + and PBXResourcesBuildPhase); dropped 10 Tidepool `.strings` FileReferences. + +### Plugin source conflicts (the 5 repos that had them) + +| Repo / File | Resolution | +|---|---| +| OmniKit / `OmnipodPumpManager.swift` | 3 regions keep DIY (`isSignalLost(at:lastPumpDataReportDate:)` reentrant-lock fix from commit `924f10d`); 3 regions take Tidepool (`setState` → `mutateState` Swift 6 migration). | +| OmniBLE / `OmniBLEPumpManager.swift` | 3 regions keep DIY (reentrant-lock fix `e9425ad`); region at line 2221 keep DIY (`completion(.communication(error))` error style — Tidepool's do/catch refactor cannot be cleanly applied to the conflict region alone; `decisionId` tracking already present in DIY's `setTempBasal` call); region at line 2722 **manual merge** (preserve DIY suspend-time-expired special case from Pod Keep Alive #165 + adopt Tidepool's properly-indented `try await withCheckedThrowingContinuation`); 3 regions take Tidepool (`mutateState`). | +| MinimedKit / `MinimedPumpManager.swift` | All 3 regions keep DIY — preserves CAGE/IAGE tracking (commit `ff07802`); the third region was Tidepool adding a duplicate `isInoperable` property that DIY already had elsewhere in the file. | +| MinimedKit / `MinimedKitUI/Views/MinimedPumpSettingsViewModel.swift` | Take Tidepool (trivial whitespace). | +| TidepoolService / `TidepoolServiceKit/Extensions/DoseEntry.swift` | Both sides changed import ordering; pre-staged resolution kept both → duplicate `import LoopAlgorithm`. Follow-up commit `5f6a064` deduped. | +| NightscoutService / `NightscoutServiceKit/NightscoutService.swift` | Keep DIY — preserves the 60-line APNS response feature (`RemoteNotificationResponseManager`, JWT-managed return notifications) from commit `0ca2c08`. Tidepool's version is a simpler switch with no response handling. | + +--- + +## 3. DIY divergences + +See `SYNC_PROGRESS.md` "DIY Divergences" section for the canonical list. New as of this sync: + +### BasalRateScheduleEditor max-basal filtering + +A DIY user (OmniBLE/Dash) reported being able to set basal schedule entries above +their configured `maximumBasalRatePerHour`. The cause was that DIY had inherited +Tidepool's PR #734 (LOOP-5767, "Basal schedule editor should ignore max basal rate", +merged 2026-02-27) in the 2026-03-10 sync, which changed the convenience initializer +in `BasalRateScheduleEditor` to pass `maximumBasalRate: nil`, disabling the picker-side +filter. + +DIY explicitly rejects this Tidepool change. Restored +`maximumBasalRate: therapySettingsViewModel.therapySettings.maximumBasalRatePerHour` +with an inline comment pointing at `memory/divergence_basal_max_filter.md`. On +2026-05-11 sync, auto-merge silently reverted this fix; manual restoration was needed +and a divergence comment was added to defend it on future syncs. + +--- + +## 4. Items to verify post-build + +- **OmniBLE temp basal error reporting:** kept DIY's `completion(.communication(error))` + pattern; verify error messages still surface correctly to Loop on temp basal failures. +- **Mock simulator features:** ensure simulator pump/CGM settings still render under + `allowDebugFeatures` flag in debug builds. +- **APNS responses (NightscoutService):** verify remote command feedback notifications + still flow end-to-end. +- **Basal schedule editor (OmniBLE / Dash):** verify the originally reported bug is + resolved — entries above the configured max basal should not be selectable. +- **Lokalise translations:** `InsulinType.swift` lost DIY's detailed insulin + descriptions in favor of Tidepool's simpler combined Fiasp/Lyumjev case. Next + Lokalise pull should repopulate. From 0f207ef2ef0700179a93f606bcaa00d6be57f895 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 11:12:43 -0500 Subject: [PATCH 019/133] Catch up Loop, CGMBLEKit, OmniBLE pins to origin/dev Pulls in 3 small origin/dev updates that landed after this sync started: - Loop: PR #2410 Live activity plot fixes (manual merge to preserve our post-Tidepool-sync API: kept async/await sample fetch + LoopUnit signature, adopted upstream's presetStart<=presetEnd guard and the adjustedChartStart/End helpers) - CGMBLEKit: PR #211 handle inactive CGM sensor sessions (clean merge) - OmniBLE: Lokalise translation update (clean merge) --- CGMBLEKit | 2 +- Loop | 2 +- OmniBLE | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CGMBLEKit b/CGMBLEKit index 69f3a85e33..48bbfad581 160000 --- a/CGMBLEKit +++ b/CGMBLEKit @@ -1 +1 @@ -Subproject commit 69f3a85e3371ec7e550151fee67bc0166fe71f69 +Subproject commit 48bbfad581d918c28dde08af237edc6f730f3696 diff --git a/Loop b/Loop index 761eb48691..60c30bf2ad 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 761eb48691c4f288b62525ea4609a924f01aff41 +Subproject commit 60c30bf2adde804da797e686e1ea5fbb550446ab diff --git a/OmniBLE b/OmniBLE index 832b124e0d..82a8a63479 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit 832b124e0d1cad4b44cfc758c689834e69d88d18 +Subproject commit 82a8a634799db33df45e820fc15e5f9459abe412 From 932d5c3f8185d041f840974894cc00e1f78b95a7 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 12:05:13 -0500 Subject: [PATCH 020/133] Bump Loop pin: post-dose updateRemoteRecommendation for NS uploads --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 60c30bf2ad..36eba3caa1 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 60c30bf2adde804da797e686e1ea5fbb550446ab +Subproject commit 36eba3caa121f56ed258917ca28ee90fe91c9f13 From d65fff9e8f6948f5b725b4d6a211d370f0996c6a Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 12:21:11 -0500 Subject: [PATCH 021/133] Bump OmniKit + OmniBLE pins: setState compile fix --- OmniBLE | 2 +- OmniKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OmniBLE b/OmniBLE index 82a8a63479..166ecfb11a 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit 82a8a634799db33df45e820fc15e5f9459abe412 +Subproject commit 166ecfb11a35846ab9987f514807c31745e47ab3 diff --git a/OmniKit b/OmniKit index 0d81565530..52d2f41c7e 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit 0d81565530e02b9de63cdb4157e0b915a4c4e7c9 +Subproject commit 52d2f41c7ee5ce42c8ffa4ea0d524f840714eb02 From 7c53ccaa42c642779135fb024019ac726aee7435 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 12:43:46 -0500 Subject: [PATCH 022/133] Bump MinimedKit pin: restore DIY CAGE/IAGE viewModel properties --- MinimedKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinimedKit b/MinimedKit index a317b3e38e..f19f99cc0b 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit a317b3e38e267297aae816ed47f657bc5c9c1077 +Subproject commit f19f99cc0b552fc6996412285f9a1e450a4f4961 From 6c7cd548e24eb679aee776818f92437a14da3fd3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 12:54:58 -0500 Subject: [PATCH 023/133] Bump LoopKit pin: restore public on ResizeablePicker --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index c073eab151..c75a9481a9 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit c073eab151ac40f11898ae6bc10ff6e2980345cc +Subproject commit c75a9481a9201025aca4eaa3adac78568cba7c76 From 83646c76a1332ae97c54848a536d4eb57948423f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 13:13:19 -0500 Subject: [PATCH 024/133] Bump Loop + LoopKit pins: remove ResizeablePicker DIY divergence --- Loop | 2 +- LoopKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Loop b/Loop index 36eba3caa1..e500280a12 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 36eba3caa121f56ed258917ca28ee90fe91c9f13 +Subproject commit e500280a12d2090ea46aec687384d6813b55fe0c diff --git a/LoopKit b/LoopKit index c75a9481a9..fd075aa5db 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit c75a9481a9201025aca4eaa3adac78568cba7c76 +Subproject commit fd075aa5db8111eda3f9ebd2e87dd77c98e9fe5d From 1f603e38247bbc8696c5f48667f1580c7118e7b6 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 14:18:24 -0500 Subject: [PATCH 025/133] Bump Loop pin: fix Live Activity preset SF Symbol rendering --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index e500280a12..522f8c1fda 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit e500280a12d2090ea46aec687384d6813b55fe0c +Subproject commit 522f8c1fda3dff8e395ec1a58e4c8fd6c77a6343 From 168e3f18254e0d230c26e52df5d3ff4d9a84196c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 14:22:19 -0500 Subject: [PATCH 026/133] Bump Loop pin: top-leading alignment for Live Activity preset label --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 522f8c1fda..6f848c7e58 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 522f8c1fda3dff8e395ec1a58e4c8fd6c77a6343 +Subproject commit 6f848c7e58265455bd4bd1777bf71bd1a2c6a9ca From 429d7ade0713c0ce8e090ccde43b9f578f30e49c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 14:28:11 -0500 Subject: [PATCH 027/133] Bump Loop pin: preset label inside plot area --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 6f848c7e58..72dc6239f1 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 6f848c7e58265455bd4bd1777bf71bd1a2c6a9ca +Subproject commit 72dc6239f1ed52c84bee8c428f9356efa7c0d3e4 From 193ef5a8ae47b69eec35f225e6619dc923dbb48b Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 11 May 2026 14:34:05 -0500 Subject: [PATCH 028/133] Bump Loop pin: promote Live Activity to top-level settings --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 72dc6239f1..830af33d06 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 72dc6239f1ed52c84bee8c428f9356efa7c0d3e4 +Subproject commit 830af33d06b462f46ee832d3d70497819c47ef01 From 4010975e45676bd449814258b0fbda8a1c866beb Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Tue, 12 May 2026 15:05:22 -0500 Subject: [PATCH 029/133] Add LibreLoop submodule for FreeStyle Libre 3 CGM plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulls in the new loopkitdev/LibreLoop repo (initial scaffold at 55b65d6), registers its xcodeproj in the workspace, and adds LibreLoopPlugin to the LoopWorkspace scheme so copy-plugins.sh embeds the .loopplugin bundle into Loop.app/Frameworks. With this in place Loop's CGM picker surfaces a "FreeStyle Libre 3" entry and runs the plugin's onboarding flow. No changes to Loop or LoopKit are required — discovery is purely via PluginManager's Info.plist scan. --- .gitmodules | 3 +++ LibreLoop | 1 + LoopWorkspace.xcworkspace/contents.xcworkspacedata | 3 +++ .../xcshareddata/xcschemes/LoopWorkspace.xcscheme | 14 ++++++++++++++ 4 files changed, 21 insertions(+) create mode 160000 LibreLoop diff --git a/.gitmodules b/.gitmodules index 3637ab97e8..88ba2a00bf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -58,3 +58,6 @@ [submodule "LibreTransmitter"] path = LibreTransmitter url = https://github.com/loopkitdev/LibreTransmitter.git +[submodule "LibreLoop"] + path = LibreLoop + url = https://github.com/loopkitdev/LibreLoop.git diff --git a/LibreLoop b/LibreLoop new file mode 160000 index 0000000000..21650f5785 --- /dev/null +++ b/LibreLoop @@ -0,0 +1 @@ +Subproject commit 21650f5785e315391fa1444498322bc58bd52a39 diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index a870f8b7c9..8b166b00fd 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -126,6 +126,9 @@ + + diff --git a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme index e09bc55654..0ddf1ccf8d 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme +++ b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme @@ -286,6 +286,20 @@ ReferencedContainer = "container:LibreTransmitter/LibreTransmitter.xcodeproj"> + + + + Date: Fri, 15 May 2026 07:45:48 -0500 Subject: [PATCH 030/133] LibreLoop: catch up to 5d6aeba on tidepool-sync base Bumps the LibreLoop submodule pointer to the head of main, covering: - onboarding restructure (Apply -> Scan) - LibreCRKit SwiftPM dep + vendored phone_cert_162b - candidate Phase 5 handshake - BLE PIN persisted before BLE auth - in-session glucose streaming + monitor - redesigned status screen, lifecycle bar, last-N readings table - always-retrying reconnect + per-attempt scan timeout - post-pair backfill via PatchControlCommand - adopted upstream Libre3GlucoseQualityAssessment API - Pair-new-sensor flow, persisted latestSample - BLE state restoration via shared scanner + retrievePeripherals --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 21650f5785..5d6aeba10e 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 21650f5785e315391fa1444498322bc58bd52a39 +Subproject commit 5d6aeba10e0293a3f8f2da672376b09b9eac8b31 From becb131307801aa9303674785b13a218e5640a90 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 08:35:35 -0500 Subject: [PATCH 031/133] LibreLoop: tidepool-sync protocol conformance + LibreCRKit pin Bump LibreLoop submodule to pick up the DeviceManager / Pluggable / AlertResponder updates needed against the tidepool-sync LoopKit. --- LibreLoop | 2 +- .../xcshareddata/swiftpm/Package.resolved | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/LibreLoop b/LibreLoop index 5d6aeba10e..8217453577 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 5d6aeba10e0293a3f8f2da672376b09b9eac8b31 +Subproject commit 821745357777c2c2c1436ab37e878b92ecd4aa21 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 181c9131fd..0f03dcba28 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "9fa433ef5fce7eff885b44f4dea36e033d61f148853051ee0494bf4e79200676", + "originHash" : "c9ff5a71b535b2309dec0c117628eb3a95dc416581be2cdedf4df33b71dfb536", "pins" : [ { "identity" : "amplitude-ios", @@ -83,21 +83,20 @@ } }, { - "identity" : "loggerapi", + "identity" : "librecrkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/Kitura/LoggerAPI.git", + "location" : "https://github.com/airedev326/LibreCRKit.git", "state" : { - "revision" : "4e6b45e850ffa275e8e26a24c6454fd709d5b6ac", - "version" : "2.0.0" + "revision" : "f690013632712b6d28e843c774d19cfd1c662898" } }, { - "identity" : "loopalgorithm", + "identity" : "loggerapi", "kind" : "remoteSourceControl", - "location" : "https://github.com/tidepool-org/LoopAlgorithm", + "location" : "https://github.com/Kitura/LoggerAPI.git", "state" : { - "branch" : "main", - "revision" : "bd1a879ef5942c18630429d25294a473c03b426c" + "revision" : "4e6b45e850ffa275e8e26a24c6454fd709d5b6ac", + "version" : "2.0.0" } }, { @@ -185,7 +184,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/LoopKit/ZIPFoundation.git", "state" : { - "revision" : "c67b7509ec82ee2b4b0ab3f97742b94ed9692494" + "branch" : "stream-entry", + "revision" : "ad465ee2545392153a64c0976d6e59227d0c1c70" } } ], From afc5ff02d692bcf7e6e6291b09c7813c8fb99978 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 12:29:12 -0500 Subject: [PATCH 032/133] LibreLoop: rolling on-disk log + lifecycle traces Bumps the LibreLoop pointer so post-background disconnect traces land in Documents/libreloop/log.txt. Adds pull-libreloop-log.sh to fetch the file via devicectl without bouncing through Console.app. --- LibreLoop | 2 +- .../xcshareddata/swiftpm/Package.resolved | 14 +++++++-- Scripts/pull-libreloop-log.sh | 29 +++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100755 Scripts/pull-libreloop-log.sh diff --git a/LibreLoop b/LibreLoop index 8217453577..b4477d0571 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 821745357777c2c2c1436ab37e878b92ecd4aa21 +Subproject commit b4477d05710baee0b85dc21124a270c158c811ef diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0f03dcba28..4cbf995bad 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "c9ff5a71b535b2309dec0c117628eb3a95dc416581be2cdedf4df33b71dfb536", + "originHash" : "f800a471f08fea932371fd46cfbf78358bc2745de47f3acd78557b5fa737b943", "pins" : [ { "identity" : "amplitude-ios", @@ -99,6 +99,15 @@ "version" : "2.0.0" } }, + { + "identity" : "loopalgorithm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tidepool-org/LoopAlgorithm", + "state" : { + "branch" : "main", + "revision" : "bd1a879ef5942c18630429d25294a473c03b426c" + } + }, { "identity" : "mixpanel-swift", "kind" : "remoteSourceControl", @@ -184,8 +193,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/LoopKit/ZIPFoundation.git", "state" : { - "branch" : "stream-entry", - "revision" : "ad465ee2545392153a64c0976d6e59227d0c1c70" + "revision" : "c67b7509ec82ee2b4b0ab3f97742b94ed9692494" } } ], diff --git a/Scripts/pull-libreloop-log.sh b/Scripts/pull-libreloop-log.sh new file mode 100755 index 0000000000..92f061d10a --- /dev/null +++ b/Scripts/pull-libreloop-log.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Pulls LibreLoop's rolling log file from Pete's iPhone. +# Outputs to /tmp/libreloop-log/. +# +# Requires a dev build of Loop installed (get-task-allow entitlement). +# Honors LIBRELOOP_DEVICE_ID and LIBRELOOP_BUNDLE_ID for override. + +DEVICE="${LIBRELOOP_DEVICE_ID:-4950044E-6D03-564F-A1D9-E86E77D99613}" +BUNDLE="${LIBRELOOP_BUNDLE_ID:-com.UY678SP37Q.loopkit.Loop}" +DEST="${1:-/tmp/libreloop-log}" + +rm -rf "$DEST" +mkdir -p "$DEST" +xcrun devicectl device copy from \ + --device "$DEVICE" \ + --domain-type appDataContainer \ + --domain-identifier "$BUNDLE" \ + --source Documents/libreloop \ + --destination "$DEST" \ + "$@" >/dev/null 2>&1 + +if [ -f "$DEST/libreloop/log.txt" ]; then + echo "Pulled $(wc -l < "$DEST/libreloop/log.txt") lines to $DEST/libreloop/log.txt" + [ -f "$DEST/libreloop/log.1.txt" ] && echo "Plus rotated log $DEST/libreloop/log.1.txt" +else + echo "No log file found at $DEST/libreloop/log.txt" + ls -la "$DEST" 2>/dev/null + exit 1 +fi From 2b834fc026b248bcccebf0266b5548f7d98df4d0 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 12:32:29 -0500 Subject: [PATCH 033/133] LibreLoop: log glucose values we forward to Loop --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index b4477d0571..43710b3829 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit b4477d05710baee0b85dc21124a270c158c811ef +Subproject commit 43710b3829286d7c0e6e4dc003e45411093805b1 From 023ed6136ec2f34de35ba60f2a33234470792e45 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 14:06:32 -0500 Subject: [PATCH 034/133] LibreLoop: bracket reconnect with UIApplication background task --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 43710b3829..896ca71afc 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 43710b3829286d7c0e6e4dc003e45411093805b1 +Subproject commit 896ca71afc8792d861a861c7005d3bc82055504a From 58e773348195e905897104f01d9c1246c03cccf1 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 15:49:14 -0500 Subject: [PATCH 035/133] LibreLoop: cached/direct reconnect handshake (skips Phase 1-4) --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index 896ca71afc..3440c05bca 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 896ca71afc8792d861a861c7005d3bc82055504a +Subproject commit 3440c05bcadbe0aa1c23398da83eafcdb6eb80a9 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4cbf995bad..ac0b8c23ae 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/airedev326/LibreCRKit.git", "state" : { - "revision" : "f690013632712b6d28e843c774d19cfd1c662898" + "revision" : "60df7ec88441f43fb1105199666072e4567973e7" } }, { From a548418319c4de06e1dbffc5e8d1898a0aa08cb0 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 15 May 2026 16:11:36 -0500 Subject: [PATCH 036/133] LibreLoop: label Recent Readings columns --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 3440c05bca..9146fcc0b7 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 3440c05bcadbe0aa1c23398da83eafcdb6eb80a9 +Subproject commit 9146fcc0b723919baac218ac4fa270c3ed5bba86 From ac78ed6a8498e86e35ec91bd1456ea4085e05daa Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 01:53:49 -0500 Subject: [PATCH 037/133] LibreLoop: drop backfill samples that duplicate realtime --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 9146fcc0b7..08dbc27f0e 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 9146fcc0b723919baac218ac4fa270c3ed5bba86 +Subproject commit 08dbc27f0ed9599d35a3ab8aab07dabfd4ec5e21 From 84c959cb290721b5affcec2b4adefd274c550aee Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 10:23:57 -0500 Subject: [PATCH 038/133] LibreLoop: handle CCCD-refresh-failed disconnect + re-arming watchdog --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 08dbc27f0e..bbe8a49fe4 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 08dbc27f0ed9599d35a3ab8aab07dabfd4ec5e21 +Subproject commit bbe8a49fe4e85c597fe1e33cc81c6562761dadd0 From 56cb70bc15ac2ef59ea2c03c76f8249b9922161f Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 10:29:31 -0500 Subject: [PATCH 039/133] Loop: diagnostic report force-unwraps watch/statusExtension managers --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 830af33d06..ce1935b54c 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 830af33d06b462f46ee832d3d70497819c47ef01 +Subproject commit ce1935b54c5bcb1fdc4c5bfbfad7d41d0ec4eb32 From 186f32bda5e51da2f1bbed6b768823bfcbb011d4 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 10:29:41 -0500 Subject: [PATCH 040/133] Bump Loop pin: diagnostic report force-unwraps watch/statusExtension managers --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 830af33d06..ce1935b54c 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 830af33d06b462f46ee832d3d70497819c47ef01 +Subproject commit ce1935b54c5bcb1fdc4c5bfbfad7d41d0ec4eb32 From de32a9d69514cbc2627a4965546e691538e43969 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 11:10:27 -0500 Subject: [PATCH 041/133] LibreLoop: throttle realtime forwarding to ~5-min cadence (opt-out toggle) --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index bbe8a49fe4..da27d76f2e 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit bbe8a49fe4e85c597fe1e33cc81c6562761dadd0 +Subproject commit da27d76f2e83a01f31efe0b2fa7052143517d8cc From e6fd8ecc3523da5fe65c5323587b8fb3fdf1512e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 16 May 2026 12:09:53 -0500 Subject: [PATCH 042/133] Bump Loop: restore predicted carb-effect line on ICE and food-insight charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up loopkitdev/Loop@4eea0b24 — widens the carbStatus.dynamicGlucoseEffects sampling window in fetchCarbAbsorptionReview and getHistoricalChartsData from `from: end` to `from: start` so the model-predicted line spans the full chart again (was only generating samples in now+1h … now+7h, outside the visible window). UI-only; no dosing-path impact. --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index ce1935b54c..4eea0b24b0 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit ce1935b54c5bcb1fdc4c5bfbfad7d41d0ec4eb32 +Subproject commit 4eea0b24b07f1ebae0b886e68a6b3cadbb23e97d From 37e84f0fb6c5ff5b53b27b1f2a87f5e7b876d395 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 12:22:54 -0500 Subject: [PATCH 043/133] LibreLoop: keep experimental-mode warning sheet alive on toggle --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index da27d76f2e..06f604a47a 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit da27d76f2e83a01f31efe0b2fa7052143517d8cc +Subproject commit 06f604a47aebe4ae60e72a577a69e206480af81e From 699cddd9872f5e20ce9491b9f87719ef7abb82ad Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 16 May 2026 15:11:04 -0500 Subject: [PATCH 044/133] Bump Loop: restore submodule SHAs in diagnostic report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up loopkitdev/Loop@30725413 — ports Marion's #2399 submodule list into LoopAppManager.generateDiagnosticReport(). The script and BuildDetails plumbing were already in place; only the report consumer was missing after the merges. --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 4eea0b24b0..3072541390 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 4eea0b24b07f1ebae0b886e68a6b3cadbb23e97d +Subproject commit 3072541390b24502f624d7eb210ab8e837a3b0f7 From 487c0dd21c6681c38fecac4009e4d38c5183bb60 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 16 May 2026 23:37:01 -0500 Subject: [PATCH 045/133] LibreLoop: stop waiting on stuck reconnect work after bg expiration --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 06f604a47a..42cc7933cf 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 06f604a47aebe4ae60e72a577a69e206480af81e +Subproject commit 42cc7933cf6f0048bbe9041d37dd4e428b0c0eb4 From a04648f1ed4a34c478aed91a5e5afc01b99b6d13 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 17 May 2026 09:43:52 -0500 Subject: [PATCH 046/133] LibreLoop: repin LibreCRKit to private loopkitdev fork + BLE timing branch --- LibreLoop | 2 +- .../xcshareddata/swiftpm/Package.resolved | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LibreLoop b/LibreLoop index 42cc7933cf..a6593cd8b4 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 42cc7933cf6f0048bbe9041d37dd4e428b0c0eb4 +Subproject commit a6593cd8b4f405287107e265c3d29d467d03a60f diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index ac0b8c23ae..30c6a53c03 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "f800a471f08fea932371fd46cfbf78358bc2745de47f3acd78557b5fa737b943", + "originHash" : "23846d3770420848dd5adbad776664c7e8de33bf591df0dd637f8adfc29f4814", "pins" : [ { "identity" : "amplitude-ios", @@ -85,9 +85,9 @@ { "identity" : "librecrkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/airedev326/LibreCRKit.git", + "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "60df7ec88441f43fb1105199666072e4567973e7" + "revision" : "2082321c86cdbcc2231bdd212d6a992bd8b111fe" } }, { From e90c77bfef7449f3c5556eeb8fc1a21a8b936b77 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 17 May 2026 14:40:11 -0500 Subject: [PATCH 047/133] LibreLoop: route PairingFlow handshake events into the file log --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index a6593cd8b4..f2735bf509 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit a6593cd8b4f405287107e265c3d29d467d03a60f +Subproject commit f2735bf509957a90a406f76707a696003c11583b From a602856f6b16fea342a1d512d8bcb77b4846831d Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 17 May 2026 15:20:35 -0500 Subject: [PATCH 048/133] LibreLoop: bump LibreCRKit pin (handshake-write timeouts) --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index f2735bf509..28b603443e 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit f2735bf509957a90a406f76707a696003c11583b +Subproject commit 28b603443e6cf3c914c362cae1e3d7e2292c506c diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 30c6a53c03..36d81f8061 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "2082321c86cdbcc2231bdd212d6a992bd8b111fe" + "revision" : "51be6941f0b97a914517d2a8d030c52c6231f797" } }, { From 3037048b8916904b9a454fd2ff6332a9d33824fa Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 17 May 2026 15:36:45 -0500 Subject: [PATCH 049/133] LibreLoop: bump LibreCRKit pin (2s awaitCommandResponse) --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index 28b603443e..07bf7f5bee 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 28b603443e6cf3c914c362cae1e3d7e2292c506c +Subproject commit 07bf7f5bee19907c98879ce60da8adbb4d1a1282 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 36d81f8061..d5b59dd287 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "51be6941f0b97a914517d2a8d030c52c6231f797" + "revision" : "3b8fffc525faae97911c6e4233705886ddc45e65" } }, { From 1473d17e5265e09b00fd709aa087b72d398a8139 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 17 May 2026 16:35:33 -0500 Subject: [PATCH 050/133] LibreLoop: bump LibreCRKit pin (write-timeout that actually fires) --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index 07bf7f5bee..1698e428f7 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 07bf7f5bee19907c98879ce60da8adbb4d1a1282 +Subproject commit 1698e428f72065b87bfddd46995a36fab9f6d802 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index d5b59dd287..9133ad487e 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "3b8fffc525faae97911c6e4233705886ddc45e65" + "revision" : "dab85991e229df4554d1bfb996912ff1de25fbfa" } }, { From 6652cfedd6cd18d7ad5908781d784fb7c0d58399 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 07:17:17 -0500 Subject: [PATCH 051/133] LibreLoop: also pull clinical backfill stream on reconnect (diagnostic) --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 1698e428f7..903e766c75 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 1698e428f72065b87bfddd46995a36fab9f6d802 +Subproject commit 903e766c751d7963ecfb1ef0296fb5357350a531 From a37bd1a62689bcd1ecbefcda116dc0f3cb8d5097 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 10:10:42 -0500 Subject: [PATCH 052/133] LibreLoop: stop forwarding clinical samples (forensic logging only) --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 903e766c75..855ace13cd 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 903e766c751d7963ecfb1ef0296fb5357350a531 +Subproject commit 855ace13cdb421354738fe2bbf2d1d17bc2c3a4b From e22b7b35aaf3c7c76c8126e9aa035d6bffe7136e Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 11:04:52 -0500 Subject: [PATCH 053/133] LibreLoop: forward clinical samples for per-minute backfill --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index 855ace13cd..180bd0fcf4 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 855ace13cdb421354738fe2bbf2d1d17bc2c3a4b +Subproject commit 180bd0fcf4f2b3dce21f7fc6114fbbac4e681fc4 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9133ad487e..0c69687a0a 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "dab85991e229df4554d1bfb996912ff1de25fbfa" + "revision" : "6606a1a62ca356681b82a95281e8274c01cb1e04" } }, { From 1f8b25af0c8df1d7c8458dfa86f5c1fb7dbf8d3a Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 15:58:06 -0500 Subject: [PATCH 054/133] LibreLoop: serialize clinical backfill after historical, retry ATT errors --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 180bd0fcf4..01595f3171 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 180bd0fcf4f2b3dce21f7fc6114fbbac4e681fc4 +Subproject commit 01595f3171ff9c7c5e664a4d922eff9d93548afe From c8c1b13fed70215841b09b295d0d7224addb085d Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 16:08:15 -0500 Subject: [PATCH 055/133] LibreLoop: drop reconnect connect-timeout, let iOS drive --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 01595f3171..d396daebef 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 01595f3171ff9c7c5e664a4d922eff9d93548afe +Subproject commit d396daebef35ed34fc9be9b2333e084b43ab4bce From 0311157b161e2681d665160fa32596a7d7b5106e Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 18:12:26 -0500 Subject: [PATCH 056/133] LibreLoop: verify central + peripheral state before connect --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index d396daebef..090f0858a5 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit d396daebef35ed34fc9be9b2333e084b43ab4bce +Subproject commit 090f0858a5a632b9df307142e5db0790818d6c99 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0c69687a0a..68d717f2c0 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "6606a1a62ca356681b82a95281e8274c01cb1e04" + "revision" : "df1e09c808ff694ee2d94f7d4f4957da6d68fb0b" } }, { From 80df1d916ac19760d737fe1c744adc0f2e78ed77 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 18 May 2026 18:17:36 -0500 Subject: [PATCH 057/133] LibreLoop: G7-style peripheral recovery + central state listener --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index 090f0858a5..1aba8baede 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 090f0858a5a632b9df307142e5db0790818d6c99 +Subproject commit 1aba8baede10a84edcf17b3fe2a6369bf522c7f2 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 68d717f2c0..a66e736824 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "df1e09c808ff694ee2d94f7d4f4957da6d68fb0b" + "revision" : "1507954f3d4a2258a38b47fe05d76eb7590de1c0" } }, { From d55b822cf894a33c75059d7acbf73a383f762b84 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Tue, 19 May 2026 15:37:38 -0500 Subject: [PATCH 058/133] LibreLoop: drop bg-task wrap around reconnect --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 1aba8baede..a95c9c8b9a 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 1aba8baede10a84edcf17b3fe2a6369bf522c7f2 +Subproject commit a95c9c8b9adc868e7a8221f499b75474c3c1904c From 3b68b6d928ccf9eb4962056ead4a5d58c5b31916 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 19 May 2026 20:21:14 -0500 Subject: [PATCH 059/133] Bump Loop: External Insulin log labeling/delete, presets cleanup Loop submodule changes: - Label manually-entered boluses as External Insulin in the delivery log, with a delete action in the event details screen - Fix Text wrapping in presets training content - Remove the unfinished Performance History entry point from presets Also ignore .claude in the workspace. --- .gitignore | 3 +++ Loop | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 02b598dfb4..af03cd5efe 100644 --- a/.gitignore +++ b/.gitignore @@ -18,12 +18,15 @@ xcuserdata/ *.xcscmblueprint *.xcuserstate .DS_Store +.claude ## Obj-C/Swift specific *.hmap *.ipa + ## Playgrounds *.playground playground.xcworkspace timeline.xctimeline + diff --git a/Loop b/Loop index 3072541390..e7a1e21081 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 3072541390b24502f624d7eb210ab8e837a3b0f7 +Subproject commit e7a1e210816a985c25755cf8a01334eaac7fd7ae From a85ee4541ab234fc8a615f9a0288088ffef7328d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 11:29:31 -0500 Subject: [PATCH 060/133] Bump Loop: merge origin/dev into tidepool-sync (resolve WatchApp plist + pbxproj localization conflicts) --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index e7a1e21081..1119574eaa 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit e7a1e210816a985c25755cf8a01334eaac7fd7ae +Subproject commit 1119574eaa0ad5d7cc1c3ebd756ba6f07a448fbf From 45214e7a94f98e56eb776e6ac94ac9dbfa8ce5d3 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Wed, 20 May 2026 15:52:55 -0500 Subject: [PATCH 061/133] LibreLoop: persist receiverID + auto-recover on fresh-pair Bumps LibreLoop submodule and the workspace's LibreCRKit pin (ae52535) for the Keychain v3 + closure-based NFC scan that auto-recovers a fresh-pair scan against an already-activated sensor when stored credentials are present. --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index a95c9c8b9a..ba287a823f 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit a95c9c8b9adc868e7a8221f499b75474c3c1904c +Subproject commit ba287a823f20bda59725684eb1b497ce58938882 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index a66e736824..3951b2b533 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/loopkitdev/LibreCRKit.git", "state" : { - "revision" : "1507954f3d4a2258a38b47fe05d76eb7590de1c0" + "revision" : "ae52535fbdfe332898b14fe4815a721a812f35eb" } }, { From 68ce29463e228c68d4ba7d9b8508beacf97c251e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 16:49:37 -0500 Subject: [PATCH 062/133] Bump Loop: fix WatchApp Info.plist (drop WKWatchKitApp) for watch embedding --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 1119574eaa..fd313d06dc 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 1119574eaa0ad5d7cc1c3ebd756ba6f07a448fbf +Subproject commit fd313d06dc8c2827ced2dbceaf24350c5389a0dd From 7d11a755805fc249eec6e8f145e90d4ac237b972 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 18:27:38 -0500 Subject: [PATCH 063/133] Bump Loop: Apple Health access status screen in Settings --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index fd313d06dc..a81435c2b7 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit fd313d06dc8c2827ced2dbceaf24350c5389a0dd +Subproject commit a81435c2b7dba98d7dd0902dc4ba35d69f49298e From 7fd02d60f817613f75dcae50711473004da1f770 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 19:03:05 -0500 Subject: [PATCH 064/133] Bump LoopKit: keep Loop-written doses on external HealthKit deletion --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index fd075aa5db..75e426db14 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit fd075aa5db8111eda3f9ebd2e87dd77c98e9fe5d +Subproject commit 75e426db144dbad4a9aac82a3b695764408ab0f4 From a31116a6aa20709591f1c4edb4c7276f65538b5f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 19:07:16 -0500 Subject: [PATCH 065/133] Bump Loop: flag-gated dose deletion from dose details (with active-insulin warning) --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index a81435c2b7..8a7dac5ff9 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit a81435c2b7dba98d7dd0902dc4ba35d69f49298e +Subproject commit 8a7dac5ff9fbf6c6137e81f74f5186a73f281f0c From d1768c3f5dbd6a95a7c006cb55e5c47d5a7c28ef Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 19:10:12 -0500 Subject: [PATCH 066/133] Bump Loop: enable dose deletion by default --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 8a7dac5ff9..1997657e98 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 8a7dac5ff9fbf6c6137e81f74f5186a73f281f0c +Subproject commit 1997657e98d39f73490590cffe3242aafb4b0d51 From a36ee937e267533683fa9a5fe6dcd207a62640e9 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 20:17:47 -0500 Subject: [PATCH 067/133] Bump Loop: clear stale Last Bolus after dose deletion --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 1997657e98..c876c5635a 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 1997657e98d39f73490590cffe3242aafb4b0d51 +Subproject commit c876c5635afca620f2dcbde815fb050a0baf629d From ffeadc06338ee86cb359d2389bf2f8811e6c723e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 20:20:37 -0500 Subject: [PATCH 068/133] Bump Loop: don't allow deleting in-progress doses --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index c876c5635a..a3c99349fb 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit c876c5635afca620f2dcbde815fb050a0baf629d +Subproject commit a3c99349fb7f648c9a49ca266844e38beae9b1ef From 9987f2adb4c21ca6769ff994bd7dd3162c45c1bf Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 20:44:14 -0500 Subject: [PATCH 069/133] Bump LoopKit: don't crash on legacy bolus without units; note divergence --- LoopKit | 2 +- SYNC_PROGRESS.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index 75e426db14..3059bb85d1 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 75e426db144dbad4a9aac82a3b695764408ab0f4 +Subproject commit 3059bb85d1ae594c924f709295f0587ea5c89613 diff --git a/SYNC_PROGRESS.md b/SYNC_PROGRESS.md index 40b6adb132..07efac3738 100644 --- a/SYNC_PROGRESS.md +++ b/SYNC_PROGRESS.md @@ -65,6 +65,7 @@ LoopWorkspace superproject commit: `3d4432c` ("Bump submodule pins to tidepool-s | MinimedKit CAGE/IAGE | DIY's `updateLastEventDates(from:)` for cannula and insulin age tracking preserved; Tidepool has no equivalent. | | NightscoutService APNS response feature | DIY's `RemoteNotificationResponseManager` + JWT-managed return notifications preserved; Tidepool's simpler version dropped. | | OmniBLE temp basal error handling | Kept DIY's `completion(.communication(error))` style; did not adopt Tidepool's `do { ... } catch` refactor because it cannot be cleanly applied to the conflict region alone. decisionId tracking already present in DIY. | +| CachedInsulinDeliveryObject bolus-without-units | Dropped the `assertionFailure` in `CachedInsulinDeliveryObject.dose` for a `.bolus` with neither programmedUnits nor deliveredUnits — legacy rows from an upgraded DIY install can have neither and trapped debug builds on read. Falls back to 0 (release behavior). Upstream keeps the assertion (fresh installs only); re-remove on future LoopKit syncs. | --- From a7c68cfbfec864a18bafc0023869c5e9ef00a4ea Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 23:03:38 -0500 Subject: [PATCH 070/133] =?UTF-8?q?Bump=20LoopKit:=20preserve=20dose=20amo?= =?UTF-8?q?unts=20across=20Modelv4=E2=86=92v6=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index 3059bb85d1..d15ab455ae 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 3059bb85d1ae594c924f709295f0587ea5c89613 +Subproject commit d15ab455ae6f78cd50661a37a0b40e5249d84d13 From f1e137a671850087c04f17f3840a294854d81ce9 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 23:17:50 -0500 Subject: [PATCH 071/133] =?UTF-8?q?docs:=20note=20one-way=20upgrade=20(Cor?= =?UTF-8?q?e=20Data=20v4=E2=86=92v6)=20in=20sync=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document that upgrading dev→sync migrates the shared store to Modelv6 and cannot be reverted: dev ships only up to Modelv4 and can't open a v6 store, so reverting leaves the app unable to load its data store (no on-disk data loss, but dev needs a delete+reinstall, rebuilding from HealthKit). Also records that the forward migration now preserves dose amounts (value→deliveredUnits). Includes the earlier 2026-03-10 LoopAlgorithm-packaging callout. --- docs/tidepool-sync-2026-03-10.md | 15 +++++++++++++++ docs/tidepool-sync-2026-05-11.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/docs/tidepool-sync-2026-03-10.md b/docs/tidepool-sync-2026-03-10.md index 5b4a8d5df0..20a98e46c1 100644 --- a/docs/tidepool-sync-2026-03-10.md +++ b/docs/tidepool-sync-2026-03-10.md @@ -7,6 +7,21 @@ This document describes the changes introduced by syncing the Tidepool fork of L back into DIY, the conflicts encountered during that merge, and the decisions made to resolve them. +> **Update (2026-05-20) — read before relying on the LoopAlgorithm decisions below.** +> A follow-up sync landed on 2026-05-11; see +> [`tidepool-sync-2026-05-11.md`](tidepool-sync-2026-05-11.md) for that round. +> +> One major decision recorded in this doc has since been **reversed**: §3 states that +> DIY keeps LoopAlgorithm embedded *inline* inside LoopKit and *omits* the +> `XCRemoteSwiftPackageReference "LoopAlgorithm"` (see "TidepoolService: import +> LoopAlgorithm — Removed" and the pbxproj rules table). As of the 2026-05-11 sync, DIY +> instead consumes the **`tidepool-org/LoopAlgorithm` Swift package** directly — pinned +> in the workspace `Package.resolved` — and the inline `LoopKit/LoopAlgorithm/` copies +> (`LoopAlgorithm.swift`, `LoopPredictionOutput.swift`, `ExponentialInsulinModel.swift`) +> were deleted (LOOP-4781). `import LoopAlgorithm` is therefore present again where this +> doc says it was removed. Where the two docs disagree on LoopAlgorithm packaging, the +> 2026-05-11 doc is authoritative. + --- ## Table of Contents diff --git a/docs/tidepool-sync-2026-05-11.md b/docs/tidepool-sync-2026-05-11.md index cb24ee94ef..540b16d82f 100644 --- a/docs/tidepool-sync-2026-05-11.md +++ b/docs/tidepool-sync-2026-05-11.md @@ -197,3 +197,32 @@ and a divergence comment was added to defend it on future syncs. - **Lokalise translations:** `InsulinType.swift` lost DIY's detailed insulin descriptions in favor of Tidepool's simpler combined Fiasp/Lyumjev case. Next Lokalise pull should repopulate. + +--- + +## 5. Upgrading is a one-way operation (Core Data) + +**You cannot revert to `dev` after upgrading to the sync build.** + +The shared LoopKit Core Data store (glucose, dose, carb, dosing decisions — all in one +`Model.sqlite` in the app group) is migrated forward from **Modelv4** to **Modelv6** on +first launch of the sync build. `dev` only ships model versions up to **Modelv4** (it has +no v5/v6 model), and Core Data migrations are forward-only, so a `dev` build cannot open a +v6 store: `addPersistentStore` fails and `PersistenceController` lands in an `.error` state. + +Consequences of going back to `dev` after upgrading: +- `dev`'s data stores won't load — the app is non-functional (no cached glucose/dose/carb, + looping won't run). +- The v6 data is **not** wiped from disk, so reinstalling the sync build reads it again. +- To actually use `dev` again you must delete + reinstall it, which wipes the local cache; + it then rebuilds from HealthKit (the long-term history lives there, not in this store). + +This is inherent Core Data forward-migration behavior, not specific to any one change. + +**Forward migration preserves insulin data.** The v4→v6 mapping originally dropped the +old single `value` attribute (auto-generated, name-based mappings had no destination), +zeroing cached bolus/basal amounts and understating IOB. `CachedInsulinDeliveryObjectMigrationPolicy` +now copies `value` → `deliveredUnits` (and `programmedUnits` for boluses); basal *rates* +already carry over via `scheduledBasalRate`/`programmedTempBasalRate`. Note this only fixes +the forward path — installs that already migrated on a build *without* the policy have +already-dropped values that this cannot recover (they read as 0). From a775f2f2fd71debac7ba0de405730cecdd2d23cb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 20 May 2026 23:48:00 -0500 Subject: [PATCH 072/133] Bump Loop: restore localized Intents.strings refs (ITMS-90626) --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index a3c99349fb..82193f41bf 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit a3c99349fb7f648c9a49ca266844e38beae9b1ef +Subproject commit 82193f41bf61a41a749c6bb8c8ef65d386bb2bae From 4046252069ce018520c9720f85787b25e7c1ebc2 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 21 May 2026 00:17:45 -0500 Subject: [PATCH 073/133] Bump OmniBLE/OmniKit pins: report pod faults as pump events --- OmniBLE | 2 +- OmniKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OmniBLE b/OmniBLE index 166ecfb11a..87606c4b88 160000 --- a/OmniBLE +++ b/OmniBLE @@ -1 +1 @@ -Subproject commit 166ecfb11a35846ab9987f514807c31745e47ab3 +Subproject commit 87606c4b88e25cf3f991c5561645a434838d2054 diff --git a/OmniKit b/OmniKit index 52d2f41c7e..e5fad99f65 160000 --- a/OmniKit +++ b/OmniKit @@ -1 +1 @@ -Subproject commit 52d2f41c7ee5ce42c8ffa4ea0d524f840714eb02 +Subproject commit e5fad99f65f9c2a80425926715e97eba526871f1 From 14d19872781e8d7ddc697b102c2ea058d54e3cba Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 21 May 2026 10:08:25 -0500 Subject: [PATCH 074/133] Bump version to 3.15.0 --- VersionOverride.xcconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VersionOverride.xcconfig b/VersionOverride.xcconfig index b176650a02..e7d27a9033 100644 --- a/VersionOverride.xcconfig +++ b/VersionOverride.xcconfig @@ -8,5 +8,5 @@ // Version [for DIY Loop] // configure the version number in LoopWorkspace -LOOP_MARKETING_VERSION = 3.14.0 +LOOP_MARKETING_VERSION = 3.15.0 CURRENT_PROJECT_VERSION = 57 From f56ea73467b774809be89487a3dd18242a6ccfcf Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Thu, 21 May 2026 15:25:48 -0500 Subject: [PATCH 075/133] LibreLoop: sensor end-of-life UX Bumps LibreLoop submodule for HUD lifecycle progress bar in the last 24h, three sensor-expiry alerts (T-24h .active, T-2h .timeSensitive, T-0 .timeSensitive) via LoopKit's AlertManager, and a sensor image at the top of the Libre 3 settings page. --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index ba287a823f..1041f6c21b 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit ba287a823f20bda59725684eb1b497ce58938882 +Subproject commit 1041f6c21bbeb0c08a96f6128989cf7b06a2e860 From abad56f1cfc23cc9425f74ad5ada92afe51555f9 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 21 May 2026 18:30:23 -0500 Subject: [PATCH 076/133] Build against LoopKit/LoopAlgorithm main Repoint workspace LoopAlgorithm package to LoopKit/LoopAlgorithm (main) and bump LoopKit pin. --- LoopKit | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LoopKit b/LoopKit index d15ab455ae..c17ef4b4ea 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit d15ab455ae6f78cd50661a37a0b40e5249d84d13 +Subproject commit c17ef4b4ea5e3c8d8e57db4ffa310c06364d5cec diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 181c9131fd..11664817cf 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -94,10 +94,10 @@ { "identity" : "loopalgorithm", "kind" : "remoteSourceControl", - "location" : "https://github.com/tidepool-org/LoopAlgorithm", + "location" : "https://github.com/LoopKit/LoopAlgorithm", "state" : { "branch" : "main", - "revision" : "bd1a879ef5942c18630429d25294a473c03b426c" + "revision" : "1ca85662b1f8799758988108f46dba5f34d4889b" } }, { From 76305d9e4d633b063a74c4e41526dda86dded0c8 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 22 May 2026 11:28:56 -0500 Subject: [PATCH 077/133] Bump Loop: show carb sharing status on Apple Health page --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 82193f41bf..427deb8cf1 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 82193f41bf61a41a749c6bb8c8ef65d386bb2bae +Subproject commit 427deb8cf1d8d0567f1df7fb08fcece68c231e19 From 817b0cd866548183a0fb754aeed2da94f06312df Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Fri, 22 May 2026 13:33:15 -0500 Subject: [PATCH 078/133] LibreLoop: tappable sample detail view from Recent Readings Bumps LibreLoop submodule for a new sample detail view (tap any row in Recent Readings) plus per-sample tracking of forwarding outcome and source path in LibreLoopGlucoseSample. --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 1041f6c21b..8f2cfa57e4 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 1041f6c21bbeb0c08a96f6128989cf7b06a2e860 +Subproject commit 8f2cfa57e4ebf56bcb2783dae92111f751f1a94f From fc9293e74ae21bf89135e4d173bd8671385e1a18 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 23 May 2026 15:14:30 -0500 Subject: [PATCH 079/133] Bump Loop: default to automatic bolus, deprecate temp basal --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 427deb8cf1..d5407fb86b 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 427deb8cf1d8d0567f1df7fb08fcece68c231e19 +Subproject commit d5407fb86b30125d52d214a9169a8016631ff11d From 1a0c51852b79a9ccb8b2ce5b1399d30576fee985 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 15:42:52 -0500 Subject: [PATCH 080/133] Bump NightscoutRemoteCGM: API Secret optional for read-only sites --- NightscoutRemoteCGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 00eefaa056..e37dc452b3 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 00eefaa0561cee23ed56cb2585d8415b316ec5f1 +Subproject commit e37dc452b3efd82639d702d75642cdf0980555fd From b26221fdc4a5605bf72d1399a86227b9dc3757eb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 16:50:53 -0500 Subject: [PATCH 081/133] Bump NightscoutRemoteCGM: add verification logging --- NightscoutRemoteCGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index e37dc452b3..0d65dade56 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit e37dc452b3efd82639d702d75642cdf0980555fd +Subproject commit 0d65dade56e4bbebda2e78fff68678dd3ff6f540 From 3ee4abd3356593bceb706495b26c841441904aec Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 17:30:56 -0500 Subject: [PATCH 082/133] Bump NightscoutRemoteCGM: 'Optional' placeholder for API Secret --- NightscoutRemoteCGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 0d65dade56..a63d924cb2 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 0d65dade56e4bbebda2e78fff68678dd3ff6f540 +Subproject commit a63d924cb266045882723d8bbc2c16272e50672f From a641759c1083f6b70bad739d14a2ed651446c41c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 17:33:22 -0500 Subject: [PATCH 083/133] Bump NightscoutRemoteCGM: log periodic glucose fetches --- NightscoutRemoteCGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index a63d924cb2..c944eeef0a 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit a63d924cb266045882723d8bbc2c16272e50672f +Subproject commit c944eeef0acf9839433528db24975799301c5d13 From f839eaa83b0f7a3ff3e614d56827675ed481f4da Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 17:45:18 -0500 Subject: [PATCH 084/133] Bump NightscoutRemoteCGM: fix glucose filtering (sort before filterDateRange) --- NightscoutRemoteCGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index c944eeef0a..526328e2e8 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit c944eeef0acf9839433528db24975799301c5d13 +Subproject commit 526328e2e8d4b7dfde0a46c0c545cf8164a26bda From 8cb791ea88a36c82e1ebce91894ca38650fb5358 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 17:58:29 -0500 Subject: [PATCH 085/133] Bump LibreTransmitter: sort glucose before filterDateRange --- LibreTransmitter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreTransmitter b/LibreTransmitter index 356824bfd8..afba845f7b 160000 --- a/LibreTransmitter +++ b/LibreTransmitter @@ -1 +1 @@ -Subproject commit 356824bfd8482dbd54e12a8553c459a698d48ede +Subproject commit afba845f7b43441fb72b91e49ce93dac631b99af From 980bf9c043f8f3362ddd4e7d3b81c7f16795dbc4 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 19:50:41 -0500 Subject: [PATCH 086/133] Bump LoopAlgorithm pin to main HEAD (sorted assert merged) --- LoopKit | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LoopKit b/LoopKit index c17ef4b4ea..12a769a593 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit c17ef4b4ea5e3c8d8e57db4ffa310c06364d5cec +Subproject commit 12a769a593e3897945b3e73658434372dc2e892c diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 11664817cf..c25bf0911c 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -97,7 +97,7 @@ "location" : "https://github.com/LoopKit/LoopAlgorithm", "state" : { "branch" : "main", - "revision" : "1ca85662b1f8799758988108f46dba5f34d4889b" + "revision" : "2f5c630084aa0d72b8d14999e1e0f7c836b0c341" } }, { From ed1bb5f8fb9182f32e25b2b686a2a4df7fe86ef0 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 20:51:57 -0500 Subject: [PATCH 087/133] Vendor LoopAlgorithm as a submodule instead of a remote package Add LoopAlgorithm as a git submodule (tracking LoopKit/LoopAlgorithm) and reference it as a local Swift package, removing the remote package pin from the workspace. LoopAlgorithm can now be edited in place like the other workspace components. Bump LoopKit pin for the local package reference. --- .gitmodules | 3 +++ LoopAlgorithm | 1 + LoopKit | 2 +- .../xcshareddata/swiftpm/Package.resolved | 11 +---------- 4 files changed, 6 insertions(+), 11 deletions(-) create mode 160000 LoopAlgorithm diff --git a/.gitmodules b/.gitmodules index 3637ab97e8..9c28df3111 100644 --- a/.gitmodules +++ b/.gitmodules @@ -58,3 +58,6 @@ [submodule "LibreTransmitter"] path = LibreTransmitter url = https://github.com/loopkitdev/LibreTransmitter.git +[submodule "LoopAlgorithm"] + path = LoopAlgorithm + url = https://github.com/LoopKit/LoopAlgorithm.git diff --git a/LoopAlgorithm b/LoopAlgorithm new file mode 160000 index 0000000000..2f5c630084 --- /dev/null +++ b/LoopAlgorithm @@ -0,0 +1 @@ +Subproject commit 2f5c630084aa0d72b8d14999e1e0f7c836b0c341 diff --git a/LoopKit b/LoopKit index 12a769a593..130c2b408c 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 12a769a593e3897945b3e73658434372dc2e892c +Subproject commit 130c2b408cea2057c201b76d195649f3500ec936 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index c25bf0911c..7f9748cfe8 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "9fa433ef5fce7eff885b44f4dea36e033d61f148853051ee0494bf4e79200676", + "originHash" : "022dd750637857e01bb9d5a686f612a656b7e41972a6c0b5144ddb9bf2d2303c", "pins" : [ { "identity" : "amplitude-ios", @@ -91,15 +91,6 @@ "version" : "2.0.0" } }, - { - "identity" : "loopalgorithm", - "kind" : "remoteSourceControl", - "location" : "https://github.com/LoopKit/LoopAlgorithm", - "state" : { - "branch" : "main", - "revision" : "2f5c630084aa0d72b8d14999e1e0f7c836b0c341" - } - }, { "identity" : "mixpanel-swift", "kind" : "remoteSourceControl", From 339b18857a3095b9b194519d3cd5be6ddf5a87e6 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 24 May 2026 21:23:48 -0500 Subject: [PATCH 088/133] Declare LoopAlgorithm as a workspace-level local package Add LoopAlgorithm to the workspace so the LoopWorkspace owns and versions it (via the submodule gitlink); projects consume the product. Bump LoopKit pin. --- LoopKit | 2 +- LoopWorkspace.xcworkspace/contents.xcworkspacedata | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index 130c2b408c..bc0b6f6b11 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 130c2b408cea2057c201b76d195649f3500ec936 +Subproject commit bc0b6f6b11d3b4c6bed8e73d34493462f9d875bc diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index a870f8b7c9..30ab15315a 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -78,6 +78,9 @@ + + From 4e5d83937f65287789fd5cef57ef6da9215da28c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 25 May 2026 12:13:29 -0500 Subject: [PATCH 089/133] Bump LoopKit: sort normalized doses before filterDateRange --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index bc0b6f6b11..70aa80c71f 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit bc0b6f6b11d3b4c6bed8e73d34493462f9d875bc +Subproject commit 70aa80c71f329a693d3990258ef8fe0db58894f2 From 262ef315d5a442030f728d0e0b965152619140bb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 26 May 2026 11:33:22 -0500 Subject: [PATCH 090/133] Correct sync-revert docs: dev can downgrade-open the v6 store The 'one-way / forward-only' claim was wrong. Core Data lightweight migration downgrades the v6 store to dev's Modelv4 in place (verified by round-trip test). It only fails once a v6 row has a null deliveredUnits (dev's 'value' is mandatory -> NSCocoaError 134110), which is why an immediately-reverted tester saw it work but a long-running sync store would not. --- docs/tidepool-sync-2026-05-11.md | 42 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/docs/tidepool-sync-2026-05-11.md b/docs/tidepool-sync-2026-05-11.md index 540b16d82f..f545eab705 100644 --- a/docs/tidepool-sync-2026-05-11.md +++ b/docs/tidepool-sync-2026-05-11.md @@ -200,24 +200,36 @@ and a divergence comment was added to defend it on future syncs. --- -## 5. Upgrading is a one-way operation (Core Data) - -**You cannot revert to `dev` after upgrading to the sync build.** +## 5. Reverting to `dev` after upgrading (Core Data) — usually works, but data-dependent The shared LoopKit Core Data store (glucose, dose, carb, dosing decisions — all in one `Model.sqlite` in the app group) is migrated forward from **Modelv4** to **Modelv6** on -first launch of the sync build. `dev` only ships model versions up to **Modelv4** (it has -no v5/v6 model), and Core Data migrations are forward-only, so a `dev` build cannot open a -v6 store: `addPersistentStore` fails and `PersistenceController` lands in an `.error` state. - -Consequences of going back to `dev` after upgrading: -- `dev`'s data stores won't load — the app is non-functional (no cached glucose/dose/carb, - looping won't run). -- The v6 data is **not** wiped from disk, so reinstalling the sync build reads it again. -- To actually use `dev` again you must delete + reinstall it, which wipes the local cache; - it then rebuilds from HealthKit (the long-term history lives there, not in this store). - -This is inherent Core Data forward-migration behavior, not specific to any one change. +first launch of the sync build. `dev` only ships model versions up to **Modelv4**. + +Contrary to an earlier "forward-only / can't go back" assumption, **`dev` can open the +v6 store in place**: Core Data's automatic lightweight migration *downgrades* it back to +`dev`'s Modelv4. The v6→v4 changes are inferrable — the v6-only attributes (`programmedUnits`, +`decisionId`, `id`, …) are optional and simply dropped, and `deliveredUnits` shares the +underlying `ZVALUE` column with v4's `value` via `elementID="value"`. (Verified with a +Core Data round-trip: create a v4 store → migrate to v6 with the sync model → open with the +dev model — succeeds.) + +**The catch — it's data-dependent.** `dev`'s `CachedInsulinDeliveryObject.value` is +**mandatory**; v6's `deliveredUnits` is **optional**. The inferred downgrade maps +`deliveredUnits → value`, so: +- A store that was **just upgraded** (every row migrated from v4, where `value` was required + and non-null) downgrades cleanly — `dev` opens it. *This is why a tester who upgraded and + immediately went back to `dev` in place saw it "just work."* +- Once the sync build **records a dose with a null `deliveredUnits`** (e.g. in-progress/mutable + or programmed-only entries), the downgrade fails: Core Data throws `NSCocoaErrorDomain` + **134110** — *"missing attribute values on mandatory destination attribute"* — + `addPersistentStore` fails and `PersistenceController` lands in `.error`, leaving the app + non-functional. You then must **delete + reinstall** `dev`, which wipes the local cache; it + rebuilds from HealthKit (the long-term history lives there, not in this store). + +So going back to `dev` in place is fine right after upgrading, but gets unreliable the longer +the sync build runs (more chance of a null-`deliveredUnits` row). The v6 data is never wiped +from disk, so reinstalling the sync build always reads it again. **Forward migration preserves insulin data.** The v4→v6 mapping originally dropped the old single `value` attribute (auto-generated, name-based mappings had no destination), From 8448b82204515a53427e3419e5644fd265c4ec1d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 26 May 2026 18:22:59 -0500 Subject: [PATCH 091/133] Bump Loop: merge dev into sync branch (brings in dev-branch warning) --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index d5407fb86b..f2f1f26adf 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit d5407fb86b30125d52d214a9169a8016631ff11d +Subproject commit f2f1f26adfbcd4500bbf7d9c2d1b97e055e3bbb8 From 66422e1047e581f5d0f8963fcd444f942895965a Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Tue, 26 May 2026 20:34:16 -0500 Subject: [PATCH 092/133] Bump LibreLoop, Loop, LoopKit submodule pointers LibreLoop: BLE reconnect reliability + backfill improvements + FSL3 image Loop: widget nil-crash fix (StatusWidgetTimelineProvider) LoopKit: pick up latest main --- LibreLoop | 2 +- Loop | 2 +- LoopKit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LibreLoop b/LibreLoop index 8f2cfa57e4..cba6d44086 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 8f2cfa57e4ebf56bcb2783dae92111f751f1a94f +Subproject commit cba6d440866579359fd30689c46075cbc33906e3 diff --git a/Loop b/Loop index 4eea0b24b0..fba1822d1e 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 4eea0b24b07f1ebae0b886e68a6b3cadbb23e97d +Subproject commit fba1822d1edb7146171357e6fac7458620d9e392 diff --git a/LoopKit b/LoopKit index fd075aa5db..a3c533bfda 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit fd075aa5db8111eda3f9ebd2e87dd77c98e9fe5d +Subproject commit a3c533bfda2c3a35eb005789255b6847e9de29b0 From c439dcbec3cdcfe6274fea4e0f65a89cb7e4f911 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sun, 31 May 2026 12:45:24 -0500 Subject: [PATCH 093/133] Bump MinimedKit: fix off-queue BLE crash in fetchPumpHistory --- MinimedKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinimedKit b/MinimedKit index f19f99cc0b..50b942bdb4 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit f19f99cc0b552fc6996412285f9a1e450a4f4961 +Subproject commit 50b942bdb44c198b611d3d4530458a78ffe9e9e4 From 967fcbb780b1746d28dc1ff5d16fde38721f720c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 31 May 2026 12:59:43 -0500 Subject: [PATCH 094/133] Bump MinimedKit: fix off-queue BLE crash in fetchPumpHistory --- MinimedKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinimedKit b/MinimedKit index f19f99cc0b..50b942bdb4 160000 --- a/MinimedKit +++ b/MinimedKit @@ -1 +1 @@ -Subproject commit f19f99cc0b552fc6996412285f9a1e450a4f4961 +Subproject commit 50b942bdb44c198b611d3d4530458a78ffe9e9e4 From 51475645c5250600cf3d4df9aeb951f8ee868807 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 1 Jun 2026 11:21:08 -0500 Subject: [PATCH 095/133] Bump Loop: sort annotated doses before filterDateRange --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index f2f1f26adf..8184dc0b0d 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit f2f1f26adfbcd4500bbf7d9c2d1b97e055e3bbb8 +Subproject commit 8184dc0b0dae17fd2e9b1ba2c44cb8bf9ea7572c From 1b894ff22937dd4a7fc7bef62f84e7be3db26e4c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 1 Jun 2026 12:06:19 -0500 Subject: [PATCH 096/133] Bump Loop: watch app crash fix, assets cleanup, missing presets image --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 8184dc0b0d..accdfc5603 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 8184dc0b0dae17fd2e9b1ba2c44cb8bf9ea7572c +Subproject commit accdfc56038c242ee57cae1550d09211dbbddd40 From f03461fceae86c3d544df17bdd831db4eb1d25da Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 1 Jun 2026 14:57:07 -0500 Subject: [PATCH 097/133] Bump TidepoolKit pin to pick up TSession backward-compat fix Includes tidepool-org/TidepoolKit#79 so sessions persisted before userRoles was added decode cleanly on upgrade -- preserves the TidepoolService configuration across the dev->sync upgrade instead of forcing the user to re-authenticate. --- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7f9748cfe8..06bc80653a 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "022dd750637857e01bb9d5a686f612a656b7e41972a6c0b5144ddb9bf2d2303c", + "originHash" : "3074fb13e969eeb07af13d2659671d107eac739de84ccaff57f73a4b6201e10f", "pins" : [ { "identity" : "amplitude-ios", @@ -168,7 +168,7 @@ "location" : "https://github.com/tidepool-org/TidepoolKit", "state" : { "branch" : "dev", - "revision" : "4f4747ff647d836c5a27cc1b9c275e5717901e83" + "revision" : "290bd0431c55e8d0e0e542b163de13b1f07b77d9" } }, { From 2064197e071048425738fcc6b6b8d564d79c24dd Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Mon, 1 Jun 2026 18:22:01 -0500 Subject: [PATCH 098/133] Bring in tidepool-sync/2026-05-11 latest; bump LibreLoop, Loop, LoopKit LibreLoop: pin LibreCRKit to 45a892d (adds generation/productType fields on Libre3NFCPatchInfo); plumb generation into CGMManager state so sensorModel is read from the sensor's own byte instead of inferred from wearDuration. Fix LibreLoopPairingService.fresh to call a real LibreCRKit scan(mode:) overload. Loop: merge loopkitdev/tidepool-sync/2026-05-11 to pick up watch app crash fix, assets cleanup, missing presets image, and the sort annotated doses before filterDateRange fix. Also bundle critical.caf in the app so the critical-alert audio fallback always has a sound to play, and switch to a primary-audio session category so it reliably triggers. LoopKit: pull in auto-extracted Localizable.xcstrings updates from LoopKit, LoopKitUI, MockKitUI. Workspace: bump TidepoolKit pin to 290bd04 (TSession backward-compat fix from the tidepool-sync branch). --- LibreLoop | 2 +- Loop | 2 +- LoopKit | 2 +- .../xcshareddata/swiftpm/Package.resolved | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LibreLoop b/LibreLoop index cba6d44086..4c7e1a292c 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit cba6d440866579359fd30689c46075cbc33906e3 +Subproject commit 4c7e1a292c0bde1cfd6be496857e0e7843bd96c1 diff --git a/Loop b/Loop index 642597e63d..b2d9428214 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 642597e63d901068a2061f3137eb5d96bacb5e60 +Subproject commit b2d942821403d0e421e1891435413c9052daa3ca diff --git a/LoopKit b/LoopKit index e58a832a3d..28ece3a43c 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit e58a832a3d80578b016c768a966d63997ec331f5 +Subproject commit 28ece3a43c7229fbd4b47af824e4bdad0f14fc82 diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index b96bb0ba59..edac9fc98c 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "022dd750637857e01bb9d5a686f612a656b7e41972a6c0b5144ddb9bf2d2303c", + "originHash" : "975d155ecb687b7f956d6545b16da633ff716d7d3e1a390dd9aff2c69c7ddd83", "pins" : [ { "identity" : "amplitude-ios", @@ -85,9 +85,9 @@ { "identity" : "librecrkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/loopkitdev/LibreCRKit.git", + "location" : "https://github.com/airedev326/LibreCRKit.git", "state" : { - "revision" : "ae52535fbdfe332898b14fe4815a721a812f35eb" + "revision" : "45a892d46e1e86d893db18a9f79be5ac6ac0ef3f" } }, { @@ -176,7 +176,7 @@ "location" : "https://github.com/tidepool-org/TidepoolKit", "state" : { "branch" : "dev", - "revision" : "4f4747ff647d836c5a27cc1b9c275e5717901e83" + "revision" : "290bd0431c55e8d0e0e542b163de13b1f07b77d9" } }, { From eacb6c805b9b2e398c290e74b63da4a0f04568a3 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Tue, 2 Jun 2026 07:58:25 -0500 Subject: [PATCH 099/133] Bump LibreLoop and NightscoutService; pin LibreCRKit 88508ae LibreLoop: pairing flow now uses illustrated SVG tutorial steps, back-button navigation is polished, and the lifecycle/CGM-status pipeline was reworked end-to-end -- warmup countdown is visible during the 60-min initial warmup, .pairingWarmup is now "Stabilizing" and exits on first reading rather than waiting on the (frequently-stuck) actionability bit, .initializing/.expired/ .signalLost get dedicated HUD pill states aligned with G7's conventions, and per-minute lifeCount frames drive a CGMManager status push so the HUD progress bar advances every minute instead of every 5-min Loop cycle. Sensor warmup/wear durations are now sourced from the NFC patch info. Forwarding to Loop also gained isDisplayOnly handling for the stabilization period and GlucoseCondition (.belowRange/.aboveRange) for censored values at the sensor's 39/501 display caps. DQ-flagged readings are suppressed entirely. Reconnect error UI no longer flashes for transient phase-6 failures that recover on retry. Adds raw byte 14 and decrypted plaintext to glucose log lines for upstream debugging. NightscoutService: stop sending Loop's isDisplayOnly to Nightscout as isCalibration -- they're different concepts. Calibration is now gated on `wasUserEntered && isDisplayOnly`. Workspace: bumps LibreCRKit pin to 88508ae, which reclassified .notActionable as advisory (not usability-blocking), matching Abbott's own app behavior. --- LibreLoop | 2 +- LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- NightscoutService | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LibreLoop b/LibreLoop index 4c7e1a292c..fab33c4fad 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 4c7e1a292c0bde1cfd6be496857e0e7843bd96c1 +Subproject commit fab33c4fad24a56e818b3331cf36d2d87534b51e diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index edac9fc98c..83a7edbec1 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,7 +87,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/airedev326/LibreCRKit.git", "state" : { - "revision" : "45a892d46e1e86d893db18a9f79be5ac6ac0ef3f" + "revision" : "88508ae45304ce87d15de3df314fb62e939578d9" } }, { diff --git a/NightscoutService b/NightscoutService index 09dc797b9a..5379bba546 160000 --- a/NightscoutService +++ b/NightscoutService @@ -1 +1 @@ -Subproject commit 09dc797b9a30682d02f20a985fec3efb79975e14 +Subproject commit 5379bba546b5e681969d0997b571414ce89a0c71 From e1ec25b68d2eb092b23a77744876902f6ff8409e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 14:51:07 -0500 Subject: [PATCH 100/133] Bump Loop: pause loop while a manual temp basal is running --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index accdfc5603..f602db49e9 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit accdfc56038c242ee57cae1550d09211dbbddd40 +Subproject commit f602db49e91ac7e145e3ae92f9b2a1779ddc0a2e From 0bf111fe4b5de4c1ff65184ed0191773a2bab43e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 20:35:28 -0500 Subject: [PATCH 101/133] Bump Loop + LoopKit: MockPump manual temp basal feature and HUD wiring --- Loop | 2 +- LoopKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Loop b/Loop index f602db49e9..1a254137eb 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit f602db49e91ac7e145e3ae92f9b2a1779ddc0a2e +Subproject commit 1a254137eb791b466d6a401e683e9e870d4986d8 diff --git a/LoopKit b/LoopKit index 70aa80c71f..9bda09bdc6 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 70aa80c71f329a693d3990258ef8fe0db58894f2 +Subproject commit 9bda09bdc6a399a7ace156e507733c1b0fff8518 From ad1a2a06e7c16eae1c0e356aacac8465b8ed1006 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 20:35:48 -0500 Subject: [PATCH 102/133] Bump Loop + LoopKit: manual temp basal localization strings --- Loop | 2 +- LoopKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Loop b/Loop index 1a254137eb..dd2fdbe0fc 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 1a254137eb791b466d6a401e683e9e870d4986d8 +Subproject commit dd2fdbe0fc8c06de7fc2d5760f43c2b034b44178 diff --git a/LoopKit b/LoopKit index 9bda09bdc6..dda4c02d06 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 9bda09bdc6a399a7ace156e507733c1b0fff8518 +Subproject commit dda4c02d063b763cd077e151c2accf13fbdb01ee From b3d223ebc516511e6524ce6752f2fa74639ec110 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 20:57:39 -0500 Subject: [PATCH 103/133] Bump LoopKit: MockPump settings UI cleanup --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index dda4c02d06..8ac4c5a432 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit dda4c02d063b763cd077e151c2accf13fbdb01ee +Subproject commit 8ac4c5a432ed6e9f63aab51fdfa6bb4266427e67 From c593efd737f5ea281583a9132709796f07dc9ee7 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 21:09:32 -0500 Subject: [PATCH 104/133] Update gitlinks --- Loop | 2 +- LoopConfigOverride.xcconfig | 3 +++ NightscoutRemoteCGM | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Loop b/Loop index dd2fdbe0fc..7f06ee5896 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit dd2fdbe0fc8c06de7fc2d5760f43c2b034b44178 +Subproject commit 7f06ee589673d92dc9059d53de7dd571df520e40 diff --git a/LoopConfigOverride.xcconfig b/LoopConfigOverride.xcconfig index 2969db2882..fac2d9ba08 100644 --- a/LoopConfigOverride.xcconfig +++ b/LoopConfigOverride.xcconfig @@ -9,6 +9,9 @@ // Customize this to change the URL to open Loop to something other than the display name //URL_SCHEME_NAME = $(MAIN_APP_DISPLAY_NAME) +// Set this to how many days you want to keep data locally on the phone +//LOOP_LOCAL_CACHE_DURATION_DAYS = 90 + // Features SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) EXPERIMENTAL_FEATURES_ENABLED SIMULATORS_ENABLED ALLOW_ALGORITHM_EXPERIMENTS DEBUG_FEATURES_ENABLED diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 526328e2e8..6ca838aa68 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 526328e2e8d4b7dfde0a46c0c545cf8164a26bda +Subproject commit 6ca838aa6872a55ffabf30c6594a32f018b74817 From 8364c865034f394fa7ef1a53a142116ef10e21db Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 22:30:50 -0500 Subject: [PATCH 105/133] Bump Loop: project ongoing suspend into display forecast, coalesce basal history --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 7f06ee5896..d971f9d258 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 7f06ee589673d92dc9059d53de7dd571df520e40 +Subproject commit d971f9d258c8090f28fa3b0c0ec041d207fc234a From 0df3885eadbb1b2184e7da464b9b55c81f8905c3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 2 Jun 2026 22:44:56 -0500 Subject: [PATCH 106/133] Bump LoopAlgorithm: merge LoopKit/main + Tidepool/main into tidepool-sync Brings the workspace's LoopAlgorithm pin onto tidepool-sync/2026-05-11 with both upstreams folded in. Includes: - the IOB partition-additivity test - LoopKit/main commits: filterDateRange sorted-assert hardening, StandardRetrospectiveCorrection unit tests, decayEffect made a continuous function of sample timestamp - Tidepool/main commits: PrecomputedInsulinInput for multi-step prediction sweeps + parallel glucose-effects, faster filterDateRange via binary search LoopKit/main already merges Tidepool/main, so merging origin/main alone covers both upstreams. --- LoopAlgorithm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopAlgorithm b/LoopAlgorithm index 2f5c630084..0ed893c1a7 160000 --- a/LoopAlgorithm +++ b/LoopAlgorithm @@ -1 +1 @@ -Subproject commit 2f5c630084aa0d72b8d14999e1e0f7c836b0c341 +Subproject commit 0ed893c1a75a355acd0b415b09ceebf2c3fb54c0 From db892a83b0ae4ea61023784ab45e1cd152314292 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 3 Jun 2026 07:39:04 -0500 Subject: [PATCH 107/133] Bump LoopKit: list Automatic Bolus first in Dosing Strategy picker --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index 8ac4c5a432..4912a7b2e2 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 8ac4c5a432ed6e9f63aab51fdfa6bb4266427e67 +Subproject commit 4912a7b2e2314b1b4b5bbe60e3719dd581597189 From 565ef39058eae0980e53b84e5fc2105b473e4923 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 3 Jun 2026 11:56:35 -0500 Subject: [PATCH 108/133] Bump Loop + LoopKit: SettingsView version row, de-brand "Tidepool Loop" --- Loop | 2 +- LoopKit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Loop b/Loop index d971f9d258..44822afd4c 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit d971f9d258c8090f28fa3b0c0ec041d207fc234a +Subproject commit 44822afd4c1d980ede8fcdac279c7f01d635478f diff --git a/LoopKit b/LoopKit index 4912a7b2e2..e40b53f36e 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 4912a7b2e2314b1b4b5bbe60e3719dd581597189 +Subproject commit e40b53f36e71b7bfbf1fdeba01a1bf434039dfd1 From ef78f9866cf30c11458b17ec248c71956688e9d5 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 3 Jun 2026 17:40:59 -0500 Subject: [PATCH 109/133] Bump Loop: focus-mode imagesets for IOSFocusModesView --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 44822afd4c..473fbcb2ea 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 44822afd4c1d980ede8fcdac279c7f01d635478f +Subproject commit 473fbcb2ea965f48094d62945f6a343b838caca4 From 5d9350cc12087d92be0c09035f2746ad8a35c34e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 4 Jun 2026 07:05:07 -0500 Subject: [PATCH 110/133] Update gitlinks --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index e40b53f36e..c5a5beb99f 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit e40b53f36e71b7bfbf1fdeba01a1bf434039dfd1 +Subproject commit c5a5beb99fe0278dc02f74cb09171919604c0200 From b2aec2931f16ac38c2362697efd5fc102e684f03 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Thu, 4 Jun 2026 08:02:52 -0500 Subject: [PATCH 111/133] Bump LibreLoop and Loop; add LibreCRKit submodule (upstream airedev326) - LibreLoop -> 84d7435 (reconnect safety, clinical-only backfill, sensor events, in-app log viewer) - Loop -> a29b6bab (alerts FAQ for no-entitlement builds, watch icon fix, orphan asset cleanup) - Add LibreCRKit as a submodule pinned to upstream airedev326 (aeb11d2), replacing the remote SPM dependency with a local workspace package. --- .gitmodules | 3 +++ LibreCRKit | 1 + LibreLoop | 2 +- Loop | 2 +- LoopWorkspace.xcworkspace/contents.xcworkspacedata | 3 +++ .../xcshareddata/swiftpm/Package.resolved | 10 +--------- 6 files changed, 10 insertions(+), 11 deletions(-) create mode 160000 LibreCRKit diff --git a/.gitmodules b/.gitmodules index 37b5584325..3cd18b51ce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -64,3 +64,6 @@ [submodule "LoopAlgorithm"] path = LoopAlgorithm url = https://github.com/LoopKit/LoopAlgorithm.git +[submodule "LibreCRKit"] + path = LibreCRKit + url = https://github.com/airedev326/LibreCRKit.git diff --git a/LibreCRKit b/LibreCRKit new file mode 160000 index 0000000000..aeb11d212a --- /dev/null +++ b/LibreCRKit @@ -0,0 +1 @@ +Subproject commit aeb11d212a38eb2ed732ed461d16fb5a68ffb61a diff --git a/LibreLoop b/LibreLoop index fab33c4fad..84d74357b6 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit fab33c4fad24a56e818b3331cf36d2d87534b51e +Subproject commit 84d74357b67867cc66bb37f685dbea422c52c05b diff --git a/Loop b/Loop index b2d9428214..a29b6bab15 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit b2d942821403d0e421e1891435413c9052daa3ca +Subproject commit a29b6bab15e53ec0d250541b89c3da01dd84b26e diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index 252aa643da..e10dbd4025 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -81,6 +81,9 @@ + + diff --git a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved index 83a7edbec1..dde155189a 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/LoopWorkspace.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "975d155ecb687b7f956d6545b16da633ff716d7d3e1a390dd9aff2c69c7ddd83", + "originHash" : "a19599d654581ff8d5d22621fe5228cb406ab622f72d9849f117b86c535a2c54", "pins" : [ { "identity" : "amplitude-ios", @@ -82,14 +82,6 @@ "version" : "2.0.1" } }, - { - "identity" : "librecrkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/airedev326/LibreCRKit.git", - "state" : { - "revision" : "88508ae45304ce87d15de3df314fb62e939578d9" - } - }, { "identity" : "loggerapi", "kind" : "remoteSourceControl", From 5ea6bdcb91056ba87ddf3eca072906a4699c33e1 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Sat, 6 Jun 2026 13:46:39 -0700 Subject: [PATCH 112/133] add OmnipodKit submodule --- .gitmodules | 3 +++ .../contents.xcworkspacedata | 3 +++ .../xcschemes/LoopWorkspace.xcscheme | 24 +++++++++++++++++++ OmnipodKit | 1 + 4 files changed, 31 insertions(+) create mode 160000 OmnipodKit diff --git a/.gitmodules b/.gitmodules index 9c28df3111..1e5bbadc3f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -61,3 +61,6 @@ [submodule "LoopAlgorithm"] path = LoopAlgorithm url = https://github.com/LoopKit/LoopAlgorithm.git +[submodule "OmnipodKit"] + path = OmnipodKit + url = https://github.com/loopandlearn/OmnipodKit diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index 30ab15315a..c964155bde 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -123,6 +123,9 @@ + + diff --git a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme index e09bc55654..2ae784b532 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme +++ b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme @@ -146,6 +146,20 @@ ReferencedContainer = "container:MinimedKit/MinimedKit.xcodeproj"> + + + + + + + + Date: Sat, 6 Jun 2026 17:16:55 -0500 Subject: [PATCH 113/133] Update Loop: selectable alarm sounds + Delay 1st Alert for highs --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index a29b6bab15..6c0d7ba33e 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit a29b6bab15e53ec0d250541b89c3da01dd84b26e +Subproject commit 6c0d7ba33e484f0abd611cb0007ce1bee8005c57 From cc2572f6cdcac03362d76afcade2eb911044af4c Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Sat, 6 Jun 2026 17:30:42 -0500 Subject: [PATCH 114/133] Update submodules: BLE timeouts/reconnect hardening, Nightscout localization - LibreCRKit: per-op BLE timeouts (already upstream 5712710) - LibreLoop: silent-link watchdog + reconnect robustness - NightscoutRemoteCGM: optional API Secret localized strings --- LibreCRKit | 2 +- LibreLoop | 2 +- NightscoutRemoteCGM | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LibreCRKit b/LibreCRKit index aeb11d212a..5712710547 160000 --- a/LibreCRKit +++ b/LibreCRKit @@ -1 +1 @@ -Subproject commit aeb11d212a38eb2ed732ed461d16fb5a68ffb61a +Subproject commit 5712710547bbd48e0ef6c74f848d870fc51f0a11 diff --git a/LibreLoop b/LibreLoop index 84d74357b6..dc76045bcc 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 84d74357b67867cc66bb37f685dbea422c52c05b +Subproject commit dc76045bcc9889081d3797cbdb5af5f2257d60b0 diff --git a/NightscoutRemoteCGM b/NightscoutRemoteCGM index 526328e2e8..443ff32ca1 160000 --- a/NightscoutRemoteCGM +++ b/NightscoutRemoteCGM @@ -1 +1 @@ -Subproject commit 526328e2e8d4b7dfde0a46c0c545cf8164a26bda +Subproject commit 443ff32ca1154c53e8ec93fda7a489de992fddb3 From 1ffa1390d1de1833ec98c9e9ee575e0752282f23 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 9 Jun 2026 14:44:22 -0500 Subject: [PATCH 115/133] Wire MedtrumKit + EversenseKit into next-dev; bump LoopKit to latest - LoopKit: bump c5a5beb9 -> 4490dddb (latest loopkitdev/LoopKit next-dev). - EversenseKit: add submodule (LoopKit/EversenseKit loop-next-dev @ 2aab7f9) -- adapted to current LoopKit CGMManager API + SwiftUI Picker. Forked to the LoopKit org since bastiaanv's repo is upstream we don't control. - MedtrumKit: add submodule (loopkitdev/MedtrumKit loop-next-dev @ 3b3af0c) -- LoopKit API compat + decisionId threading + voltage formatter; mirrors loopandlearn/MedtrumKit#2. - Workspace + scheme: add EversenseKit/MedtrumKit FileRefs and BuildActionEntries so both build as part of LoopWorkspace. LoopWorkspace scheme builds clean on Xcode 26.5 / iOS 17 simulator. --- .gitmodules | 8 ++++++++ EversenseKit | 1 + LoopKit | 2 +- MedtrumKit | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) create mode 160000 EversenseKit create mode 160000 MedtrumKit diff --git a/.gitmodules b/.gitmodules index 1e5bbadc3f..56664d0b7e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -64,3 +64,11 @@ [submodule "OmnipodKit"] path = OmnipodKit url = https://github.com/loopandlearn/OmnipodKit +[submodule "EversenseKit"] + path = EversenseKit + url = https://github.com/LoopKit/EversenseKit.git + branch = loop-next-dev +[submodule "MedtrumKit"] + path = MedtrumKit + url = https://github.com/loopkitdev/MedtrumKit.git + branch = loop-next-dev diff --git a/EversenseKit b/EversenseKit new file mode 160000 index 0000000000..2aab7f9d10 --- /dev/null +++ b/EversenseKit @@ -0,0 +1 @@ +Subproject commit 2aab7f9d10254655bd266991b266b92980afa454 diff --git a/LoopKit b/LoopKit index c5a5beb99f..4490dddb20 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit c5a5beb99fe0278dc02f74cb09171919604c0200 +Subproject commit 4490dddb20024a462bc85116af16e940d3effc14 diff --git a/MedtrumKit b/MedtrumKit new file mode 160000 index 0000000000..3b3af0cb5a --- /dev/null +++ b/MedtrumKit @@ -0,0 +1 @@ +Subproject commit 3b3af0cb5a88068156ced42a4c88bd1afd0ba894 From 15193ae01ef3eaf5e2748ad2c0e37109981ee15d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 9 Jun 2026 14:53:45 -0500 Subject: [PATCH 116/133] Drop OmniBLE + OmniKit (superseded by OmnipodKit) OmnipodKit replaces both legacy Omnipod drivers, matching upstream LoopKit/dev 3.14.2. Removes: - OmniBLE + OmniKit submodules (.gitmodules + gitlinks) - their .xcodeproj FileRefs from the workspace - their plugin BuildActionEntries and *Tests TestableReferences from the LoopWorkspace scheme Loop loads pump drivers as plugins and has no compile-time reference to either, so the app builds clean without them. --- .gitmodules | 6 -- .../contents.xcworkspacedata | 6 -- .../xcschemes/LoopWorkspace.xcscheme | 62 ------------------- OmniBLE | 1 - OmniKit | 1 - 5 files changed, 76 deletions(-) delete mode 160000 OmniBLE delete mode 160000 OmniKit diff --git a/.gitmodules b/.gitmodules index 56664d0b7e..9be3a7b0ad 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,9 +31,6 @@ [submodule "LogglyService"] path = LogglyService url = https://github.com/loopkitdev/LogglyService.git -[submodule "OmniBLE"] - path = OmniBLE - url = https://github.com/loopkitdev/OmniBLE.git [submodule "NightscoutRemoteCGM"] path = NightscoutRemoteCGM url = https://github.com/loopkitdev/NightscoutRemoteCGM.git @@ -46,9 +43,6 @@ [submodule "TidepoolService"] path = TidepoolService url = https://github.com/loopkitdev/TidepoolService.git -[submodule "OmniKit"] - path = OmniKit - url = https://github.com/loopkitdev/OmniKit.git [submodule "MinimedKit"] path = MinimedKit url = https://github.com/loopkitdev/MinimedKit.git diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index c964155bde..87dd903bae 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -111,12 +111,6 @@ - - - - diff --git a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme index 2ae784b532..416f525810 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme +++ b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme @@ -160,34 +160,6 @@ ReferencedContainer = "container:OmnipodKit/OmnipodKit.xcodeproj"> - - - - - - - - - - - - - - - - - - - - Date: Tue, 9 Jun 2026 15:18:33 -0500 Subject: [PATCH 117/133] Bump LibreLoop: update glucose-alerting safety section --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index dc76045bcc..bb2f1e5488 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit dc76045bcc9889081d3797cbdb5af5f2257d60b0 +Subproject commit bb2f1e548826a3de5961d703925a9513da05a38d From b643e2a382d6de9c48e403e01e66d61c4523b8bb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 02:27:26 -0500 Subject: [PATCH 118/133] Actually wire MedtrumKit + EversenseKit into workspace + scheme Follow-up fix to 1ffa139, which added the submodules/gitlinks but silently dropped the workspace and scheme edits (they were never staged before commit, then discarded with the worktree). As a result neither MedtrumKitPlugin nor EversenseKitPlugin was being built, so the drivers weren't embedded/offered by Loop. This commit adds: - the .xcodeproj FileRefs in LoopWorkspace.xcworkspace - the plugin BuildActionEntries in the LoopWorkspace scheme Verified both MedtrumKitPlugin.loopplugin and EversenseKitPlugin.loopplugin now build into the products dir (parity with OmnipodKit); the existing Install Plugins phase globs *.loopplugin so embedding follows. --- .../contents.xcworkspacedata | 6 ++++ .../xcschemes/LoopWorkspace.xcscheme | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/LoopWorkspace.xcworkspace/contents.xcworkspacedata b/LoopWorkspace.xcworkspace/contents.xcworkspacedata index 87dd903bae..28d2721cab 100644 --- a/LoopWorkspace.xcworkspace/contents.xcworkspacedata +++ b/LoopWorkspace.xcworkspace/contents.xcworkspacedata @@ -120,6 +120,12 @@ + + + + diff --git a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme index 416f525810..ed83670e38 100644 --- a/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme +++ b/LoopWorkspace.xcworkspace/xcshareddata/xcschemes/LoopWorkspace.xcscheme @@ -160,6 +160,34 @@ ReferencedContainer = "container:OmnipodKit/OmnipodKit.xcodeproj"> + + + + + + + + Date: Wed, 10 Jun 2026 12:39:07 -0500 Subject: [PATCH 119/133] Bump LoopOnboarding: link NightscoutServiceKitUI to fix explicit-modules build race --- LoopOnboarding | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopOnboarding b/LoopOnboarding index da95d69d2c..c7a0b9270e 160000 --- a/LoopOnboarding +++ b/LoopOnboarding @@ -1 +1 @@ -Subproject commit da95d69d2c3f35861066dbe704fadb4e4117e787 +Subproject commit c7a0b9270e733ddb8d085ad41f2ce0683d113195 From b7682a9a5ee8df99deee4e7f572c3512f50c4892 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 13:33:41 -0500 Subject: [PATCH 120/133] Point LibreLoop submodule at LoopKit/LibreLoop CI couldn't clone https://github.com/loopkitdev/LibreLoop.git (that repo no longer exists -- it's now LoopKit/LibreLoop_old). The canonical fork is LoopKit/LibreLoop, which is public and already contains the pinned commit bb2f1e54, so only the URL changes -- the gitlink is unchanged. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 649d56be85..56a312df57 100644 --- a/.gitmodules +++ b/.gitmodules @@ -54,7 +54,7 @@ url = https://github.com/loopkitdev/LibreTransmitter.git [submodule "LibreLoop"] path = LibreLoop - url = https://github.com/loopkitdev/LibreLoop.git + url = https://github.com/LoopKit/LibreLoop.git [submodule "LoopAlgorithm"] path = LoopAlgorithm url = https://github.com/LoopKit/LoopAlgorithm.git From c9d849f9851424c8fd9d23ae797130bd722b3adb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 13:42:52 -0500 Subject: [PATCH 121/133] CI: bump CircleCI Xcode 16.4 -> 26.4, drop simulator OS pin The Xcode 16 Swift type-checker times out on LibreCRKit's crypto expressions ("unable to type-check this expression in reasonable time"); Xcode 26 compiles them fine. Aligns CircleCI with the GitHub Actions workflow, which already runs Xcode 26.4 on macos-26. Also removes the hardcoded OS=18.5 from the simulator destination -- the Xcode 26 image ships iOS 26.x simulators, so pinning 18.5 would fail to find a matching destination. --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ead42a398e..d4e40f7c29 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ jobs: build_and_test: macos: - xcode: 16.4 + xcode: 26.4 steps: - checkout - run: @@ -9,10 +9,10 @@ jobs: command: git submodule update --init --recursive --depth 1 - run: name: Build Loop - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.5' build | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16' build | xcpretty - run: name: Run Tests - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.5' test | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16' test | xcpretty workflows: version: 2 build_and_test: From b2bc1b31f0d38f3d6fd91b78a14a8725929d62dc Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 13:52:05 -0500 Subject: [PATCH 122/133] CI: use iPhone 17 simulator (iPhone 16 not on the iOS 26 runtime) In the CircleCI Xcode 26.4 image the iPhone 16 family only exists on iOS 18.6; the iOS 26.4.1 runtime ships the iPhone 17 family. With the OS unpinned (latest = 26.4.1), iPhone 16 had no match. iPhone 17 is present at 26.4.1, matching the local build destination. --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d4e40f7c29..8d37ae4f17 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,10 +9,10 @@ jobs: command: git submodule update --init --recursive --depth 1 - run: name: Build Loop - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16' build | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' build | xcpretty - run: name: Run Tests - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 16' test | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' test | xcpretty workflows: version: 2 build_and_test: From b9fa1d617453295a4e02fedfad5a3344a976ff2e Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 14:54:20 -0500 Subject: [PATCH 123/133] Repoint OmnipodKit at loopkitdev fork for the OmniTests decisionId fix loopandlearn/OmnipodKit loop-next-dev HEAD (f529581a) has a test that fails to compile -- UnfinalizedDose's bolus init now requires decisionId but PodCommsSessionTests wasn't updated, breaking the CI `test` step. Points OmnipodKit at loopkitdev/OmnipodKit loop-next-dev @ d03b34d (f529581a + the one-line test fix); upstream PR is loopandlearn/OmnipodKit#77. Revert to loopandlearn once that merges. --- .gitmodules | 3 ++- OmnipodKit | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 56a312df57..60a66fbe76 100644 --- a/.gitmodules +++ b/.gitmodules @@ -63,7 +63,8 @@ url = https://github.com/airedev326/LibreCRKit.git [submodule "OmnipodKit"] path = OmnipodKit - url = https://github.com/loopandlearn/OmnipodKit + url = https://github.com/loopkitdev/OmnipodKit.git + branch = loop-next-dev [submodule "EversenseKit"] path = EversenseKit url = https://github.com/LoopKit/EversenseKit.git diff --git a/OmnipodKit b/OmnipodKit index f529581a7d..d03b34d60c 160000 --- a/OmnipodKit +++ b/OmnipodKit @@ -1 +1 @@ -Subproject commit f529581a7db383f0941ee9b51fe80878ab2639db +Subproject commit d03b34d60cbd814aab41e76ae68ea4033d3dc4d0 From ba9f5d05397aa571c950a31010679f9cf4faaa40 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 15:01:57 -0500 Subject: [PATCH 124/133] Bump Loop: add isManualTempBasalRunning to MockDeliveryDelegate (fixes LoopTests compile) --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 2bcec3def1..c35d308c56 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 2bcec3def19824be939446827e723cd09c25d5d2 +Subproject commit c35d308c56389f5eb57136366d67225f144dfb30 From 19fd676f2ee6ea28a42765bb30881d363ea2b2d1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 18:10:53 -0500 Subject: [PATCH 125/133] Bump LoopKit: fix stale LoopKitTests expectations (guardrails 87/67, continuous decay, sorted appendedUnion input) --- LoopKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LoopKit b/LoopKit index 916085e53e..ae1ff94f78 160000 --- a/LoopKit +++ b/LoopKit @@ -1 +1 @@ -Subproject commit 916085e53eed5fb19cd007c88b108def269d8194 +Subproject commit ae1ff94f7868642334c32aa7ed703806ef45f83a From 1537b18bfc13e54523c583f94866b7f98701792f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 18:47:51 -0500 Subject: [PATCH 126/133] Bump Loop: LoopDataManagerTests current with LoopAlgorithm + DIY behavior LoopTests now 297 tests, 0 failures. --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index c35d308c56..9333f76659 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit c35d308c56389f5eb57136366d67225f144dfb30 +Subproject commit 9333f7665919731927dec6d04cfab83fc51068df From 09ba9eba8ab009935d550314260b8d6b4e3f7c5c Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 19:34:24 -0500 Subject: [PATCH 127/133] Bump Loop: fix full-scheme test isolation (testOpenLoopCancelsTempBasal) LoopWorkspace scheme now passes: 1242 tests, 0 failures. --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index 9333f76659..e88086a016 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit 9333f7665919731927dec6d04cfab83fc51068df +Subproject commit e88086a01697f07674bb670553b89273256e3c0f From c7cd0b5859503ed06893390f00b880f7e22e1c9f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 20:15:41 -0500 Subject: [PATCH 128/133] CI: use xcbeautify instead of xcpretty so test failures surface xcpretty rendered every test as passing while xcodebuild itself exited 65 (set -o pipefail propagated the code, so the job correctly went red, but the failing tests were invisible in the log). xcbeautify preserves the exit code and prints the failing-test detail. Also emit a JUnit report + store_test_results so failures show in the Tests tab. --- .circleci/config.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8d37ae4f17..ef02ead944 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,12 +7,17 @@ jobs: - run: name: Checkout submodules command: git submodule update --init --recursive --depth 1 + - run: + name: Install xcbeautify + command: brew list xcbeautify >/dev/null 2>&1 || brew install xcbeautify - run: name: Build Loop - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' build | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' build | xcbeautify - run: name: Run Tests - command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' test | xcpretty + command: set -o pipefail && time xcodebuild -workspace LoopWorkspace.xcworkspace -scheme 'LoopWorkspace' -destination 'platform=iOS Simulator,name=iPhone 17' test | xcbeautify --report junit --report-path test-results/results.xml + - store_test_results: + path: test-results workflows: version: 2 build_and_test: From 71b5ffd3052942012b3c2423ed5036b7538c18fe Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 10 Jun 2026 23:14:53 -0500 Subject: [PATCH 129/133] Bump OmnipodKit: CryptoSwift 1.9+ compatibility (Data.bytes -> Array(data)) Fixes RawSpan build errors for anyone whose CryptoSwift resolves to 1.9.0/1.10.0 on the Xcode 26 SDK. Verified building against 1.10.0. --- OmnipodKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OmnipodKit b/OmnipodKit index d03b34d60c..c5162ea03c 160000 --- a/OmnipodKit +++ b/OmnipodKit @@ -1 +1 @@ -Subproject commit d03b34d60cbd814aab41e76ae68ea4033d3dc4d0 +Subproject commit c5162ea03cbf1c33ca2f3206d23f4262ac5a48ff From b98982ecbe49d895baa838243a3800941762ffe1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 11 Jun 2026 09:00:54 -0500 Subject: [PATCH 130/133] Bump EversenseKit: set deployment target to 17.0 Fixes EversenseKitPlugin failing to load on older iOS (Symbol not found: _swift_coroFrameAlloc) - the framework was building for the iOS 26.5 SDK default instead of a back-deployable target. --- EversenseKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EversenseKit b/EversenseKit index 2aab7f9d10..e7b1ad74cd 160000 --- a/EversenseKit +++ b/EversenseKit @@ -1 +1 @@ -Subproject commit 2aab7f9d10254655bd266991b266b92980afa454 +Subproject commit e7b1ad74cd5f7ddcc6619a29d1793652549e70ba From 9c5b5da43592178a8fb9866e1bc8bdc528b4d317 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 11 Jun 2026 09:31:08 -0500 Subject: [PATCH 131/133] Bump Loop: glucose alerts issue only the most severe low-side alert A sudden drop past low into urgent low now issues just the urgent-low notification instead of both low and urgent low. --- Loop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop b/Loop index e88086a016..d563104fe6 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit e88086a01697f07674bb670553b89273256e3c0f +Subproject commit d563104fe6443bfff976af34ef15237569524ba2 From c3e6b65b820dbd6e1ebc7df12a5ee2fd7b4d61b3 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Thu, 11 Jun 2026 23:04:43 -0500 Subject: [PATCH 132/133] Bump Loop + LibreLoop: AlarmKit critical alerts; backfill recent-window + syncId Loop next-dev (25f79bda): AlarmKit critical-alert path on iOS 26+ without the entitlement (near-future fire, Stop acknowledges the alert, audio fallback). LibreLoop main (4e49d0c): per-minute clinical backfill limited to a recent window; unified backfill/realtime syncIdentifier to prevent duplicate points. --- LibreLoop | 2 +- Loop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibreLoop b/LibreLoop index bb2f1e5488..4e49d0c053 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit bb2f1e548826a3de5961d703925a9513da05a38d +Subproject commit 4e49d0c053505ac8a9cf4cd3610b0e103e60a183 diff --git a/Loop b/Loop index d563104fe6..25f79bda9c 160000 --- a/Loop +++ b/Loop @@ -1 +1 @@ -Subproject commit d563104fe6443bfff976af34ef15237569524ba2 +Subproject commit 25f79bda9cd2d219cbd393a03cce7b8f5b4b6aac From bc52c9739f3611022416510bc9397d37de83dc88 Mon Sep 17 00:00:00 2001 From: loopkitdev Date: Thu, 11 Jun 2026 23:30:49 -0500 Subject: [PATCH 133/133] Bump LibreLoop: forward llog events to Loop's DeviceLog --- LibreLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibreLoop b/LibreLoop index 4e49d0c053..a3aeba528a 160000 --- a/LibreLoop +++ b/LibreLoop @@ -1 +1 @@ -Subproject commit 4e49d0c053505ac8a9cf4cd3610b0e103e60a183 +Subproject commit a3aeba528a2d18f231aba5a5f68148b7a4d9d1a5