Skip to content

Marshaling: live enter/exit re-detection with manual commit#348

Merged
ryan-johnson2 merged 1 commit into
develfrom
redetect-marshaling
Jul 3, 2026
Merged

Marshaling: live enter/exit re-detection with manual commit#348
ryan-johnson2 merged 1 commit into
develfrom
redetect-marshaling

Conversation

@ryan-johnson2

Copy link
Copy Markdown
Contributor

The RotorHazard-style marshaling flow, per user spec: move the entry/exit levels live over the captured RSSI trace, watch the re-detected laps populate as a preview, and Commit to make them official.

How it works

  • Tune detection panel (Marshaling screen, shown for a traced heat when the session can control): enter/exit inputs two-way-bound with draggable threshold handles on the graph (keyboard-nudgeable, aria sliders). Initial values are the thresholds the timer actually detected against (falling back to sample percentiles).
  • Live preview, zero writes: every adjustment re-runs the timer's own hysteresis semantics over the captured samples (redetect.ts — crossing opens ≥ enter, peak-timed, closes ≤ exit; dense per-sample timestamps preferred; incomplete trailing windows excluded), diffs against the current official passes (greedy nearest-match, 500ms tolerance), and shows added candidates (dashed hollow markers) and would-be-removed laps (struck/dimmed) on the graph plus a preview lap list — "would be N laps (+A, −R)".
  • Commit sends the diff as the existing auditable primitives — a VoidDetection per removed pass, a heat-tagged InsertLap per added one — so every re-detection lands in the audit trail and is reversible like any other ruling. Reset restores the recorded thresholds.
  • Thresholds are preview-only: pushing calibration back to RH via the plugin is a noted future feature.

Verification

33 new tests (detection math incl. noisy double-peaks/ties/boundary-inclusive edges/dense-vs-uniform timing; graph drag/keyboard/preview rendering; screen gating, live-preview-sends-nothing, exact commit command batches, Reset). Suite: 41 files / 524 tests green, both svelte-check passes, lint clean. Display-only graph behavior is unchanged when the new props are absent (all 11 pre-existing graph tests untouched).

🤖 Generated with Claude Code

The RotorHazard-style "Recalculate with draggable thresholds" the RssiGraph
deferred (marshaling.html §5), frontend-only:

- lib/redetect.ts (pure, tested): detectPasses re-runs RH-semantics
  enter/exit hysteresis over the captured trace (open at ≥enter, track the
  window peak, close at ≤exit; pass = peak time; an open window at trace end
  emits nothing; enter must exceed exit). diffPasses greedy-nearest-matches
  the re-detection against the current official passes (500ms tolerance,
  each pass matches at most once) into kept/added/removed; previewLaps
  derives the would-be lap list (first pass = holeshot); officialPasses
  reconstructs a competitor's boundary passes from the corrected lap list;
  defaultThresholds gives a 75th/25th-percentile fallback for unset traces.

- RssiGraph.svelte: opt-in tuning props — `onthresholds` grows draggable
  (pointer) + keyboard-nudgeable (±1) handles on the enter/exit lines;
  `tuned` overrides the drawn levels (and the shaded crossing windows) for
  the competitor being adjusted; `preview` draws hollow dashed markers for
  would-be-ADDED passes and strikes/dims lap markers whose closing pass
  would be REMOVED. Without the new props the graph stays exactly the old
  display-only surface.

- Marshaling.svelte: a "Tune detection" panel (trace + control only, scoped
  to the marshaled pilot) with enter/exit number inputs seeded from the
  trace's recorded thresholds, two-way with the graph drag. The preview
  re-detects live — "Would be N laps (+A added, −R removed)" plus the
  preview lap list — sending NOTHING while adjusting. Commit turns the diff
  into the existing primitives (a VoidDetection per removed pass, then a
  heat-tagged InsertLap per added one, sequentially), refreshes, and toasts
  a summary with the resolved callsign; Reset restores the recorded levels.
  The thresholds are a UI/preview concern only — never written back to the
  timer (pushing calibration to RH via the plugin is a separate future
  feature).

Tests: 20 redetect unit tests (hysteresis incl. double-peak/open-window/
boundary/dense-times, diff tolerance edges, preview laps, official passes,
percentile fallback), 6 graph tuning tests (drag/keyboard emit, tuned
override, preview markers, display-only without props), 7 screen tests
(panel gating + seeding, live preview without sends, exact commit batches,
invalid-threshold flag, reset). Full suite 524 green; svelte-check + lint
clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ryan-johnson2 ryan-johnson2 merged commit 80c9787 into devel Jul 3, 2026
3 checks passed
@ryan-johnson2 ryan-johnson2 deleted the redetect-marshaling branch July 3, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant