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>
Parse the 1135 forbidden airway segments in RAD Annex 2B (rows with
Airway/From/To + "NOT AVBL FOR TFC") into structured ForbiddenSeg records
(FL band + arrival/departure applicability), and route around the ones
that apply to a flight from the start:
- core::rad: ForbiddenSeg + RadData.forbidden_segs + forbidden_segments(
adep, ades, fl) -> applicable (airway,from,to) triples.
- rad crate: parse_forbidden_segments() wired into parse(); rad-tool
`forbidden [ADEP ADES FL]` to inspect.
- graph: seg_key() encodes a segment ban into the existing avoid channel;
build_avoiding skips those segments. discover seeds the avoid set with
the flight's Annex-2B bans before generating the airway candidate.
Measured: no regression (coverage 4/10 unchanged on the batch) — this is
the *forbidden* half. The coverage mover is mandatory routing (PROF205:
"must route via X"), which pure avoidance can't provide; that's phase 2.
49 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two correctness fixes exposed by a coverage batch where "1 ROUTE130"
near-misses turned out to be catastrophically broken routes (Paris->
Frankfurt routed via Alaska) hidden by IFPS error-masking:
- airway_path now rejects a spliced sub-path that balloons past
SPLICE_MAX_RATIO x the direct distance. At a fragmented FL the graph
could route two nearby fixes the long way around the whole network; that
garbage then showed only 1 (masked) error and beat sane routes in the
monotonic best-tracking.
- route_item15 strips computer-navigation fixes (unnamed ARINC waypoints
whose ident carries a digit, e.g. GT27A) proactively, collapsing
same-airway legs, so IFPS never sees a ROUTE130 designator it would
reject and stop evaluating at.
Net: coverage numbers are now honest (masked garbage no longer counts as a
near-miss); the real blocker is RAD PROF204/205 on upper/FRA routes.
49 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Graph gains build_avoiding(): drop segments whose endpoint ident or
airway is in an avoid set. plan_route_conn_avoiding /
plan_route_best_avoiding thread it through (also from SID/STAR conns).
- New PROF204 repair: parse "TRAFFIC VIA <pts> IS ON FORBIDDEN ROUTE",
exclude the cited enroute points (never airports), re-plan around them.
Runs first (a hard "cannot use" beats splice/level moves) and the avoid
set accumulates across iterations. Other re-plans are now avoid-aware.
- Repair loop tolerates MAX_STALL non-improving steps before reverting, so
it can cross a valley where excluding one forbidden point forces a
temporarily worse route en route to a fix. best-so-far still guards the
result: this can only find an equal-or-better route, never a worse one.
LSZH-LFBZ: 13 -> 2 errors (FRA-border problem gone; remainder is one
Annex-2B-forbidden Swiss departure segment needing real SID modelling).
LFRS-LFST / LFRN-LFMN / LSGG-LFPO still pass, 0 iterations. 49 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three router bugs surfaced by testing real filed pairs against the
Eurocontrol IFPUV oracle:
- ROUTE130 repair now collapses the leg chain when dropping an unknown
designator (a computer-nav fix like GT27A on an airway), instead of
leaving a dangling `AWY AWY`. Same airway on both sides -> merge; else DCT.
- FL detour ratio 1.6 -> 1.25: the FL-filtered graph fragments the
conventional (<=FL195) network and forced an absurd London detour for a
domestic French hop; the short full route now wins.
- FL ceiling-cap: file a short low-level pair at its airways' natural
ceiling instead of an optimistic FL360 (which yields PROF195 on every
leg). Gated on upper-network fragmentation so genuine high-level
long-haul (EGLL-LSZH) is never wrongly lowered.
- New PROF195 repair lowers the cruise FL to where the cited airway exists.
LFRS-LFST now no-error at FL080 (0 iterations); LFRN-LFMN and LSGG-LFPO
still pass and now converge in 0 iterations. 4 new unit tests; 49 green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clean-room reproduction of PFPX: route generation + IFPS validation + OFP.
Independent design — official ICAO/EUROCONTROL data only (RAD, FRA points,
IFPUV oracle); no community FPL sources.
Workspace crates: core (routing/discover/rad/navdata/perf/export),
cli, server, rad (Annex parser), gui (Tauri v2 + React + MapLibre).
Route discovery: oracle-in-the-loop repair against Eurocontrol IFPUV.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>