Note d’exploration — libc-compat Air (piste, NON engagée)
Statut : exploration. Pas une décision, pas un ADR, pas de spec. Capture un raisonnement pour le futur. Aucune ressource engagée. À revisiter seulement quand les couches 0–2 seront solides. Datée 2026-06-12.
Idée
Fournir une libc pour « asseoir les outils C sur la stack Air » : le nécessaire
et suffisant d’une libc standard, implémenté par-dessus les couches 0/1 d’Air.
Modèle : musl, pas glibc (glibc = trop grosse, vieux bugs gardés pour compat,
et surtout LGPL → hors allowlist deny.toml ; musl = MIT, lean, éthos
proche d’Air). glibc n’est citée que comme la lib répandue, pas comme modèle.
Placement : NON couche 3 — altitude couches 0/1
Une libc est une fondation, ses dépendances pointent vers le bas (le
kernel) ; tout le userspace C dépend d’elle. La couche 3 (composition/rendu) est en
haut et dépend de la couche 2 (runtime/AirCom) — y poser une libc inverserait les
flèches. ⇒ brique transverse « libc-compat » ancrée aux couches 0/1, jumeau
d’air-base-lib tourné vers le monde C plutôt que vers les crates Rust d’Air.
Règle de fer : les crates d’Air ne dépendent jamais de cette libc-compat
(sinon on réintroduit la dépendance libc délibérément supprimée — couche 0 asm!
sans libc/rustix). C’est un sidecar d’hébergement, pas un socle commun.
Deux concepts à ne pas confondre
- (A) Fondation interne d’Air — déjà libc-free : couche 0 (
asm!) + couche 1 (Rust + ABI C). Air n’a pas besoin de libc pour lui-même. - (B) Libc de compatibilité —
libc.so+ en-têtes standard +ld.so+ CRT, pour héberger l’écosystème C existant par-dessus 0/1. C’est (B) la piste.
Fourche & périmètre (réalités)
- Source-compatible (recompiler, façon musl) ✅ vs ABI-compatible glibc (faire tourner des binaires existants bug-pour-bug) ❌ = bourbier de décennies.
- Périmètre réel ≫ ISO C (string/stdio/stdlib/math, modeste) : **linker dynamique
- CRT** (TLS,
__libc_start_main, par arche),malloc,pthreads(exige un futex synchrone — manque couche 0 déjà signalé parair-thread, cf. [[air-strategie-systemd-remplacement]] et la dette futex),dlopen,getaddrinfo(s’adosserait au résolveur DNS maison d’Air), NSS, locale,libm. Ordre de grandeur musl/glibc, pas un week-end.
- CRT** (TLS,
Valeur — analyse honnête (la vraie question)
Une libc de pure compatibilité n’apporte quasi rien à l’application elle-même : par construction, l’app ne peut pas distinguer glibc/musl/Air-libc (c’est le but d’un standard). Le coût servirait surtout à être invisible. La valeur réelle est ailleurs :
- Instrumentation debug/diagnostic (la plus tranchante à court terme — intuition
de Thierry). La libc est le goulot par où passent toute la mémoire, tous
les syscalls, toutes les chaînes. Donc l’endroit idéal pour : malloc durci de
debug (use-after-free, double-free, overflow, fuites avec backtrace + rapport à
la sortie — façon scudo/
MALLOC_CHECK_/electric-fence), traçage de syscalls en log structuré journald (mieux que strace), stdio/chaînes bornées (_FORTIFYtoujours actif en debug), diagnostics d’abort/assert nets. Valeur = expérience développeur, alignée sur l’objectif « Air = environnement de dev de qualité ». - Durcissement par défaut (builds release) — malloc durci, safe-linking,
pointer mangling, CFI : tout programme C sur Air hérite d’une sécurité de base
meilleure sans rien faire (modèle bionic/Android). Point d’application du
2ᵉ pilier [[air-pilier-integrite-binaires]] : c’est
ld.soqui vérifie la signature avant de mapper un exécutable/.so. - Cohérence —
getaddrinfo→ DNS maison, logs → journald, threads → futex Air : le programme C hérite des politiques Air de façon transparente. - Indépendance — ne pas dépendre de glibc/musl-externe (même logique que systemd/udev).
Le découplage clé (insight)
Les deux ambitions sont séparables :
- (B1) « Être la libc système de tout C » = énorme, faible valeur applicative, surtout plomberie + indépendance.
- (B2) « Une libc de debug/diagnostic qui tue » = petite, séparable,
LD_PRELOAD-able, marche même par-dessus glibc/musl, sans s’engager à remplacer la libc système. ROI court terme élevé, c’est exactement l’angle qu’a vu Thierry.
⇒ Si on touche un jour à ce sujet, commencer par (B2) (le sidecar diagnostic), pas par (B1).
Caveat : (B2) recoupe valgrind/ASan/sanitizers, qui existent et sont bons. L’avantage Air n’est pas une capacité nouvelle mais le zéro-friction + l’intégration (toujours actif en debug, sortie structurée Air, sans toolchain spécial ni recompilation lourde). Ne pas survendre.
Position
Même forme stratégique que la discussion systemd : énorme, à seamer et
différer (horizon V2+, après couches 0–2 solides). Si poursuivi : partir de
musl (MIT) + extensions Air, jamais d’une réécriture glibc-ABI ex nihilo ; garder
la libc minimale (le runtime Air reste à côté, déjà en ABI C — un programme C
linke libair-runtime.so/libair-aircom.so séparément) ; et attaquer d’abord la
tranche debug (B2), qui apporte de la valeur sans contrat à vie.
Liens
[[air-strategie-systemd-remplacement]] · [[air-pilier-integrite-binaires]] · ADR-024 (règle 80 % / licences) · dette couche 0 « futex synchrone » (air-thread).
Licence du document : MPL 2.0 Statut : note d’exploration, non engageante. Toute suite passerait par un ADR.