Marjorie vs BionicLoop Algorithm I/O Gap Analysis
Last updated: 2026-03-09
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) + explicit meal path (mealAnnounce) + manual BG path (bgCheck) |
Different by design |
| Step 0 gate | requires CGM or BG | requires fresh, in-range CGM only | Intentional divergence (locked) |
| 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 | wired for manual BG submit path (bgCheck), with step-0 rescue disabled by policy |
Intentional divergence |
| 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:
- mapped from manual BG submit path (
bgCheck) to algorithmBGval. - accepted range is
20...600 mg/dL. - submit replaces any pending candidate and applies to current due step or immediate next step.
- step-0 BG rescue is currently disabled; submission is rejected before first successful anchored step.
- 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 | Step-0 BG rescue is disabled (manual BG rejected before first successful anchored step) | startup recovery remains blocked when CGM step-0 gate is not met | Accepted policy divergence |
| GAP-02 | Step 0 policy differs from Marjorie (CGM-only gate vs CGM-or-BG gate) | behavior mismatch in CGM downtime startup | Accepted policy divergence |
| 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.
- Manual BG runtime input gap:
- manual BG submit path is wired (bgCheck), mapped to BGval, with pending-candidate replacement and immediate-next-step expiry semantics.
Recommended Next Work (From Current State)
Phase A: BG step-0 policy lock (highest priority)
- Finalize/approve step-0 BG rescue policy (
SRS-BG-008) with clinical team. - Decision as of 2026-03-09: keep strict CGM-only step-0 gate for current build.
- Maintain explicit user-facing rejection messaging and traceability for the locked policy (
SRS-CGM-002,SRS-BG-012).
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 | Policy divergence accepted (current build keeps CGM-only step 0) |
| 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 | Partial (implemented for bgCheck; step-0 rescue intentionally disabled in current build) |
Step-0 Policy Decision (Locked)
- Current build decision: keep strict CGM-only step 0.
- Manual BG step-0 rescue remains disabled and is explicitly guarded by runtime policy.
- Any future change to enable step-0 BG rescue is a new requirements decision and must update SRS/SDD/SVVP/RTM with dedicated verification.