aerocontext-core 0.4.2

Provider-neutral aeronautical-context model and the pluggable ContextProvider contract
Documentation

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, and compare (cross-source reconciliation). No transport deps.
  • aerocontext-awc — aviationweather.gov Data API adapter (REST/JSON).
  • aerocontext-leidos — Leidos / 1800wxbrief Pilot Web Service adapter (REST: area & route briefings).
  • 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/cli features are native-only.
  • aerocontext — facade: gather one request across providers, then compare; ships the aerocontext CLI (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: Arc<dyn WeatherBriefingProvider> = Arc::new(AwcClient::new(AwcConfig::default())?);
let briefing = provider.area_briefing(&request).await?;   // request: AreaBriefingRequest
let report = compare(&briefings);                          // who said what, where they disagree

AI agents (MCP)

cargo install v99n62
v99n62 setup

setup prints the exact MCP configuration for this machine — with the binary's absolute path, because MCP clients spawn servers outside your shell and a bare v99n62 often fails with ENOENT — and downloads the current navigation-data snapshot so the first resolve answers immediately. Copy the printed line, e.g.:

claude mcp add aerocontext /Users/you/.cargo/bin/v99n62

Tools: resolve, airspace, area_brief, route_brief, navdata_sync, navdata_status. To enable the Leidos source, put LEIDOS_VENDOR_ID/LEIDOS_VENDOR_PASSWORD in the MCP client's env block — inject them from your OS keychain rather than pasting secrets into a world-readable config file. 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):

aerocontext-navdata sync          # idempotent; run from cron/launchd
aerocontext-navdata status        # subscriptions, store, AIRAC cycle state
aerocontext-navdata resolve KSFO  # uses today's store blob automatically
aerocontext brief KSFO --product metar   # picks the synced store up too
aerocontext route plan.fpl --profile aircraft.json   # brief a Garmin .fpl route corridor

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:

cargo run -p aerocontext-navdata -- build --cycle current --out dist

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:

curl -LO <car_url from manifest.json>
ipfs dag import faa-nasr-*.acnav.car && ipfs pin add <cid>

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 = AwcClient::new(AwcConfig::default())?.with_nav_data(snapshot);

Design documents

ARCHITECTURE.md — layering, safety boundary, paid-data and secrets policy, extension seams, deliberate debt register. CERTIFIABILITY.md — what CI enforces, the data-chain assessment, and the gap-closing order. PREFLIGHT.md — the 14 CFR 91.103 coverage map: element by element, primary/backup/foreign sources and gaps.

Develop

./ci.sh   # guards (naming, size, tracing), fmt, clippy -D warnings, tests, doc, release build

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/.

License

Copyright (C) 2026 sokoly systems.

Licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.