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-114 — air-json : promotion du JSON minimal maison en crate couche 1 partagée (fuzzée, sans serde, os-free)

Statut : Accepté (2026-07-26, décision BDFL). RFC de direction (ADR-015). S’appuie sur ADR-099 (origine : air-sshd/src/json.rs, interchange de config E.6), ADR-024 (règle des 80 % — pas de serde_json en production), ADR-088 (os-free), ADR-029 (nommage), ADR-019 (modèle d’erreurs). Compagnon d’ l’ADR CLI air-keystore (vague 2 #3) : premier consommateur du mode JSON agent-safe.

Catégorie : Architecture couche 1 (extraction d’une crate utilitaire). Vague 2 #2.

Contexte

Le triage OpenSSH a acté que la CLI air-keystore ([ADR-108], vague 2 #3) exposera un mode JSON in/out agent-safe (entrée sur stdin, sortie structurée), pour qu’un outil ou un agent LLM manipule le keystore sans le piège du parsing shell (simples/doubles/back quotes). Il faut donc un codec JSON — mais pas serde_json : la doctrine config binaire ([ADR-073]) proscrit le JSON au runtime, et la règle des 80 % ([ADR-024]) déconseille une grosse dépendance dont on n’utilise qu’une fraction, sur une cible os-free ([ADR-088]).

Or ce codec existe déjà : air-sshd/src/json.rs ([ADR-099] E.6) — un JsonValue + un parseur borné (MAX_DEPTH, anti-débordement de pile) + un sérialiseur, faits main, sans serde, qui ne paniquent jamais (Result), surface hostile fuzzée, périmètre entiers (pas de flottants). Il est enfermé dans air-sshd alors qu’il devient un besoin partagé.

Directive BDFL (2026-07-26). « Ajouter à l’outil air-keystore une capacité de lire/écrire JSON en entrée/sortie, pour qu’un outil (un agent LLM ?) manipule l’in/out de manière sûre, sans problème de parsing de ligne de commande. » → et, en cadrage : extraire air-json comme crate partagée fuzzée.

Décision

1. Extraire air-json — crate couche 1 partagée

Le contenu de air-sshd/src/json.rs est promu en crate air-json (couche 1), utilitaire pur codec, sans I/O, no_std + alloc, erreurs AirError ([ADR-019]). Elle est consommée par air-keystore (couche 1), air-sshd et air-ssh (couche 2) — un codec pur en couche 1 est utilisable par les couches au-dessus. air-sshd cesse d’héberger le module et dépend d’air-json (non-régression garantie par les tests d’interchange E.6 existants).

2. Pas de serde_json en production — codec possédé

air-json reste fait main (pas de serde/serde_json dans [dependencies] de production) : cohérent [ADR-024] (on n’utilise pas 80 % de serde_json), [ADR-088] (os-free, deps minimales), et [ADR-073] (le JSON n’est jamais lu au runtime — uniquement import/export et mode CLI, hors chemin de démarrage). (serde reste permis en dev/test-only au titre d’[ADR-030] si un oracle différentiel de fuzz l’exige.)

3. Périmètre conservé, sûreté renforcée

Périmètre inchangé : objets, tableaux, chaînes (échappements standards + \uXXXX BMP), entiers i64 (fractionnaires/exponentiels refusés — Air n’en a pas besoin ; Principe 5 : on n’ajoute les flottants que si un besoin réel apparaît), true/false/null. Invariants durcis en tant que crate publique : parseur borné (MAX_DEPTH), ne panique jamais (Result, Principe 3 : parsing schema-first, zéro unwrap), fuzz obligatoire (cargo-fuzz — c’est l’entrée d’un agent externe sur stdin), proptest round-trip (parse∘serialize = identité). Coverage 100 % (couche 1). Nommage [ADR-029].

4. Contrat du mode JSON agent-safe (défini ici, consommé par la CLI)

air-json fournit la brique ; la CLI air-keystore ([ADR-115]) l’exploitera ainsi : entrée JSON sur stdin (zéro quoting shell), sortie structurée sur stdout, erreurs en JSON (stdout + code de sortie ≠ 0), zéro prompt TTY (secret admin par champ/stdin). Ce contrat est l’interface recommandée pour l’usage programmatique/agent — il contourne tout parsing shell (anti-injection ticks/backticks).

Conséquences

Positives.

  • Réutilisation : un seul codec JSON, fuzzé, partagé (keystore CLI, air-sshd, air-ssh) — fin de la duplication.
  • Os-free, deps minimales : pas de serde_json sur *-linux-air ; cohérent [ADR-024]/[ADR-088].
  • Interface agent-safe : le mode JSON contourne le parsing shell — sûr pour un agent/outil.
  • Sûreté prouvée : borné + jamais-panique + fuzz, hérités et durcis.

Négatives / coûts assumés.

  • Codec maison à maintenir (vs serde_json) : périmètre volontairement réduit (entiers, pas de flottants) → coût faible ; extension seulement sur besoin mesuré.
  • Migration air-sshd (retrait du module local → dépendance air-json) : incrément avec non-régression E.6.
  • Nouvelle crate aux exigences couche 1 (coverage 100 %, fuzz, proptest).

Mise en œuvre (référence, hors décision). Incréments : (a) crate air-json (déplacement de json.rs + API publique + doc) ; (b) fuzz + proptest round-trip ; (c) migration air-sshd ; (d) consommation par la CLI air-keystore ([ADR-115]). Non engagés par cet ADR.

Alternatives rejetées

Aucune alternative n’a été consignée lors de l’instruction.