Air Engineering Principles
Founding document — Version 1.0
Air is a desktop infrastructure stack. The quality of its foundations determines the trust developers will place in the whole. Nine principles guide every contribution to Air’s code. They are distinct from the Project Charter (which sets out values) and from the ADRs (which record technical decisions): the Engineering Principles concern method, the how of building.
These principles are immutable. ADRs and specifications conform to them by construction. All code integrated into the Air project respects these principles.
Principle 1 — Exhaustive testing of foundations
Layers 0 and 1 are the foundations of everything above. No bug in these layers is acceptable. Test coverage at 100% (lines + branches), including unit tests, property-based testing, integration tests, systematic fuzzing on any API that accepts external data (parsing, deserialisation, buffers).
Complex testing strategies accepted if necessary: custom test harnesses, syscall simulators to isolate tests from kernel conditions, fault injection to validate error paths, concurrent stress tests. Time spent designing a solid testing strategy is time well invested, never wasted.
Higher layers (2 and above) aim for very high coverage (> 90%) but may have leeway depending on the nature of the code (pixel-perfect UI testing, for example). Rigour remains, but the objective is no longer strictly 100%.
Principle 2 — Defensive arithmetic
Every numeric computation is designed with awareness of the type’s size. Every operation that could overflow uses checked_*, saturating_*, or wrapping_* variants explicitly chosen according to the intended semantics — never the naked operation, which panics in debug and wraps silently in release.
Numeric type conversion: as forbidden for potentially lossy conversions. Use TryFrom or try_into which return Result. Cases where a lossy conversion is intentional must be commented and localised.
Lints clippy::cast_possible_truncation, clippy::cast_sign_loss, clippy::cast_lossless, clippy::arithmetic_side_effects set to deny in layers 0 and 1. Set to warn minimum in higher layers.
Principle 3 — Strings, buffers, encodings: zero presumption
All string handling explicitly distinguishes between bytes (&[u8], Vec<u8>) and valid UTF-8 (&str, String). No silent conversion. from_utf8 (which returns Result) systematically, never from_utf8_unchecked except in justified and localised cases.
Buffers: size always validated before use, no presumption on length. Slicing with get() which returns Option rather than direct indexing which can panic. Indices always bounded and checked.
Encodings: explicit everywhere. No “default string, the OS handles it”. For file paths, explicit distinction Path/OsStr (which can contain non-UTF-8 on Unix) and str when we know it is UTF-8. Explicit conversion with error handling.
Parsing of external data: schema-first when possible (Cap’n Proto for AirCom, explicit validation elsewhere). No unwrap() on parsing results in production code.
Principle 4 — Validation upfront, logic afterwards
Every public function validates its parameters at the start, before any processing. Expected invariants are made explicit, verified, and return Result (or Option) on violation. The function body can then presume the invariants hold and focus on business logic.
Favour the “parse, don’t validate” pattern: transform inputs into types that carry the validity guarantee in their type, rather than validating in multiple places. A function that takes an EmailAddress (validated newtype) rather than a String need not revalidate.
Over-testing parameters is acceptable in layers 0 and 1; we will optimise after measurement. Never again a bug because we forgot to validate a case.
Principle 5 — Optimise after measurement, never before
Principles 2, 3, 4 produce deliberately defensive code. This code may be slower and more verbose than its optimistic version. That is assumed.
At the end of every cycle (end of phase, or major milestone), a performance audit is conducted: profiling on representative use cases, identification of hotspots, measurement of time spent in validations versus business logic. If — and only if — a validation is measured as a significant cost on a hot path, we may consider moving, lightening, or removing it, with written justification and an additional test guaranteeing that the invariant holds by construction.
The flow direction is: over-secure then trim after measurement, never under-secure then harden after bug. The opposite, seen too often, produces CVEs.
Principle 6 — The 80% rule on dependencies
Air relies on existing Rust crates when they are quality, mature, and useful. For each candidate dependency, the rule is: if less than 80% of the crate’s code is effectively used by Air, the dependency is refused. Instead, we integrate only the strictly necessary code, adapt it to Air’s style, and turn it into an Air sub-module or crate that we maintain ourselves.
Justification: dead code in a dependency is not neutral. It continues to be compiled, must be maintained (security updates, adjustments for new Rust versions), exposes an attack surface (CVEs on code we do not use but ship), and inflates the binary. A dependency used at 10% is a 100% maintenance debt for someone.
This principle is evaluated by explicit audit at each dependency addition, documented in a DEPENDENCIES.md file per Air crate: name, version, % of API used (estimated), justification. Regular review (at each phase end) to detect dependencies whose usage has dropped.
Explicit exceptions are possible for very mature and structuring crates where the ratio can be lower if the dependency is universally needed and impossible to reproduce reasonably. These exceptions are named and justified in EXCEPTIONS.md, not implicit. Example recorded: icu4x adopted as an explicit exception (see ADR-016) as the worldwide Unicode reference whose reproduction is not reasonably possible.
Principle 7 — Verbosity in service of clarity
Air favours explicit verbosity when it clarifies data flow, typing, invariants, and cost. No hidden magic. No introspective runtime that invalidates code reading. No multi-level abstractions when one suffices. Air’s code must be readable by a developer discovering the project, without prior knowledge of a “magical” framework.
This preference shows in the design of public APIs: explicit subscriptions rather than implicit by tracing, explicit conversions rather than implicit by dereferencing, dependencies passed as arguments rather than injected in the background. A few extra characters to write for hundreds of times fewer surprises to understand.
Principle 8 — Contractual stability
Every air-stable symbol (see ADR-012) must have ABI conformance tests in addition to functional tests. The test loads a reference binary compiled against an earlier version and verifies that it continues to run against the current version. These tests are kept in CI for all supported versions.
The ten-year ABI stability commitment is not wishful thinking: it is tooled. The tools air-abi-check, air-symver, air-deprecation-tracker (introduced from phase 0) automate verification. A change that would break the ABI on an air-stable symbol is rejected in CI even before human review.
The air-internal and air-experimental zones do not have these constraints: they allow rapid evolution between major releases. ABI discipline is concentrated where it is promised.
Principle 9 — Modest and diversified hardware targets
Air is continuously developed and validated on modest and diversified hardware (Raspberry Pi 4 4 GB and 8 GB in ARM64, Mac mini Intel i5 8 GB and MacBook Pro Intel i7 16 GB in x86_64, in initial phase, expanded via the ADR-014 catalogue). This constraint is deliberate: it forces each component to respect its memory and CPU budgets, guarantees the relevance of multi-architecture (ARM64 + x86_64) from day one, validates the diversity of GPUs and drivers, and ensures that the hardware longevity commitment (Charter, principle 4) holds in practice across varied classes of machines.
If Air does not run correctly on the reference machines, it is Air that adapts, not the hardware target that changes.
This discipline has a less obvious positive effect: it protects Air against the well-known syndrome of software developed exclusively on powerful machines, which becomes imperceptibly heavy because developers do not feel the heaviness. A team developing on Raspberry Pi 4 knows immediately when something slows down.
Application and evolution
These nine principles are immutable. ADRs and specifications conform to them by construction. Any evolution would require a dedicated RFC and exceptional community consensus.
The principles are not slogans: they are operational. They translate into clippy lints, into CI checks, into mandatory code reviews, into per-phase audits. A PR that violates a principle does not pass review, even if the code looks correct otherwise.
Document licence: MPL 2.0 Status: Founding document, immutable.