Aller au contenu

ADR : ne pas adopter bridge pour la génération de prototypes Figma

Statut : accepted. L'outil n'est pas retenu, mais l'évaluation a produit les corrections livrées dans bricks-design 0.2.0 (commit 9a59b99). ADR écrite pour ne pas refaire le spike : les dossiers de test ont été supprimés.

Contexte

Notre générateur figma-bricks-proto (BRI-299) fait écrire à Claude du JS Plugin API directement, et vérifie la conformité au design system après coup par capture d'écran.

noemuch/bridge (MIT, plugin Claude Code) propose l'approche inverse : Claude écrit une spec déclarative (« CSpec » YAML), un compilo TypeScript la traduit en Plugin API, et refuse à la compilation toute valeur qui n'est pas un token du DS. Il ajoute une base de connaissance du DS extraite par API et synchronisée par cron, plus une boucle fix qui apprend des corrections manuelles.

Deux promesses qui adressent nos manques réels : la conformité par construction plutôt que par vérification, et la mémoire des corrections.

Options envisagées

Option A : adopter bridge tel quel

  • Description : setup bridge sur le DS Uimmo, remplacer notre skill.
  • Avantages : compilo maintenu par un tiers ; conformité tokens garantie ; boucle d'apprentissage déjà écrite.
  • Inconvénients : trois blocages constatés au spike (ci-dessous), tous sur notre chemin d'usage principal.
  • Coût estimé : ~2 h de spike (fait) + reprise complète du workflow.

Option B : forker et corriger

  • Description : reprendre le compilo, patcher les trois défauts.
  • Avantages : on garde le compilo.
  • Inconvénients : maintenance d'un fork TypeScript contre un DS qui bouge ; le gain principal (tokens liés) est déjà acquis chez nous par le clone-and-adapt, qui hérite gratuitement des variables.
  • Coût estimé : élevé et récurrent.

Option C : ne pas adopter, reprendre les idées

  • Description : abandonner l'outil, reprendre les deux mécanismes qui nous manquaient — registre du DS généré depuis Figma, et boucle d'apprentissage des corrections.
  • Avantages : coût borné, aucun fork ; les deux mécanismes sont indépendants du compilo.
  • Inconvénients : on n'a pas la garantie à la compilation, seulement des gates de vérification.

Décision

Option retenue : C.

Le spike a exécuté la chaîne complète (extraction du DS Uimmo, CSpec d'un écran de confirmation d'investissement, compilation, exécution dans le bac-à-sable App Invest). Le rendu structurel est excellent : sur la carte produite, itemSpacing, les 4 paddings, les 4 rayons, fills et strokes étaient tous liés aux variables Uimmo, du premier coup.

Trois blocages, tous sur notre cas d'usage :

  1. Le transport officiel est cassé en multi-chunk. Le compilo découpe la sortie en chunks qui se passent l'état via globalThis. Vérifié : entre deux appels use_figma, globalThis ne survit pas. Tout écran non trivial produit ≥ 2 chunks → le second échoue. Le chemin réellement testé côté amont est figma-console-mcp (Figma Desktop + token personnel), pas le MCP officiel que nous utilisons.
  2. REPEAT ne remplit pas les composants. La substitution {{clé}} ne s'applique qu'aux nœuds texte, jamais aux propriétés d'instance. Toute liste faite de composants du DS (ListItem, FinancialLineItem, ProjectCard) sort avec les placeholders littéraux.
  3. Les échecs sont silencieux. Variante introuvable → repli sur defaultVariant sans erreur ; propriété non résolue → instruction sautée sans erreur. Premier run du spike : 0 variante sur 4 trouvée, aucun texte appliqué, et pourtant compilation exit 0 et exécution success: true. C'est l'inverse de la promesse « compiler-grade trust » : la garantie porte sur les tokens, pas sur le contenu.

Le second run, avec un registre exact, a matché 4 variantes sur 4 et appliqué tous les textes — l'outil fonctionne, mais seulement si la base de connaissance est juste, ce qui est précisément le problème qu'il prétend supprimer.

Conséquences

Positives attendues

  • Registre du DS généré depuis Figma (ds-registry.json) au lieu d'une antisèche écrite à la main : 125 variables, 13 styles, 22 composants avec leurs clés de propriétés et tuples de variantes exacts.
  • Dix clés fausses corrigées dans le cookbook au passage — dont trois sur ListItem, qui rendaient ses éditions inopérantes. Comme setProperties ignore silencieusement une clé inconnue, ces échecs ne remontaient pas : des maquettes sortaient avec les placeholders du DS sans que personne ne le voie.
  • Boucle d'apprentissage des corrections manuelles (fix-loop.md) : snapshot de l'arbre, diff, classement LEARNING (lié à un token → persisté) / FLAG (valeur en dur → remonté).
  • Phase D du skill durcie en trois gates prouvés par une sortie.

Négatives acceptées

  • Pas de garantie à la compilation : on reste sur de la vérification a posteriori, donc dépendants de la discipline des gates.
  • Le registre doit être régénéré quand le DS bouge — la procédure est documentée, la cadence reste à tenir.
  • Une retouche faite à l'intérieur d'une instance sur un nœud qui n'est pas une propriété de composant échappe au diff de la boucle fix (limite assumée, sinon les snapshots deviennent inexploitables).

Reversibilité

  • Coût d'annulation : bas. bridge est public et sous licence MIT, reclonable à tout moment. Les dossiers de spike locaux (~/Dev/bridge, ~/Dev/bridge-spike) ont été supprimés : cette ADR est la trace.

Plan d'implémentation

  • [x] Spike complet sur le DS Uimmo — 2026-08-17
  • [x] ds-registry.json + procédure de régénération + gate setPropsChecked
  • [x] Correction des dix écarts du cookbook (vérifiés : 9 composants, 0 propriété en échec)
  • [x] Boucle fix documentée, script de snapshot testé sur un écran réel
  • [x] Livré dans bricks-design 0.2.0 (commit 9a59b99)
  • [ ] Premier cycle fix complet de bout en bout — jamais exécuté : seule la partie snapshot est testée. C'est ce tour qui dira si le mécanisme tient.
  • [ ] Tenir la régénération du registre à chaque publication notable du DS

Métriques de succès

  • Plus aucune maquette livrée avec un placeholder du DS resté en place (« Label », « 0,00 € », « Value »).
  • Une correction manuelle faite une fois n'a pas à être refaite à la génération suivante.
  • Aucune clé fausse détectée au prochain contrôle du registre.

Vérification post-implémentation

Le gate propriétés (failed: []) et le gate visuel de la Phase D sont les contrôles permanents. Signal d'alerte : un setProperties qui échoue = registre périmé, à régénérer avant d'aller plus loin. Le premier cycle fix complet reste à faire — jusque-là, la boucle est en place mais non éprouvée.

Sources

  • noemuch/bridge — dépôt évalué (MIT)
  • Spike local du 2026-08-17 (conversation avec remy) — extraction Uimmo, CSpec, compilation et exécution dans le bac-à-sable App Invest q8Qg9VOpr6jriTVOt5X7Os, page « 🧪 Spike bridge »
  • Commit 9a59b99 de ce repo — corrections et boucle fix
  • projects/figma-bricks-proto · BRI-299
  • ds-registry-extract.md — table des dix écarts corrigés

Révisions

  • 2026-08-17 : créée en accepted