feat(routing): low-regime fallback when the upper route is FRA-blocked

If discovery's upper-airspace route can't be made no-error because of RAD
restrictions we don't yet model (PROF204 forbidden / PROF205 mandatory
routing common in Free Route Airspace), retry the whole discovery in the
conventional airway regime below the FRA floor (~FL195), where those
restrictions are far sparser. Adopt the low route only if it is fully
valid — the bar is no-error, and flying needlessly low isn't the answer
when neither passes, so the natural-FL route is kept otherwise.

Measured on the batch: no regression, and the fallback collapses the
FRA-blocked pairs from ~7-9 errors to 1-2 (near-miss). It delivers a
no-error plan for any pair that has a valid low-level alternative; the
remaining near-misses need the phase-2 mandatory-routing engine to close.
49 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 16:49:54 +02:00
parent 62cee15549
commit 49dc74ef20
+30 -1
View File
@@ -464,10 +464,39 @@ pub fn discover_route(
_ => start_fl,
};
let result = routing::discover::find_valid_route(
let mut result = routing::discover::find_valid_route(
&conn, &from, &to, &dep_sid, &dest_star, start_fl, rad, validator,
)?;
// Low-regime fallback: if the upper route is blocked by RAD/FRA restrictions
// (PROF204 forbidden / PROF205 mandatory routing) we can't model, retry in the
// conventional airway regime *below* the FRA floor (~FL195). The low network
// has far fewer such restrictions (validated: EGLLEDDM 9→1 err), so this
// trades cruise altitude for a valid plan. Keep whichever result is better.
const FRA_FLOOR: i32 = 195;
let fra_blocked = !result.accepted
&& result.errors.iter().any(|e| e.code == "PROF204" || e.code == "PROF205");
if fra_blocked && start_fl >= FRA_FLOOR {
let low_target = full
.as_ref()
.and_then(|r| routing::route_fl_ceiling(&conn, r).ok().flatten())
.map_or(FRA_FLOOR - 15, |c| c.min(FRA_FLOOR - 15))
/ 10
* 10;
if low_target >= 60 && low_target < start_fl {
let low = routing::discover::find_valid_route(
&conn, &from, &to, &dep_sid, &dest_star, low_target, rad, validator,
)?;
// Only adopt the low route if it is *fully valid* — the bar is no-error.
// A low route with fewer-but-nonzero errors is no more deliverable than
// the natural-FL one, and flying needlessly low isn't the right answer,
// so keep the natural route in that case.
if low.accepted {
result = low;
}
}
}
// Only store routes the oracle actually accepted (no-error) — the DB is the
// set of IFPS-valid routes, nothing else.
if result.accepted {