Skip to content

Developer Change Plan

Last updated: 2026-03-25 09:35 EDT

This document outlines where code changes are intended to land as the integration work continues. It is meant for internal engineering coordination.

Planning Document Ownership

  • Docs/Planning/ExecutionPlan.md is the source of truth for prioritized workstreams, sequencing, and checkbox status.
  • Docs/Planning/DevChangePlan.md defines intended code boundaries, implementation design notes, and behavior contracts.
  • If a topic appears in both files, checklist/progress belongs in ExecutionPlan.md, while architecture/code-location detail belongs here.

Clinical Settings (Workstream K)

Execution tracking: Docs/Planning/ExecutionPlan.md -> Workstream K. Detailed contract: Docs/Planning/ClinicalAlgorithmConfigContract.md.

UX contract

  • Add dedicated Clinical Settings section under settings as a navigated destination (chevron row from main settings list).
  • Gate entry by passcode prompt:
  • temporary default passcode: 020508
  • non-production control, pending Cognito/role-based auth replacement (Workstream I)
  • Keep clinician-only controls out of participant-facing setup sections.

Current implementation status: - Clinician-only section and passcode gate are implemented in Home settings. - Subject ID, Weight, Start Algo, and Reset Algo are now hosted under clinician-gated controls. - Target / meal-upfront / TMAX selectors are implemented with bounded normalization. - Versioned ClinicalAlgorithmConfigV1 persistence blob is implemented for the clinical config. - Current focus: participant-facing target governance layered on top of the persisted clinical config.

Locked behavior decisions (next slice): - Clinical input edits are draft-only until explicit Save confirmation. - Save must open a review surface showing old -> new values. - OK commits new settings; Cancel preserves prior applied settings. - Saving settings does not trigger runtime doWork. - Runtime consumes committed settings at the next executed algorithm step only. - Exiting the Clinical Settings destination auto-locks clinician controls. - Save+OK closes settings after commit and returns user to Home. - Clinical Settings owns a participant target-access profile: - Pregnancy -> expose 90/100/110 - Standard -> expose 110/120/130 - Participant-facing target changes require approval capture: - clinical staff member name - approximate approval time - Clinical Settings target options follow the selected participant target-access profile and normalize the draft target into that range when the profile changes.

Clinical-settings telemetry contract (required): - ui.critical.state_viewed: emitted when save-review sheet opens. - ui.critical.submit: emitted on Save+OK with old/new values and changed fields. - ui.critical.cancel: emitted on review cancel/dismiss. - ui.critical.blocked: emitted when save is blocked by validation/policy. - ui.critical.state_viewed / submit / cancel / blocked: emitted for participant target-change approval capture with current/requested target, target-access profile, and approval metadata when submitted. - loop.step.executed includes applied clinical config snapshot (target_mgdl, meal_upfront_percent, tmax_minutes) for activation traceability.

Controls moving into Clinical Settings

  • Subject ID
  • Weight (lbs integer entry in UI; persisted/used as kg for algorithm input)
  • Start Algo
  • Reset Algo

New clinical configuration controls

  • Target selector: profile-bounded options (Pregnancy: 90/100/110, Standard: 110/120/130)
  • Meal upfront selector: 75% or 90%
  • TMAX selector: 40...70 in increments of 5
  • Participant target-access profile selector: Pregnancy / Standard
  • Participant-facing target buttons:
  • Pregnancy: 90, 100, 110
  • Standard: 110, 120, 130

Planned implementation touchpoints

  • BionicLoop/Features/Home/
  • Move settings rows + control actions into clinician-gated section.
  • Keep reusable passcode-gate view/state local to Home settings feature.
  • BionicLoop/Runtime/
  • Read/update clinical settings through a single persisted model for runtime use.
  • BionicLoopCore/Sources/BionicLoopCore/Algorithms/
  • Consume mapped target/upfront/TMAX values through the algorithm input/config boundary.
  • BionicLoopCore/Sources/BionicLoopCore/Persistence/
  • Store versioned clinical settings payload and migration defaults.

Verification hooks to wire

  • Unit:
  • passcode gate state transitions
  • lbs->kg conversion and bounds validation
  • selector range/step validation
  • UI:
  • locked/unlocked behavior
  • moved control visibility
  • participant target approval capture
  • clinical target options follow selected profile and normalize on profile switch
  • unchanged start/reset behavior after relocation

Core Loop + Algorithm

  • BionicLoopCore/Sources/BionicLoopCore/Algorithms/
  • Extend RealBUDosingAlgorithm to map additional inputs/outputs as the C++ API evolves.
  • Translation logic for meal announcements is implemented (MealAnnouncement -> Algo2015 mealTime / mealSize).
  • Add translation logic for pregnancy targets.
  • BionicLoopCore/Sources/BionicLoopCore/Runtime/
  • Enhance LoopRuntimeCoordinator scheduling, retry logic, and offline fallback tracking.
  • Persist last‑run timestamps and loop health state.

Marjorie I/O Parity Workstream

  • Detailed comparison and extracted requirements are documented in:
  • Docs/Analysis/Marjorie_AlgorithmIO_GapAnalysis.md
  • Priority implementation slices:
  • Add canonical per-step telemetry persistence (input + output + applied delivery) as a single source of truth.
  • Expand bridge/output mapping to include key fields needed for audit and chart parity.
  • Maintain and verify pump-unavailable execution policy (execute-with-unavailable, command blocked) across relaunch/reconnect cases.
  • Add test matrix coverage for degraded CGM/pump states and step continuity.

Reconnect fallback baseline (implemented)

  • App runtime now listens for pump-status recovery notifications from PumpStatusObserver and dispatches guarded pumpReconnect wake attempts through LoopRuntimeEngine.
  • Guarded reconnect fallback is secondary to CGM and is intentionally not triggered from raw BLE didConnect.
  • Current implemented guardrails:
  • only after firstSuccessfulStepAt exists
  • only when accepted CGM receipt age is > 5 minutes
  • current due step only
  • no step 0
  • no cadence re-anchor
  • no backlog replay
  • fresh accepted CGM receipt suppresses reconnect fallback again
  • Remaining closure work is real-device validation of reconnect/background behavior and same-slot duplicate suppression with physical G7 + DASH timing.

Algorithm Update Plan (Detailed)

  • Input mapping:
  • Build a single Swift “input model” that mirrors the C++ structs (glucose history, insulin history, device status, user weight, target selection, meal announcements).
  • Centralize unit conversions (mg/dL, U/hr, minutes) and keep them in one file to prevent drift.
  • Output mapping:
  • Translate the C++ recommendation into DosingRecommendation with explicit 5‑minute dosing output (bolus/micro‑dose), plus any flags or status codes.
  • Preserve algorithm status details for logging and UI visibility (e.g., “insufficient data”, “using fallback basal”, “safety limited”).
  • State handling:
  • Maintain a stable per‑subject state (subject ID, last run time, persistent algorithm state if required by the C++ API).
  • Add a versioned “algorithm state blob” store if the C++ interface needs to persist internal state across app restarts.
  • Error handling:
  • Normalize error codes from the C++ layer into a small set of Swift errors; log full raw codes for debugging.
  • Ensure the loop fails closed (no dosing) on malformed inputs.
  • Testing strategy:
  • Add a golden‑input test harness that runs fixed inputs through the C++ wrapper and checks for deterministic outputs.
  • Add “missing data” tests (no CGM, stale CGM, missing pump status).
  • Add regression tests for target selection and meal sizing changes.

Algo2015 Full Verification Campaign (Workstream L)

Execution tracking: Docs/Planning/ExecutionPlan.md -> Workstream L.
Verification protocol and targets: Docs/Planning/Algo2015VerificationPlan.md.

Planned implementation touchpoints

  • BionicLoopCore/Tests/BionicLoopCoreTests/
  • Add TV-ALG-* suites:
    • bridge contract edge cases
    • deterministic replay vectors
    • state continuity/reload/reset
    • pregnancy-config differential replay
    • soak/stability replay
  • Algo2015/ + Scripts/
  • Add an instrumented coverage build/run path for Algo2015 (llvm-cov compatible outputs).
  • Keep standard non-instrumented xcframework build path unchanged for app builds.
  • Docs/Quality/Evidence/
  • Add STR artifact structure for algorithm campaign output with command logs and coverage artifacts.

Verification outputs required before closure

  • Coverage summary + full report artifacts for C bridge and Algo2015 C++ sources.
  • Deterministic vector diff reports for baseline and changed configurations.
  • Explicit uncovered-lines rationale log (if thresholds not fully achieved).

Implemented baseline (2026-02-18)

  • Added bridge-contract suite in:
  • BionicLoopCore/Tests/BionicLoopCoreTests/Algo2015BridgeContractTests.swift
  • Added deterministic golden-vector coverage in:
  • BionicLoopCore/Tests/BionicLoopCoreTests/Algo2015GoldenVectorTests.swift
  • First evidence captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-001-004/
  • Additional evidence captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-005-006-008/
  • Stateful continuity evidence captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-007/
  • Added coverage automation script:
  • Scripts/run_algo2015_coverage.sh
  • Coverage artifacts captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-010-coverage/
  • Expanded coverage artifacts captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-010-coverage-v2/
  • Latest expanded coverage artifacts captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-010-coverage-v7/
  • Consolidated STR rollup captured:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-rollup-v1/
  • Current measured coverage (Algorithm_2015_10_13.cpp):
  • Function 100.00%
  • Line 88.33%
  • Branch 78.87%
  • Residual uncovered-branch rationale map:
  • Docs/Quality/Evidence/STR-ALG-001/2026-02-18-tv-alg-010-coverage-v7/uncovered-branch-gap-map.md

Algorithm Changes for Protocol Requirements

  • Pregnancy targets:
  • Use configurable target set 90/100/110/120/130 mg/dL and surface it in UI + input mapping.
  • Meal fraction:
  • Expose configurable meal upfront options 75% and 90%.
  • Ensure both modes are explicitly traceable/tested in algorithm path.
  • Initialization:
  • Enforce weight‑only initialization (no carb ratios or correction factors).
  • Expose configurable TMAX range 40...70 in increments of 5 (default remains team-configured).
  • CGM downtime rules:
  • Accept fingerstick BG as CGM input during CGM downtime.
  • Use weight‑based basal early, then adaptive basal after >= 24 hours of history.

Loop Timing + Step Semantics (doWork Plan)

Operational cadence assumptions (current hardware behavior)

  • CGM cadence assumption: new G7 glucose values arrive approximately every 5 minutes.
  • Pump transport cadence assumption: Omnipod DASH BLE disconnect/reconnect occurs approximately every 3 minutes (pod-driven).
  • Implication:
  • Current runtime execution is primarily CGM-driven, with explicit user-triggered execution paths for manual BG (bgCheck) and meal announce (mealAnnounce).
  • Current implemented policy: pump reconnects are transport/state events and do not independently advance algorithm step.
  • Planned future policy under review: pump reconnect may become a guarded fallback wake only after step 0 is anchored and only when accepted CGM receipt age has already exceeded the approved freshness limit.
  • If both G7 and DASH are out of BLE range, the app has no reliable wake/data path and cannot safely execute algorithm steps.

Legacy BUMarjorie timing behavior to mirror

  • MasterController computes next step wall-clock as:
  • timeOfNextStep = firstStepTime + algorithmTime * 300s
  • Work is driven by doWork and split into:
  • Device reads (CGM, insulin pump, glucagon pump)
  • Algorithm execution scheduling
  • A single cycle trigger uses an early window:
  • It schedules once when timeUntilStep <= 300s and last schedule is older than 273s (300 - 27).
  • Practical effect: one device/algorithm scheduling pass per 5-minute cycle, approximately 27 seconds before nominal boundary.
  • Step skipping is wall-clock based:
  • If late beyond grace, inferred step is floor((now - firstStepTime) / 300s) + 1.
  • algorithmTime is advanced to inferred step before next run.
  • AlgorithmController only increments step after a successful run:
  • Input uses current algorithmTime as inputData.time.
  • After success, state saves and algorithmTime = algorithmTime + 1.
  • Step 0 is blocked until either CGM or BG exists.
  • BLE/device-driven wake behavior exists through device notifications:
  • DeviceController.deviceStateChanged triggers scheduleWorkNow.
  • This supports "run when awakened by BLE" even without always-on silent audio.

Current BionicLoop behavior (implemented)

  • Runtime path:
  • LoopRuntimeEngine in app layer receives G7 state updates and calls LoopRuntimeCoordinator.doWork(cause: .cgmUpdate).
  • Runtime engine responsibilities are now split into dedicated app-layer components:
    • LoopSessionStore (armed/runtime persistence boundary)
    • LoopWorkScheduler (CGM wake dedupe/arming boundary)
    • LoopAlertMediator (signal-loss tracking/reporting boundary)
    • LoopTelemetryWriter (telemetry write boundary)
    • LoopRuntimeWorkExecutor (doWork execution snapshot boundary)
  • Start Algo arms runtime and waits for the next new G7 reading timestamp.
  • Step 0 executes on that next new reading.
  • Timing/cadence:
  • LoopRuntimeCoordinator computes due step with early window:
    • expectedStep = floor((now + 27s - firstSuccessfulStepAt) / 300s)
  • firstSuccessfulStepAt, lastExecutedStep, and related runtime fields are persisted in UserDefaultsLoopRuntimeStateStore.
  • Duplicate wake attempts within an already-executed step index are skipped with stepNotDue.
  • Gate behavior:
  • Step 0 requires fresh usable CGM (missingFreshGlucose on failure).
  • Step > 0 can execute with unavailable CGM input (CGM_VALUE_NONE, -1) when CGM is stale/missing/out of range.
  • Pump status refresh failure executes with unavailable pump input (deliveryState = unknown) and blocks command application.
  • A single in-flight guard prevents concurrent execution overlap.
  • Home loop badge age states (Active/Aging/Stale) are based on cadence phase (firstSuccessfulStepAt + nextStep * 300s) rather than lastSuccessfulRunAt, so borrowed meal steps do not falsely age the loop before the next due boundary.
    • Current thresholds: Active to due+2m, Aging to due+15m, then Stale.
  • Meal announce behavior:
  • LoopRuntimeCoordinator.announceMeal(...) supports early execution of future step slots.
  • Borrow is only allowed when:
    • current slot is not due yet (expectedStep < nextStep)
    • pump availability is known (deliveryState != unknown)
    • pump is not currently delivering
    • next scheduled slot is within 2 * 300s from now
  • Availability checks treat missing cached pump status (nil) as a cache-miss, not immediate signal loss; signal-loss gating is driven by policy state or explicit unknown status.
  • Once a current known pump status is recovered after reconnect, meal availability should reopen immediately from current state and must not remain blocked solely by stale historical signal-loss bookkeeping from the most recent failed step.
  • Meal submit remains conservative: the announce attempt still requires a fresh known pump status at submit time, and a submit-time refresh failure should continue to block the request instead of relying only on previously cached status.
  • On successful borrow, execution runs immediately as nextStep and consumes that slot.
  • If request occurs after slot is due/missed (expectedStep >= nextStep), execution uses current due step (expectedStep) with meal input.
  • Borrow remains rejected with cannotBorrow for pump delivering/unknown, no anchor, or out-of-window pre-due requests.
  • tooLate wait messaging is bounded to the immediate due-step boundary (no forced extra +5 minute delay).
  • This due/missed meal behavior is provisional and requires explicit team review before release lock.
  • Planned hardening work:
    • implemented baseline: persist pending meal-request state across relaunch using the concrete target step accepted by the coordinator so duplicate entry is blocked while that request remains unresolved
    • implemented baseline: defer Home success UI/telemetry until runtime/coordinator result is known and show explicit blocked/rejected messaging when outcome is not executed
    • implemented baseline: add explicit uncertain-command-outcome handling so comms interruptions do not invite blind re-announce; uncertain requests remain blocked until reconciliation against pump-delivery evidence or session reset/disarm
    • implemented baseline: preserve uncertain-vs-blocked semantics in loop-command telemetry via explicit command_outcome
    • implemented baseline: block slot_conflict when CGM/reconnect claims the observed meal slot before coordinator acceptance, rather than silently reassigning the meal to a new borrowed step
    • implemented baseline: persist meal flow_id with pending state and emit correlated accepted + resolved lifecycle transitions when the request is accepted, reconciled, or cleared by session reset
  • Step synchronization:
  • Runtime computes expectedStep.
  • RealBUDosingAlgorithm is synchronized to expectedStep before recommendation generation.
  • Bridge call still increments step by one after successful algorithmRunStep.
  • Session control:
  • Manual test bolus UI is removed.
  • Reset Algo performs full fresh-session reset:
    • clears persisted algorithm state (UserDefaultsAlgoStateStore)
    • clears persisted runtime cadence state (UserDefaultsLoopRuntimeStateStore)
    • clears pump adapter request/delivery carry-over metadata
    • clears persisted recent-step timeline used by UI

Pump-unavailable policy alignment (BUMarjorie parity review)

  • Legacy BUMarjorie behavior (documented in Docs/Analysis/BUMarjorie.md):
  • Step executes even when pump is unavailable.
  • Algorithm input marks pump unavailable and uses invalid request/delivery fields.
  • Delivery is skipped if unavailable, but step/time still advances.
  • Current BionicLoop behavior:
  • doWork executes with unavailable pump input when pump status is unavailable/unknown and blocks command application.
  • Decision/work item:
  • Policy selected and implemented: POLICY-B (run step with unavailable pump input and gate delivery path only).
  • Implementation tasks after policy decision:
  • Keep step executed separate from delivery applied in persisted runtime telemetry.
  • Ensure next-step input carries last request/delivery fields only when they are valid.
  • Keep reconnect/recovery path deterministic and visible in logs/UI.
  • Required tests:
  • Pump unavailable at step boundary.
  • Reconnect before next step with valid status read.
  • Delivery command failure after successful status read.
  • Step counter behavior under each policy.
  • CGM sanitization safety: <39 and >401 map to CGM_VALUE_NONE (-1) before algorithm input.

Remaining implementation plan (no silent-audio dependency)

  • Keep doWork CGM-driven for study closed-loop operation unless requirements change.
  • Add explicit fallback mode state machine (degraded/offline) and user status messaging.
  • Add fingerstick BG fallback path for step 0 when protocol behavior is enabled.
  • Evaluate additional wake paths (BGTask, reconnect-triggered run attempts) only after policy review.

BG check doWork policy (implemented baseline + pending policy details)

  • Goal:
  • Allow manual BG entry to drive algorithm execution when CGM-triggered execution is not viable.
  • Runtime trigger model:
  • Introduce dedicated wake cause bgCheck.
  • Manual BG-triggered execution is loop-armed only; Algorithm Off state blocks bgCheck dispatch.
  • bgCheck executes current due step when still pending; otherwise carries the submitted BG forward to the immediate next step only.
  • bgCheck never borrows a future step and never advances cadence anchor by pre-running future slots.
  • Input mapping model:
  • Manual BG maps to algorithm BG input (BGval).
  • Manual BG accepted range is 20...600 mg/dL; values outside range are rejected before runtime dispatch.
  • CGM input mapping remains independent (CGM may be -1 when unavailable/unusable).
  • Runtime records manualBG source tag in telemetry.
  • Deterministic behavior:
  • Maintain one pending BG candidate at a time.
  • If due step already executed at submit time, candidate is assigned to immediate next step.
  • If candidate is not consumed at that immediate next step, discard as too old.
  • If a newer BG is submitted while a candidate is pending, replace candidate with the newer value.
  • Manual BG freshness-window rejection and user-visible stale messaging remain pending policy/implementation detail.
  • Pump-unavailable policy remains unchanged: step may execute, command application remains blocked.
  • Edge-case execution:
  • No CGM wake events: bgCheck can run due step and prevent cadence stall.
  • CGM wake exists but CGM unusable: bgCheck can run due step with BGval + CGM unavailable.
  • Step 0 with no fresh usable CGM:
    • current policy is blocked; manual BG submit is rejected before first successful anchored step.
    • optional BG-rescue remains provisional and requires clinical/team sign-off before behavior lock.
  • Cross-document quality references:
  • SRS: SRS-BG-001..012 (Docs/Quality/SoftwareRequirementsSpecification.md)
  • SDD: SDD-BG-001, SDD-POL-010, SDD-POL-011, SDD-POL-012 (Docs/Quality/SoftwareDesignDescription.md)
  • SVVP: TV-BG-001..012 (Docs/Quality/SoftwareVerificationAndValidationPlan.md)

Step increment and catch-up policy (implemented)

  • Source of truth is persisted algorithm state (timeStep) plus runtime anchor metadata.
  • expectedStep is derived from wall-clock anchor and early window (+27s lead).
  • If runtime is late, coordinator catches up by synchronizing algorithm step before running.
  • If expectedStep <= lastExecutedStep, algorithm execution is skipped for idempotency.
  • On successful algorithm call, bridge increments algorithm step by one.

Testable requirements for timing behavior

  • TIMING-01: Step 0 gate
  • Given no fresh CGM, step 0 is not executed and step counter does not advance.
  • TIMING-01b: Step 0 manual BG guard
  • Given no first successful anchored step, manual BG submission is rejected and no pending BG candidate is created.
  • TIMING-01a: Step > 0 degraded CGM execution
  • Given stale/missing/out-of-range CGM and step index > 0, runtime executes using CGM_VALUE_NONE (-1) input.
  • TIMING-02: Single-step increment
  • One successful run advances step exactly by 1.
  • TIMING-03: Wall-clock catch-up
  • If app wakes after missing >= 1 cycle, step aligns to inferred wall-clock step before next run.
  • TIMING-04: No duplicate execution in one cycle
  • Multiple wake events inside same cycle do not cause extra step increments.
  • TIMING-05: CGM-driven trigger
  • A new G7 reading timestamp triggers doWork attempt within bounded latency.
  • TIMING-06: Restart continuity
  • After app quit/relaunch, scheduler restores prior step timeline and does not reset to step 0.
  • TIMING-07: Freshness gate (step 0)
  • If latest CGM exceeds configured max age before first successful step, run is skipped and reason is logged.
  • TIMING-08: Delivery feedback continuity
  • Next-step input contains prior request time/units requested/units delivered when available.
  • TIMING-09: Observability
  • Each attempt logs: cause, expected step, persisted step, run/skip reason, and post-run step.
  • TIMING-10: Pump reconnect non-trigger
  • Current implemented baseline: pump reconnect events alone do not trigger algorithm execution.
  • TIMING-11: Foreground non-trigger
  • App foreground/active transition alone does not trigger algorithm execution.
  • TIMING-12: CGM-step coupling
  • With CGM values at ~5-minute cadence, algorithm executes at most once per 5-minute step index.
  • TIMING-13: Reset fresh start
  • After Reset Algo, next run starts at step 0 with no carried-over request/delivery metadata.
  • TIMING-14: Out-of-range hard gate
  • Step 0 still requires usable CGM; for step > 0, unavailable CGM and unavailable pump execute in degraded mode with no command application.
  • TIMING-15: Fallback transition (planned)
  • After configured outage threshold (for example >= 15 minutes without valid CGM + successful run), loop transitions to offline/degraded mode and emits user-visible status.
  • TIMING-16: Fallback recovery (planned)
  • Once connectivity/data gates recover, loop exits offline/degraded mode and resumes normal step scheduling without resetting step timeline.
  • TIMING-17: Meal borrow window and consumption
  • Two immediate meal borrows are allowed when within 10 minutes of future slots, third is rejected.
  • A borrowed step does not execute again at its original wall-clock slot.
  • TIMING-18: Meal borrow rejection paths
  • Borrow is rejected for pre-due out-of-window requests, pump delivering, pump unknown, or missing anchor.
  • TIMING-19: Meal announce on due/missed slot (provisional)
  • If meal announce is requested after a slot is due/missed, runtime executes meal on current due step (expectedStep) rather than rejecting for late borrow.
  • Requires team/clinical sign-off before release behavior lock.
  • TIMING-20: Delivery-state auto-clear visibility
  • While pump reports delivering, status is polled and Home/meal gating clear to non-delivering state without user entering pump settings.
  • TIMING-21: BG check due-step execution only
  • BG-triggered doWork executes only current due step (expectedStep) and never borrows a future slot.
  • TIMING-22: BG check rescue path for CGM wake failure
  • If CGM wake does not occur, BG entry can still trigger execution (subject to other gates).
  • TIMING-23: BG check rescue path for invalid CGM data
  • If CGM wake occurs but CGM input is unusable, BG entry can still trigger execution with BG input mapping.
  • TIMING-24: BG late-submit carry-forward behavior
  • If BG is submitted after current due step already executed, BG is applied to immediate next step only.
  • TIMING-25: BG pending candidate replacement behavior
  • If multiple BG submissions occur before pending BG is consumed, newest submission replaces prior pending value.
  • TIMING-26: BG pending candidate expiry behavior
  • Pending BG candidate expires if not consumed on the immediate next step after it becomes eligible.
  • TIMING-27: Reconnect fallback gating (planned)
  • After first successful anchored step exists, reconnect-triggered execution is permitted only when accepted CGM receipt age exceeds the approved freshness limit (current proposal: > 5 minutes) and expectedStep > lastExecutedStep.
  • TIMING-28: Reconnect fallback cadence safety (planned)
  • Reconnect fallback never executes step 0, never re-anchors cadence, and never replays multiple missed slots; each reconnect-triggered execution may service only the current due step.
  • TIMING-29: Reconnect fallback suppression on resumed CGM (planned)
  • Once fresh accepted CGM receipts resume, reconnect-triggered fallback is suppressed and CGM remains the primary trigger for subsequent slots.

Deterministic Simulation Harness Plan (Medium now, High later)

Medium-fidelity target (implementation phase)

  • Scope:
  • deterministic runtime decision testing without real BLE transport
  • full exercise of cadence, gating, degraded-mode behavior, and alert lifecycle
  • Planned implementation surfaces:
  • BionicLoopCore/Sources/BionicLoopCore/Ports/
    • keep production protocols as-is; add test doubles conforming to CGMService and PumpService
  • BionicLoopCore test targets
    • add scenario runner + virtual clock to drive coordinator/runtime with timestamped inputs
  • BionicLoop/Runtime/
    • optional launch-argument hook for deterministic preview scenarios in app UI/system tests
  • BionicLoopTests/
    • scenario fixtures and expected-output snapshots
  • Scenario event model:
  • CGM value/reliability/timestamp
  • pump status transition (idle, delivering, unknown, reconnect)
  • pump command success/failure and reconciliation updates
  • alert issue/retract transitions
  • Required scenario outputs/assertions:
  • expected vs executed step index
  • skip reason and gating reason
  • algorithm input/output snapshot
  • command-application decision/result
  • alert center active/recent state

High-fidelity target (eventual, not current critical path)

  • Scope:
  • BLE/session-level emulation for Omni/G7 behavior not captured by medium mocks
  • Candidate surfaces:
  • reconnect jitter/timing edges
  • ACK latency/failure patterns
  • platform-specific session restoration quirks
  • Goal:
  • confidence amplification for hardware-specific behavior after medium-fidelity harness is stable

Safety/testing impact

  • Improves repeatability for rare hazard paths that are difficult to reproduce on-demand with hardware alone.
  • Reduces risk of regressions in command-block, degraded execution, and alert escalation logic.
  • Produces traceable, deterministic evidence artifacts for RA/SRS/TV linkage before real-device validation.
  • Complements (does not replace) hardware-in-the-loop testing for transport/physical-delivery behavior.

Identity and Onboarding (Cognito) - In Progress

Implemented baseline (current)

  • Added secure auth-session/token boundary in app layer:
  • BionicLoop/App/AuthSessionNetworking.swift
  • AppAuthSessionManager (Keychain-backed token persistence, expiry check, refresh)
  • AuthenticatedAPIClient (bearer injection + one-time refresh retry on 401)
  • Session lifecycle behavior now includes:
  • launch-time silent session-restore/refresh when persisted auth state is authenticated; explicit login only when restore fails
  • sign-out path clearing secure token session in addition to local auth flag
  • active-loop continuity fallback: login screen can expose Go to Home while loop state is active, and Home shows persistent auth-recovery alert with direct Log In action
  • Added targeted unit coverage in BionicLoopTests/BionicLoopInfrastructureTests.swift for:
  • sign-in response token parsing (AccessToken/IdToken/RefreshToken/ExpiresIn)
  • refresh-token exchange behavior
  • session-manager refresh/persist semantics
  • authenticated request retry after unauthorized response
  • Added email/password recovery flow in unauthenticated routing and Cognito service layer:
  • ForgotPassword reset-code request
  • ConfirmForgotPassword code-confirmed password reset
  • UI path for request/reset/resend with explicit user feedback banners
  • targeted unit coverage for request/confirm happy paths
  • auth form metadata aligned for iOS Password AutoFill/Strong Password support (username, password, newPassword content types) across login/create/reset flows
  • Runtime lifecycle safety gate updated:
  • unauthenticated auth/session state no longer stops or resets loop runtime state
  • auth is treated as cloud/protected-operation gating only, preserving local therapy continuity

Scope (pending team decision)

  • Add user onboarding/sign-in with:
  • Sign in with Apple
  • Google
  • Email (password flow + reset currently implemented; policy still pending on long-term mode)
  • Gate cloud API access (telemetry and dashboard endpoints) behind authenticated identity context.

Proposed implementation surfaces

  • App:
  • BionicLoop/Features/Onboarding/ for sign-in flow screens and session state presentation.
  • BionicLoop/Runtime/ for auth/session coordinator and protected-request policy.
  • Infra:
  • AWS Cognito User Pool (+ optional Identity Pool if temporary AWS credentials are needed).
  • API authorization integration via JWT validation and role/scope checks.

Open design questions (must be resolved with team)

  • Whether current investigational phase requires per-user sign-in or can remain unauthenticated for limited use.
  • Preferred email auth method (magic link vs password) and operational support burden.
  • Required role model (clinical, engineering, admin) and least-privilege mapping.
  • Account recovery/deprovisioning workflows and emergency-access policy.
  • Exact privacy/consent copy and legal text in onboarding.

Safety and verification notes

  • Authentication must never block safety-critical local loop behavior in a way that causes unsafe operation.
  • Cloud-side authorization failure handling must fail closed for protected data actions while preserving safe local behavior.
  • Add dedicated tests for:
  • first-run onboarding permutations (Apple/Google/Email),
  • token expiration/refresh/revocation,
  • unauthorized access attempts and expected denial paths.

AWS Telemetry and Observability - Planned

Execution tracking: Docs/Planning/ExecutionPlan.md -> Workstream J.
Detailed contract/taxonomy: Docs/Planning/TelemetryCloudIntegrationPlan.md.

Scope

  • Send app/runtime/device/alert/UI-critical telemetry to BionicScout POST /v1/telemetry.
  • Capture enough correlated context to reconstruct subject incidents and stuck-user flows.
  • Keep telemetry transport fully non-blocking to local loop safety operation.

App-side implementation touchpoints (planned)

  • BionicLoop/Runtime/
  • Add app telemetry emitter boundary with typed DTOs and envelope builder.
  • Add persistent outbox and flush worker (retry/backoff/idempotency metadata).
  • Add telemetry transport health events (flush.started/succeeded/failed, drop summaries).
  • Add client logging upload sink with severity filtering and batching (app.log.batch).
  • BionicLoopCore/Sources/BionicLoopCore/Algorithms/
  • Add deterministic Algo2015 native-log capture adapter integration point (session-aware).
  • BionicLoopCore/Sources/Algo2015Bridge/ (optional phase-2 path)
  • Evaluate callback-based native log sink to replace/augment file-tail capture.
  • BionicLoop/Integrations/CGM/
  • Emit CGM reading processed/masked/state/connection events.
  • BionicLoop/Integrations/Pump/
  • Emit pump status/command result/pod lifecycle events.
  • BionicLoop/Features/Home/, BionicLoop/Features/CGM/, BionicLoop/Features/Pump/
  • Emit critical UI interaction events (tap, submit, cancel, blocked, state_viewed).
  • Propagate flow_id for multi-step flows (meal announce, BG entry, setup).
  • BionicLoop/Shared/
  • Shared event-id/session-id helpers and redaction-safe metadata population.

Client log-level upload controls (planned)

  • Level model: debug, info, warning, error.
  • Default cloud upload threshold: error.
  • Threshold behavior: upload selected level and above.
  • Planned settings control:
  • Cloud Log Upload Level selector in app settings.
  • persisted locally and included in telemetry context.
  • Planned precedence logic:
  • remote override (if active and not expired)
  • local settings choice
  • default error
  • Remote override target behavior (future):
  • backend-pushed/fetched subject-scoped override with TTL
  • automatic expiry/revert without user action
  • telemetry audit event when override applied/reverted

Algo2015 native stream capture notes (planned)

  • Preferred near-term capture source:
  • tail BP_LOG_<timestamp>.txt emitted by Algo2015/Algorithm_2015_10_13.cpp RecordConsole().
  • Do not rely on device console scraping (cout) for cloud routing.
  • Keep algorithm matrix/data dump files (BP_<timestamp>.txt, read-matrix helpers) out of routine cloud pipeline.
  • Map native lines to shared cloud log DTO with:
  • subsystem = algo2015.native
  • parsed prefix/step metadata where available
  • raw line retained for forensic replay.

Cloud-side integration assumptions (BionicScout)

  • Current contract accepts envelope with required fields:
  • event_type, schema_version, subject_id, created_at, payload
  • Current route is JWT scope-protected (bionicscout.dev.api/telemetry.ingest) and returns 202.
  • Planned next cloud increments:
  • per-event schema validation by event_type + schema_version
  • idempotent durable persistence keyed by (subject_id, event_id)
  • query support for incident timeline reconstruction

Reliability model (planned)

  • Persistent outbox states:
  • pending, inflight, acked, failed_permanent
  • Ordered local sequencing for deterministic replay.
  • Exponential backoff + jitter retries for transient failures.
  • Non-retry for permanent schema/auth failures with explicit drop-summary telemetry.
  • Priority flush path for safety-critical events (alerts, blocked loop commands, severe device states).

Open design questions (team review required)

  • Crash capture stack choice (Sentry/Crashlytics vs AWS-only path).
  • First-release dashboard scope for clinician vs engineering audiences.
  • Retention windows by event class and timeline depth for incident review.
  • Initial server-side schema evolution policy (strict reject vs staged compatibility).
  • Remote log override governance:
  • roles allowed to issue override
  • max override duration
  • production constraints for debug uploads

Safety and verification notes

  • Telemetry failures must never block loop execution, alerting, or safe state transitions.
  • Cloud auth failures must fail closed for data access while preserving safe local behavior.
  • Verification must include deterministic incident-story replay proving:
  • device observations,
  • algorithm decisions,
  • command apply/block outcomes,
  • alert lifecycle transitions,
  • critical user actions.
  • Formal evidence path for this workstream is STR-CLOUD-* (quality-controlled runs only).

OmniBLE Integration

  • BionicLoopCore/Sources/BionicLoopCore/Ports/
  • Keep PumpService interface stable for OmniBLEPumpManager adapter use.
  • BionicLoop/Integrations/Pump/
  • Maintain PumpServiceAdapter and reconciliation of pump history using dosesForStorage() after reconnect.
  • BionicLoop/Features/Pump/
  • Wire Pump UI entry points, pairing flow, and status display.

G7 Integration

  • BionicLoopCore/Sources/BionicLoopCore/Ports/
  • Keep CGMService interface stable for G7SensorKit adapter use.
  • BionicLoop/Integrations/CGM/
  • Maintain CGM manager adoption/restore flow and sensor lifecycle edge handling.
  • BionicLoop/Features/CGM/
  • Continue onboarding/settings UI integration and edge‑case handling.

Offline/Fallback Behavior

  • BionicLoopCore/Sources/BionicLoopCore/Runtime/
  • Add offline mode state machine (trigger at >= 15 min without valid CGM + algorithm).
  • Define and enact offline basal via DASH.
  • BionicLoop/Features/Home/
  • Show offline mode banner and recovery messaging.

User Alerts

  • BionicLoop/Runtime/
  • Add alert normalization service that consumes runtime/policy events and produces canonical alert objects.
  • Runtime-derived algorithm stepping interruption detection is now implemented for armed sessions when no successful algorithm step completes for 15 minutes; this remains distinct from G7-provided unreliable/failed lifecycle alerts and from Home-only Aging / Stale status.
  • Current implementation measures interruption from the most recent successful step (or session start / first-step wait state if none exists yet), schedules/resets a local deadline from that baseline, recomputes interruption state on app foreground, and clears interruption alerting when stepping resumes or loop is disarmed/reset.
  • Current normalized alert is ALERT-ALGORITHM-STEPPING-INTERRUPTED, with blocker detail (No CGM, No Pod, signal loss, other runtime gates) surfaced without replacing stronger source-native alerts.
  • BionicLoop/Integrations/Pump/
  • Map Omni alert/state events into normalized alert types with severity and dedupe keys.
  • BionicLoop/Integrations/CGM/
  • Map G7 alert/state events (sensor reliability, disconnect duration, critical glucose conditions) into normalized alert types.
  • BionicLoop/Features/Home/ and settings/modals
  • Add consistent alert presentation surfaces and acknowledgment/clear interactions.
  • Cross-cutting
  • Add alert precedence/debounce policy and trace to SRS-ALERT-* and TV-ALERT-*.

Persistence + State Restore

  • BionicLoopCore/Sources/BionicLoopCore/Persistence/
  • Persist loop state, last successful run, and last known device status.
  • BionicLoop/Integrations/
  • Restore device sessions on app launch and avoid unnecessary re‑pairing.

Reinstall Continuity (Planned)

Goal: allow safe continuity across app delete/reinstall without silently corrupting Pod session state or algorithm cadence state.

Continuity snapshot architecture

  • BionicLoopCore/Sources/BionicLoopCore/Persistence/
  • Add a versioned continuity payload model containing:
    • algorithm continuity (stateData, timeStep, cadence anchor metadata)
    • pump continuity (restore-critical manager/session fields)
    • provenance (subject_id, account_id, created_at, schema version).
  • Add integrity metadata and verification hooks so stale/tampered snapshots are rejected.
  • BionicLoop/App/
  • Add continuity bootstrap coordinator at launch to decide:
    • restore from same-device snapshot
    • optionally fetch cloud escrow snapshot
    • or require clean setup/fresh algorithm start.

Tiered restore model (proposed)

  • Tier 1 (same-device reinstall):
  • Store encrypted continuity payload in device-only Keychain so app-delete/reinstall on same phone can recover.
  • Tier 2 (account recovery):
  • Store encrypted continuity snapshot in cloud (account-scoped, device-bound envelope) for authenticated recovery.
  • Auth/session checks must gate cloud restore.

Pod continuity path

  • BionicLoop/Integrations/Pump/
  • Restore manager/session fields from continuity snapshot before default setup flow.
  • Immediately run live session/status verification; if invalid, force clean Pod setup.
  • Never adopt snapshot across subject/account mismatch.

Algorithm continuity path

  • BionicLoop/Runtime/ + BionicLoopCore/Sources/BionicLoopCore/Runtime/
  • Restore algorithm state/cadence only when snapshot integrity and compatibility checks pass.
  • Resume from restored expected cadence anchor, not forced step 0.
  • If restore preconditions fail, perform explicit fresh-session reset with user-visible reason and telemetry event.

Safety and verification notes

  • Add deterministic reinstall scenarios in simulation harness:
  • successful continuity recovery
  • tampered/stale snapshot rejection
  • mismatch fallback to clean setup/fresh session.
  • Extend quality trace docs with reinstall-specific controls/tests before implementation closure.

Home Charts (Scout Reuse Plan)

Legacy chart code review summary

  • Source reviewed:
  • /Users/jcostik/Scout/evan2020/Charts/EGVChart.swift
  • /Users/jcostik/Scout/evan2020/Charts/InsulinChart.swift
  • Keep:
  • Lightweight SwiftUI rendering (no heavy chart framework dependency).
  • Drag-to-scrub interaction pattern.
  • Time-axis labels and glucose visual zones from EGVChart.
  • Refactor:
  • Remove dependency on Scout ChartData/Egv model.
  • Remove legacy interpolation assumptions tied to remote API payload shape.
  • Convert insulin bars from equal-spacing to time-based x positioning so insulin and CGM align on the same timeline.

Current implementation status

  • Implemented in HomeView:
  • Shared-range CGM + insulin overlay chart with aligned x-axis placement by timestamp.
  • Time window selector (4h, 8h, 12h, 24h).
  • Scrub pills above chart (CGM, Dose) driven by chart scrub position.
  • Dose scrub output includes 0.0U cases and time output even when no nearby insulin step exists.
  • Recent step timeline moved into Bionic Loop Settings -> Recent Dose Steps.
  • Styling/interaction state now implemented:
  • Dashed rounded plot border with matching corner radius.
  • Left/right y-axis labels anchored to chart container edges.
  • Continuous scrub line tracking across chart area.

Single source of truth for Home chart/list data

  • Implemented:
  • LoopTelemetryStore in app layer as Home chart/list projection source.
  • Persist rolling CGM and step telemetry windows in UserDefaults JSON.
  • Runtime now writes executed-step telemetry from DoWorkResult and reconciles with pump status updates.
  • G7 view model ingests both current reading and persisted history into telemetry store.
  • Canonical records:
  • CGMPoint: timestamp, glucose mg/dL, trend (optional), source (live, backfill).
  • DosePoint: algorithm step, requested units, delivered units, request timestamp, delivered timestamp, status.
  • StepContext: step, CGM used by algorithm (value + timestamp), loop cause.
  • Home UI (charts + step list) reads from this store.
  • Runtime/pump/CGM adapters write to this store; Home must not compute independent state copies.

Ingestion paths

  • CGM stream:
  • Capture readings in AppCGMManagerDelegate.cgmManager(_:hasNew:) from CGMReadingResult.
  • Persist every valid sample used for display, not just the latest sample.
  • Algorithm/runtime stream:
  • On executed step, write StepContext (step index, CGM used, execution timestamp, wake cause).
  • Pump stream:
  • Continue reconciling delivery via PumpStatusObserver + PumpServiceAdapter.
  • Upsert DosePoint by step ID so requested vs delivered can evolve as pod finalizes bolus.

UI composition plan

  • Replace current "Recent Dose Steps" ad-hoc rendering with projection from telemetry store.
  • Add two Home chart components backed by the same projection:
  • EGVChartView (ported/refactored from Scout EGVChart).
  • InsulinDoseChartView (ported/refactored from Scout InsulinChart with time-based x-axis).
  • Keep text list under charts for quick debugging:
  • Step, requested/delivered units, step timestamp, CGM value/timestamp used.
  • Scrubbing behavior:
  • CGM chart scrub shows glucose + absolute timestamp.
  • Insulin chart scrub shows delivered/requested units + step + absolute timestamp.

Acceptance requirements (testable)

  • CHART-01: Single-source projection
  • Home chart data and Home step list are generated from the same telemetry store snapshot.
  • CHART-02: CGM history persistence
  • After app relaunch, Home chart still renders recent CGM points without requiring a new read first.
  • CHART-03: Dose reconciliation update
  • When pod delivery status transitions (in-progress -> finalized), existing step point is updated in place (no duplicate step rows).
  • CHART-04: Step reset behavior
  • Reset Algo clears telemetry tied to prior session; next session begins with step 0 and fresh chart/list history.
  • CHART-05: Time-axis alignment
  • CGM and insulin charts place points/bars by timestamp, not by array index.
  • CHART-06: Zero-dose visibility
  • Step list/chart still include executed steps with 0.0U delivery so skipped/no-dose behavior is visible.

Rollout order

  1. Done: Add telemetry store models and persistence schema.
  2. Done: Move Home chart/list reads to telemetry store snapshot.
  3. Done: Wire ingestion from CGM + loop runtime + pump reconciliation.
  4. Done: Add store unit tests (LoopTelemetryStoreTests) and coordinator telemetry tests.
  5. Pending: Add UI smoke tests for range switching and scrub behavior with sparse CGM/dose data.

Testing

  • BionicLoopTests/
  • Add unit tests for loop scheduling, offline fallback, and reconciliation logic.
  • BionicLoopUITests/
  • Add onboarding flow smoke tests for G7 and DASH.

Docs

  • Docs/Architecture/Architecture.md, Docs/Requirements/Requirements.md, and Docs/Quality/RiskAnalysis.md should be updated alongside any new scheduling or device-integration behavior.