Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
644 commits
Select commit Hold shift + click to select a range
24d5842
Merge pull request #252 from GridFPV/reset-laps-on-abort
ryan-johnson2 Jun 26, 2026
350c53c
feat(heats): custom heat label for build-heat (overrides the auto-name)
ryan-johnson2 Jun 26, 2026
2bbe191
Merge pull request #253 from GridFPV/custom-heat-label
ryan-johnson2 Jun 26, 2026
b5b569a
ux(build-heat): auto-generate the heat id, only ask for the optional …
ryan-johnson2 Jun 26, 2026
ccc2b5b
Merge pull request #254 from GridFPV/autogen-heat-id
ryan-johnson2 Jun 26, 2026
00b07a3
feat(testkit): realistic mock RSSI signal (gate-pass profile + noise …
ryan-johnson2 Jun 26, 2026
9c3bc62
Merge pull request #255 from GridFPV/realistic-mock-signal
ryan-johnson2 Jun 26, 2026
53e4be3
fix(rotorhazard): dense heat-save fires once (was looping, flapping t…
ryan-johnson2 Jun 26, 2026
0e2bca8
Merge pull request #256 from GridFPV/fix-densesave-loop
ryan-johnson2 Jun 26, 2026
938c443
ux(rounds): add-round + build-heat as modal Dialog forms
ryan-johnson2 Jun 26, 2026
7f3ce67
Merge pull request #257 from GridFPV/rounds-modal-forms
ryan-johnson2 Jun 26, 2026
7d301f0
feat(marshaling): graph hover time/RSSI readout + add-a-new-lap
ryan-johnson2 Jun 26, 2026
665c781
Merge pull request #258 from GridFPV/graph-hover-addlap
ryan-johnson2 Jun 26, 2026
8fd1e43
fix(testkit): realistic mock signal reliably triggers lap detection
ryan-johnson2 Jun 26, 2026
e038a21
fix(live): stamp HeatStarting's recorded_at so the Armed tone countdo…
ryan-johnson2 Jun 26, 2026
412a29f
Merge pull request #259 from GridFPV/realistic-signal-detect
ryan-johnson2 Jun 26, 2026
63a245d
Merge pull request #260 from GridFPV/fix-armed-countdown
ryan-johnson2 Jun 26, 2026
c4f29e9
fix(marshaling): resolve pilot callsigns from the durable heat binding
ryan-johnson2 Jun 26, 2026
82b56ab
docs: add CLAUDE.md project rules β€” always display friendly names, ne…
ryan-johnson2 Jun 26, 2026
6c50a76
Merge pull request #261 from GridFPV/add-claude-md
ryan-johnson2 Jun 26, 2026
8207f52
Merge pull request #262 from GridFPV/marshaling-durable-names
ryan-johnson2 Jun 26, 2026
6d8ff13
feat(rotorhazard): Grid owns all start/stop timing; RH is start/stop/…
ryan-johnson2 Jun 26, 2026
13a1dd9
Merge pull request #263 from GridFPV/rh-grid-owns-timing
ryan-johnson2 Jun 26, 2026
0cf43d2
fix(rotorhazard): seat the heat's bound pilots on RH nodes so passes …
ryan-johnson2 Jun 26, 2026
0accd2e
Merge pull request #264 from GridFPV/rh-seat-pilots
ryan-johnson2 Jun 26, 2026
c2778ca
docs: pivot timer strategy β€” require an RH plugin, retire own-the-stack
ryan-johnson2 Jun 26, 2026
1821603
Merge pull request #265 from GridFPV/docs-rh-plugin-pivot
ryan-johnson2 Jun 26, 2026
9ed52c5
docs(rotorhazard): plugin design + sliced build plan (D16)
ryan-johnson2 Jun 26, 2026
fe95615
feat(rotorhazard): RH v4.4.0 mock-node plugin dev harness (plugin S0)
ryan-johnson2 Jun 27, 2026
5a035da
test(server): migrate full_event_live to the event-rooted router (#72)
ryan-johnson2 Jun 27, 2026
5df4203
feat(rotorhazard): plugin handshake + guided install + mock-control (…
ryan-johnson2 Jun 27, 2026
1214ad4
Merge pull request #266 from GridFPV/rh-plugin-design
ryan-johnson2 Jun 27, 2026
f0921e9
Merge pull request #267 from GridFPV/rh-plugin-s0-harness
ryan-johnson2 Jun 27, 2026
2870df8
Merge pull request #269 from GridFPV/rh-plugin-s1-handshake
ryan-johnson2 Jun 27, 2026
ee3015d
Merge pull request #268 from GridFPV/fix-server-full-event-live-72
ryan-johnson2 Jun 27, 2026
d96429c
feat(rotorhazard): live dense RSSI over the plugin (plugin S2)
ryan-johnson2 Jun 27, 2026
1556394
Merge pull request #270 from GridFPV/rh-plugin-s2-live-signal
ryan-johnson2 Jun 27, 2026
10c4b65
perf(rotorhazard): incremental dense signal streaming (plugin S2.1)
ryan-johnson2 Jun 27, 2026
694a30e
test(rotorhazard): relax rh_signal trace-from assertion for the live …
ryan-johnson2 Jun 27, 2026
734bbd1
Merge pull request #271 from GridFPV/rh-plugin-s2-incremental
ryan-johnson2 Jun 27, 2026
337c6f7
feat(rotorhazard): mock race-day autopilot via the test plugin
ryan-johnson2 Jun 27, 2026
73c08f2
Merge pull request #272 from GridFPV/rh-mock-race-days
ryan-johnson2 Jun 27, 2026
df36041
feat(rotorhazard): per-node passes via the plugin (plugin S3, part 1)
ryan-johnson2 Jun 27, 2026
72ca3ba
Merge pull request #273 from GridFPV/rh-plugin-s3-clean-control
ryan-johnson2 Jun 27, 2026
f1d0ba0
docs: mock race-day run guide
ryan-johnson2 Jun 27, 2026
6e1e5af
Merge pull request #274 from GridFPV/docs-mock-race-day
ryan-johnson2 Jun 27, 2026
a089b20
feat(projection): threshold-recalculate core β€” re-detect laps over a …
ryan-johnson2 Jun 27, 2026
d553682
Merge pull request #275 from GridFPV/rh-plugin-s4-recalc
ryan-johnson2 Jun 27, 2026
7b76e84
fix(components): buffer backdrop click-to-close so near-misses don't …
ryan-johnson2 Jun 27, 2026
12bb27a
Merge pull request #276 from GridFPV/ux-dialog-backdrop-buffer
ryan-johnson2 Jun 27, 2026
6b1ff59
feat(rounds): open-ended Time Trials β€” "Heats per pilot = 0" generate…
ryan-johnson2 Jun 27, 2026
a855bd7
feat(marshaling): shade the enter/exit band + show every lap on the R…
ryan-johnson2 Jun 27, 2026
26abad2
Merge pull request #277 from GridFPV/time-trials-open-ended
ryan-johnson2 Jun 27, 2026
57c6202
Merge pull request #278 from GridFPV/marshaling-graph-bands
ryan-johnson2 Jun 27, 2026
5f7dabb
feat(marshaling): shade per-crossing detection windows on the RSSI graph
ryan-johnson2 Jun 27, 2026
2d66c98
Merge pull request #279 from GridFPV/marshaling-crossing-windows
ryan-johnson2 Jun 27, 2026
5668d34
feat(marshaling): marshal one pilot at a time via a pilot picker
ryan-johnson2 Jun 27, 2026
c930317
Merge pull request #280 from GridFPV/marshaling-pilot-picker
ryan-johnson2 Jun 27, 2026
7c85ab1
fix(marshaling): plot the RSSI trace at actual sample times (uncompre…
ryan-johnson2 Jun 27, 2026
8ad6344
feat(marshaling): marshal any heat (default to current) + rename Live…
ryan-johnson2 Jun 27, 2026
5f834cb
Merge pull request #281 from GridFPV/marshaling-trace-actual-times
ryan-johnson2 Jun 27, 2026
15443af
Merge pull request #282 from GridFPV/marshaling-heat-picker-race-control
ryan-johnson2 Jun 27, 2026
957426a
fix(rotorhazard): zero RH's prestage pad so the race starts on the co…
ryan-johnson2 Jun 27, 2026
73861f2
Merge pull request #283 from GridFPV/rh-zero-prestage-pad
ryan-johnson2 Jun 27, 2026
6ed86ed
feat(rounds): require a race time for Best Lap / Best N Consecutive q…
ryan-johnson2 Jun 27, 2026
4f835f6
Merge pull request #284 from GridFPV/rounds-timed-qual-race-time
ryan-johnson2 Jun 27, 2026
239d910
fix(clocks): anchor the start countdown + race clock to server time (…
ryan-johnson2 Jun 27, 2026
26ec654
Merge pull request #285 from GridFPV/clocks-server-time-anchor
ryan-johnson2 Jun 27, 2026
90a2c09
feat(marshaling): finalize / revert / void the marshaled heat from th…
ryan-johnson2 Jun 27, 2026
dd968b4
Merge pull request #286 from GridFPV/marshaling-heat-transitions
ryan-johnson2 Jun 27, 2026
9ec4e33
docs(design): server-time clock offset, marshaling pickers/transition…
ryan-johnson2 Jun 27, 2026
7fae709
Merge pull request #287 from GridFPV/docs-recent-features
ryan-johnson2 Jun 27, 2026
d31637f
fix(rounds): show finalize-progress instead of an all-tied round ranking
ryan-johnson2 Jun 27, 2026
8483010
Merge pull request #288 from GridFPV/round-ranking-finalize-progress
ryan-johnson2 Jun 27, 2026
2852cdc
fix(rounds): require an end condition for scored rounds + accept both…
ryan-johnson2 Jun 27, 2026
aa8561f
test(contract): give scored-round fixtures a race time for the new en…
ryan-johnson2 Jun 27, 2026
315acbf
Merge pull request #289 from GridFPV/rounds-end-condition-and-seeding…
ryan-johnson2 Jun 27, 2026
7100c8d
fix(bracket): carry race time into advance-to-bracket rounds + add br…
ryan-johnson2 Jun 27, 2026
29d2019
Merge pull request #290 from GridFPV/bracket-advance-racetime-carry
ryan-johnson2 Jun 27, 2026
04e8bba
test(session): tolerate a 1ms tick in the pre-sync clock assertion
ryan-johnson2 Jun 27, 2026
5f114bc
Merge pull request #291 from GridFPV/flaky-clock-test-tolerance
ryan-johnson2 Jun 27, 2026
f3899af
feat(rounds): group a single-elim bracket's levels into one Bracket c…
ryan-johnson2 Jun 27, 2026
218fc13
Merge pull request #292 from GridFPV/bracket-container
ryan-johnson2 Jun 27, 2026
f413a8f
fix(rounds): polish the bracket container β€” drop the champion emoji, …
ryan-johnson2 Jun 27, 2026
7d6b150
Merge pull request #293 from GridFPV/bracket-container-polish
ryan-johnson2 Jun 27, 2026
96910cc
feat(engine): add the Chase the Ace final format (first to N race-wins)
ryan-johnson2 Jun 27, 2026
2133e7b
Merge pull request #294 from GridFPV/chase-the-ace-engine
ryan-johnson2 Jun 27, 2026
1456df3
feat(rounds): final-format selector β€” pick Single race or Chase the A…
ryan-johnson2 Jun 27, 2026
6bd52ac
Merge pull request #295 from GridFPV/final-format-selector
ryan-johnson2 Jun 27, 2026
7634bfc
feat(rounds): full-chain bracket builder in a modal (build-ahead, siz…
ryan-johnson2 Jun 27, 2026
b299ab3
test(rounds): type the bracket-builder mock + import NewRoundReq (fix…
ryan-johnson2 Jun 27, 2026
e311b42
Merge pull request #296 from GridFPV/bracket-builder-modal
ryan-johnson2 Jun 27, 2026
abf1e75
fix(rounds): hide bracket formats from the Add-round picker (they're …
ryan-johnson2 Jun 27, 2026
c6dab8d
Merge pull request #297 from GridFPV/hide-bracket-formats-from-add-round
ryan-johnson2 Jun 27, 2026
a2e78d1
feat(rounds): name brackets β€” "β€ΉBracket nameβ€Ί β€” β€ΉLevelβ€Ί" so an event …
ryan-johnson2 Jun 27, 2026
ab0d147
Merge pull request #298 from GridFPV/bracket-names
ryan-johnson2 Jun 27, 2026
aa0b39a
feat(rounds): shelve Multi-Main from the Add-round menu (defer until …
ryan-johnson2 Jun 28, 2026
d925991
Merge pull request #299 from GridFPV/shelve-multi-main
ryan-johnson2 Jun 28, 2026
56b32bb
docs: the format model β€” round types + scoring taxonomy (D17)
ryan-johnson2 Jun 28, 2026
8a9ac12
Merge pull request #300 from GridFPV/docs-format-model
ryan-johnson2 Jun 28, 2026
4a01916
feat(rounds): pick the win condition for a bracket (First-to-N / Most…
ryan-johnson2 Jun 28, 2026
b619520
Merge pull request #301 from GridFPV/bracket-win-condition
ryan-johnson2 Jun 28, 2026
ab09807
docs: core tenet β€” all racing is built from atomic formats; structure…
ryan-johnson2 Jun 28, 2026
4b4ea02
Merge pull request #302 from GridFPV/docs-format-tenet
ryan-johnson2 Jun 28, 2026
d95fada
feat(engine): Head-to-Head β€” the atomic racing building block (D17)
ryan-johnson2 Jun 28, 2026
bbab385
Merge pull request #303 from GridFPV/head-to-head-generator
ryan-johnson2 Jun 28, 2026
6d636ef
feat(engine): shared finishing-position scoring + configurable points…
ryan-johnson2 Jun 28, 2026
dfbe34c
Merge pull request #304 from GridFPV/shared-scoring-points-table
ryan-johnson2 Jun 28, 2026
a0a234a
feat(engine): multi-main bump-up ladder (configurable bump count)
ryan-johnson2 Jun 28, 2026
ba166af
Merge pull request #305 from GridFPV/multi-main-bumpups
ryan-johnson2 Jun 28, 2026
bf54493
test(contract): drive multi-main bump-up, double-elim, and round-robi…
ryan-johnson2 Jun 28, 2026
8e915be
Merge pull request #306 from GridFPV/structures-contract-tests
ryan-johnson2 Jun 28, 2026
403dba9
feat(rounds): Add-round taxonomy = Practice / Time Trial / Head-to-He…
ryan-johnson2 Jun 28, 2026
459b4f8
test(contract): GET /formats now offers head_to_head (the new round t…
ryan-johnson2 Jun 28, 2026
5e13cec
Merge pull request #307 from GridFPV/add-round-taxonomy
ryan-johnson2 Jun 28, 2026
3699285
fix(rounds): order the Add-round Format dropdown Open Practice β†’ Time…
ryan-johnson2 Jun 28, 2026
b6a6772
Merge pull request #308 from GridFPV/format-dropdown-order
ryan-johnson2 Jun 28, 2026
9705af5
feat(rounds): Head-to-Head form refinements + converge Time-Trial win…
ryan-johnson2 Jun 28, 2026
9caf419
Merge pull request #309 from GridFPV/h2h-form-refinements
ryan-johnson2 Jun 28, 2026
55d870c
feat(rounds): Build tournament (single-elim) β€” seed from a round OR a…
ryan-johnson2 Jun 28, 2026
2b6b211
Merge pull request #310 from GridFPV/build-tournament-single-elim
ryan-johnson2 Jun 28, 2026
06327e2
feat(rounds): polish single-elim tournament β€” pilots/advance per heat…
ryan-johnson2 Jun 28, 2026
8a06957
Merge pull request #311 from GridFPV/tournament-ui-polish
ryan-johnson2 Jun 28, 2026
751b37a
style(rounds): let EventRounds fill the workspace width (like standings)
ryan-johnson2 Jun 28, 2026
5cd7465
Merge pull request #312 from GridFPV/event-rounds-fill-width
ryan-johnson2 Jun 28, 2026
384e87b
fix(live): scope the live standing to the current heat's run, not a c…
ryan-johnson2 Jun 28, 2026
92da43f
Merge pull request #313 from GridFPV/live-standings-current-heat
ryan-johnson2 Jun 28, 2026
fd874e3
feat(tournament): polish Chase-the-Ace (series score + one-node viz) …
ryan-johnson2 Jun 28, 2026
536bcf9
Merge pull request #314 from GridFPV/chase-results-polish
ryan-johnson2 Jun 28, 2026
2412ca4
refactor(results): drop the Heat-result card (it belongs on Race cont…
ryan-johnson2 Jun 28, 2026
4bfeb04
Merge pull request #315 from GridFPV/results-remove-heat-result
ryan-johnson2 Jun 28, 2026
c904525
feat(results): time-trial standings detail + full-field tournament pl…
ryan-johnson2 Jun 29, 2026
3c9ec92
Merge pull request #316 from GridFPV/standings-detail-and-placement
ryan-johnson2 Jun 29, 2026
2473c64
feat(tournament): round-robin structure β€” builder + standings/rotatio…
ryan-johnson2 Jun 29, 2026
da1e1f7
Merge pull request #317 from GridFPV/tournament-round-robin
ryan-johnson2 Jun 29, 2026
755dddf
fix(results): score the heat-result projection with the round's win c…
ryan-johnson2 Jun 29, 2026
a62b8c6
Merge pull request #318 from GridFPV/fix-heat-result-win-condition
ryan-johnson2 Jun 29, 2026
f48869a
fix(results): source round-robin Best-lap from the standings endpoint
ryan-johnson2 Jun 29, 2026
c4b73fe
Merge pull request #319 from GridFPV/rr-bestlap-from-standings
ryan-johnson2 Jun 29, 2026
b63c888
refactor(results): round-robin viz shows standings only (drop the rot…
ryan-johnson2 Jun 29, 2026
f09c04f
Merge pull request #320 from GridFPV/rr-standings-only
ryan-johnson2 Jun 29, 2026
4107fa0
feat(round-robin): break points ties by fastest single lap
ryan-johnson2 Jun 29, 2026
fb890b5
test(components): add best_lap_micros to the HeatResult fixture (CI t…
ryan-johnson2 Jun 29, 2026
28314fa
Merge pull request #321 from GridFPV/rr-fastest-lap-tiebreak
ryan-johnson2 Jun 29, 2026
ee5b7da
feat(tournament): multi-main structure β€” builder + standings viz
ryan-johnson2 Jun 29, 2026
eb447a4
Merge pull request #322 from GridFPV/tournament-multi-main
ryan-johnson2 Jun 29, 2026
a12ac89
feat(seeding): range + combine seeding rules (foundation for real mul…
ryan-johnson2 Jun 30, 2026
62022f3
Merge pull request #323 from GridFPV/seeding-range-combine
ryan-johnson2 Jun 30, 2026
567d3d9
feat(tournament): compose+run the real MultiGP multi-main (64-pilot) …
ryan-johnson2 Jun 30, 2026
350c517
Merge pull request #324 from GridFPV/real-multi-main-compose
ryan-johnson2 Jun 30, 2026
71d49f2
refactor!: carve tournaments out for a primitives-first release base
ryan-johnson2 Jun 30, 2026
662d349
Merge pull request #327 from GridFPV/carve-out-tournaments
ryan-johnson2 Jun 30, 2026
091ca59
feat(rounds): rename the "Open Practice" format label to "Practice"
ryan-johnson2 Jun 30, 2026
67ba1aa
Merge pull request #328 from GridFPV/rename-practice
ryan-johnson2 Jun 30, 2026
6e2d483
fix(results): adjudications now reach standings, seeding & class resu…
ryan-johnson2 Jun 30, 2026
3bc501d
style: prefer-const in protestClock test (eslint)
ryan-johnson2 Jun 30, 2026
2e5551a
Merge pull request #329 from GridFPV/fix-adjudications-standings
ryan-johnson2 Jun 30, 2026
e5d5eb1
fix(primitives): backend validation + safety hardening for v1
ryan-johnson2 Jun 30, 2026
f87bee0
test(contract): roster+select class before membership (new validation)
ryan-johnson2 Jun 30, 2026
118fca1
Merge pull request #330 from GridFPV/backend-validation-hardening
ryan-johnson2 Jun 30, 2026
6d8e174
feat(time-trial): chunk large fields into heats of heat_size (#326) +…
ryan-johnson2 Jun 30, 2026
a3ca6a7
Merge pull request #331 from GridFPV/timed-qual-chunking
ryan-johnson2 Jun 30, 2026
e22a3bb
feat(rounds): bound the FromRanking cut at the source rounds' real field
ryan-johnson2 Jul 3, 2026
db64549
feat(head-to-head): rotations β€” the same groups race N heats, scoring…
ryan-johnson2 Jul 3, 2026
b15e3d3
Merge pull request #332 from GridFPV/h2h-rotations
ryan-johnson2 Jul 3, 2026
3c09e4c
docs: reconcile dev docs with the primitives-first v1 state
ryan-johnson2 Jul 3, 2026
4b70109
Merge pull request #333 from GridFPV/docs-primitives-v1
ryan-johnson2 Jul 3, 2026
78eb6d1
fix(results): close the residual defensible-results holes (release re…
ryan-johnson2 Jul 3, 2026
f675129
Merge pull request #342 from GridFPV/adjudication-scoring-fixes
ryan-johnson2 Jul 3, 2026
6633771
fix(seeding): freeze a carry seeding's field at first fill (#334)
ryan-johnson2 Jul 3, 2026
52b6cc3
fix(app): auto-official finalize respects the open-protest gate (#338)
ryan-johnson2 Jul 3, 2026
76666b0
test: drop unreachable fill-outcome arm (-D warnings)
ryan-johnson2 Jul 3, 2026
904f3b3
Merge pull request #343 from GridFPV/seeding-freeze-at-fill
ryan-johnson2 Jul 3, 2026
79d2c8d
Merge pull request #344 from GridFPV/auto-official-protest-gate
ryan-johnson2 Jul 3, 2026
d73abde
fix(console): marshaling friendly names + robustness batch (#337, #34…
ryan-johnson2 Jul 3, 2026
fe1587e
Merge pull request #345 from GridFPV/frontend-robustness-batch
ryan-johnson2 Jul 3, 2026
5f4d16b
fix(server): batch-2 backend validation β€” ScheduleHeat guards, member…
ryan-johnson2 Jul 3, 2026
7990758
Merge pull request #346 from GridFPV/backend-validation-batch2
ryan-johnson2 Jul 3, 2026
95f2513
feat(console): GridFPV brand home link on the directory pages
ryan-johnson2 Jul 3, 2026
7506236
Merge pull request #347 from GridFPV/brand-home-link
ryan-johnson2 Jul 3, 2026
43dc78b
feat(marshaling): live enter/exit re-detection with manual commit
ryan-johnson2 Jul 3, 2026
80c9787
Merge pull request #348 from GridFPV/redetect-marshaling
ryan-johnson2 Jul 3, 2026
ec5caae
fix(build): make the live RotorHazard transport a DEFAULT feature
ryan-johnson2 Jul 3, 2026
3ee4e51
Merge pull request #349 from GridFPV/live-by-default
ryan-johnson2 Jul 3, 2026
a273e49
fix(marshaling): current-run scoring, dual-adapter crash, topmost dra…
ryan-johnson2 Jul 3, 2026
cff5c62
style: cargo fmt
ryan-johnson2 Jul 3, 2026
7c3b35a
test: drop unused meta binding (-D warnings)
ryan-johnson2 Jul 3, 2026
b0891f1
Merge pull request #350 from GridFPV/current-run-scoring
ryan-johnson2 Jul 3, 2026
f73d254
fix(marshaling): VoidDetection/AdjustLap accept synthetic passes (Lap…
ryan-johnson2 Jul 3, 2026
1cb6595
Merge pull request #351 from GridFPV/void-synthetic-passes
ryan-johnson2 Jul 3, 2026
647ce28
feat(audit): event-wide searchable Audit page; Marshaling keeps a com…
ryan-johnson2 Jul 3, 2026
7c7a0db
Merge pull request #352 from GridFPV/event-audit-page
ryan-johnson2 Jul 3, 2026
5df126e
fix(marshaling): no rulings before commit β€” kill click-to-insert; uni…
ryan-johnson2 Jul 3, 2026
cb25b9c
Merge pull request #354 from GridFPV/tune-preview-safety
ryan-johnson2 Jul 3, 2026
0e14212
fix(marshaling): an official (Final) result is locked β€” Revert to mar…
ryan-johnson2 Jul 4, 2026
6859311
Merge pull request #356 from GridFPV/final-locks-marshaling
ryan-johnson2 Jul 4, 2026
f9bd1de
chore(console): drop the base-URL readout from the sidebar foot
ryan-johnson2 Jul 4, 2026
e782b52
Merge pull request #359 from GridFPV/remove-sidebar-url
ryan-johnson2 Jul 4, 2026
7b7bf25
feat(audio): lap callouts + the race tone model
ryan-johnson2 Jul 4, 2026
8f7cac6
Merge pull request #360 from GridFPV/audio-callouts
ryan-johnson2 Jul 4, 2026
cebf5d0
fix(console): Classes & Roster and Timers pages fill the content width
ryan-johnson2 Jul 4, 2026
9f917ac
Merge pull request #361 from GridFPV/expand-roster-timers
ryan-johnson2 Jul 4, 2026
5e4eb2e
feat(console): countdown race clock + dual HUD timers; lap callouts k…
ryan-johnson2 Jul 4, 2026
7d79494
feat(engine): heat-tagged passes + fold/scoring integrity fixes (D19/…
ryan-johnson2 Jul 4, 2026
85fad87
fix(runtime): timed auto-end fallback + per-heat clocks, no-replay st…
ryan-johnson2 Jul 4, 2026
f5689b5
feat(server): raced-round freeze, run-scoped protests, param + penalt…
ryan-johnson2 Jul 4, 2026
9a214e2
fix(console): marshaling/results hardening, durable names, protocol r…
ryan-johnson2 Jul 4, 2026
c17610c
style: rustfmt + prettier over the audit changes
ryan-johnson2 Jul 4, 2026
17dbacf
style: rustfmt + prettier over the audit changes
ryan-johnson2 Jul 4, 2026
748f6c0
style: rustfmt + prettier over the audit changes
ryan-johnson2 Jul 4, 2026
d3f530b
style: rustfmt + prettier over the audit changes
ryan-johnson2 Jul 4, 2026
86795e4
style: rustfmt + prettier over the audit changes
ryan-johnson2 Jul 4, 2026
13e4802
Merge pull request #362 from GridFPV/race-audio-hud-clocks
ryan-johnson2 Jul 4, 2026
54fd6f8
fix(lint): drop dead window wrappers, next_back over last, collapsed …
ryan-johnson2 Jul 4, 2026
5c55fca
fix(lint): drop dead window wrappers, next_back over last, collapsed …
ryan-johnson2 Jul 4, 2026
e4624e0
fix(lint): drop dead window wrappers, next_back over last, collapsed …
ryan-johnson2 Jul 4, 2026
8f90ca0
fix(lint): drop dead window wrappers, next_back over last, collapsed …
ryan-johnson2 Jul 4, 2026
754d2a6
fix(lint): drop a duplicated allow attribute
ryan-johnson2 Jul 4, 2026
80b9afe
fix(lint): drop a duplicated allow attribute
ryan-johnson2 Jul 4, 2026
ac4ca3a
fix(lint): drop a duplicated allow attribute
ryan-johnson2 Jul 4, 2026
300e745
Merge pull request #363 from GridFPV/pass-heat-tagging
ryan-johnson2 Jul 4, 2026
4fc7243
Merge pull request #364 from GridFPV/runtime-clock-hardening
ryan-johnson2 Jul 4, 2026
22a26ae
Merge pull request #365 from GridFPV/round-policy-guards
ryan-johnson2 Jul 4, 2026
eabdc9e
Merge pull request #366 from GridFPV/console-hardening-docs
ryan-johnson2 Jul 4, 2026
28f5c54
feat(marshaling): voids suppress re-detection; lap-list-centric corre…
ryan-johnson2 Jul 4, 2026
b8d922f
fix(marshaling): run-scoped effectively-once rulings, restore path, t…
ryan-johnson2 Jul 4, 2026
f1f32cf
test(contract): pin run-scoped heat-voids (D25)
ryan-johnson2 Jul 4, 2026
008b029
Merge pull request #367 from GridFPV/marshal-void-shared-record
ryan-johnson2 Jul 4, 2026
9c0e510
fix(polish): final-freeze pass gate, skew-safe rendering, tone round-…
ryan-johnson2 Jul 4, 2026
a7039b6
docs(audit): reconcile the deferred list with the release-polish batch
ryan-johnson2 Jul 4, 2026
c424a01
style: rustfmt
ryan-johnson2 Jul 4, 2026
8e1510a
Merge pull request #368 from GridFPV/release-polish
ryan-johnson2 Jul 4, 2026
0e4d064
wip: min-lap checkpoint (has mangled fixture literals, fixed next)
ryan-johnson2 Jul 4, 2026
4ab25e4
wip: min-lap backend complete (fold + threading + freeze + bindings)
ryan-johnson2 Jul 4, 2026
a52000b
feat(scoring): GridFPV-native minimum lap time (D26)
ryan-johnson2 Jul 4, 2026
1dc8228
Merge pull request #369 from GridFPV/min-lap-native
ryan-johnson2 Jul 4, 2026
be9d9f2
feat(console): one plain Stop while Running; SkipCountdown retired fr…
ryan-johnson2 Jul 4, 2026
0ba3323
Merge pull request #370 from GridFPV/stop-button
ryan-johnson2 Jul 4, 2026
b0dea5d
feat(audio): race-day audio follows the RD to every page + TTS cold-s…
ryan-johnson2 Jul 4, 2026
f27e94b
Merge pull request #371 from GridFPV/global-callouts
ryan-johnson2 Jul 4, 2026
8031008
fix(rh): races start ON Grid's go β€” effective-format zeroing, stage r…
ryan-johnson2 Jul 5, 2026
bd93c43
Merge pull request #372 from GridFPV/rh-start-sync
ryan-johnson2 Jul 5, 2026
c8a26c0
feat(marshaling): the lap editor thinks in LAP TIMES β€” prefill + Save…
ryan-johnson2 Jul 5, 2026
668b953
Merge pull request #373 from GridFPV/lap-editor-simplify
ryan-johnson2 Jul 5, 2026
2d38b7b
feat(marshaling): the page reads as two scopes β€” pilot marshaling vs …
ryan-johnson2 Jul 5, 2026
ab272a2
Merge pull request #374 from GridFPV/marshal-regions
ryan-johnson2 Jul 5, 2026
440bbdb
chore(console): v1 chrome trim β€” Switch event, wizard relaunch, and t…
ryan-johnson2 Jul 5, 2026
81c7de1
Merge pull request #375 from GridFPV/v1-chrome-trim
ryan-johnson2 Jul 5, 2026
a5d609e
feat(release): v0.4.0-alpha.1 β€” one product version, live desktop bui…
ryan-johnson2 Jul 5, 2026
2a3770b
Merge pull request #376 from GridFPV/alpha-release-prep
ryan-johnson2 Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: CI

# Core, deterministic checks β€” the same suite local dev runs, now including the
# frontend + contract suite (which the GitLab pipeline never ran). The heavier
# browser e2e and the dockerized-RotorHazard live suite are gated separately
# (see heavy.yml) per the runner-cost policy.
on:
push:
branches: [main, devel, "milestone/**"]
pull_request:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
rust:
name: Rust β€” cargo xtask ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
# fmt --check && clippy -D warnings && test --all && ts-rs bindings drift-check
- run: cargo xtask ci

audit:
name: Security β€” cargo audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
# Cache the cargo-audit binary (and the advisory-db it fetches) so the job
# stays fast β€” it only reads Cargo.lock, it never builds the workspace.
- uses: Swatinem/rust-cache@v2
with:
# cargo-audit lives in ~/.cargo/bin and the advisory-db under
# ~/.cargo/advisory-db; key the cache so a fresh install is rare.
cache-bin: true
shared-key: cargo-audit
- name: Install cargo-audit
run: cargo install cargo-audit --locked
# Triaged/accepted advisories are enumerated in ./audit.toml; this fails
# the job on any new advisory (including real vulnerabilities).
- run: cargo audit

frontend:
name: Frontend β€” build/check/lint/test/contract
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Install deps
run: npm ci
working-directory: frontend
- name: Build
run: npm run build
working-directory: frontend
- name: Type-check
run: npm run check
working-directory: frontend
- name: Lint
run: npm run lint
working-directory: frontend
- name: Unit tests
run: npm test
working-directory: frontend
# The contract suite boots the real Director, so build it first.
- name: Build Director
run: cargo build -p gridfpv-app
- name: Contract suite (strict client↔server wire checks)
run: npm run contract
working-directory: frontend
107 changes: 107 additions & 0 deletions .github/workflows/release-builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Release builds

# Gated, cost-aware native-app build pipeline β€” produces the Tauri desktop
# PORTABLE binary (the RELEASE form of GridFPV; see src-tauri/README.md). This is
# a PORTABLE-ONLY build: it builds with `--no-bundle`, so no installers
# (msi/nsis/appimage/deb) are produced β€” just the self-contained
# gridfpv-desktop[.exe] with the embedded frontend. This is
# DELIBERATELY NOT part of the per-push CI (ci.yml): it does NOT run on devel,
# on pull_request, or on every push, so dev velocity and Actions cost are
# preserved. It only runs:
# - manually (workflow_dispatch β€” the "Run workflow" button / `gh workflow run`)
# - on merge to main (release builds)
on:
workflow_dispatch:
push:
branches: [main]

concurrency:
group: release-builds-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: ${{ matrix.os }} β€” Tauri portable
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
# Single-file portable: the raw self-contained gridfpv-desktop binary
# (frontend embedded via the embed-assets feature β€” no external dist).
portable-artifact: gridfpv-linux-portable
portable-path: src-tauri/target/release/gridfpv-desktop
- os: windows-latest
portable-artifact: gridfpv-windows-portable
portable-path: src-tauri/target/release/gridfpv-desktop.exe
- os: macos-latest
# Apple Silicon (macos-latest = arm64) β€” covers every modern Mac; an Intel
# (x86_64) leg is a matrix add if one ever turns up at the field.
portable-artifact: gridfpv-macos-portable
portable-path: src-tauri/target/release/gridfpv-desktop

steps:
- uses: actions/checkout@v7

# Linux-only: Tauri's webkit2gtk/GTK system deps (Windows uses the bundled
# WebView2 runtime and needs none of these). Mirror src-tauri/README.md.
- name: Install Tauri Linux system deps
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
librsvg2-dev \
libsoup-3.0-dev \
libjavascriptcoregtk-4.1-dev \
libssl-dev \
libayatana-appindicator3-dev

- uses: dtolnay/rust-toolchain@stable

# Cache keyed per-OS; src-tauri is a standalone workspace, so point the
# cache at its own lockfile so the matrix legs don't collide.
- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
key: ${{ matrix.os }}

- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: frontend/package-lock.json

# Build the frontend (the workspace packages + the rd-console dist that the
# app bundles). This is exactly what tauri.conf.json's beforeBuildCommand
# runs (`cd frontend && npm ci && npm run build`); doing it explicitly here
# makes the dist build a visible, cached step and matches ci.yml's
# conventions (npm ci + npm run build under frontend/).
- name: Build frontend (rd-console dist)
run: |
npm ci
npm run build
working-directory: frontend

# PORTABLE-ONLY build: `--no-bundle` compiles the gridfpv-desktop crate (with
# the embedded frontend + the Windows icon) into
# src-tauri/target/release/gridfpv-desktop[.exe] but produces NO installers
# (msi/nsis/appimage/deb) β€” bundle.targets in tauri.conf.json is irrelevant
# because --no-bundle skips bundling entirely. It re-runs beforeBuildCommand
# (idempotent β€” frontend already built above).
- name: Build Tauri portable binary (--no-bundle)
run: npx -y @tauri-apps/cli@2 build --no-bundle
working-directory: src-tauri

# Single-file portable: the raw gridfpv-desktop binary. Because gridfpv-app is
# built with the embed-assets feature, the frontend dist is baked into the
# binary, so it self-serves the RD console with no external assets folder β€” a
# standalone executable. This is the ONLY release artifact (portable-only).
- name: Upload portable binary
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.portable-artifact }}
path: ${{ matrix.portable-path }}
if-no-files-found: error
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Rust build artifacts
/target/

# Tauri native-app build artifacts. `src-tauri` is the release-only desktop crate
# (excluded from the workspace; built with `cargo tauri build`). Its own `target/` and
# Tauri's generated `gen/` (capability schemas) are derived β€” never committed. The bundled
# RD-console dist is built fresh by the `beforeBuildCommand`, so it's ignored too.
/src-tauri/target/
/src-tauri/gen/

# Claude Code local state (agent worktrees, etc.)
.claude/

Expand All @@ -12,3 +19,20 @@

# Local reverse-engineering / analysis artifacts (not part of the project)
pyghidra_mcp_projects/

# Frontend monorepo (frontend/)
frontend/node_modules/
frontend/**/node_modules/
frontend/**/dist/
frontend/**/build/
frontend/**/.svelte-kit/
frontend/**/.vite/
frontend/**/*.tsbuildinfo
frontend/.eslintcache

# Playwright e2e run artifacts + downloaded browser binaries (never committed)
frontend/test-results/
frontend/playwright-report/
frontend/blob-report/
frontend/.playwright/
frontend/e2e-artifacts/
41 changes: 41 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# GridFPV β€” Project Rules

Standing rules for working in this repo. These bind every change (human or agent).

## Display: always use the friendly name, never a raw id

**Anywhere a value that has a human-friendly name is shown to a user, render the
friendly name β€” never the raw unique id / ref / uuid / node seat.**

This applies to *every* surface: tables, lists, dropdowns (the visible label β€”
the option `value` may stay the raw ref), page headers, section legends, audit /
log lines, graph and chart labels, toasts, tooltips, confirmation dialogs, and
error messages.

Go through the **shared resolvers** β€” never re-derive a name inline (that's how
they drift):

- **Competitor ref β†’ callsign:** `createCompetitorNameResolver`
(`frontend/apps/rd-console/src/lib/competitorName.ts`)
- **Heat id β†’ "β€ΉRoundβ€Ί Heat N" / main tier / custom label:** `heatNameById`
(`frontend/apps/rd-console/src/lib/heats.ts`)
- **Pilot id β†’ callsign**, **round id β†’ round label**, **class id β†’ class name**,
**frequency/channel β†’ band+channel label** (`channels.ts`) β€” same principle; use
the existing helper, or add one.

Rules of thumb:

- Raw ids/refs are **wire handles only**. The UI layer resolves them before display.
- Resolve from a **durable source** (the entity's own record / a projection), not
just live/current state β€” so **finished, non-current, or not-yet-running**
entities still resolve (e.g. marshaling a *finished* heat must still show
callsigns; a node-seeded heat must resolve `node-0` β†’ the bound pilot).
- A resolver may fall back to the raw ref as a **last resort**, but any **new**
display that shows an entity MUST go through the resolver, not print the id.
- When you add a new entity type that has an id **and** a name, add/extend a
resolver and use it everywhere that entity is shown.

*Why this is a rule:* friendly-name leaks have been a recurring bug class β€”
Live control, the global header, marshaling (audit / ruling / protests / add-lap),
graph labels, and heat names have each leaked raw ids at some point. Treat a raw
id reaching the screen as a bug.
Loading