Dive planner Phase 4: CCR planning and worst-case bailout#488
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Implements Phase 4 of the dive planner redesign by adding true CCR planning support (constant-ppO₂ loop schedules, setpoint handling, and CCR-specific consumption) plus a worst-case open-circuit bailout solver and corresponding canvas UI readouts.
Changes:
- Add
CcrLoopAscentGasto compute loop decompression schedules via depth-dependent effective inert fractions (no engine-core stop-search changes). - Extend
PlanEnginewith CCR mode (setpoint breathing, loop schedule, metabolic O₂ + loop-fill diluent consumption, newnoBailoutCarriedissue) and addBailoutSolver+ provider for worst-case bailout sizing. - Update canvas UI to toggle OC/CCR, edit setpoints, and display bailout results + scrub-to-bailout; add l10n keys and tests.
Reviewed changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/features/planner/plan_engine_ccr_test.dart | Adds unit tests covering CCR schedule, consumption, and CCR-specific issues. |
| test/features/planner/dive_plan_state_mapper_test.dart | Updates/extends mapping tests to include CCR mode + setpoints round-trip behavior. |
| test/features/planner/ccr_ui_test.dart | Adds widget tests for OC/CCR toggle and bailout section visibility. |
| test/features/planner/bailout_solver_test.dart | Adds tests validating bailout solver behavior (worst case, monotonicity, sufficiency). |
| test/core/deco/ccr_loop_ascent_gas_test.dart | Adds tests proving loop effective-fraction equivalence and switch/clamp behavior. |
| lib/core/deco/ascent/ccr_loop_ascent_gas.dart | New ascent gas plan representing the CCR loop for schedule computation. |
| lib/features/planner/domain/services/plan_engine.dart | Adds CCR breathing/schedule path, CCR consumption model, and noBailoutCarried issue. |
| lib/features/planner/domain/services/bailout_solver.dart | New worst-case bailout solver producing sampled bailout demand and sufficiency. |
| lib/features/planner/presentation/providers/plan_canvas_providers.dart | Adds planBailoutProvider to compute bailout outcome live from current plan state. |
| lib/features/planner/presentation/widgets/plan_results_sheet.dart | Displays bailout section when applicable and localizes noBailoutCarried. |
| lib/features/planner/presentation/widgets/plan_canvas_chart.dart | Adds scrub-to-bailout readout appendage using nearest sampled bailout point. |
| lib/features/planner/presentation/widgets/ccr_settings_section.dart | New UI section for CCR setpoint low/high + switch depth editing. |
| lib/features/planner/presentation/pages/plan_canvas_page.dart | Adds OC/CCR toggle chip and conditionally shows CCR settings section. |
| lib/features/planner/domain/services/dive_plan_state_mapper.dart | Maps mode/setpoints between UI state and persisted plan aggregate. |
| lib/features/planner/domain/entities/dive_plan.dart | Adds effective CCR setpoint getters with spec defaults. |
| lib/features/planner/domain/entities/plan_outcome.dart | Adds new issue type noBailoutCarried. |
| lib/features/dive_planner/domain/entities/plan_result.dart | Extends planner UI state with mode + CCR setpoint fields. |
| lib/features/dive_planner/presentation/providers/dive_planner_providers.dart | Adds notifier methods to update mode and CCR setpoints. |
| lib/l10n/arb/app_en.arb | Adds new planner canvas keys for bailout + CCR setpoint UI. |
| lib/l10n/arb/app_de.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_ar.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_es.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_fr.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_he.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_hu.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_it.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_nl.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_pt.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_zh.arb | Adds translations for new bailout/CCR canvas strings. |
| lib/l10n/arb/app_localizations.dart | Updates generated localization interface for new keys. |
| lib/l10n/arb/app_localizations_en.dart | Updates generated English localization implementation. |
| lib/l10n/arb/app_localizations_de.dart | Updates generated German localization implementation. |
| lib/l10n/arb/app_localizations_ar.dart | Updates generated Arabic localization implementation. |
| lib/l10n/arb/app_localizations_es.dart | Updates generated Spanish localization implementation. |
| lib/l10n/arb/app_localizations_fr.dart | Updates generated French localization implementation. |
| lib/l10n/arb/app_localizations_he.dart | Updates generated Hebrew localization implementation. |
| lib/l10n/arb/app_localizations_hu.dart | Updates generated Hungarian localization implementation. |
| lib/l10n/arb/app_localizations_it.dart | Updates generated Italian localization implementation. |
| lib/l10n/arb/app_localizations_nl.dart | Updates generated Dutch localization implementation. |
| lib/l10n/arb/app_localizations_pt.dart | Updates generated Portuguese localization implementation. |
| lib/l10n/arb/app_localizations_zh.dart | Updates generated Chinese localization implementation. |
| docs/superpowers/plans/2026-07-05-dive-planner-phase4-ccr.md | Adds the Phase 4 implementation plan document (reference/traceability). |
…-planner-phase4-ccr # Conflicts: # lib/features/planner/domain/services/plan_engine.dart # lib/features/planner/presentation/pages/plan_canvas_page.dart
- CCR switch depth accepts 0 m (surface); setpoints still require a positive value (allowZero on that field only) - Bailout required/available volumes now use UnitFormatter (respect L vs cuft); drop the hardcoded L from the bailout strings across locales - Cover the CCR settings section and the bailout volume formatting
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
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.
Summary
Phase 4 of the dive planner redesign (plan). Stacked on #486 (Phase 3 canvas) — review #484 → #485 → #486 first.
Removes the Phase 1 limitation "CCR deco schedules still breathe OC": CCR plans now get real loop decompression schedules, setpoint handling, O2/diluent consumption, and a worst-case bailout solver with scrub-to-bailout.
The key move
CcrLoopAscentGasexpresses the constant-ppO2 loop as a depth-dependent effective-fraction ascent gas: at any depth, the loop's inspired partial pressures (viaClosedCircuit) divide by alveolar pressure to give exact effective fN2/fHe — so the unchanged Bühlmann stop-search machinery computes loop deco exactly at constant-depth stops (proven by a round-trip equivalence test). Zero engine-core edits; setpoint switches split ascent legs like gas switches.PlanEngine CCR mode
noBailoutCarriedalert for CCR deco plans without a bailout tank (the OC "no deco gas" alert correctly no longer fires for CCR).Bailout solver
Walks the bottom phase at bounded sample intervals (≤ ~40 samples), computing the full OC bailout from each instant — schedule on the bailout-role gases, stressed SAC liters over travel legs + stops — and reports the worst case vs the compressibility-corrected carried volume. Verified: worst case lands at end-of-bottom for square profiles, demand is monotonic across the bottom, and sufficiency flips with cylinder size.
Canvas UI
BO {tts}′from the nearest sampled instant — point at any moment of the dive and see the bailout time home.Verification
310 deco + 113 planner/dive_planner tests green;
flutter analyzeclean; python3-derived vectors for the loop's effective fractions.