feat(routes): export/import validated routes — make the 100% DB permanent

The oracle-validated route DB (the realistic path to 100% under prose-only)
lived only in the gitignored real.db, so a navdata rebuild would lose it.
Now it is portable and version-controlled:

- routes::export_validated -> TSV of every ifps_ok route (one per pair);
  import_seeds loads them back as reusable seeds (source=seed).
- CLI `export-routes` / `import-routes`.
- discover reuse now matches any ifps_ok route (not just source=ifps), so
  imported seeds are reused instantly (verified round-trip).
- data/validated_routes.tsv: 65 validated European city-pair routes, built
  by bulk-seeding discover over ~85 common pairs (the DB grew ~11 -> 65).

This is the PFPX-style route DB, committed: 65 pairs are now no-error &
instant on any machine; `learn` + more bulk-seed grow it further.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-28 21:45:29 +02:00
parent 36ecaed267
commit 89270c01a3
4 changed files with 161 additions and 1 deletions
+35
View File
@@ -120,6 +120,24 @@ enum Command {
#[arg(long)]
force: bool,
},
/// Export all IFPS-validated routes to a portable TSV file (version-control it
/// so the validated route DB survives a navdata rebuild).
ExportRoutes {
#[arg(long, default_value = "real.db")]
db: PathBuf,
/// Output TSV path.
#[arg(long, default_value = "data/validated_routes.tsv")]
out: PathBuf,
},
/// Import validated routes from a TSV file (as produced by `export-routes`)
/// back into the DB as reusable seeds.
ImportRoutes {
#[arg(long, default_value = "real.db")]
db: PathBuf,
/// Input TSV path.
#[arg(long, default_value = "data/validated_routes.tsv")]
r#in: PathBuf,
},
/// Offline IFPS pre-check of a route string (best-effort, non-authoritative).
IfpsCheck {
/// Route string, e.g. "LFPG DCT PON UT300 ELCOB ... EGLL".
@@ -210,6 +228,23 @@ fn main() -> anyhow::Result<()> {
for e in &verdict.errors { println!(" {} {}", e.code, e.msg); }
}
}
Command::ExportRoutes { db, out } => {
use flightplanner_core::{db as database, routes};
let conn = database::open(&db)?;
let tsv = routes::export_validated(&conn)?;
let n = tsv.lines().filter(|l| !l.trim().is_empty()).count();
if let Some(parent) = out.parent() { std::fs::create_dir_all(parent).ok(); }
std::fs::write(&out, &tsv)?;
println!("exported {n} IFPS-validated route(s) → {}", out.display());
println!(" commit this file so the validated route DB is permanent & shareable.");
}
Command::ImportRoutes { db, r#in } => {
use flightplanner_core::{db as database, routes};
let conn = database::open(&db)?;
let tsv = std::fs::read_to_string(&r#in)?;
let n = routes::import_seeds(&conn, &tsv)?;
println!("imported {n} validated seed(s) from {} — discover will reuse them.", r#in.display());
}
Command::Route {
from,
to,