État au 29 octobre 2026. Ce dossier décrit gnosix.ds au commit a7fbfc8 (version 4.6.0, avec l'amendement AMD-001). Les liens soulignés mènent aux fichiers de ce commit, figés.

Dossier · Le design system

gnosix.ds — un design system qu'une machine peut vérifier

Un design system, ce sont des décisions que d'autres prennent chaque jour. gnosix.ds les écrit sous une forme qu'une machine peut vérifier — 29 règles, 16 rôles, 14 composants — et les porte vers le web, Rust, Android et FigCraft, sans qu'aucune boîte à outils ne devienne le design system.

v4.6.0 Licence MIT 36 contrôles au vert

Sur cette page
  1. En une image
  2. Le problème
  3. Le sens d'abord
  4. 36 contrôles
  5. Écrit une fois
  6. Des noms mesurés
  7. Historique
  8. Projections
  9. Ce que ce n'est pas
  10. Selon qui vous êtes
  11. Pour aller plus loin
29règles numérotées, chacune avec ce qu'on observe et le test qui le vérifie
16rôles : ce à quoi sert une couleur, sur fond clair et sur fond sombre
14 + 36composants, et 36 arrangements mesurés sur le terrain
36contrôles en 24 secondes, la même commande sur le poste et en CI

En une image

L'analogie

Pensez au mètre étalon : une règle de référence, rangée à part, et des instruments qui comparent chaque copie à l'original. Une copie qui s'allonge d'un millimètre est refusée, même si personne ne l'a voulu.

gnosix.ds fait cela pour une interface. La couleur d'un texte, le rayon d'un coin, le nom d'un composant ont une valeur de référence ; chaque plateforme en reçoit une copie, et 36 contrôles comparent chaque copie à l'original. Une couleur qui dérive est un mètre faux, et le contrôle le voit.

Le problème : la même décision, prise mille fois

Choisir le gris d'une légende prend une seconde. Le choisir dans onze interfaces, sans règle commune, donne des centaines de gris presque pareils.

C'est ce que l'audit du terrain a mesuré avant d'écrire une seule règle. Il a lu onze interfaces — des sites, des portails, des outils — et relevé tout ce qu'elles utilisent sans que le système le prévoie. L'une compte 1 263 couleurs hors palette, une autre 421, une troisième 294. Des polices de rechange, des espacements de 9, 10 ou 11 pixels quand l'échelle n'en prévoit pas.

Aucune de ces valeurs n'est une faute. Chacune était raisonnable le jour où elle a été écrite. Ce qui manquait, c'est une référence qu'on puisse consulter — et un instrument qui dise « stop » quand une copie s'en écarte.

À retenir

L'inventaire complet est public : chaque couleur, police et longueur hors contrat, interface par interface, avec un plan d'absorption qui dit quoi changer et dans quel ordre (l'inventaire, le plan).

Le sens d'abord, la couleur ensuite

Le système ne dit pas « #111418 », il dit « le texte qui se lit en premier ». La couleur n'est que la valeur de ce rôle sur un fond donné.

Tout le contrat tient en quatre étages, et chacun est un fichier qu'on peut lire :

ÉtageCe qu'il contientFichier
Les règles29 obligations numérotées (COL-001, A11Y-001…), chacune avec ce qu'on observe et le test qui le vérifierules.json
La palette5 couleurs approuvées, leurs nuances, les paliers d'élévation des surfaces, l'espacement, la policeTOKENS.json
Les rôles16 rôles — surface, ink, accent, focus, positive… — liés à une valeur sur chaque fondROLES.json
Les composants14 éléments (bouton, champ, badge, dialogue…), leurs états, leurs variantes et l'accessibilité qu'ils doivent ; 36 arrangementsCOMPONENTS.json

Tout le reste est une projection : généré depuis ces fichiers, rangé dans le dépôt, et refusé dès qu'il s'en écarte. On ne retouche jamais une copie à la main ; on change l'original, et les copies suivent.

Un exemple : le vert qui ne porte pas de texte

Le vert approuvé mesure 4,09:1 contre le fond clair. C'est assez pour une marque, pas pour une phrase : la lisibilité d'un texte demande 4,5:1. Plutôt que de tricher sur la couleur, le système sépare deux rôles. positive est la pastille posée à côté du mot ; positive-surface est le fond teinté derrière le mot. Chaque paire qui porte du texte est mesurée à 4,5:1 sur les deux fonds.

36 contrôles, une seule commande

La même commande tourne sur le poste et en intégration continue : 36 contrôles, 24 secondes, un verdict. Un contrôle qui change d'avis fait échouer l'ensemble.

python3 -m tools.ci
…
PASS  the severity register is honest
PASS  the surfaces render as the system carries them
PASS  test suite

PASS: 36 gates in 23.8s

Le relevé ci-dessus a été obtenu au commit a7fbfc8, le 29 octobre 2026 (relevé complet). Quelques-uns de ces contrôles disent bien l'esprit du projet :

  • « Chaque couleur est l'une des nôtres. » Une valeur qui n'est pas dans la palette, où qu'elle apparaisse, fait échouer le contrôle.
  • « La table de contraste mesure ce que dit la palette. » Les rapports de contraste ne sont pas recopiés : ils sont recalculés à chaque passage.
  • « Chaque contrôle dit ce qu'il doit dire. » Un contrôle qui sort sans erreur mais affiche autre chose que ce que prévoit la liste des attendus échoue quand même.
  • L'œil. Un navigateur piloté rend les surfaces web du système sur les deux fonds, les passe à un outil d'accessibilité, et compare les images, octet pour octet, à celles que le système transporte. Aujourd'hui : 3 surfaces, 0 constat.
  • Le registre des écarts. Ce que le système et le terrain ne font pas pareil est consigné, avec sa gravité et son responsable. Un écart clos porte une sonde : s'il revient, le contrôle échoue.
Ce que ça change

Personne n'a à se souvenir des règles : la machine s'en souvient. Une erreur est trouvée sur le poste, en 24 secondes, et pas trois semaines plus tard dans une capture d'écran.

Écrit une fois, porté partout

Une page web, une application Rust et une application Android lisent la même décision, chacune dans sa langue : une feuille CSS, une constante Rust, une fonction Kotlin.

<body data-gnosix-substrate="dark">           web : le fond est choisi une fois

let surface = gnosix_ds::roles::DARK.surface;   Rust : la constante du contrat

val surface = GnosixRoles.of("dark", "surface") Kotlin : la même valeur
CibleCe qu'elle reçoitOù en est la preuve
WebTrois feuilles CSS (jetons, rôles, composants) et un module d'étatRendue et regardée par l'œil, à chaque passage
RustUn paquet sans dépendance qui porte les constantes du contratCompilé et testé à chaque passage ; pas encore vu à l'écran
AndroidLa traduction Compose et une application d'exempleÉcrite, pas encore vérifiée sur un appareil
Formats d'échangeLes jetons en DTCG et en Style Dictionary, lisibles par d'autres outilsUn contrôle vérifie que les deux disent la même chose
FigCraftUn projet de dessin : planches, vocabulaire de composants, bibliothèque publiéeGénéré, et comparé octet pour octet à sa source

Ce site lui-même en est un client : ses couleurs, ses deux thèmes et ses encadrés viennent de gnosix.ds. La rangée de triangles à gauche de chaque encadré est l'amendement AMD-001, décrit plus bas.

Des noms mesurés, pas choisis

Les quatorze composants ne viennent pas d'un goût : ce sont les noms que plusieurs interfaces indépendantes utilisaient déjà, comptés une fois par lignée.

Pourquoi « par lignée » ? Parce que deux copies d'une même feuille de style ne font pas deux votes. Deux dépôts qui partagent une feuille écrite une fois portent une seule opinion ; les compter deux fois ferait passer un avis pour un accord. Compté ainsi, 26 noms apparaissent dans au moins deux lignées ; une fois écartés les morceaux d'un même composant et les motifs propres à un métier, il en reste quatorze.

Le terrain utilisait aussi 36 arrangements que le système ne décrivait pas : 29 motifs (un registre, un rail, une note, un bloc de texte) et 7 primitives. Le contrat les décrit désormais tels que la feuille du terrain les écrit, et un contrôle vérifie dans les deux sens : un élément que le contrat nomme et que la feuille n'a pas est une erreur, et l'inverse aussi.

Source : la table de convergence.

Historique : jusqu'au premier amendement

Du premier import à l'amendement AMD-001, qui remplace un filet par une rangée de triangles : comment un changement entre dans un système qui refuse qu'on retouche ses copies.

DateCe qui se passe
20 octobre 2026Le dépôt public commence, à la version 3.4.2. Les versions plus anciennes circulaient en archives et ne sont pas reconstituées. Le soir même, après 92 commits, le système est en 4.6.0 : rôles, composants, l'œil, le registre des écarts, l'audit du terrain.
21 octobreUne enquête sur les sources amont du terrain entre au dépôt (10 commits, PR #2).
29 octobrePremier amendement, AMD-001 : le filet gauche d'une note devient une rangée de triangles égaux pointant vers le contenu (PR #3).
29 octobre, plus tardLe README annonçait encore 22 contrôles et 14 rôles. La correction devient un écart consigné, DEV-022, avec une sonde qui l'empêche de revenir (PR #4, fusionnée).

Pourquoi un « amendement »

La feuille de style que livre le système est découpée depuis une copie historique, que trois dépôts embarquent à l'octet près. Écrire les triangles dans cette copie aurait été effacé au découpage suivant, ou aurait fait mentir la copie sur ce qu'elle est. Le système écrit donc ses changements à part, dans une couche d'amendements ajoutée en dernier : elle l'emporte, et la copie historique reste celle que le terrain connaît.

Projections : l'œil sur une surface native

Aujourd'hui, l'œil regarde des pages web. La suite : regarder aussi les écrans natifs, ceux que dessinent gnosix et GPUI.

La réponse n'est pas acquise, et la feuille de route le dit : il faut d'abord savoir si le moteur de rendu du bureau peut tourner sans écran. Si oui, les surfaces natives seront regardées comme les pages web ; si non, la raison sera consignée. Les deux issues comptent comme une preuve.

Le reste de la feuille de route suit le même format : pour chaque tâche, où elle atterrit, ce qui prouve qu'elle est finie, ce qu'elle attend et ce qu'elle coûte. Deux interfaces ont déjà adopté le système, à la version 4.2.1 : le portail de documentation et le corpus d'ingénierie, avec zéro couleur hors contrat. Les autres suivront une à une, par la même méthode en six étapes, sur une branche.

Ce que ce n'est pas

Les limites, sans détour
  • Pas une bibliothèque de composants. Le dépôt ne livre pas de boutons React prêts à l'emploi : il livre des décisions, et leurs traductions par plateforme.
  • Pas encore vu sur un écran natif. Les traductions Rust et Android sont écrites ; Rust compile et passe ses tests, mais aucune n'a encore été regardée à l'écran, et Android n'a pas été essayé sur un appareil.
  • Pas fini. Le registre compte des écarts encore ouverts, publiés avec leur gravité et leur responsable.
  • Le terrain est surtout privé. Sur les onze interfaces auditées, la plupart ne sont pas publiques ; l'inventaire l'est.

Ce que ça change, selon qui vous êtes

Designer

Une décision de couleur ou d'espacement s'écrit une fois, avec sa raison, et elle arrive telle quelle dans le navigateur, l'application native et l'outil de dessin.

Développeur

Pas de valeur à recopier : on lit le rôle. Et une seule commande, sans dépendance, dit en 24 secondes si une modification casse une règle.

Décideur

Une identité visuelle qui ne dérive pas d'un produit à l'autre, et un état des lieux chiffré de ce qui reste à harmoniser, interface par interface.

Pour aller plus loin