Skip to content

Developer Change Plan

Last updated: 2026-06-02 16:30 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 subject-scoped offline clinical unlock code:
  • verifier material is provisioned locally and stored per subject in secure storage
  • single-use counters are burned locally before clinician controls open
  • no internet is required to verify a code after material is provisioned
  • production master secrets are not embedded in app source
  • broader production role-based authorization remains outside the current IDE baseline
  • Keep clinician-only controls out of participant-facing setup sections.

Current implementation status: - Clinician-only section and offline clinical unlock 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. - Clinical unlock remains active until the provisioned expiration timestamp or explicit manual lock. - 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 clinical-unlock 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:
  • offline clinical unlock verifier vectors and 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”).
  • Expose the algorithm's native hourly basal outputs (nominalBasal, instantBasal) through the bridge and telemetry surface so fallback design work can use algorithm-owned U/hr values instead of deriving them from 5-minute micro-dose output.
  • 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.
  • Add differential checks showing that a higher setpoint track reduces the exposed hourly basal outputs for the same hyperglycemic input sequence.

Offline fallback staging note

  • Algorithm-owner feedback now sets the current fallback policy direction:
  • if current target is 110 mg/dL or below, safety-track target becomes 120 mg/dL
  • if current target is already 120 mg/dL or higher, safety-track target is raised to the next higher allowed target, capped at the highest target
  • true autonomous post-disconnect fallback should use a masked fallback schedule, not a threshold-time command sent after comms is already gone
  • for the current autonomous implementation, derive a four-period local-time fallback schedule from the safety track's Swift-maintained q5 nominalBasal profile and program it as the masked fallback schedule
  • keep the scalar single-rate fallback as a backup only when no q5 nominal profile can yet be generated
  • keep that programmed fallback schedule masked with repeated 0.0 U/hr temp basals while communication remains healthy
  • refresh the masked schedule at the configured cadence through a controlled reprogram-and-immediate-remask maintenance sequence while communication remains healthy; do not intentionally allow the mask to expire in steady state
  • once the active mask has 20 minutes or less remaining, renewal enters the maintenance window and should happen before the next step executes rather than waiting for a later successful-step callback
  • if a valid fallback candidate is already known but no fallback is currently armed, the same pre-step maintenance pass should arm fallback before the next step rather than after that step has a chance to start bolus delivery
  • if a bolus or other blocked pump state prevents renewal while the mask is still active, record deferred maintenance and retry on the next safe wake instead of escalating immediately to failure, including late bolus in progress failures surfaced by the temp-basal command path
  • current field-test expectation: fallback schedule arm and each 6 hour refresh may emit the normal DASH confidence beep whenever pod confidence beeps remain enabled, because the existing basal-schedule programming path is still treated as a manual/profile save command; the repeating 0.0 U/hr mask temp basal follows automatic-command beep rules separately
  • do not add fallback-specific TMAX changes for this basal-only mode
  • The first implementation slices are now moving beyond exposure-only scaffolding and into connected masked-fallback maintenance:
  • extend Algo2015Bridge to carry nominalBasal and instantBasal
  • surface those values through RealBUDosingAlgorithm telemetry
  • persist a latest FallbackBasalCandidate in LoopRuntimeState
  • persist a structured FallbackBasalEvent in runtime/telemetry state for masked-fallback maintenance and reconnect reconciliation tracking
  • run a secondary/safety algorithm track with a separate persisted algorithm-state store and a fallback target derived from the active target
  • project fallback events into Recent Dose Steps
  • maintain separate primary and safety q5 nominal-basal profiles in runtime state for traceability
  • maintain the connected 0.0 U/hr mask and program/refresh/disarm the four-period safety-profile fallback schedule only through explicit safety-gated maintenance operations
  • when maskExpiredOffline is observed, persist a reconciliation-required masked-fallback recovery state and block ordinary loop stepping, manual BG, meal announce, and new algorithm arm until reconnect recovery resolves
  • while that recovery remains pending, attempt connected restore/disarm of the original programmed basal schedule on runtime start, app foreground, or pump reconnect
  • if restore succeeds while the loop remained armed and reconnect evidence is confirmed or corrected, preserve the existing session/cadence anchor and account the pump-reported fallback delivery delta by replaying missed 5-minute algorithm steps with CGM=-1, per-step pump delivery input, and no catch-up pump commands, but only when same physical pod continuity and delivery-counter credibility are both proven
  • if reconnect evidence is ambiguous, the pod is different/new, pod identity is unknown, or delivery history is discontinuous, preserve the existing session/cadence anchor but keep the current due-slot resume on the explicit unreconciled/logging-only feasibility path instead of treating it as authoritative reconciliation; do not aggregate the missing fallback delivery into the resumed live step
  • With that feedback in hand, the planned runtime design is:
  • keep the secondary/safety track running with the same accepted inputs as primary
  • derive setPointNominal and setPoint from the active target using the safety-target escalation policy above
  • keep TMAX and meal-upfront equal to the primary track
  • derive the programmed pod fallback schedule from the safety track's q5 nominalBasal profile by averaging local-time blocks 00:00-06:00, 06:00-12:00, 12:00-18:00, and 18:00-24:00; impute missing slots from observed slot averages so the profile is usable after step 1 and improves with history
  • maintain a 0.0 U/hr temp-basal mask in repeating DASH-supported 30 minute windows while communication is healthy and successful loop steps continue; enter renewal once 20 minutes or less remain on the active mask, defer blocked renewals while the current mask is still active, and only allow fallback delivery to activate if step execution stalls or deferral runs long enough for the active mask to expire
  • refresh that fallback schedule no more often than the configured refresh cadence, and only through a controlled maintenance sequence: when the derived rounded four-entry schedule changes, use a healthy connected window with no active bolus and known pump state to replace the programmed schedule, then immediately reapply the 0.0 U/hr / 30 minute mask in the same sequence so nominal connected operation remains masked while step execution continues
  • backlog a small OmniBLE follow-on so masked-fallback schedule programming can opt into a silent maintenance path without changing the user's global confidence-beep preference; do not block current feasibility work on that refinement
  • when communication is lost and the active mask expires, allow the pod to resume the programmed nominal-derived fallback schedule autonomously
  • current implemented recovery boundary after that expiry is a persisted reconciliation-required blocked state plus connected restore/disarm retry on start, foreground, or pump reconnect, with confirmed/corrected pump-delta accounting only when same physical pod continuity is proven and credible pump-reported delivered-insulin delta spans the outage
  • the current code also captures a basal-only reconnect snapshot containing the programmed basal schedule, automatic temp-basal evidence, and pod cumulative delivered-insulin total; against persisted fallback state, that snapshot records confirmed, corrected, or ambiguous recovery detail
  • when the algorithm session is reset/disarmed, attempt to restore the original programmed basal schedule and emit explicit restore success/failure review events
  • keep instantBasal surfaced in telemetry and review tooling for future design evaluation, but do not make it part of the first autonomous schedule path
  • project fallback command/reconciliation details into Home review surfaces, especially Recent Dose Steps, so operators can see the programmed fallback rates/schedule, that it was sourced from safety-track nominalBasal, the escalated safety target used for that track, any later reconnect correction, and the comparison between modeled fallback delivery and the pump-reported delivered insulin delta since the last connected fallback baseline
  • emit the full 288-point safety q5 profile to cloud only on fallback schedule programming events (armed / schedule_refreshed), together with the four programmed schedule entries, observed/imputed slot counts, and timezone metadata
  • confirmed/corrected reconnect recovery now applies basal-only pump-delta accounting as no-command missed-step primary/secondary algorithm replay before the current due step only when same-pod continuity is proven; local step telemetry / CSV export records CGM=-1 replay rows with per-step delivered-insulin input, then the resumed live step uses actual refreshed pump status without duplicate recovered-delivery injection. Delivery accounting is scaled from credible pump-reported delivered-insulin delta only, while modeled expected fallback delivery remains logging/review evidence when pump verification is unavailable or pod continuity is not proven

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.
  • Runtime reconciles persisted cadence state with the algorithm bridge's reported next step before ordinary cadence or meal-announce step selection. If the algorithm has already consumed the current due step while persisted runtime state lags, runtime advances lastExecutedStep without re-anchoring so live executedStep, pump request-step attribution, and algorithm input stepTime remain aligned.
  • 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.
  • Meal step selection occurs after cadence reconciliation against the algorithm bridge's current step, preventing a borrowed meal from labeling an already consumed algorithm step as an earlier runtime step.
  • 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
    • next hardening target: fold uncertain meal-delivery recovery into the broader reconnect reconciliation architecture so Home cancel affordances, duplicate blocking, and resumed dosing state are keyed off authoritative request identity rather than generic pumpDelivering
  • 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.
  • Extend the current reconciliation-required fallback state into a complete reconnect recovery state machine with operator status messaging and explicit resolution actions.
  • 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.
  • Design a shared reconnect reconciliation subsystem for autonomous fallback, uncertain meal bolus, and other in-flight insulin commands before any extended offline dosing behavior is allowed.

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.
  • Implemented no-active-pod critical alert policy: any scenario where the user does not have an active pod raises a safety-critical local alert after debounce and repeats local notification attempts every 30 minutes until active pod state is restored or an explicitly approved exit/dismissal condition is met. This is broader than the armed-loop stepping-interruption alert and covers inactive, deactivated, expired, missing, unpaired, setup-incomplete, and otherwise no-active-pod states.
  • 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, do not start, stop, reset, or replace the algorithm session automatically. Continue only after explicit user action, and record the blocked/unreconciled reason for operator review.

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.
  • Extend Recent Dose Steps for fallback work:
  • show when a dose row reflects offline fallback rather than ordinary loop or meal delivery
  • include fallback rate, source (nominalBasal from the safety track for the first autonomous masked implementation), safety target, mask duration / renewal state, and post-reconnect reconciliation result
  • 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.
  • CHART-07: Fallback detail visibility
  • When a step or reconciled delivery reflects offline fallback, Recent Dose Steps shows fallback-specific metadata (rate U/hr, rate source, safety target, duration, reconciliation outcome`) without requiring log inspection.

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.