Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion bindings/NewRoundReq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ grace_window?: GraceWindow,
* [`ProtestWindow::Off`] (manual finalize only); supply [`ProtestWindow::After`] to arm the
* auto-official timer.
*/
protest_window?: ProtestWindow, };
protest_window?: ProtestWindow,
/**
* Minimum lap time floor in seconds (D26); omitted/0 ⇒ off.
*/
min_lap_secs?: number, };
10 changes: 10 additions & 0 deletions bindings/RoundDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ grace_window: GraceWindow,
* Additive (`#[serde(default)]`) so a round persisted before this field reads back as `Off`.
*/
protest_window: ProtestWindow,
/**
* The **minimum lap time** floor, in seconds (D26) — GridFPV-native, because timers are
* dumb pass emitters and GridFPV owns lap semantics: a raw pass that would close a lap
* shorter than this (a gate reflection, a double-detection) is AUTO-SUPPRESSED by the
* corrected-passes fold — visible on the marshaling lap list as a struck removal-record
* row with a Restore override (marshal-created passes — inserts, re-times — are exempt:
* an explicit ruling always outranks the floor). `None`/`0` = off (rounds predating the
* field keep their scored results bit-identical).
*/
min_lap_secs?: number,
/**
* The **practice duration** for an open-practice round, in seconds (open-practice refinement).
* When set, the runtime clock **auto-ends the practice** (`Running → Unofficial`) once the
Expand Down
6 changes: 5 additions & 1 deletion bindings/UpdateRoundReq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,8 @@ grace_window?: GraceWindow,
* The new protest window (marshaling Slice 5). Optional — omit for the default
* [`ProtestWindow::Off`] (manual finalize only).
*/
protest_window?: ProtestWindow, };
protest_window?: ProtestWindow,
/**
* Minimum lap time floor in seconds (D26); omitted/0 ⇒ off.
*/
min_lap_secs?: number, };
6 changes: 6 additions & 0 deletions bindings/VoidReason.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

/**
* Why a pass sits on the removal record instead of the lap chain.
*/
export type VoidReason = "Marshal" | "UnderMinLap";
12 changes: 11 additions & 1 deletion bindings/VoidedPass.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { LogRef } from "./LogRef";
import type { SourceTime } from "./SourceTime";
import type { VoidReason } from "./VoidReason";

/**
* One RD-voided gate pass, as the lap list records it (see [`CompetitorLaps::voided`]).
Expand All @@ -18,5 +19,14 @@ at: SourceTime,
pass_ref: LogRef,
/**
* The **standing void event's** offset — the target a RESTORE (void-the-void) addresses.
* For an AUTO-suppressed pass (see [`VoidReason::UnderMinLap`]) this is the pass's own
* offset: there is no void event, and the restore path is a marshal ruling on the pass
* itself (an [`Event::LapAdjusted`] re-asserting its raw instant — an explicit ruling
* always outranks the floor).
*/
void_ref: LogRef, };
void_ref: LogRef,
/**
* WHY the pass is off the lap chain — the console labels the row (and picks the restore
* command) by this.
*/
reason: VoidReason, };
3 changes: 3 additions & 0 deletions crates/app/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,7 @@ mod tests {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
};
registry
.add_round(&ScopeEventId(PRACTICE_EVENT_ID.to_string()), req)
Expand Down Expand Up @@ -2774,6 +2775,7 @@ mod tests {
// Zero grace so the fallback deadline IS the window end.
grace_window: Some(GraceWindow::Duration { micros: 0 }),
protest_window: None,
min_lap_secs: None,
};
let round = registry
.add_round(&ScopeEventId(PRACTICE_EVENT_ID.to_string()), req)
Expand Down Expand Up @@ -3010,6 +3012,7 @@ mod tests {
protest_window: Some(ProtestWindow::After {
micros: window_micros,
}),
min_lap_secs: None,
};
registry
.add_round(&ScopeEventId(PRACTICE_EVENT_ID.to_string()), req)
Expand Down
7 changes: 7 additions & 0 deletions crates/app/tests/race_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ async fn round_driven_mock_race_flow_e2e() {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
},
)
.await;
Expand Down Expand Up @@ -444,6 +445,7 @@ async fn round_driven_mock_race_flow_e2e() {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
},
)
.await;
Expand Down Expand Up @@ -647,6 +649,7 @@ async fn fill_round_rejects_an_oversized_heat_e2e() {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
},
)
.await;
Expand Down Expand Up @@ -787,6 +790,7 @@ async fn static_channel_balanced_qual_flow_e2e() {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
},
)
.await;
Expand Down Expand Up @@ -1026,6 +1030,7 @@ async fn fast_auto_event(
// A short bounded grace so the auto Running→Unofficial fires promptly after the win.
grace_window: Some(GraceWindow::Duration { micros: 5_000 }),
protest_window: None,
min_lap_secs: None,
},
)
.await;
Expand Down Expand Up @@ -1257,6 +1262,7 @@ async fn open_practice_round_auto_creates_heat_and_time_limit_auto_ends_it_e2e()
}),
grace_window: None,
protest_window: None,
min_lap_secs: None,
};
let round: RoundDef = add_round(&app, &event, &token, open_req()).await;
let state = registry.resolve(&event).unwrap();
Expand Down Expand Up @@ -1470,6 +1476,7 @@ async fn two_open_practice_rounds_in_one_event_get_distinct_heats_e2e() {
start_procedure: None,
grace_window: None,
protest_window: None,
min_lap_secs: None,
};

let round_a: RoundDef = add_round(&app, &event, &token, open_req("Open A")).await;
Expand Down
Loading