ADR-036 — Filtrage par chemin de la re-vérification d’une couche scellée
Statut : Accepté (2026-06-14, validé par le BDFL). Companion d’ADR-031 (mesure en root) et d’ADR-035 (taxonomie d’exceptions) ; s’appuie sur le Principe 1 (rigueur des couches fondatrices) et ADR-025 (reproductibilité). N’amende pas le standard 100 % de la couche 0.
Catégorie : Méthode (gouvernance technique / CI).
Contexte
La couche 0 est scellée au tag couche-0-v1 (commit 08f6d77) : ses sources
(crates/air-sys-types, crates/air-sys-syscall) sont gelées. Le travail de la
couche 1 ne les modifie pas.
Or la CI (test-coverage, matrice x86_64 + aarch64) re-mesure intégralement la
couverture 100 % (lignes + branches) de la couche 0 à chaque PR, y compris les PR
qui ne touchent que la couche 1. Sur le runner raspi-srv-2 (Raspberry Pi 4,
aarch64), ce travail redondant est le poste de coût dominant et ralentit chaque
itération.
Re-vérifier une couche scellée à chaque PR couche 1 n’apporte presque rien :
les sources sont identiques au sceau. Sauf un cas réel : la dérive de
toolchain. Les résultats de clippy et de llvm-cov peuvent changer quand le
nightly (ou le stable pinné) est bumpé, à sources identiques — c’est la seule
voie par laquelle la couche 0 scellée pourrait « régresser » sans changement de code.
Décision
1. La vérification lourde de la couche 0 est conditionnée par chemin
Les étapes coûteuses propres à la couche 0 — mesure de couverture (lignes + branches) et fuzzing — ne s’exécutent que si une PR touche l’un de :
crates/air-sys-types/**oucrates/air-sys-syscall/**(sources couche 0) ;rust-toolchain.toml, ou leCargo.lock/manifestes affectant la couche 0 (changement de toolchain ou de dépendance) ;.github/workflows/**,deny.toml, ou les fichiers de politique de couverture (docs/COVERAGE-EXCEPTIONS.md).
2. Pour les autres PR : bâtie + testée, pas re-mesurée
Une PR qui ne touche aucun de ces chemins bâtit toujours la couche 0 comme dépendance (via cache, cf. sccache) et exécute ses tests unitaires + doctests (cheap), mais ne re-mesure pas sa couverture et ne relance pas le fuzzing.
3. Garde-fous anti-dérive (la rigueur est préservée, pas réduite)
La barrière complète de la couche 0 (couverture + fuzz) s’exécute toujours :
- (a) sur la PR qui bumpe la toolchain ou une dépendance couche 0 (règle 1) ;
- (b) sur
push/merge versmain— doncmainn’est jamais dans un état non vérifié : une éventuelle régression de dérive de toolchain est bloquée au merge, pas seulement signalée ; - (c) en planifié hebdomadaire — détecte une dérive d’environnement runner même sans activité de PR.
Un rouge sur l’une de ces exécutions rouvre le sceau (traitement prioritaire).
4. Le tag couche-0-v1 reste la référence d’autorité
Aucune de ces optimisations ne déplace la référence : l’état attesté reste le sceau.
Conséquences
- Itérations couche 1 nettement plus rapides sur le Pi : on ne repaye plus la
re-mesure de la couche 0 à chaque
pushd’une branche de feature. - Garantie du sceau préservée : la vérification complète a toujours lieu là où
elle compte (merge vers
main) et périodiquement (hebdo). Le compromis n’est pas « moins de rigueur » mais « pas de rigueur redondante par PR ». - Cohérence outillage : les gates
barrier/couvrable-videduxtask(060) peuvent honorer le même périmètre par chemin (option, pas obligation). - Orthogonal au cache : se combine avec
sccache(recompilation évitée) et, plus tard, avec un éventuel offload de compilation (cross-compile sur speedy, exécution des tests sur le Pi).
Alternatives écartées
- Tout re-vérifier à chaque PR (statu quo) : sûr mais lent — le problème qu’on corrige. La redondance n’achète aucune sécurité supplémentaire entre deux bumps de toolchain.
- Ne plus jamais re-vérifier après le sceau : rejeté — ignore la dérive de toolchain, seule voie réaliste de régression à sources gelées.
- Offload de compilation seul : utile mais orthogonal ; ne supprime pas la redondance de re-mesure, seulement son coût de compilation.
Risques et mitigations
- Une régression de dérive de toolchain introduite entre deux runs hebdo pourrait
passer inaperçue sur une PR couche 1. → Mitigé par le garde-fou (b) : le merge
vers
mainre-vérifie tout, donc une telle régression ne peut pas atteindremain. Au pire, elle est détectée au merge plutôt qu’à l’ouverture de la PR. - Mauvais périmètre de filtre (un changement couche 0 non couvert par les globs). → Les globs sont conservateurs (sur-déclencher plutôt que sous-déclencher) et testés ; tout doute déclenche la barrière complète.
Adoption
Câblage CI dans un prompt relais dédié, après l’ADR accepté. La doc CI
(docs/CI.md) décrira le périmètre, les déclencheurs et les trois garde-fous.