ADR-119 — Extensions SFTP OpenSSH (posix-rename, hardlink, fsync, statvfs, limits@) + surface statvfs couche 1
Statut : Accepté (2026-07-26, décision BDFL). RFC de direction
(ADR-015).
S’appuie sur ADR-104 (SFTP v3 :
air-sftp-proto + worker), ADR-091 (motif sans-IO),
ADR-062 (couche 1 scellée — évolution additive v1.x),
ADR-029 (nommage).
Catégorie : Couche 2 (extensions air-sftp-proto) + additif couche 1 (air-filesystem).
Vague 2 #7.
Contexte
Le sous-système SFTP d’Air ([ADR-104], S.1→S.5) implémente SFTP v3. OpenSSH y ajoute des
extensions largement utilisées : posix-rename@openssh.com (renommage POSIX atomique),
hardlink@openssh.com, fsync@openssh.com, statvfs@openssh.com/fstatvfs@openssh.com
(statistiques de système de fichiers), limits@openssh.com (limites annoncées par le serveur).
Sans elles, des clients (dont sftp/rsync) tombent sur des chemins dégradés.
Bonne nouvelle de layering : la plupart reposent déjà sur la couche 1
(air-filesystem : fsync = sync_all/sync_data, rename, hard_link), et
statfs/fstatfs existent déjà en couche 0 (air-sys-syscall, StatFsResult) — il ne
manque que la surface couche 1 et le câblage protocole. Aucun descellement couche 0.
Directive BDFL (2026-07-26). « Extensions SFTP : oui. » (avec statvfs = additif
air-filesystem, « mécanique »).
Décision
1. Extensions dans air-sftp-proto (couche 2, sans-IO) + worker
Les extensions sont ajoutées au cœur sans-IO air-sftp-proto ([ADR-104]/[ADR-091] :
fuzzable) et servies par le worker SFTP d’air-sshd. Le worker traduit chaque extension
en appel air-filesystem (couche 1) :
posix-rename@openssh.com→rename(déjà L1).hardlink@openssh.com→hard_link(déjà L1).fsync@openssh.com→sync_all/sync_data(déjà L1).statvfs@openssh.com/fstatvfs@openssh.com→ nouvelle surfacestatvfs(§2).limits@openssh.com→ pur protocole : le serveur annonce ses limites (taille de paquet, tailles max de lecture/écriture) — aucun appel FS.
2. Surface statvfs couche 1 (air-filesystem) — additif pur, pas de descellement L0
air-filesystem gagne une méthode de statistiques de système de fichiers (espace total/
libre, taille de bloc, inodes…), bindant la couche 0 existante (air-sys-syscall::statfs/
fstatfs, StatFsResult — déjà présents). C’est un additif couche 1 (évolution v1.x,
[ADR-062]) : aucun nouveau syscall couche 0 à desceller. Newtypes/champs nommés [ADR-029].
3. Périmètre et sûreté
Les extensions parsent des requêtes réseau ⇒ intégrées au fuzz existant du cœur SFTP
([ADR-104]). Les erreurs FS remontent en statuts SFTP (mapping AirError → code SFTP) sans
unwrap. Coverage à la hauteur du volet SFTP.
Conséquences
Positives.
- Compatibilité client accrue (
sftp/rsync/clients riches) : renommage atomique, hardlink, fsync, quotas d’espace, limites négociées. - Coût faible : 3 extensions sur 5 réutilisent la couche 1 existante ;
statvfs= additif L1 pur (couche 0 déjà pourvue) ;limits@= pur protocole. - Layering respecté : extensions en couche 2, FS en couche 1, aucun descellement couche 0.
Négatives / coûts assumés.
- Surface protocole élargie = plus d’entrées à fuzzer/tester (intégré au harnais SFTP existant).
statvfs= additif couche 1 à écrire + tester (mappingStatFsResult→ champs SFTP), mais mécanique (primitive L0 présente).
Mise en œuvre (référence, hors décision). Incréments : (a) surface statvfs dans
air-filesystem (binding de statfs/fstatfs couche 0) ; (b) extensions dans air-sftp-proto
- worker (
posix-rename/hardlink/fsync/statvfs/limits@) ; (c) fuzz/tests. Non engagés par cet ADR.
Alternatives rejetées
Aucune alternative n’a été consignée lors de l’instruction.