Add replay chart v2 with ceiling/GF overlays and fullscreen (PRO-51) - #163
Conversation
Adds core/mutants.out/ and core/mutants.out.old/ to .gitignore so local mutation-testing runs don't clutter git status. Made-with: Cursor
Phase 4 of the dive replay engine (PRO-23). Ports the PR #160 animation work forward onto latest main now that PRO-60 (deco accuracy) and PRO-61 (actual-dive samples) have reshaped ReplayProfileSheet. - ReplayChartData precomputes depth, ceiling, GF99, SurfGF, gas-switch and deco-stop data with O(1) scrub lookups. - ReplayChartFullscreenView presents the chart landscape with overlay toggle chips (Ceiling, GF99, SurfGF). - ReplayProfileSheet wires the chart into the existing parameter sheet. - planned_stops added to ProfileGenResult (Rust + UDL + Swift bindings) to surface the pass-1 stop schedule for chart band visualization. Tests: - Rust: planned_stops ordering, duration, and sample-hold correspondence (test_planned_stops_surface_deco_dive, test_shallow_no_deco extended). - Swift: FFI round-trip for plannedStops on both shallow NDL (empty) and deep conservative-GF (non-empty) dive profiles. Closes PRO-51. Supersedes #160 (closed due to ReplayProfileSheet conflicts from PRO-60/61). Completes the Replay Complete milestone and unblocks PRO-53 (Phase 5 comparison view). Made-with: Cursor
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…bundle id Addresses second-opinion review on PR #163 (gpt-5.3-codex subagent): 1. Actual-dive mode now renders planned deco stop bands. The second engine call (planAscent: true) was dead code — ReplayChartData's actual-dive initializer hardcoded decoStopBands = []. Now accepts plannedStops: [DecoStop] and matches stops against sample depth with a 1.0 m tolerance (wider than synthetic's 0.5 m to accommodate real diver behavior). Uses the max-depth sample as the bottom-end proxy so descent pass-through at stop depths can't open spurious bands. 2. Parallelize dual deco engine call with `async let`. The two calls (overlay + planned) are independent; previously serialized, now run concurrently, roughly halving perceived latency on longer dives. 3. Defensive sort on samples in actual-dive ReplayChartData init. The O(1) scrub lookup and band matching rely on monotonic tSec; sort at entry protects against any out-of-order imports. 4. Revert PRODUCT_BUNDLE_IDENTIFIER to azlucis.Profundum. The change to com.azlucis.Profundum was accidental Xcode drift when saving project.pbxproj for the new Swift files — out of scope for PRO-51 and would affect app signing/provisioning. Made-with: Cursor
Cursor's Task tool supports subagents with explicit model overrides (e.g. gpt-5.3-codex, claude-opus-4-7-thinking-medium). This provides the independent-model perspective that step 8 asks for without the MCP setup cost. External MCP not required. Made-with: Cursor
Second-opinion review (gpt-5.3-codex) — REQUEST-CHANGES → addressed in
|
… unstick guard - Sort actual-dive samples before passing to ReplayChartSection so nearestTSec binary search matches ReplayChartData's defensive sort - extractResultData uses max tSec instead of unsorted .last for recorded total time - Empty-params guard in generateFromActualSamples now resets isGenerating and surfaces an error instead of silently returning Co-authored-by: Cursor <cursoragent@cursor.com>
Second-opinion review round 2 (gpt-5.3-codex) — no blockers → addressed in
|
- fullScreenCover has no built-in interactive dismissal; add a downward drag gesture that pauses the animation and dismisses - Reset path now requests portrait geometry and calls setNeedsUpdateOfSupportedInterfaceOrientations() — UIKit caches supported orientations, so the orientationLock reset alone was never picked up and rotation stayed locked after closing Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Phase 4 of the dive replay engine (PRO-23). Ports the animation work from closed PR #160 forward onto latest main now that PRO-60 (deco accuracy) and PRO-61 (actual-dive samples) have reshaped
ReplayProfileSheet.ReplayChartDataprecomputes depth, ceiling, GF99, SurfGF, gas-switch, and deco-stop data with O(1) scrub lookups.ReplayChartFullscreenViewpresents the chart landscape with overlay toggle chips (Ceiling, GF99, SurfGF).ReplayProfileSheetwires the chart into the existing parameter sheet.planned_stopsadded toProfileGenResult(Rust + UDL + Swift bindings) to surface the pass-1 stop schedule for chart band visualization.Closes PRO-51. Supersedes #160 (closed due to
ReplayProfileSheetconflicts from PRO-60/61). Completes the "Replay Complete" milestone and unblocks PRO-53 (Phase 5 comparison view).Tests
test_planned_stops_surface_deco_dive,test_shallow_no_deco(extended) — ordering, duration, and sample-hold correspondence.plannedStopson both shallow NDL (empty) and deep conservative-GF (non-empty) profiles.Test plan
Follow-ups
Made with Cursor