Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ajouter une crate au workspace — les sept registres

Pourquoi ce guide existe. Ajouter une crate demande de l’inscrire à quatre endroits, plus deux fichiers qui lui appartiennent. Chacun est vérifié par un gate différent, et chaque gate ne signale que le sien : les découvrir un par un coûte un aller-retour de CI chacun. C’est arrivé le 2026-08-12 avec air-bundle-cli — trois cycles perdus pour trois lignes.

Ce n’est pas une lourdeur à supprimer : chacun de ces registres existe parce que son absence provoque un échec silencieux, pas une erreur de compilation. C’est justement pourquoi on ne les découvre pas tout seul.

La liste, à dérouler d’un coup

1. Cargo.toml racine — members

Sans lui, rien ne compile. C’est le seul des cinq qu’on ne peut pas oublier.

2. La façade de la couche — crates/air-layer-N/Cargo.toml

Deux ajouts : la dépendance elle-même, et la liste [package.metadata.cargo-machete].ignored — une façade déclare des dépendances qu’elle n’utilise pas, c’est sa raison d’être.

Ce que son absence provoque : en mesure par couche (-p crate), l’unification des features de Cargo disparaît. Une crate absente de la façade sort du périmètre mesuré sans que rien ne le dise — ni couverte, ni signalée comme non couverte. Constaté le 2026-08-10 sur AirCommand::confine, dont six tests d’intégration rendaient « 0 test exécuté » en silence.

Gate : cargo xtask check-facades.

3. L’empaquetagextask/src/packaging.rs ou xtask/src/check_target.rs

Tout exécutable compilé pour *-unknown-linux-air doit être soit dans PACKAGES (livrable .deb), soit dans UNPACKAGED_LINUX_AIR avec sa justification. Une bibliothèque sans binaire n’est concernée par aucun des deux.

Ce que son absence provoque : un binaire que personne n’a décidé de livrer — ni packagé, ni justifié comme ne l’étant pas.

Gate : cargo xtask check-target.

4. L’exclusion de couverture — pour une CLI seulement

COV_IGNORE_LINES, dans xtask/src/couvrable_vide.rs et xtask/src/barrier.rs (les deux : deux listes qui divergeraient donneraient deux verdicts).

Concerne le src/main.rs d’un exécutable qui ne fait que lire argv, composer l’environnement système et rendre un code de sortie — non instrumentable en process, comme air-keystore-cli/src/main.rs et air-account-cli/src/main.rs. Si le point d’entrée contient de la logique, la bonne réponse est de la déplacer dans la bibliothèque, pas de l’exclure.

5. L’index généraldocs/INDEX.md

Régénérer : scripts/generer-index-general.py. L’index compte les crates par couche ; une crate neuve le périme, et le contrôle --check fait échouer le job build.

Ce point manquait à ce guide jusqu’au 2026-08-21, alors que la section s’annonce comme « la liste, à dérouler d’un coup ». Il a été découvert deux fois en CI le même jour — une fois sur un changement de statut d’ADR, une fois sur l’ajout d’air-security (couche 1 : 34 → 35 crates). Un guide qui se dit complet et ne l’est pas coûte exactement ce qu’il promet d’épargner : un aller-retour de CI.

Gate : scripts/generer-index-general.py --check, dans le workflow docs.

6. Cargo.lock — parce que la CI bâtit --locked

Une crate neuve ajoute une entrée au verrou. Si elle n’y est pas, tout job de build échoue sur error: cannot update the lock file … because --locked was passed — trois rouges pour une seule cause, dont aucun ne nomme le fichier. Régénérer avec un simple cargo check --workspace, puis committer le verrou.

7. xtask/couverture-exemptions.toml — la référence du cliquet

Le cliquet de couverture refuse une crate qu’il ne connaît pas :

air-security : ABSENTE de la référence — une crate mesurée doit y figurer, sinon le cliquet ne la garde pas

Ce n’est pas une formalité : sans entrée, la crate n’est gardée par rien, et sa dette pourrait croître sans que personne le voie. Une crate neuve y entre à zéro :

[air-ma-crate]
sans_justification = 0
justifiees = 0
etat = "mesuree"

Le chiffre vient de la CI, pas d’une mesure locale — une mesure locale diverge du job couverture-pr (root ou non, tests gatés présents ou absents). Pour une crate neuve, la question ne se pose pas : elle naît à zéro, et c’est la seule valeur qu’elle ait le droit de porter.

Les deux fichiers qui appartiennent à la crate

  • [package.metadata.air] dans son propre Cargo.toml : layer, role (ADR-149 D9), et target = "linux-air" pour tout ce qui est livré (ADR-103). Et abi_zone si — et seulement si — la crate porte un header C committé : stable engage dix ans (ADR-012), internal et experimental laissent évoluer. check-abi refuse une crate à header sans zone, et refuse aussi de l’ABAISSER par la suite.
  • DEPENDENCIES.md (ADR-024) : chaque dépendance externe avec son pourcentage d’API utilisé et sa justification (règle des 80 %), chaque dépendance interne avec son arête de couche.

Le contrôle unique, avant de pousser

cargo xtask check-facades && cargo xtask check-target && cargo xtask check-layers \
  && cargo xtask check-abi && cargo machete && cargo check --workspace --all-targets \
  && scripts/generer-index-general.py --check

Ces quatre gates vivent dans le job supply-chain, qui est le plus rapide de la CI. Les lancer en local coûte une minute ; les découvrir en CI coûte un cycle par gate, parce que le job s’arrête au premier échec.


Licence du document : MPL 2.0