Skip to content

Sync upstream Trio dev (3f6b238b4, 1.0.2.71) into Tai dev - #44

Open
mountrcg wants to merge 15 commits into
devfrom
sync/trio-2026-11-14
Open

mountrcg wants to merge 15 commits into
devfrom
sync/trio-2026-11-14

Conversation

@mountrcg

@mountrcg mountrcg commented Nov 14, 2026 •

Copy link
Copy Markdown
Owner

Sync upstream Trio dev (3f6b238, 1.0.2.71) into Tai dev

Brings Tai dev up to upstream nightscout/Trio dev at 3f6b238b450d423f9aa2585e173d50d212d5273d (1.0.2.71) — 11 upstream commits (6 functional, 5 build-counter bumps) over 27 upstream paths since the last sync base 9098d1e (PR #43, 1.0.2.66). The merge lands as 26 files changed, +711 / −441 on top of Tai dev; the only upstream path not carried over is .github/FUNDING.yml, which stays deleted. Merge commit on this branch: 9c78b2a3d (9098d1e + 3f6b238b4), merge base 902be75e8.

What changed

A watch bolus of 0 U can no longer be confirmed by accident

The watch reset bolusAmount, carbsAmount and confirmationProgress every time the phone became reachable again — which happens on every wrist raise. A user sitting on the confirm screen who lowered and raised their wrist had the amount replaced with 0 and confirmed a 0 U bolus, and because APSManager.enactBolus returned without calling back for amounts of 0 or less, the watch never got an answer and its 5 s view-level fallback never started. Now reachability changes leave entries in progress alone (WatchState.handleReachabilityChange), sendBolusRequest refuses amounts of 0 or less with a visible message, every treatment request shows "iPhone not reachable. Nothing was sent." instead of an empty screen, and WatchState owns a single 15 s acknowledgment timeout that is cancelled by any answer. On the phone side APSManager.enactBolus answers every caller with a failure for amounts of 0 or less or amounts that round to 0 on the pump, so no request is left unanswered.

Watch carbs/bolus entries expire after two minutes

An amount typed on the watch previously survived as long as the app stayed open, so an old entry could be confirmed much later. Entries now expire 2 minutes after their last edit: opening an input screen or changing the amount restarts the clock, confirming sends only an entry edited within the window (an older or never-edited one is cleared and the watch reports nothing was sent), returning to the app clears a stale entry and drops back to the main screen, and Cancel/return/send all end the entry.

Tidepool login-rejected alert

TidepoolManager now publishes a tidepoolLoginRequired state (persisted under TidepoolLoginRequired, since TidepoolService cannot be restored without a session) driven by an observed Tidepool session, raises the new Alert.tidepoolLoginRequired ("Tidepool Login Required") through TrioAlertManager via issueAlert(_:), and retracts it once the login is back. Deleting the service skips the alert, and the sign-out path is dropped because TidepoolKit clears it. Home surfaces it as a banner in the multi-use panel and navigates to the Tidepool settings screen; the existing dosing warnings keep precedence over it.

TestFlight notes for the browser build

fastlane/Fastfile gained bundled_release_notes (reads BundledReleaseNotes.json from the IPA, written by scripts/capture-release-notes.sh, and renders summary + callouts + highlights as plain text), a dev-version suffix for off-main builds (dev 1.0.2.71 abc1234), creation of the What-to-Test note from localized_build_info when no note was ever entered by hand, an en-US fallback when the primary-locale lookup fails, and UTF-8 reading of the bundled notes regardless of runner locale. Release notes are appended on main builds only.

Bundle-name localization removed

InfoPlist.xcstrings no longer carries CFBundleName / CFBundleDisplayName translations (upstream issue #1754) — 276 lines removed. Info.plist binds the names to APP_DISPLAY_NAME rather than to the removed localized keys, so Tai still shows "Tai".

Upstream commits

Functional:

  • d0b62df51 — Stop the watch from sending a 0 U bolus after the phone reconnects (#1751)
  • 9a5cac061 — Expire watch carbs/bolus entries after 2 minutes
  • 67110b99a — Remove localization strings for CFBundleName and CFBundleDisplayName (#1767, issue #1754)
  • d1dda095d — Alert when Tidepool login is rejected (#1706)
  • 204c43bd6 — Improve automated TestFlight notes for browser build (#1695)
  • 86a9b5ea4 — Fix "Sponsor this project" link (#1772)

Version bumps (build counter only): ade3a11a6 (1.0.2.67), 233c31aaf (1.0.2.68), 6246f33bc (1.0.2.69), 1197b518e (1.0.2.70), 3f6b238b4 (1.0.2.71).

What Tai keeps

  • autoISF end-to-end: trio-oref/, AutoISF*, Determination+AutoISF, the OpenAPS autoISF columns and the autoISF settings/history modules — outside this range's upstream file set, untouched by the merge.
  • Garmin watch support: GarminManager, GarminCommandRouter and their tests — untouched.
  • Tai branding: APP_DISPLAY_NAME = Tai, BUNDLE_IDENTIFIER = org.nightscout.$(DEVELOPMENT_TEAM).tai, Tai colours/app icons and BuildDetails.plist.
  • Testflight/ (What-to-Test notes) is left as-is, see the checklist below.
  • Tai's watch UI (icon set, layout) and Tai's tab layout survive the watch and Home changes; the upstream acknowledgments/inputs are behaviour only.
  • .github/FUNDING.yml stays deleted — Tai deliberately carries no upstream donation link, so the sponsor-link fix does not apply here.
  • No Tai-only file is deleted, reverted or silently overwritten by the merge.

Conflict resolutions

Seven paths conflicted; each resolution keeps Tai's structure and adopts the upstream change inside it:

  1. .github/FUNDING.yml — stays deleted. Upstream only rewrote the donation URL (nightscoutfoundation.org/donate → donate.nightscoutfoundation.org); Tai does not ship a funding file.
  2. Trio.xcodeproj/project.pbxproj — Tai's project, plus exactly the four upstream registration lines for the new TrioTests/BolusSafetyTests/EnactBolusAmountTests.swift (file reference, build file, group membership, TrioTests sources phase). No other project change; all Tai targets intact.
  3. Trio/Sources/APS/APSManager.swift — Tai's concentration-adjusted rounding of the bolus amount is kept, and the upstream callback failure for non-positive/NaN amounts and amounts that round to 0 U on the pump is added on top, with the shared error string.
  4. Trio/Sources/Modules/Home/View/MultiUsePanelState.swift — Tai's bolus and adjustment panel cases are kept; the Tidepool warning case is inserted after the dosing warnings and before the adjustments, so dosing warnings keep precedence.
  5. Trio/Sources/Modules/Home/View/HomeRootView+BottomControls.swift — Tai's layout is kept; the Tidepool banner gets upstream's blur transition and navigates to the Tidepool settings tab (tab 4), matching Tai's tab layout and the navigation-reset guard.
  6. TrioTests/CoreDataTests/MultiUsePanelStateTests.swift — Tai's tests are kept and upstream's helper argument/priority test is added.
  7. fastlane/Fastfile — Tai's lane naming, build-number logic and verbose upload are kept; upstream's bundled-release-note extraction, dev version/hash notes, primary-locale fallback and localized_build_info are added. ruby -c fastlane/Fastfile: Syntax OK.

Verification

Independent review on card t_4935d94b — verdict PASS at head 9c78b2a3d, working tree clean, submodules clean:

  • Merge integrity: merge commit 9c78b2a3d with parents 9098d1e + 3f6b238b4; the merge delta holds 26 paths, all inside the upstream file set — zero Tai-only paths touched, no silent reverts. 11 non-merge upstream commits; .gitmodules and all gitlinks unchanged.
  • Conflict resolutions: all seven match the architect spec (card t_11e09467) and the upstream intent survives end to end.
  • Localization: both .xcstrings files are byte-identical to upstream; no dangling references to the removed bundle-name keys.
  • pbxproj: parsed with plutil, 0 duplicate IDs, 0 unresolved references, all six pre-existing targets intact, new test file fully registered.
  • Tests/build: swift test --package-path AlgorithmPackage --build-system native — 297 tests in 37 suites, exit 0; unsigned build-for-testing of the Trio scheme — TEST BUILD SUCCEEDED.
  • Known, pre-existing: the default SwiftPM engine (swift test --package-path AlgorithmPackage) fails before running tests on documented string-symbol collisions in the localization catalog. Reproduced on the baseline, not a merge regression.
  • CI: no PR existed for this branch at review time, so exact-head PR CI (Algorithm Package (swift test) + Run Unit Tests) still has to run and go green on 9c78b2a3d before merge.

Checklist before merge

  • CI green on the exact head 9c78b2a3d of this PR.
  • Testflight/WhatToTest.en-CA.txt still reads based on Trio dev 1.0.0.5 — untouched by this sync on purpose; Robert bumps it to the 1.0.2.71 line when preparing the build.

Not included

  • No new Tai features and no Tai-specific behaviour change — this is a synchronization; APP_DEV_VERSION moves 1.0.2.66 → 1.0.2.71 (upstream's build counter only, APP_VERSION stays 1.0.2).
  • Upstream's FUNDING/sponsor-link change is intentionally not adopted.
  • No release notes or version promotion beyond the upstream counter.

Screenshots

Not applicable for a Tai-side change: the watch input/confirmation screens and the Tidepool banner are upstream's own UI and are shown in the upstream PRs (#1751, #1706); the merge adds no Tai-only UI.

jwoglom and others added 15 commits November 7, 2026 14:01
The watch reset bolusAmount, carbsAmount and confirmationProgress every time
the phone became reachable again, which happens on each wrist raise. A user
on the confirm screen who lowered and raised their wrist had their amount
replaced with 0 and confirmed a 0 U bolus. The phone's enactBolus returned
without calling back for amounts of 0 or less, so the watch never got an
answer, and the Processing screen's 5 s fallback never started because
showCommsAnimation was already true when the view appeared.

Watch:
- Reachability changes no longer touch entries in progress; the main view
  still resets them when it appears.
- sendBolusRequest refuses amounts of 0 or less with a visible message.
- Every treatment request shows "iPhone not reachable. Nothing was sent."
  instead of an empty screen when the phone is unreachable.
- WatchState times out a missing answer after 15 s, and on a send error,
  with a message to check Trio on the iPhone (a send error does not prove
  the request was not delivered). The view-level timer is removed.

Phone:
- enactBolus answers every caller with a failure for amounts of 0 or less,
  or amounts that round to 0 on the pump.

Tests:
- Watch: reconnect keeps the bolus entry, 0 U and negative boluses are
  refused, unreachable requests say nothing was sent, the timeout fires and
  is cancelled by an answer, a send error ends processing.
- Phone: enactBolus calls back once with a failure for 0, negative and NaN.
- Bring the watch test target back to compiling: drop assertions on members
  that no longer exist (isBolusCanceled, maxCOB, bolus cancel) and import
  SwiftUI instead of SwiftUICore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An amount entered on the watch stayed on the input and confirm screens for
as long as the app was left open, so an old entry could be confirmed much
later. Entries now expire 2 minutes after their last edit.

- Opening the carbs or bolus input screen, or changing the amount there
  (crown, +/-, a recommendation landing), restarts the entry's clock.
- Confirming with the crown and "Log Carbs" send only an entry edited within
  the last 2 minutes; an older one is cleared and the watch says nothing was
  sent. An entry with no recorded edit is never sent.
- When the app becomes active again, an entry older than 2 minutes is
  cleared and the watch returns to the main screen.
- Returning to the main screen, Cancel and sending end the entry.

Tests cover the 2 minute boundary, refusing expired and unedited entries,
sending fresh ones, carbs-only entries and clearing on return to the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Watch: stop 0 U boluses after a reconnect, time out Processing, expire entries after 2 min
Remove localization strings for CFBundleName and CFBundleDisplayName
* Alert and flag when Tidepool login is rejected

* Drop Tidepool sign-out now TidepoolKit clears it

* Skip Tidepool re-login alert when deleting service
* Include dev version in TestFlight build notes

Builds with a 4-part APP_DEV_VERSION (anything off main) now show it alongside the branch and commit, e.g. "dev 1.0.2.33 abc1234".

* Create TestFlight What to Test note without a manual first entry

fastlane's changelog option only updates What to Test notes that already exist on a build, so apps that never had one entered by hand got no notes. Passing the app's primary locale through localized_build_info makes fastlane create the note.

* Add bundled release notes to TestFlight build notes

Reads BundledReleaseNotes.json from the IPA (written by scripts/capture-release-notes.sh) and appends the newest release's summary, callouts and At A Glance bullets, matching what the in-app sheet shows. Builds without bundled notes keep the branch, version and commit line only.

* Only add release notes to TestFlight notes on main builds

Also fall back to en-US if the primary locale lookup fails, and read the
bundled notes as UTF-8 regardless of the runner's locale.
# Conflicts:
#	.github/FUNDING.yml
#	Trio.xcodeproj/project.pbxproj
#	Trio/Sources/APS/APSManager.swift
#	Trio/Sources/Modules/Home/View/HomeRootView+BottomControls.swift
#	Trio/Sources/Modules/Home/View/MultiUsePanelState.swift
#	TrioTests/CoreDataTests/MultiUsePanelStateTests.swift
#	fastlane/Fastfile
@mountrcg

Copy link
Copy Markdown
Owner Author

Exact-head CI is green on 9c78b2a3d (run 43569285972):

  • Algorithm Package (swift test) — success, 46s
  • Run Unit Tests — success, 20m11s

No commits were added after the review card's PASS at 9c78b2a3d, so the reviewed merge is exactly what CI just validated. All checklist items in the PR body are now satisfied except the merge itself, which stays with Robert.

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.

6 participants