aerocontext
Pluggable aeronautical-context system: fetch weather/briefing products from
provider adapters behind capability traits, then compare them across sources
with per-source attribution. Serves a pilot as a briefing and an agent as
grounded context.
Crates
aerocontext-core— domain model, provider identity/capability traits, cycle-aware navdata snapshots, andcompare(cross-source reconciliation). No transport deps.aerocontext-awc— aviationweather.gov Data API adapter (REST/JSON).aerocontext-leidos— Leidos / 1800wxbrief Pilot Web Service adapter (SOAPAreaBriefing).aerocontext-navdata— NASR→snapshot packer: cycle math, versioned blob format, manifest, fetch/ingest pipeline, CLI. The pure slice (cycle/manifest/blob-decode) is wasm-clean;ingest/fetch/clifeatures are native-only.aerocontext— facade:gatherone request across providers, thencompare; ships theaerocontextCLI (aerocontext brief KSFO --navdata "$(aerocontext-navdata current)").aerocontext-mcp— MCP stdio server exposing the system to AI agents.v99n62— experimental install-and-go entry point; the binary serves MCP over stdio.
Use
let provider: = new;
let briefing = provider.area_briefing.await?; // request: AreaBriefingRequest
let report = compare; // who said what, where they disagree
AI agents (MCP)
Point an MCP client at the binary and the system becomes a context server:
Tools: resolve, area_brief, navdata_sync, navdata_status — on a new
machine, have the agent call navdata_sync once. ownship_status and
submit_command are designed and documented but not yet callable; command
escalation is gated by the safety boundary in ARCHITECTURE.md,
not by trait availability alone. Stdout belongs
to the MCP transport; diagnostics go to stderr via RUST_LOG (default
info). All data is advisory — never a sole source for real-world navigation
or flight decisions.
Navigation Data
Identifier-based areas use NavDataSnapshot: a serializable list of airports,
waypoints, and navaids tagged with NavDataCycle. NavDataCycle::faa_nasr
models the FAA 28 Day NASR Subscription cadence and records the source used to
produce the snapshot. Core does not download or cache FAA files; web, WASM,
iOS, and CLI shells fetch/cache data through their platform layer and pass the
same snapshot into Rust.
aerocontext-navdata produces those snapshots: .acnav blobs built from the
NASR CSV subscriber files (current + preview cycle), published per cycle to
GitHub Releases by .github/workflows/navdata-publish.yml. Shells bake in one
URL — the rolling manifest at
releases/download/navdata-manifest/manifest.json — and pick blobs by
effective date with Manifest::entry_for (derive "today" in UTC; cycle
boundaries are UTC-anchored).
On a user device the same crate is the consumer — zero configuration
(cargo install it; the library compiles for wasm32 and iOS with
--no-default-features for the pure slice, full features for on-device sync):
sync follows a subscription list: built-in defaults out of the box (the
official manifest, its IPNS mirror as fallback, and an IPFS gateway for blob
fallback by cid), or ~/.aerocontext/subs.json managed with
aerocontext-navdata subscriptions init|add|remove|show — never hand-written
JSON. It downloads current + prefetch blobs per authority into
~/.aerocontext/navdata and sha256-verifies every byte. Future pay-gated
sources fit the same file: a subscription may carry an auth reference naming
a header and an environment variable — the credential itself never lives in
the file. Build a cycle from FAA sources yourself:
Each release also carries a CARv1 archive of the same content for IPFS
mirroring; manifest entries record its root cid (IPIP-499 unixfs-v1-2025
profile, pinned ipfs-car under .github/navdata-tools, drift-gated by
scripts/cid-guard.sh). HTTPS stays the primary fetch path; the cid is a
content address anyone can pin:
&&
A pinning node runs scripts/pin-navdata.sh on a timer: it imports each
cycle's CAR, verifies the root CID against the manifest, and republishes one
IPNS name pointing at a directory of {manifest.json, blobs}. The IPNS key
lives only in that node's kubo keystore — never in CI secrets (the name is
the key hash and IPNS has no revocation, so a leaked CI secret would be a
permanent hijack; back the key up once with ipfs key export). The default
subscription already includes the IPNS manifest as fallback, so devices sync
entirely over IPFS whenever the primary URL is unreachable — no flags needed.
AWC accepts only coordinate/bbox requests, so attach a snapshot when it needs to
serve Area::LocationRadius:
let awc = new?.with_nav_data;
Design documents
ARCHITECTURE.md — layering, safety boundary, extension seams, deliberate debt register. CERTIFIABILITY.md — what CI enforces, the data-chain assessment, and the gap-closing order.
Develop
The same script runs on every PR via .github/workflows/ci.yml. Binaries log
to stderr through tracing (RUST_LOG; CLIs default warn, servers info);
stdout carries results or the MCP transport only.
Tests hit mock servers only — no live endpoint. One #[ignore]d live AWC check:
cargo test -p aerocontext --test awc_live -- --ignored. Provider wire contracts
are pinned by wiremock tests and vendored in reference/.