Marjorie vs BionicLoop Algorithm I/O Gap Analysis
Last updated: 2026-02-11
Purpose
This document compares legacy BUMarjorie and current BionicLoop algorithm I/O behavior. It focuses on runtime scaffolding, input/output contracts, and persistence/traceability. It does not evaluate algorithm math quality.
Evidence Reviewed
BUMarjorie
/Users/jcostik/BUMarjorie/ControllerFramework/Interfaces/AlgorithmInterface.h/Users/jcostik/BUMarjorie/ControllerFramework/Controllers/AlgorithmController.m/Users/jcostik/BUMarjorie/ControllerFramework/Controllers/MasterController.m/Users/jcostik/BUMarjorie/ControllerFramework/Controllers/StateController.m/Users/jcostik/BUMarjorie/ControllerFramework/Models/AlgorithmStep.h/Users/jcostik/BUMarjorie/Marjorie/Data/MStepDataModel.m
BionicLoop (current implementation)
BionicLoopCore/Sources/BionicLoopCore/Algorithms/RealBUDosingAlgorithm.swiftBionicLoopCore/Sources/BionicLoopCore/Runtime/LoopRuntimeCoordinator.swiftBionicLoopCore/Sources/BionicLoopCore/Domain/LoopStepTelemetry.swiftBionicLoopCore/Sources/BionicLoopCore/Persistence/LoopRuntimeStateStore.swiftBionicLoop/Runtime/LoopRuntimeEngine.swiftBionicLoop/Integrations/Pump/PumpServiceAdapter.swiftBionicLoop/Integrations/Pump/PumpStatusObserver.swiftBionicLoopCore/Sources/Algo2015Bridge/include/Algo2015Bridge.hBionicLoopCore/Sources/Algo2015Bridge/Algo2015Bridge.c
Executive Snapshot
| Area | BUMarjorie | BionicLoop (Current) | Status |
|---|---|---|---|
| Step index source | algorithmTime + persisted state |
persisted Algo2015State.timeStep + runtime anchor reconciliation |
Aligned |
| Trigger model | scheduler + device events | new G7 timestamp (cgmUpdate) and explicit meal request path |
Different by design |
| Step 0 gate | requires CGM or BG | requires fresh, in-range CGM only | Gap |
| CGM stale/out-of-range for step > 0 | run with CGM_VALUE_NONE |
run with -1 (CGM_VALUE_NONE) for step > 0 |
Aligned |
| Pump unavailable policy | run step with unavailable flags; block delivery | run step with unavailable pump status; block command application | Aligned |
| Pump delivery feedback input | explicit request/delivered tuple | explicit tuple (insulinRequestTime, requested, delivered) via adapter + reconciliation |
Aligned (different data source mechanics) |
| Meal timing behavior | borrow future slots | borrow future slots; also executes current due step when already due/missed | Partial parity (extra behavior in BionicLoop) |
| Meal prerequisites | pump-ready + schedule constraints | pump-ready + schedule constraints + must have first successful step anchor | Partial parity |
| BG/BGCal input | supported | not wired (bgValue = -1) |
Gap |
| Glucagon path | supported | output field present but no glucagon device flow | Out of scope gap |
| Output persistence breadth | rich per-step persisted model | per-step telemetry persisted with typed algorithm input/output subset + pump command + reconciliation | Improved, still partial vs Marjorie |
| Single source for chart/list | algorithm-step data model | LoopTelemetryStore (LoopStepRecord) with CSV export |
Implemented |
Current BionicLoop I/O Contract
Input path (as executed)
- Step cadence is 5 minutes with 27-second lead-time window in coordinator scheduling.
- Step 0:
- requires fresh in-range CGM.
- if missing/stale/out-of-range, returns
missingFreshGlucoseand does not execute. - Step > 0:
- stale/missing/out-of-range CGM is converted to
-1and execution continues. - Pump status:
refreshStatus()success with known state uses real availability + delivery tuple.- refresh failure or
deliveryState == .unknownexecutes with unavailable pump flags and invalid tuple sentinels. - command application is blocked while unavailable/unknown.
- BG input:
- currently hardcoded unavailable (
bgValue = -1). - no production UI/runtime BG submit path to algorithm yet.
- Meal input:
mealTime+mealSizemapped fromMealAnnouncement.- meal path requires first successful step anchor and pump-ready state.
Output path (as executed)
- Algorithm output currently captured and exposed as:
- bolus insulin requested
- basal insulin requested
- meal insulin requested
- glucagon requested
- open-loop mode
- checkBG flag
- CGM slope
- Recommendation mapping:
- meal+bolus output becomes bolus recommendation.
- basal output is currently emitted as bolus micro-dose recommendation.
- Pump command telemetry captures attempt kind, amount, success/failure, errors.
Persistence and traceability
- Runtime cadence state persisted (
LoopRuntimeState): firstSuccessfulStepAt,lastExecutedStep,lastSuccessfulRunAt, etc.- Algorithm internal state persisted (
Algo2015StateSnapshot): timeStep+ state blob.- Step telemetry persisted (
LoopTelemetryStore): - executed step, wake cause, CGM used, requested/delivered, recommendation, pump command, pump delivery state, algorithm input snapshot, algorithm output snapshot.
- CSV export generated asynchronously from step telemetry records.
Gap Register (Current)
| Gap ID | Gap | Risk/Impact | Priority |
|---|---|---|---|
| GAP-01 | No BG/BGCal runtime input path to algorithm (BGval remains -1) |
step 0 may be blocked when CGM unavailable; no manual rescue path | High |
| GAP-02 | Step 0 policy differs from Marjorie (CGM-only gate vs CGM-or-BG gate) | behavior mismatch in CGM downtime startup | High |
| GAP-03 | Not all Marjorie output fields are surfaced/persisted | reduced audit parity for some legacy fields/customs | Medium |
| GAP-04 | Glucagon device/control flow not implemented | expected for insulin-only scope; parity gap remains | Medium |
| GAP-05 | Open-loop/basal-multiplier user controls not implemented | less configurability than legacy scaffolding | Low/Medium |
| GAP-06 | Meal due/missed-slot execution behavior is broader than strict borrow-only interpretation | requires team/clinical lock for final behavior | Medium |
What Was Closed vs Prior Gap Analysis
The following previously-listed gaps are now implemented and should be treated as closed:
- Pump-unavailable hard skip mismatch:
- coordinator now executes step with unavailable pump status and blocks command application.
- Step > 0 stale/out-of-range CGM hard-skip mismatch:
- coordinator now executes with unavailable CGM (-1) for step > 0.
- Minimal observability claim:
- typed per-step telemetry now persists algorithm input/output snapshots and pump command/result fields.
Recommended Next Work (From Current State)
Phase A: BG rescue path (highest priority)
- Add BG entry UI and runtime wake cause (
bgCheck). - Map manual BG to algorithm
BGval. - Enforce no-borrow rule for BG-triggered execution (due-step only).
- Define/approve step-0 BG-only policy and add test coverage.
Phase B: Output parity expansion
- Expand bridge/output snapshot coverage for remaining clinically useful fields.
- Keep CSV/schema versioning stable as fields expand.
Phase C: Meal policy lock
- Keep current implementation behavior documented:
- pre-due borrow window rules,
- due/missed-slot execution on current due step,
- anchor prerequisite.
- Obtain final team/clinical sign-off and freeze behavior.
Extracted Requirements (Status)
| ID | Requirement | Status |
|---|---|---|
| MIO-01 | Step 0 requires valid CGM or BG | Partial (CGM only implemented) |
| MIO-02 | Step > 0 can execute with unavailable CGM sentinel | Implemented |
| MIO-03 | Step index increments once per executed step | Implemented |
| MIO-04 | Late catch-up aligns step index to wall clock | Implemented |
| MIO-05 | Per-step pump availability + request/delivery tuple included in input | Implemented |
| MIO-06 | Pump unavailable executes step with unavailable input flags | Implemented |
| MIO-07 | Delivery only attempted when pump available and recommendation valid | Implemented |
| MIO-08 | Meal metadata applied once, reset after step | Implemented |
| MIO-09 | Persist per-step algorithm input/output + command outcome | Implemented (current subset) |
| MIO-10 | Persist full Marjorie-equivalent rich output surface | Partial |
| MIO-11 | Persist/restore algorithm state blob deterministically | Implemented |
| MIO-12 | Fresh reset clears runtime + algorithm + step history | Implemented |
| MIO-13 | BG/BGCal fallback path into algorithm input | Planned |
Key Open Decision
- Final step-0 rescue policy with manual BG:
- keep strict CGM-only step 0,
- or allow BG-driven step 0 execution when CGM is unavailable.
This decision should be locked before implementing bgCheck so runtime behavior, tests, and clinical messaging stay consistent.