ADR-002 — Modèle d’objet hybride asymétrique, C-ABI pour le périmètre CoreFoundation/AppKit
Statut : Accepté — document fondateur. Édition directe autorisée en phase de design pré-ouverture publique ; immuable après ouverture publique (toute évolution via RFC, ADR-015). Catégorie : Architecture (couche 2 — modèle d’objet, frontière C-ABI).
Contexte
Air est conçu polyglotte : ses services et son modèle d’objet doivent être consommables depuis d’autres langages que Rust. Or exposer une surface en C-ABI a un coût — comptage de références atomique, vtable de classe, introspection à l’exécution.
Tout exposer ferait payer ce coût à du code qui n’en a nul besoin ; ne rien exposer fermerait la porte aux bindings. Il faut donc tracer une frontière, et dire explicitement ce qui la traverse.
Décision
La couche 2 expose un modèle d’objet C-ABI pour tout ce qui est susceptible d’être observé, bindé depuis d’autres langages, ou inspecté par des outils : collections, strings Unicode, URLs, services, vues, contrôleurs, propriétés observables. Pour tout le reste — algorithmique interne, parseurs, structures de données privées — on reste en Rust pur.
Frontière explicite : un type qui dérive #[derive(AirObject)] ou équivalent rejoint le monde C-ABI et accepte ses contraintes (compteur de référence atomique, classe = vtable + métadonnées, propriétés observables, introspection runtime). Pont entre les deux mondes par conversion explicite quand nécessaire.
Conséquences
Conséquence stratégique : Air est conçu polyglotte dès le départ. Un binding Python générique appelle air_object_get_property pour tout, sans code spécifique par classe. Idem Swift via @dynamicMemberLookup. Modèle qui fait que PyObjC marche sans glue par classe sur macOS.
Alternatives rejetées
Aucune alternative n’a été consignée lors de l’instruction.
Licence du document : MPL 2.0