Skip to content

Sync upstream Trio dev (45cd2cacb) into Tai dev - #41

Merged
mountrcg merged 55 commits into
devfrom
sync/trio-2026-10-27
Oct 28, 2026
Merged

mountrcg merged 55 commits into
devfrom
sync/trio-2026-10-27

Conversation

@mountrcg

Copy link
Copy Markdown
Owner

Sync upstream Trio dev (45cd2ca) into Tai dev

Tai dev (fc7090e55, 1.0.2) is merged with upstream nightscout/Trio dev at 45cd2cacb — 52 upstream commits, 193 files, +9877 −2913 since the last sync. Branch sync/trio-2026-10-27: merge commit f0b820b42, plus aa0744039 aligning Tai's own logging with the new rules on top. Net against dev: 212 files, +10204 −4582 (32 files added, 6 deleted, 174 modified).

This is the logging release. Upstream replaces the file-based SimpleLogReporter/IssueReporter stack with os.Logger plus a sink architecture, so the merge is mostly mechanical, and the real work is on Tai's side: every Tai-only subsystem had to be migrated to the new categories.

What comes in from upstream

  • Logging core. LogRecord/LogSink/LogRetentionPolicy contracts, TrioLogger and an in-memory sink; every line goes through os.Logger and is also accepted by the sinks (Logger.swift is now free functions debug/info/warning/error/fault(_ category:_ message:…) behind enum Logger.Category).
  • Categories by subject instead of by folder. 18 cases — loop, algorithm, pump, cgm, bolus, treatments, nightscout, tidepool, remote, healthKit, alerts, watch, liveActivity, storage, settings, telemetry, ui, lifecycle — replacing the old default/service/deviceManager/apsManager/watchManager/… set, which is retired.
  • App log in Core Data. AppLogStore + AppLog.xcdatamodeld keep the app log persistently; the LoopKit device log is persisted too (DeviceLogStore), and the store re-opens after a missed unlock.
  • Retention. Logs are kept for 8 days and purged a day at a time (LogRetentionPolicy), for the app log and the device log separately. This replaces the old per-launch file cleanup.
  • Export and redaction. LogExport/LogFileWriter/LogFileHeader write one file per log kind, device logs are exportable from Settings and from the device screens, and Redactor/SensitiveValues strip exact stored sensitive values and Syai IDs. Errors are logged as plain text instead of serialized objects.
  • Watch logs. WatchLogEntry/WatchLogRing/WatchLogIngest: the watch keeps a persistent ring, ships queued files, the phone ingests them as structured entries and only acknowledges them once stored, and exported lines are labelled by source.
  • "Report a Problem". New settings entry (ReportProblemView) that builds a redacted diagnostic report; "Share Logs" becomes "Share Trio Logs" ("Share CGM Logs", "Share Pump Logs" live on the device screens).
  • Smaller upstream items. DST-safe schedule tests, Dynamic Island compact text that scales instead of truncating, and the treatment button moved into the side tab rail on iPhone Duo.

Tai-specific logging alignment (aa0744039, 34 files, +187 −281)

Tai's own code now logs through the new categories with plain sentences, and print/debugPrint are gone from Tai-owned paths:

  • autoISF / AimiB30 / AutoISF helpers → .algorithm, with units (BG 123 mg/dL, IOB 1.25 U).
  • Export module (ExportStateModel 39 sites, ExportRootView 11 prints) → .settings; object dumps, traces and emoji prefixes removed, failures at warning/error with error:.
  • Profile scheduler / AdaptProfile / ProfileSeeder / profile expiration / ActiveProfileMirror → .settings, .storage, .alerts, .loop by subject, with the schedule-firer's dead commented-out legacy calls dropped.
  • Garmin (GarminManager, GarminCommandRouter) → .watch; WatchCommandProcessor's injectable log closure is now (LogLevel, String) instead of (String) -> Void, so rejections and failures log at info/warning rather than everything at debug, and messages lost their Garmin:/emoji prefixes.
  • Insulin concentration and DIA (APSManager, PumpHistoryStorage, DeviceDataManager, PumpConfigStateModel) → .pump, IU/hr corrected to U/h.
  • CGM/glucose path (FetchGlucoseManager, DetermineBasalGenerator, ForecastGenerator, CSFEditorStateModel, UserNotificationsManager, Shortcuts temp presets) → .cgm/.algorithm/.nightscout/.alerts/.treatments by subject.
  • Tests. GarminCommandRouterTests and WatchCommandTestDoubles follow the (LogLevel, String) closure; LogCapture.record records the level.

Tai specifics that stay

autoISF/AimiB30/KetoProtect, the insulin-concentration rounding and DIA editor, the UKF/adaptive/exponential glucose smoothing selection (smoothingAlgorithmSection), Garmin (timer-queue concurrency, multi-datafield loop, sendRetryDelay, GarminCommandRouter), watch-command authorization (AdjustmentManager authorize overloads), the profile scheduler with SettingsScope writes (Autotune/BasalProfileEditor keep writing through the scope, never storage.save), Bobble/CGM status, the Export module, Trio Chart, glucose peaks, the CSF editor, TrioAlertManager.acknowledgeOnDevice, the Tai UI/icon set (the treatment button keeps taiCircledNoBackground), and Tai's versioning in Config.xcconfig (APP_DEV_VERSION = 1.0.2.30, APP_VERSION = 1.0.2).

Conflicts

28 paths / 46 hunks: 24 content conflicts plus 4 modify/delete. Rule applied throughout: Tai wins on behaviour, upstream wins on logging shape.

  • Kept Tai, migrated the log call: GarminManager (4 hunks), AdjustmentManager (authorize overloads), APSManager (concentration rounding), CarbsStorage (rollback + rethrow), AutotuneConfig/BasalProfileEditor (SettingsScope writes), TrioAlertManager (device acknowledge).
  • Took upstream: Logger.swift (file is now fully upstream-shaped), TrioApp migration logging, AppleWatchManager (WatchLogIngest + info(.watch) dispatch), SettingsStateModel (logKinds replaces logItems/copyLogs/createZipArchive), SettingsRootView ("Report a Problem" + ReportLinkRows), TreatmentsStateModel, NightscoutManager, PluginSource, AlgorithmLoggingShim, both DST test files.
  • Integrated both sides: PumpConfigRootView (Tai's Insulin Curve + Concentration sections plus upstream's "Share Pump Logs"), CGMRootView (upstream's "Share CGM Logs" plus Tai's smoothing picker), HomeRootView (upstream's GeometryReader/treatmentButtonPosition plus Tai's branding), AlgorithmAdvancedSettings (Tai's useProfileCSF), FetchGlucoseManager (Tai's UKF store kept, upstream's duplicate store and exponential-only path dropped), BasalProfileEditor (Tai's rounding resets plus upstream's initialItems reset).
  • Modify/delete: CONTRIBUTING.md restored from upstream (it now carries the binding logging rules), SimpleLogReporter.swift deleted with the rest of the IssueReporter framework, both ConfigEditor files stay deleted.
  • Deviations from the architecture spec, all verified correct in review: Tai's DIA editor already lives in PumpConfigStateModel, so AlgorithmAdvancedSettings took our side; upstream's modernTabSelection was dropped because RootView.treatmentTabTag does not exist in Tai and the rail feature is carried by treatmentButtonPosition(in:); CGMRootView.smoothGlucoseSection was kept instead of upstream's inline toggle because Tai's version documents the UKF option.
  • Cleanup: the GroupedIssueReporter DI block and SimpleLogReporter.cleanupAllLogsAsync() in TrioApp.cleanupOldData() are gone (retention in AppLogStore replaces them), Tai's Signpost.swift does not survive (no call sites outside the old Logger.swift), and TrioTests/ShareLogsTests was removed because it tested the retired zip export.
  • Project file: Tai's project.pbxproj with upstream's objects grafted in — 31 new files wired (17 Logger sources, AppLog.xcdatamodeld, ReportProblemView, LogShareRow, 11 TrioTests/Logging files), ShareSheet.swift already existed in Tai at the same path, and the five deleted Logger files plus ShareLogsTests are removed from the build phases and groups.
  • Localization: Localizable.xcstrings is exactly upstream's 2795 keys. The four Tai-only keys (Submit Ticket on GitHub, Trio Discord, Tai Discord, Trio Facebook) are not re-added — the settings buttons that referenced them were replaced by upstream's report links, and git grep finds zero references.
  • Submodule pins are untouched.

Upstream commits

Logging core (5):

596a197a0 Add logging contracts and scaffold
efd24bce9 Route logging through os.Logger and a sink
152856649 Persist the LoopKit device log
854c565a1 Store the app log in Core Data
d2eb49da0 Add log categories by subject

Message cleanup by subject (7):

84c1e6af7 Clean up Nightscout and remote log messages
94b0e8b76 Clean up loop, pump and CGM log messages
6ab7957e1 Clean up storage and lifecycle log messages
c0932dff9 Clean up bolus, treatment and alert log messages
2bac3321c Clean up watch and Live Activity log messages
96fd02740 Retire legacy log categories
9f0b8faf3 Clean up log messages added on dev

Retention (3):

220252316 Fix log retention at 8 days
f6b1618a1 Purge the app log a day at a time
7383cb24e Purge the device log a day at a time

Export, redaction and the new entry point (9):

20c3b6dc9 Simplify log export to one file per kind
34947f986 Export device logs from Settings and device screens
2b03e2c2a Add diagnostic report with redaction
a233d377e Redact exact stored sensitive values only
9a068c27a Redact Syai IDs and capture Syai traces
d8c098ebd Log errors as plain text
d581ac315 Finish log export performance pass
fac057353 Rename Share Logs to Share Trio Logs
5628b0f4b Add Report a Problem

Watch logs (8):

6df8c0c75 Add shared watch log entry
c7902e41b Keep watch logs in a persistent ring
34e28385a Send watch logs as queued files
6aed89eb8 Ingest structured watch logs on the phone
85b756aa2 Label watch lines in exports
96f8762d1 Clean up watch log messages
9969176bc Acknowledge watch logs only once stored
e0d6af93a Add watch log tests

Store robustness (2):

242866064 Fix log store robustness bugs
8426682cc Retry store open after a missed unlock

Tests (3):

96cd81fd0 Add logging stress tests
ae755fb4f Add 90-day long-run logging stress test
e614f416b Make schedule tests DST-safe

UI (2):

76961bc07 Scale compact Dynamic Island text instead of truncating it in a narrow island
369e8754d Put the treatment button in the side tab bar on iPhone Duo

Chores (7):

065f5f310 Remove code comments
bc66515b4 Re-run CI
b86d399ae Re-run CI on current dev
b4de74760 CI: Bump APP_DEV_VERSION to 1.0.2.27 [skip ci]
a60d8b3b8 CI: Bump APP_DEV_VERSION to 1.0.2.28 [skip ci]
7ff1f777e CI: Bump APP_DEV_VERSION to 1.0.2.29 [skip ci]
45cd2cacb CI: Bump APP_DEV_VERSION to 1.0.2.30 [skip ci]

Tai side (1):

aa0744039 Align Tai-specific logging with the new logging rules

Merge: f0b820b42 sync(trio): merge upstream/dev at 45cd2cacb.

Testing

PR CI is the gate and runs on this exact head (aa0744039): Algorithm Package (swift test) and Run Unit Tests (macOS 26 runner, iPhone 17 / iOS 26.2 simulator) from .github/workflows/unit_tests.yml. No local build or test suite was run for this branch.

What was actually checked before the PR:

  • Zero conflict markers; git diff --check clean; merge commit has the correct parents (fc7090e55, 45cd2cacb) and no trailers.
  • git grep over Trio/Sources: no legacy log category, no SimpleLogReporter/GroupedIssueReporter/CollectionIssueReporter/IssueReporter/Signpost/LoggerTestMode, no live print/debugPrint/NSLog (only commented-out lines remain in NightscoutAPI.swift and a dead block in WatchState.swift).
  • plutil -lint on the project file and xcodebuild -list resolving all 6 targets; every referenced object ID defined, all 32 upstream paths present.
  • swiftc -parse clean on the changed files (34 in the logging commit, plus ExportStateModel, FetchGlucoseManager, GarminManager, AimiB30 re-checked in review).
  • Localizable.xcstrings key count equal to upstream (2795); submodule pointers unchanged in the range.

Known residual, cosmetic: 16 commented-out debugPrint/print lines remain in upstream-owned NightscoutAPI.swift and a dead legacy block in WatchState.swift, and GarminManager.swift embeds an error name in one warning message instead of passing error:. None of them affect behaviour.

Screenshots

Not included — nothing in this branch is Tai's visual work. If you want them for the PR, these are the screens that changed visibly:

  • Settings → "Report a Problem" (new entry, and the report screen itself).
  • That screen's "Share Trio Logs" row (renamed from "Share Logs") and the share sheet behind it.
  • CGM settings → "Share CGM Logs"; pump settings → "Share Pump Logs".
  • Home screen on a compact Dynamic Island device (text now scales instead of truncating).
  • Home screen on iPhone Duo — treatment button in the side tab rail.

gordolio and others added 30 commits October 21, 2026 23:11
Apps built with the iOS 27.1 SDK get a vertical tab bar down the side of
the iPhone Duo's screen. The + button was still drawn at the bottom
centre, over the home screen cards, leaving an empty slot in the rail.

Vertical bars add side safe-area insets, and Trio's iPhone layout is
otherwise portrait-only, so a side inset means the rail: put the button
in its empty slot. Every other layout keeps the bottom-centre position.
dnzxy and others added 25 commits October 25, 2026 17:02
Scale compact Dynamic Island text instead of truncating it in a narrow island
Put the treatment button in the side tab bar on iPhone Duo
[Part 1/n] Logging Rework: Durable logs, One-tap Export, Log Messages Cleanup
Merge 52 upstream commits, including the new logging subsystem
(TrioLogger, AppLogStore, LogExport, watch log ingest, ReportProblemView).

Conflicts were resolved per the architect spec: Tai keeps its fork
behaviour (Garmin timer queue, multi-datafield and command router,
insulin concentration rounding, glucose smoothing selection, profile
scope writes, watch command authorization, device alert acknowledge,
carb save rollback), upstream wins on logging shape and new features.
The project file is Tai's with upstream's new logging files grafted in
and the removed IssueReporter, Signpost and Error+Extensions files
dropped. The obsolete ShareLogsTests suite for the old file-based log
export is removed along with it.
Migrate the remaining legacy log categories in Tai-owned code to the
upstream Logger.Category set, rewrite messages as plain sentences with
units, log swallowed errors at warning with error:, and replace print and
debugPrint calls. Garmin watch command logging now carries a log level.
- UserNotificationsManager: rename the notification payload binding
  from `info` to `userInfo` in both schedule-notification handlers so it
  no longer shadows the global `info(_:_:)` logging function.
- TreatmentsStateModel: restore Tai's `minPredBG` source for the
  simulated determination; the merge brought in upstream's
  `minPredBGFromReason`, which Tai does not define.
- WatchCommandIntegrationTests: pass a level to `LogCapture.record`,
  which now takes `(LogLevel, String)`.
@mountrcg
mountrcg merged commit 24483a9 into dev Oct 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants