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

ADR-041 — Coexistence /etc : projection générée, lecture seule sélective, air-config seul écrivain

Statut : Accepté (2026-06-25, validé par le BDFL). Companion d’ADR-033 (modèle de configuration : source typée → compilateur → artefact binaire) — détaille la règle 7 (backends d’émission) au-delà de systemd. Cohérent avec ADR-005 (systemd socle V1), ADR-040 (artefact Cap’n Proto), ADR-032 (zéro discard) et le Principe 4 (valider en amont).

Catégorie : Architecture (transverse — air-config couche 1 + intégration OS couche 5).

Contexte

ADR-033 a posé que la configuration Air a pour source de vérité une source typée compilée en artefact binaire (Cap’n Proto, ADR-040), le texte n’étant qu’une projection. Reste un problème de coexistence avec le monde C-Unix : tant qu’Air n’apporte pas sa propre libc et ne recompile pas les outils C contre elle, on ne peut pas empêcher un programme C de lire — ni de tenter d’écrire — sous /etc. La libc (glibc/musl) et les services Unix classiques lisent directement /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts, /etc/passwd, /etc/systemd/system/…, etc. au runtime, indépendamment d’Air.

L’objectif : un utilisateur faillible ne doit modifier la configuration qu’à travers l’outil Air validant (Principe 4) ; mais les consommateurs C doivent continuer à lire leur config. Il faut donc que /etc reflète la source Air sans redevenir une surface d’édition libre.

Décision

Les fichiers /etc que possède Air sont des projections générées par air-config (backend d’émission, ADR-033 §7), protégés en lecture seule sélective ; air-config en est le seul écrivain (réécriture par swap atomique). Les consommateurs C les lisent, ne les écrivent jamais. C’est un garde-fou, pas une frontière de sécurité.

Six règles :

  1. Projection générée, pas source. Les fichiers /etc possédés par Air sont dérivés de la source typée par le backend d’air-config (cohérent ADR-033 §7) ; jamais édités à la main. La source typée (compilée en artefact Cap’n Proto, ADR-040) reste canonique.

  2. air-config seul écrivain, par swap atomique. Les régénérations passent par air-filesystem::write_atomic (tmpfile + fsync + rename). Le runtime Air-natif ne lit pas /etc (il lit l’artefact binaire) ; /etc n’existe que pour le monde C.

  3. Lecture seule SÉLECTIVE, pas globale. Seuls les fichiers possédés par Air sont rendus immuables-aux-autres (bind ro par fichier, chattr +i, ou overlay à lower RO). Un /etc entièrement RO est rejeté : il casserait des écrivains runtime légitimes (passwd/useradd/etc/shadow/passwd ; ldconfigld.so.cache ; installations de paquets). Donnée du réel : même les OS « immuables » (Fedora Silverblue, openSUSE MicroOS) gardent /etc inscriptible (overlay) et rendent /usr immuable — précisément pour cette raison.

  4. Mutables-runtime → redirigés vers /run. Les fichiers qu’un service réécrit en continu (resolv.conf…) sont des symlinks vers /run (tmpfs inscriptible), pattern systemd-resolved. /etc/machine-id : symlink /run ou pré-provisionné (premier boot).

  5. systemd : air-config possède /etc/systemd/system. L’activation de services (enable/disable/mask), les drop-ins (edit) et hostnamectl/localectl/ timedatectl écrivent normalement sous /etc ; dans le modèle Air, l’humain les déclare dans la source Air et le backend systemd d’air-config émet les symlinks /etc/systemd/system/*.wants + drop-ins. systemd ne fait que LIRE cette zone ⇒ elle peut être RO-aux-autres, air-config seul écrivain. Les opérations runtime (start/stop/restart/status, via sd-bus → état dans /run) ne touchent pas /etc et restent intactes sous /etc RO.

  6. Garde-fou, pas frontière de sécurité. root peut mount -o remount,rw. Le RO sélectif empêche les accidents et le « vim /etc/resolv.conf » distrait, et signale « fichier généré » (le tool C reçoit EROFS, échec bruyant plutôt qu’écrasement silencieux). La contrainte dure viendra avec air-launchd (sandbox/Landlock) ou le bit immuable — hors périmètre ici.

Conséquences

  • Deux responsabilités distinctes. air-config (couche 1) génère les projections /etc ; la protection (montage RO sélectif / chattr / overlay / symlinks /run) est une décision d’intégration OS (couche 5) — réalisable par une unit systemd de montage dès maintenant, avant air-launchd.
  • Périmètre croissant (progressif). Au début, peu de fichiers gérés/verrouillés ; une zone /etc ne passe en RO-sélectif qu’une fois que le backend d’air-config couvre les mutations correspondantes (mêmes incréments que ADR-033 §7). Tant qu’une mutation n’est pas couverte, sa zone reste inscriptible.
  • Bootstrap bidirectionnel. Sur installation/migration existante, l’outil doit importer /etc existant → source Air (sens inverse) avant d’émettre. Import et émission.
  • Périmètre de possession explicite. Tout /etc n’appartient pas à Air (des paquets en possèdent) ; air-config déclare les fichiers qu’il possède — les autres restent hors de sa gestion.

Alternatives rejetées

  • /etc globalement read-only. Casse passwd/useradd/ldconfig/installations ; plus agressif que l’état de l’art (Silverblue/MicroOS gardent /etc inscriptible).
  • Régénération qui écrase en silence (sans RO). L’écriture d’un tool C « réussit » puis est écrasée plus tard → surprise, dérive non signalée. Le RO sélectif échoue tout de suite (EROFS), plus honnête (Principe 4 / ADR-032).
  • Interdiction dure par défaut (Landlock/sandbox) dès maintenant. Prématuré sans air-launchd ; le garde-fou par montage suffit pour la phase de coexistence.

Hors périmètre

  • L’enforcement dur (air-launchd, Landlock, bit immuable) — couche 5, ADR ultérieur.
  • Le langage de la source typée, l’ergonomie du compilateur, le schéma Cap’n Proto et la liste précise des backends/fichiers possédés — spec air-config (couche 1).

Adoption

Documentaire immédiat (ADR-041 + registre/INDEX/SUMMARY). Mise en œuvre échelonnée : la spec air-config détaillera les backends d’émission (dont /etc/systemd/system), l’import inverse et le périmètre de possession ; l’intégration OS (unit de montage RO sélectif + symlinks /run) viendra côté couche 5, de façon progressive.