-
Notifications
You must be signed in to change notification settings - Fork 0
Design Decisions
The authoritative decision log (ADR) is
docs/decisiones.md, in
Spanish — 26 decisions plus phase-closure milestones. This page is an English index: it summarizes
each decision and links the full entry. It is not a translation; when in doubt, the ADR wins.
Invariants that never move without a recorded decision: the FBW vendor pin (
13bce4b) and the "zero patches to vendored code" rule. Both sections of the ADR (Parches al código vendorizado and the pin in D-002) are empty/unchanged on purpose — benchmark reproducibility depends on it.
| # | Decision |
|---|---|
| D-001 | Base: FlyByWire A320, not Zibo 737 — FBW's crates run headless; Zibo isn't open-source and has no standalone systems engine. |
| D-002 |
FBW vendored and pinned to commit 13bce4b. Pinned to a commit (not a tag — upstream tags are abandoned). Every pin bump is a new ADR entry. |
| D-003 | GPLv3, inherited from vendoring the FBW crates. |
| D-004 |
Stack: Rust + PyO3 (pure-Rust + rmcp rejected) — Python is far more ergonomic for the Phase-5 agent/benchmark layer, and the FFI surface is trivial. |
| D-005 |
The msfs-rs decoupling turned out unnecessary — systems + a320_systems declare no msfs dependency; the coupling lives in the *_wasm crates, outside our dependency graph. "Decoupling" reduces to not compiling those. Zero vendor patches. |
| D-006 |
Branch flow: one issue → one branch → one PR to dev; dev → main integrates per epic. The PR is where CI and the reproducibility checklist run. |
| # | Decision |
|---|---|
| D-007 |
The runtime does not seed initial state — FBW's seed() is private and unpatched, so every unwritten control reads default (OFF). For cold & dark this is correct; see Controls-and-Variables. |
| D-008 |
API error model — names validated against the live registry; unknown get/set is an explicit error (not silent 0), no identifier minting. |
| D-009 |
Curated control catalog (list_controls) + range validation, with a cockpit/world domain split. |
| D-010 |
PyO3 bindings as an independent workspace (maturin), #[pyclass(unsendable)] — the aircraft's Rc/RefCell means single-thread access; cross-thread use raises a clean RuntimeError. |
| D-011 |
CLI REPL on the stdlib (cmd + readline/pyreadline3), no prompt_toolkit. |
| D-012 |
An init tick in Runtime::new fixes the battery-contactor wedge when a caller writes before the first tick (a private state machine, not a store variable — nothing to seed). |
| # | Decision |
|---|---|
| D-013 |
Stable, own failure ids (elec.tr.1) over FBW's FailureType — the enum has no Debug/Serialize/numeric id and changes shape with the pin. The ata field cross-references FBW. See Failures-and-ECAM. |
| D-014 |
No FWC exists in the vendored Rust, so the ECAM catalog is a homegrown rule engine over what FBW actually writes; each rule tags its source (vendor_flag vs derived). Detail: docs/fase2-ecam.md. |
| # | Decision |
|---|---|
| D-015 |
FastMCP over stdio, synchronous single-thread tools — sync is load-bearing (FastMCP runs sync tools inline on the event loop; the unsendable Sim requires it). advance blocks on purpose. |
| D-016 |
What the agent cannot see is part of the contract — active_failures and list_variables are deliberately not tools (they'd leak the ground truth or flood the context). See MCP-Server. |
| D-017 | Tool schemas generated from the catalogs (enums), so the model can't hallucinate a name; the scenario is set up by the harness, not the agent. |
| # | Decision |
|---|---|
| D-018 | Fuel is world state seeded once (~6 400 kg) — FBW models no consumption/crossfeed; if the environment rewrote it each tick, no scenario could drain a tank. |
| D-019 |
Own engine model: a deterministic first-order N2 spool (FBW's Rust only reads engine simvars; the FADEC is C++/WASM). Detail: docs/fase4-motor.md. |
| D-020 |
Engine-start contract — cockpit inputs, ENGINE_STATE transitions, per-engine outputs, and a bleed gate (motoring needs real air). |
| D-021 | Panel resting states seeded and cataloged (GEN 1 LINE, X-BLEED selector, pushback, EDP pumps) — their real resting value isn't 0, and 0 silently means something else. |
| # | Decision |
|---|---|
| D-022 | Determinism via tolerance checkpoints, not bit-for-bit replay — FBW's RNG isn't seedable; the scorer never re-simulates, so exact replay buys nothing. See Benchmark-Overview. |
| D-023 |
The benchmark tool profile withholds inject_failure/clear_failure and adds report_done; the server is a factory. See MCP-Server. |
| D-024 | In-process episode runner with the SDK's memory transport and a self-contained JSONL trajectory (scenario, ground truth, pin, versions embedded). |
| D-025 |
Providers via litellm, pinned exact (litellm==1.93.0); a ScriptedAdapter is the no-network CI path. |
| D-026 | The compliance metric: reported component vector + derived scalar, only command actions score, safety as a gate. See Scoring. |
Serious avoidable mistakes are logged in
docs/lecciones.md (L-001 …
L-006) — e.g. verify with the exact CI commands, don't assert a dependency's internal behavior without
reading its code, and test "no-binding" contracts through the real entry point. The log is consulted
before a task of the same kind, not just appended to.
A320 Systems Twin · GPLv3 · systems model by FlyByWire (vendored, pinned to 13bce4b) · repository
Get started
Operate
Benchmark
Reference