Repository navigation
Sample correction range per prediction point in insulinCorrection - #39
Merged
Merged
Conversation
The correction range was sampled once at the decision time and applied to every predicted point. LoopKit's DoseMath samples the range at each prediction point's own time (correctionRange.quantityRange(at: prediction.startDate)), so a forecast that crosses a target-band boundary (e.g. an evening band ending and a higher overnight band beginning) is corrected to the band in effect at each point. Sampling once over-corrects the portion of the forecast that lands in a higher later band, and under-corrects for a lower later band. Match LoopKit: look up the correction range at each prediction point. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XEGCDE2D9wF3zig7uQ9PY2
Camji55
approved these changes
Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sample correction range per prediction point in insulinCorrection
What
insulinCorrectionsampled the correction range once, at the decision time, and used that single band for every predicted point. LoopKit'sDoseMathsamples the range at each prediction point's own time (correctionRange.quantityRange(at: prediction.startDate)), so a forecast that crosses a target-band boundary is corrected to the band actually in effect at each point.This change matches LoopKit: look up the correction range per prediction point.
Why
With a schedule like evening 100 mg/dL → overnight 110 mg/dL, a forecast generated near the boundary extends into the overnight band, but the port corrected those points to 100 instead of 110 — systematically over-correcting into the higher band (and under-correcting into a lower one).
Replay verification against deployed Loop (real dosing history, LoopEval): this discrepancy was the dominant source of auto-bolus mismatch for a donor with an evening/overnight band change. The fix lifted exact auto-bolus agreement with the deployed app from 75.6% to 82.9% (agreement within one 0.05 U increment: 93.1% → 95.1%).
Behavior change
Only forecasts that cross a correction-range boundary are affected; with a single band (or none within the forecast horizon) the result is unchanged. The precondition message changes from "must cover date" to "must cover prediction", since the range must now cover the forecast horizon —
AlgorithmInput.targettimelines already do.Testing
testCorrectionRangeSampledPerPredictionPoint: a flat-high forecast with the target band stepping up at t+2h requires less correction than the same forecast against the uniform low band.🤖 Generated with Claude Code
https://claude.ai/code/session_01XEGCDE2D9wF3zig7uQ9PY2