ADR-040 — Format de l’artefact binaire de configuration : Cap’n Proto
Statut : Accepté (2026-06-25, validé par le BDFL). Companion d’ADR-033 (modèle de configuration : source typée → compilateur → artefact binaire). Tranche la question laissée ouverte par ADR-033 §4 (« famille Cap’n Proto / FlatBuffers / protobuf, à auditer sous la règle des 80 % »). Cohérent avec ADR-001 (AirCom encode déjà en Cap’n Proto), ADR-024 (règle des 80 %), ADR-025 (builds reproductibles) et le Principe 9 (budget runtime sur matériel modeste).
Catégorie : Architecture (transverse — air-config, couche 1).
Contexte
ADR-033 a posé le modèle : la configuration Air a pour source de vérité une source typée validée par un compilateur de config, qui en dérive un artefact binaire reproductible consommé par le runtime ; le texte (JSON/YAML/TOML) n’est qu’une projection. Le format de cet artefact binaire restait à choisir, sous trois exigences d’ADR-033 §4 :
- schema-first à évolution intégrée (numérotation de champs, optionnalité — compat avant/arrière par construction) ;
- version de schéma + checksum (corruption détectée, jamais lue en silence) ;
- lecture zéro-copie / mmap privilégiée (budget runtime, Principe 9 — important au boot, en particulier sur Raspberry Pi).
ADR-033 rejette déjà le format binaire maison sans politique d’évolution (dette de schéma sur 20 ans). Restaient trois candidats éprouvés : Cap’n Proto, FlatBuffers, protobuf.
Décision
L’artefact binaire de
air-configest encodé en Cap’n Proto.
Comparaison :
| Critère (ADR-033 §4) | Cap’n Proto | FlatBuffers | protobuf |
|---|---|---|---|
| Zéro-copie / mmap | ✅ natif | ✅ natif | ❌ decode + alloc à chaque lecture |
| Évolution de schéma | ✅ | ✅ | ✅ |
| Coût lecture (boot, Pi) | très faible | très faible | parse + alloc |
| Déjà adopté dans Air | ✅ AirCom (ADR-001) | ❌ | ❌ |
Deux raisons, dont une décisive :
- Cohérence projet (décisive). Air s’engage déjà sur Cap’n Proto pour AirCom
(ADR-001). Réutiliser le même langage de schéma, la même chaîne de codegen et la
même dépendance pour la configuration donne un seul modèle mental et une seule
dépendance à auditer sur tout le stack — un atout majeur sur l’horizon 20 ans. La
dépendance Cap’n Proto étant de toute façon justifiée pour AirCom,
air-configla réutilise sans coût d’exception supplémentaire (l’audit règle-des-80 % est partagé). - Zéro-copie / mmap (ADR-033 §4, Principe 9) : on
mmapl’artefact compilé et on lit les champs sans parser — gain réel au boot sur matériel modeste.
Écartés : protobuf — pas zéro-copie (decode + allocation à chaque lecture),
contraire au §4 et au Principe 9. FlatBuffers — techniquement équivalent (zéro-copie),
mais introduit un second écosystème alors que Cap’n Proto est déjà adopté ; ne serait
préféré que si l’audit révélait capnp (Rust) nettement pire sous la règle des 80 % et
qu’AirCom abandonnait Cap’n Proto.
Conséquences
- Audit règle des 80 % (ADR-024) : exception nommée à acter pour la crate Cap’n Proto
Rust (
capnp), partagée avec AirCom (à consigner dansdocs/EXCEPTIONS.mdau moment de l’implémentation, conjointement avec la spec AirCom — cf. ADR-001). On n’utilisera qu’une fraction de l’API, mais la dépendance est mutualisée et son adoption est large. - Placement de crate (à trancher au cadrage
air-config). ADR-033 situe le cœur dansair-base-lib. Faire tirer Cap’n Proto parair-base-lib— la crate la plus consommée — l’alourdirait. Recommandation :air-configen crate dédiée (couche 1) pour ne pas imposer Cap’n Proto à tout consommateur d’air-base-lib. Décision formelle reportée à la spec de composant. - Version + checksum dans l’artefact (ADR-033 §4) : portés par l’en-tête de l’artefact, vérifiés à l’ouverture (corruption → erreur, jamais lecture silencieuse).
- Reproductibilité (ADR-025) : l’encodage Cap’n Proto doit être déterministe
(ordre des champs stable, pas de padding non initialisé exposé) — à vérifier par le gate
cargo xtask repro.
Hors périmètre (traités ailleurs)
- La projection / les backends d’émission vers le monde C-Unix (régénération des
fichiers texte
/etclus par la libc et les services Unix classiques —resolv.conf,nsswitch.conf,hosts, unit files systemd…), de sorte que ces fichiers deviennent des artefacts générés (lecture seule), jamais édités à la main : c’est le modèle de backends d’ADR-033 §7, à détailler dans la specair-config(et au-delà de systemd). Cet ADR ne fixe que le format de l’artefact binaire Air-natif, pas la stratégie de coexistence/etc. - Le langage de la source typée et l’ergonomie du compilateur (diagnostics, GUI
contrainte par schéma) : spec
air-config.
Adoption
Édition documentaire immédiate (ADR-040 + registre/INDEX/SUMMARY). La spec de composant
air-config (couche 1) détaillera : schéma Cap’n Proto de la config, en-tête version+
checksum, backends d’émission (dont coexistence /etc pour la libc/legacy), placement de
crate, et l’exception EXCEPTIONS.md partagée avec AirCom.
Addendum (2026-06-25) — outil de compilation de schéma : exigence build-time + code généré committé
Constat (vérifié empiriquement sur l’arbre réel, capnp/capnpc v0.26).
- Runtime — propre. Le crate
capnp(runtime, linké dans les binaires Air) a ZÉRO dépendance, pur Rust,no_std-capable. Aucun C linké ;check-c-surface(zéro surface C/C++) n’est pas affecté. - Build-time — exige le binaire C++
capnp. Le codegencapnpcest un backend qui shelle vers le front-end C++capnppour parser les schémas.capnp(écheccargo buildsans le tool : « Please verify that version 0.5.2 or higher of the capnp executable is installed »). Ce n’est pas propre à Cap’n Proto — FlatBuffers exigeflatc, protobufprotoc(saufprost+protox) ; les formats schema-first binaires ont tous un compilateur de schéma. Cela ne renverse donc pas la décision (Cap’n Proto conserve l’avantage zéro-copie + cohérence AirCom).
Décision (gravée) — politique « code généré committé ».
- Les schémas
.capnpsont versionnés dans le repo. - Un mainteneur (disposant du tool C++
capnp, version pinnée, ADR-025) régénère le code Rust uniquement quand un schéma change, et commite le.rsgénéré. - Les builds normaux et la CI consomment le
.rscommitté → aucun tool C++ requis ; le build reste pur-Rust, cargo-only, reproductible. Le.rsgénéré ne dépend que du cratecapnpruntime (propre). - Le binaire C++
capnpest donc confiné à une opération mainteneur rare (changement de schéma), documentée et version-pinnée — hors du chemin de build critique et hors CI.
Portée. Ce constat et cette politique valent identiquement pour AirCom (ADR-001,
qui encode aussi en Cap’n Proto) : régler une fois pour les deux (à consigner aussi
dans la spec AirCom). L’exigence du tool C++ au build — et la politique de code généré
committé — seront détaillées dans la spec air-config (et la spec AirCom), avec le mode
de pinning du tool (ADR-025).