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

Roadmap — clôture de la couche 1 pour la libc C et le PAL Rust

✅ PLAN ACCOMPLI (2026-07-10) — ce document est désormais HISTORIQUE. La couche 1 a été scellée couche-1-v1.0 le 2026-07-03 (ADR-062) puis re-scellée additivement jusqu’à couche-1-v1.9 (v1.1→v1.9 : errno_location, signaux/futex, air-account, credentials/drop_to_user, air-handle+moteur socket, Managers de domaine, spawn_process, introspection thread cible). Ses deux toits sont prouvés : la libc C-ABI (~256 symboles) et le PAL Ruststd lie et tourne sur la libc d’Air, zéro glibc, 2 arches (jalon M5 atteint). Ce document décrit le plan d’origine ; le statut vivant est dans etat-avancement.md, et la prochaine phase = air-sshd (ADR-074). Le tableau de bord §8 ci-dessous reflète l’état au moment du plan, pas l’état courant.

Plan détaillé §-numéroté (les specs/audits y renvoient via « §5.3 P0.x »). Le statut vivant (ce qui est fait/en cours/à venir) est tenu dans le document de suivi etat-avancement.md, pas ici — ce document décrit le plan, le tableau de bord §8 en donne l’ossature.

But. Faire une passe de production complète de la couche 1 avant de la sceller (couche-1-v1.0), plutôt que sceller/desceller au fil de l’eau comme on l’a subi sur la couche 0. On n’éliminera pas tout descellement futur — on transforme les descellements structurels (« il manque une brique entière ») en descellements additifs mineurs (« il manque une fonction dans une brique existante »).

Principe directeur. La couche 1 a deux toits qui s’y assoient — la libc C-ABI (ADR-046/047/053) et le PAL Rust (la std cible *-linux-air, ADR-049/052). Seule la couche 1 consomme la couche 0 (ADR-052) : les deux toits sont au-dessus, clients, jamais dedans. Chaque brique de cette roadmap doit répondre à « quelle fonction libc et/ou quelle primitive PAL la réclame ? » — sinon elle attend. La complétude est pilotée par la demande des deux consommateurs, pas par une exhaustivité abstraite.

Sources. Inventaire couche 1 (crates + specs docs/specs/layer-1/), docs/notes/audits/RAPPORT-CONSOLIDE-libc-fr.md (41 familles musl), ADR-046/047/053 (libc), docs/notes/audit-icu4x-rust-pur-fr.md (i18n), ADR-049/052/055/056 (PAL/runtime). Statut de départ : main = 2689d69.

Légende

  • ☐ à faire · ◐ partiel/en cours · ☑ fait
  • Criticité : 🔴 bi-consommateur (libc ET PAL — rigueur maximale, dette figée si erreur) · 🟠 mono-libc · 🟡 mono-PAL · ⚪ interne/packaging
  • Colonnes Libc / Pal : ● consommateur direct · ○ indirect · — non concerné

1. Ce qui est DÉJÀ en place (socle acquis)

Ne pas refaire ; à auditer face-libc/face-PAL avant le sceau (§5).

BriqueRôleLPno_stdStatut
air-base-coreerreurs, ids, chemins-octets, temps monotone, encodage, log (ADR-054)oui
air-cryptohash, AEAD, signatures, AirRandom (CSPRNG getrandom)non¹
air-socketTCP/UDP/Unix + résolveur DNS maisonoui
air-filesystemcanonicalize, écriture atomique, watcher, globoui◐ (find_regex différé ; prendra une dép sur air-stdio, §2.D.2)
air-memoryarène/pool/slab + comptabilitéoui◐ (backing mmap différé)
air-deviceénumération/surveillance (uevent/evdev)oui
air-processclone3/pidfd/execve/signaux/drop_privilegesoui
air-envenvironnement process (octets), zéro-dép (ADR-055)oui
air-allocallocateur global mallocGlobalAlloc (ADR-056)oui
air-libmmath flottante no_std (façade libm, ADR-057)oui
air-config*compilateur config + backends /etc (passwd/shadow/hosts/resolv/fstab)oui
air-runtimeTCB/TLS/reloc/crt0/fork/spawn (ADR-052) — prouvé on-target 2 archesoui◐ (async runtime dans la passe, §4-K)
air-base-capifrontière ABI C (libair-base.so)n/a◐ (T1 fait ; T2/T3 §4-J)

¹ air-crypto/air-base-lib tirent encore des deps qui bloquent le no_std strict → visés par §2.

Bi-consommateurs déjà acquis (🔴 mais faits) : air-alloc, air-env, air-crypto::AirRandom, air-process, air-socket, air-runtime (TCB/TLS). Ils restent sacrés : toute évolution passe par RFC une fois scellés.


2. Chantiers RESTANTS — bi-consommateurs 🔴 (rigueur maximale, chemin critique)

Ce sont les briques qui portent le plus de risque : une erreur d’API casse les deux toits, et la garantie ABI libc (10 ans, Principe 8) fige la dette.

2.A — i18n : Air utilise icu4x (Option V, ADR-059) 🔴 · L● P●

Sert la libc (ctype, locale, collation, strcoll, normalisation, segmentation, calendriers) et le PAL/str (to_uppercase, normalisation, comparaison Unicode). Brique sensible — mais plus le long pole.

DÉCISION BDFL (ADR-059, data-backée). Vérification empirique faite : la fermeture icu4x compile pour *-linux-air (--release + default-features = false ; LSTM inclus, libm OK) — la réécriture du socle n’est pas nécessaire. Air utilise icu4x (extension exception ADR-016), possède l’API air-string dual-face + le pipeline de données (à terme). ⇒ le §2.A se réduit à un chantier no_std, pas une réimplémentation.

  • 2.A.1 air-base-lib#![no_std] — dernière crate cœur non-no_std. #![cfg_attr(not(test), no_std)] + extern crate alloc (posé #152, ADR-048 ; confirmé ici, fermeture icu prouvée on-target). Débloque la fermeture couche 1 complète (i18n comprise) pour la cible.
  • 2.A.2 deps icu_* d’air-base-libdefault-features = false (coupe transitivement la feature std ; 6 lignes du [workspace.dependencies] racine). Fermeture (air-base-lib + icu + socle) prouvée compilable on-target x86_64/aarch64-unknown-linux-air en release (build-std=core,alloc) — le repli logging debug d’icu_provider est inactif en release.
  • 2.A.3 air-string dual-face : ajouter la face C-ABI (libc) au-dessus de l’AirString existant (le moteur existe déjà via icu4x).
  • 2.A.4 Re-sonder la fermeture couche 1 complète pour *-linux-air (post-no_std air-base-lib) — preuve on-target.
  • 2.A.5 (optionnel/différé) pipeline datagen Air (host, réutilise le datagen icu4x sur sources CLDR/UCD) si Air veut maîtriser ses propres tables — compiled_data suffit pour démarrer.
  • Abandonné (ADR-059) : vendoring des 6 utils, port du socle, port de calendrical_calculationsinutiles, icu4x compile tel quel. air-libm (☑) reste surface math Air publique mais n’est pas requis par icu (icu tire libm via core_maths).
  • Segmentation LSTM incluse (décision BDFL) : fournie par icu_segmenter feature autocompile déjà pour la cible (prouvé).

2.B — air-thread en no_std + futex maison 🔴 · L● P●

Sert pthread_mutex/rwlock/cond (libc) et std::sync + std::thread (PAL). C’est aussi la zone non-déterministe discutée pour l’instrumentation (loom).

  • 2.B.1 Migrer AirMutex/AirRwLock/AirSemaphore du backend std::syncfutex maison DÉJÀ FAIT : la migration a eu lieu de facto au passage #![no_std] d’air-thread (#182, ADR-055) — sync.rs montre les 3 primitives sur air_sys_syscall::futex + AtomicU32, « aucune dépendance à std::sync ». (L’inventaire INDEX/etat-avancement était périmé sur ce point.)
  • 2.B.2 Spawn Air-natif : closure boxée via air-alloc (☑) — retirer le std::thread conditionnel (cfg(not(target_env="air"))).
  • 2.B.3 Couvrir les branches de contention de façon déterministe — voir §3 (loom) : à cadrer avant le sceau, car sceller fige la surface.

2.C — Temps (monotone + horloge murale) 🔴 · L● P●

clock_gettime/time/nanosleep/gmtime (libc) ↔ Instant/SystemTime (PAL).

  • 2.C.1 Confirmer que AirInstant/AirSystemTime (base-lib core) couvrent monotone + mur + nanosleep, no_std-propres, et exposables aux deux faces. (Le calendaire au-dessus dépend de 2.A.3.)

2.D — air-stdio : brique stdio/console bas-niveau 🔴 · L● P●

FILE* (libc) ↔ std::io::{Stdin,Stdout,Stderr} (PAL). Le niveau brut (handles fd 0/1/2 + isatty + verrou) est partagé ; le moteur FILE* bufferisé et printf/scanf restent libc (§4). Aujourd’hui non spécifié côté PAL (rapport PAL : « stdio bas-niveau MANQUE »).

  • 2.D.1 Créer air-stdio (brique dédiée, décision BDFL) : handles standard partagés (lecture/écriture brutes, isatty, verrou par flux, sécurité atfork), no_std, consommée par les deux toits.
  • 2.D.2 air-filesystem prend une dépendance sur air-stdio (décision BDFL) — les E/S de plus haut niveau s’appuient sur les handles standard.

2.E — Finitions des briques acquises 🔴/🟠

  • 2.E.1 air-memory : backing mmap (différé) — piles/TLS des threads spawn.
  • 2.E.2 air-crypto : rendre no_std-strict (auditer les deps qui bloquent). FAIT : default-features = false sur sha2/sha3/aes-gcm/chacha20poly1305/ argon2/ed25519-dalek (coupe la fuite std transitive ; features réactivées = strict nécessaire, aléa toujours via AirRandom couche 0). Preuve on-target x86_64-unknown-linux-air (release, build-std=core,alloc) : fermeture crypto entière no_std, zéro libc/std. Reste (chantier dédié) : sur aarch64, cpufeatures (dép non-optionnelle, détection ARMv8) lie libc (getauxval) qui n’a pas de profil env=air → chemin libc-free air_auxval(AT_HWCAP) à fournir. Détail : crates/air-crypto/DEPENDENCIES.md.

3. Étude PRÉ-SCEAU — instrumentation déterministe (à trancher avant §5)

Non une brique livrée : un outillage test-only à cadrer avant le sceau (le sceau fige la surface, autant avoir les seams dans la bonne forme). Détail en mémoire projet ; motivé par la variance de couverture (plancher 96→94, #189) et par la testabilité de contrats libc.

  • 3.1 loom — déterminisme de concurrence. FAIT (ADR-058) : gouvernance gravée + harnais (alias d’atomique core/loom + shim futex yield/no-op). Tous les verrous futex de couche 1 modélisés : air-thread AirMutex/AirRwLock/AirSemaphore (5 modèles) + le Mutex d’air-alloc + le StreamLock (verrou par flux) d’air-stdio7 modèles verts, exécutés en CI par un job loom dédié (--cfg loom, --locked). Plancher couverture lignes remonté 94→96 sur mesure empirique (5 passes : 96.65–96.66 %, variance 0.01 % ⇒ #189 annulé, filet resserré). Cargo.lock complété (arêtes loom, repro ADR-025). Garde-fou : loom = sûreté ; vivacité validée on-target.
  • 3.2 air-fault (nom proposé ; pas air-debug, réservé au LIB_AIR_DEBUG runtime) — injection de fautes syscall (EINTR, EFAULT, mmap/malloc échoue au N-ième). Rend testables des contrats aujourd’hui quasi-intestables : ADR-021 « EINTR remonté à l’appelant », vision « malloc échoue plutôt que hang ». Seam cfg-gated à la frontière L1→L0, zéro coût prod.
  • Garde-fou non négociable : le selftest on-target (rt/, 2 arches) reste juge de la réalité. L’instrumentation monte le % de couverture ; elle ne remplace jamais la preuve on-target (piège du mock — fatal pour un projet « fait ce qu’il dit »).

4. Chantiers RESTANTS — mono-toit (importants, moins « sacrés »)

Rigueur normale couche 1 (100 % couverture), mais un seul consommateur → une erreur ne casse qu’un toit.

#BriqueCrit.LPContenuStatut
4-Ftermios (L0, ADR-060) + air-terminal (L1, ADR-061)🟠Descellement couche 0 famille termios/tty (attributs/contrôle-ligne/winsize/PTY/session) puis objet couche 1 air-terminal = tag + codec + modèle canonique (1ᵉʳ codec ansi/termios). Branche feat/termios-couche0 (type Termios fait). air-termdb/termcap RETIRÉ du périmètre libc = ncurses/couche 2 (xterm-only, différé).
4-Gcomptes passwd/grp/shadow🟠itérateurs owned (pas de buffer static), lckpwdf réel, atfork. S’appuie sur les backends /etc d’air-config (☑) → API comptes au-dessus.
4-Hîlot asm setjmp/longjmp🟠inexprimable en Rust sain (saute les Drop) → surface FFI unsafe C-ABI seule, asm x86_64 + aarch64. À éviter si OpenSSH s’en passe.
4-Imoteur regex🟠POSIX basic/extended. Différé post-sceau (décision BDFL/reco) : ce sera une crate additive neuve → son ajout ultérieur ne descelle rien de l’API figée. Ne bloque que air-filesystem::find_regex + libc regcomp (non-critiques). Règle 80 % (ADR-024) interdit de vendorer regex tel quel → impl. minimale possédée le moment venu.☐ (post-sceau)
4-JABI C — air-base-capi T2/T3 + libair-base.soT2 (AirLog), T3 (temps POD), assemblage cdylib, liste des symboles exportés + versioning, header air_base.h. Au-dessus du sceau couche 1 (packaging de la face C).
4-Kair-runtime async (io_uring)Exécuteur air-runtime-{core,io,time,signal,sync} (spec v1.0 validée). Consommateur = applis couche 2+, pas la libc/PAL (sync) — mais inclus dans la passe et le sceau (décision BDFL : sceller toute la couche 1 en une fois). Voir bloc ci-dessous.

4-K (détail) — air-runtime async io_uring, dans la passe

Spec docs/specs/layer-1/air-runtime.md (v1.0 validée BDFL), non implémentée. Objet couche 1 : consomme air-sys-syscall (io_uring) directement (il EST couche 1).

  • 4-K.1 air-runtime-core : exécuteur mono-thread, Task/spawn/block_on, réacteur.
  • 4-K.2 air-runtime-io : futures sur complétions, AirIoBuf (modèle buffers possédés, décision centrale de la spec), enregistrement fd.
  • 4-K.3 air-runtime-time : sleep/timeout/intervalle.
  • 4-K.4 air-runtime-signal : signaux async via signalfd (ADR-020).
  • 4-K.5 air-runtime-sync : AirAsyncMutex, AirNotify, channel async.
  • 4-K.6 Mode multi-cœur : thread-per-core via msg_ring (peut suivre en v1.x additif si besoin).

Note de cohérence. L’async ne sert pas d’assise à la libc/PAL, mais le BDFL a tranché de le produire et le sceller dans la même passe que le reste — le sceau couche-1-v1.0 couvre toute la couche 1, pas seulement le sous-ensemble face-libc/face-PAL.

5. Porte de SCEAU — couche-1-v1.0

Après §2 (et le mono-toit §4 requis par le périmètre v1), avant de construire la libc et le PAL au-dessus :

  • 5.1 Audit face-libc : rejouer les 41 familles musl contre l’inventaire couche 1 — chaque fonction du périmètre v1 (ADR-046 : ~25-30 familles, cible OpenSSH) a-t-elle sa brique ? (completeness critic)
  • 5.2 Audit face-PAL (fait, docs/notes/audit-face-pal-cloture-fr.md) : ZÉRO gap fondateur ; les manques (Condvar/Once/dtors TLS/env-mutation/os_str) livrés en chantier A du PAL. Toit std en cours (chantier B, option A, ADR-076) : std compile sur la libc d’Air.
  • 5.3 Combler les manques additifs remontés par 5.1/5.2. (L’async §4-K est inclus dans la surface scellée mais n’a pas d’audit « face-toit » — ses consommateurs sont couche 2+.)
  • 5.4 Sceller : figer l’API Rust couche 1 en couche-1-v1.0 (RFC). ⚠️ Sceau couche 1 = API Rust ; la C-ABI vit au-dessus (crate libc/air-base-capi) avec son propre régime de stabilité (zones air-stable). Sceau couche 1 ≠ figer les signatures C.
  • Modèle de re-sceau (précédent couche 0, ADR-051) : les manques futurs se traitent en descellement additif v1.x (jalons antérieurs conservés), pas en refonte. On accepte qu’il y en aura — moins souvent que sur la couche 0.

6. Hors périmètre de ce sceau (à ne pas confondre)

  • libc C-ABI (ADR-046/047) et PAL std::sys (ADR-049 phase 3) : ce sont les toits, construits sur la couche 1 scellée — hors de cette roadmap (qui prépare leur assise).
  • (NB : l’air-runtime async, un temps envisagé hors passe, est finalement inclus dans le sceau — cf. §4-K, décision BDFL.)
  • Familles libc différées post-v1 (ADR-046 D7) : aio, ipc SysV, mq, ldso/dlopen, wordexp/glob (rejetés — RCE/injection).

7. Ordre d’exécution proposé (topologique)

  1. §3.1 loom (parallèle, faible risque) — stabilise la couverture avant tout figeage.
  2. §2.B air-thread no_std + futex — brique de synchro fondatrice ; débloque le spawn Air-natif (adosse air-alloc ☑).
  3. §2.C temps + §2.D air-stdio + §2.E finitions — petits, parallélisables.
  4. §2.A i18n Rust-pur — le long pole : 2.A.1 → 2.A.2 → 2.A.3/2.A.4 → 2.A.5 → 2.A.6 (LSTM). Peut avancer en parallèle des petits chantiers.
  5. §4-K air-runtime asynctrack parallèle indépendant (ne dépend ni de la libc ni du PAL) ; peut démarrer tôt et avancer en fond.
  6. §4 mono-toit (F/G/H) — une fois le cœur stable ; parallélisables. 4-I regex différé post-sceau (crate additive).
  7. §5 audits face-libc/face-PAL (completeness critic) → sceau couche-1-v1.0 (couvre toute la couche 1, async inclus).
  8. Au-dessus du sceau : §4-J (ABI C), puis libc C-ABI et PAL std::sys ; puis §4-I regex (additif).

8. Tableau de bord (à cocher au fil des PR)

ChantierCrit.Statut
2.A.1 air-base-lib → no_std (Option V, ADR-059)🔴
2.A.2 deps icu_* → default-features=false🔴
2.A.3 air-string face C-ABI (libc)🔴
2.A.4 re-sonde fermeture couche 1 on-target🔴
2.A.5 datagen Air (optionnel/différé)🟡
vendoring/port socle icu✗ abandonné (ADR-059)
2.B.1 futex maison air-thread🔴☑ (via #182)
2.B.2 spawn Air-natif🔴
2.B.3 couverture contention déterministe🔴
2.C.1 temps monotone/mur/nanosleep🔴
2.D.1 air-stdio (brique bas-niveau)🔴
2.D.2 air-filesystem → dép air-stdio🔴
2.E.1 air-memory backing mmap🟠
2.E.2 air-crypto no_std strict🔴◐ (deps df=false ; x86_64 on-target ☑ ; aarch64 = cpufeatureslibc env=air, chantier dédié)
3.1 loom (déterminisme concurrence)☑ (air-thread ×3 + air-alloc)
3.2 air-fault (injection fautes)
4-F termios L0 (ADR-060, couche-0-v1.8) ☑ · air-terminal L1 + air-termdb🟠
4-G comptes passwd/grp/shadow🟠
4-H îlot asm setjmp/longjmp🟠
4-K air-runtime async (core/io/time/signal/sync)
4-J ABI C T2/T3 + libair-base.so (au-dessus)
5.1 audit face-libc
5.2 audit face-PAL
5.4 sceau couche-1-v1.0 (async inclus)
4-I moteur regex (post-sceau, additif)🟠