From fca1cebdc03f5a6b48b46dd947a108baf3e954eb Mon Sep 17 00:00:00 2001
From: Baptiste LAFOURCADE
Date: Fri, 30 Oct 2026 12:15:02 +0100
Subject: [PATCH 01/26] docs(aidd-ui): frame the ui plugin rework
Co-Authored-By: Claude Opus 5.5
---
.../2026_10_30_aidd-ui-rework/brainstorm.md | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/brainstorm.md
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/brainstorm.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/brainstorm.md
new file mode 100644
index 000000000..128dd1f7e
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/brainstorm.md
@@ -0,0 +1,71 @@
+---
+status: approved
+---
+
+# aidd-ui : un design system qui vit avec le code
+
+Pour un dev qui conçoit l'UI avec une IA : le plugin crée, fait évoluer et versionne un design system, et le relie aux écrans et au code, pour que chaque changement soit tracé et propagé sans travail manuel.
+
+## Clair
+
+### Périmètre
+
+- Tout est dans le périmètre de la première version, versionnage par élément compris. Les étapes forment une seule chaîne, pas des outils séparés.
+- La chaîne : marque et identité (projet, utilisateurs, domaine, plateformes), tokens, atomes, molécules, compositions, parcours et wireframes, écrans finis, code.
+- La marque part du contexte réel (utilisateurs, domaine, plateformes), pas d'un style par défaut.
+- Deux points de départ : un projet vierge, où le DS est construit, et un projet existant, où le DS est extrait du code.
+- Les skills suivent le format lean de brainstorm, plan et implement : chaque mot a sa place.
+
+### Emplacement
+
+- Tout vit dans `aidd_docs/ui/`, un dossier dédié avec un fichier par élément. Les parcours vont dans `ui/journeys/`. Rien n'est posé à côté du code.
+- L'IA écrit les fiches, chacune suivant son template : token, atome, molécule, composition, écran, parcours.
+- Les artefacts ne dépendent d'aucune techno. Les tokens suivent le format W3C DTCG 2025.10. Figma et Claude Design se branchent, le contrat du projet fait foi.
+
+### Lien
+
+- Le lien entre le design system, les écrans et le code est le cœur du plugin. On relie composants et écrans, pas chaque token.
+- Chaque élément correspond à un seul fichier de code, identifié par son chemin et le nom du composant.
+- Les usages se lisent dans les compositions du DS, et le rapport d'impact remonte cet arbre.
+
+### Feature
+
+- Chaque feature a son `ui.md`, le contrat UI de la feature. Une fois la feature implémentée, le code est vérifié contre ce contrat et l'index est mis à jour.
+- Quand un élément change : rapport d'impact, validation, régénération de ce qui est touché, nouvelle validation si besoin, puis nouvelle version du DS.
+
+### Vitrine
+
+- Un script génère la vitrine à partir des fiches et de templates HTML fixes, sans IA : le rendu est identique à chaque fois et se régénère à volonté.
+- Elle montre les éléments, leurs liens et l'endroit où chacun est utilisé.
+- Les écrans y apparaissent dans leur version validée, la maquette HTML créée par l'IA avec les vrais tokens, et chacun porte un lien vers le réel (route ou fichier).
+
+### Vérifications
+
+- Des scripts Node déterministes, qui tournent partout sans IA, vérifient le format de chaque fichier généré (écrans HTML compris), un lien vers un fichier absent, un fichier UI absent de l'index, une composition qui utilise un élément inexistant, et une valeur en dur dans le code.
+- Une fiche mal formée bloque la construction de la vitrine.
+- Des hooks (`SessionStart`, `PostToolUse` sur `aidd_docs/ui/`) lancent ces scripts. Ce sont les mêmes scripts qu'on lance à la main, donc ils marchent aussi dans les outils sans hooks.
+- L'IA juge le sens : le code fait-il ce que dit le `ui.md` ?
+
+### Audit et review
+
+- L'audit UI appartient au plugin. Il constate et ne corrige rien. Il compare le validé et le réel : capture d'écran sur le web, fiche contre code ailleurs. Le volet UI de l'audit dev est retiré une fois cet audit en place.
+- La review design se fait dans une page HTML interactive : OK ou pas OK par écran, avec un commentaire, et les verdicts sont enregistrés dans un fichier du projet. Quand l'utilisateur dit qu'il a fini, l'IA lit le fichier et continue.
+- La review code reste dans dev. L'accessibilité fait partie du plugin.
+
+### Signal de réussite
+
+Sur un projet vierge comme sur un projet existant :
+
+- le flow complet passe de bout en bout jusqu'à tous les écrans voulus ;
+- les features générées ensuite sont liées, sans dérive, et testées ;
+- les mises à jour et le cycle de vie s'enchaînent de façon cohérente.
+
+## Supposé
+
+- On repart de zéro et l'ancienne PR aidd-ui est fermée. Seules ses idées sont gardées : boucle delta, ordre de priorité entre sources, classes de dérive.
+- La vitrine s'inspire d'un outil propriétaire vu en démo : DS, liens et usages visibles, tout normé et vérifié par script.
+- Le réel n'est rendu que sur le web. Ailleurs, l'audit compare la fiche au code.
+
+## Ouvert
+
+- Projet pilote : Gouvernail ou Keros pour le cas vierge. Le cas existant demande un projet qui a déjà du code UI.
From 67b659c55665dcecb1a9ee22794aba45f6183492 Mon Sep 17 00:00:00 2001
From: Baptiste LAFOURCADE
Date: Fri, 30 Oct 2026 14:39:03 +0100
Subject: [PATCH 02/26] docs(aidd-ui): specify the ui plugin rework and its
roadmap
Co-Authored-By: Claude Opus 5.5
Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
---
.../2026_10_30_aidd-ui-rework/roadmap.md | 33 ++++
.../2026_10/2026_10_30_aidd-ui-rework/spec.md | 147 ++++++++++++++++++
2 files changed, 180 insertions(+)
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/roadmap.md
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/spec.md
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/roadmap.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/roadmap.md
new file mode 100644
index 000000000..4a1410d59
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/roadmap.md
@@ -0,0 +1,33 @@
+# aidd-ui : feuille de route
+
+Cinq pull requests empilées, chacune planifiée, codée et revue à son tour. Le contrat est dans [spec.md](./spec.md).
+
+## Skills
+
+| Skill | Fait | Produit |
+| --- | --- | --- |
+| `01-system` | pose la marque, les tokens, les assets et les composants, depuis rien ou en les extrayant du code ; conduit un changement de l'impact jusqu'aux nouvelles versions | `system.md`, `brand.md`, `tokens.json`, `assets/`, `components/` |
+| `02-screens` | dessine les parcours, les wireframes puis les écrans avec leurs états | `journeys/`, `screens/` |
+| `03-review` | ouvre la page de review et reprend à partir des verdicts | `reviews/` |
+| `04-feature` | écrit le `ui.md` d'une feature, puis vérifie son code et met à jour les liens | `ui.md` dans le dossier de la tâche |
+| `05-audit` | constate les écarts sans rien corriger | un rapport |
+
+Un skill ne nomme jamais un autre skill.
+
+La vérification est un hook, déclenché à chaque écriture dans `aidd_docs/ui/` : chaque skill en hérite et voit l'erreur pendant qu'il travaille. Elle se lance aussi à la main. Chaque skill porte ses propres scripts de génération : `tokens.css` pour `01-system`, la vitrine pour `02-screens`, la page de review pour `03-review`.
+
+`01-hello` disparaît avec la PR 2.
+
+## Pull requests
+
+| # | Contenu | Fini quand |
+| --- | --- | --- |
+| 1 | Socle : règles de chaque fiche, vérification complète en hook et à la main | chaque règle de la spec a un cas qui la fait échouer ; un projet exemple complet passe |
+| 2 | `01-system` : marque, tokens, assets, composants, extraction depuis le code, génération de `tokens.css`, flux de changement | sur le pilote vierge, puis sur Gouvernail et Kairos, le design system est posé, puis un changement de token produit son impact et ses versions |
+| 3 | `02-screens`, `03-review`, vitrine | sur le pilote vierge, tous les écrans voulus sont validés en review, vitrine générée deux fois identique |
+| 4 | `04-feature`, et la lecture du `ui.md` par le plan et l'implémentation | une feature du pilote passe du `ui.md` au code vérifié, liens à jour |
+| 5 | `05-audit`, retrait du volet UI de l'audit dev | l'audit du pilote signale chaque écart semé exprès, et rien d'autre |
+
+## Limites connues
+
+- Le retour du hook à l'agent est garanti sur Claude Code. Codex ne lance le hook qu'une fois approuvé ; Kilo et opencode perdent sa sortie ; Cursor et Copilot le lancent sur chaque outil. Ailleurs, la commande à la main est la garantie.
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/spec.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/spec.md
new file mode 100644
index 000000000..8a39fb546
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/spec.md
@@ -0,0 +1,147 @@
+# aidd-ui : un design system qui vit avec le code
+
+## Target
+
+Dans un projet, un dev qui conçoit l'UI avec une IA obtient un design system versionné, relié à ses écrans et à son code, dont chaque changement est tracé, propagé et vérifiable sans IA.
+
+## Hard constraints
+
+### Arborescence
+
+Tout le design system vit dans `aidd_docs/ui/`, un fichier par élément, rien à côté du code.
+
+```txt
+aidd_docs/ui/
+├── system.md racine du design system
+├── brand.md identité de marque
+├── tokens.json tokens, format W3C DTCG 2025.10
+├── tokens.css généré depuis tokens.json, jamais écrit à la main
+├── assets/.md icône, image, illustration, avec son fichier à côté
+├── components/.md atome, molécule ou composition
+├── components/.html rendu du composant, toutes variantes et tous états
+├── screens/.md écran
+├── screens/.html maquette de l'écran, tous ses états dans un seul fichier
+├── journeys/.md parcours utilisateur
+├── reviews/.md verdicts d'une review du design system
+└── showcase/ vitrine générée, jamais écrite à la main, ignorée par git
+```
+
+Le contrat UI d'une feature, `ui.md`, vit dans le dossier de sa tâche, à côté du plan. Il n'est jamais versé dans `aidd_docs/ui/`.
+
+### Fiches
+
+Chaque fiche porte en tête : `id` (égal au nom du fichier, unique), `kind`, `status`, `version`.
+
+| Fiche | Contient en plus |
+| --- | --- |
+| `system.md` | version du design system, plateformes, breakpoints, thèmes, langues et sens d'écriture, dossiers UI du code, chemins ignorés, librairies de composants utilisées |
+| `brand.md` | projet, utilisateurs, domaine, plateformes, personnalité et ton, charte imposée s'il y en a une, références et anti-références |
+| asset | type (icône, image, illustration), fichier, texte alternatif attendu |
+| atome, molécule, composition | éléments utilisés, tokens utilisés, variantes, états (au moins défaut, survol, focus, désactivé, et chargement ou erreur quand ils existent), comportement clavier et rôle accessible, lien vers le code |
+| écran | éléments utilisés, états (au moins défaut, vide, chargement, erreur, sans droits quand ils existent), breakpoints couverts, route ou fichier réel, lien vers le code |
+| parcours | persona, étapes ordonnées, chaque étape un écran et l'action qui mène à la suivante |
+| review | écrans revus, verdict OK ou pas OK par écran et par état, commentaire, écrans restants |
+
+### Cycle de vie
+
+- `proposé` : créé, pas encore validé.
+- `validé` : rendu approuvé en review.
+- `codé` : un lien vers le code existe et le validateur le confirme.
+- `déprécié` : ne doit plus être utilisé, nomme son remplaçant ou dit pourquoi il n'en a pas.
+- Le lien vers le code est obligatoire à `codé`, facultatif avant.
+- Modifier un élément `codé` le repasse à `proposé` le temps de la review ; il redevient `codé` quand le code suit sa nouvelle version.
+- Un élément non déprécié n'utilise jamais un élément déprécié.
+
+### Lien avec le code
+
+- Un élément correspond à un seul fichier de code, identifié par son chemin et le nom du composant exporté.
+- Un composant de librairie est lié à son paquet et à son nom exporté.
+- Chaque fichier sous un dossier UI déclaré est lié à une fiche ou couvert par un chemin ignoré.
+- Les usages se lisent dans les fiches : un token mène aux composants qui le déclarent, un composant aux compositions et écrans qui l'utilisent, un écran aux parcours, chaque élément à son fichier de code. Le rapport d'impact suit ce chemin.
+
+### Versions et historique
+
+- Chaque élément a une version entière et un historique : une ligne par version, avec le changement, s'il est cassant, et la tâche qui l'a fait.
+- Est cassant : retirer une variante, un état ou une propriété, renommer ou supprimer un token, déprécier un élément.
+- Le design system a sa propre version dans `system.md` : un changement cassant monte la majeure, un autre la mineure.
+- Deux lignes d'historique qui revendiquent la même version d'un élément sont signalées, pour que la personne tranche, comme un conflit git.
+
+### Changements
+
+- Un changement produit d'abord un rapport d'impact : éléments, écrans, parcours et fichiers de code touchés.
+- Après validation, les rendus HTML touchés sont régénérés, revus si leur aspect change, puis versions et historiques sont mis à jour.
+- Le code suit dans la feature qui porte le changement, jamais en dehors.
+
+### Feature
+
+- Une feature qui touche l'UI a son `ui.md` : écrans et éléments réutilisés, créés ou modifiés, et ce que le code doit respecter.
+- Une feature sans UI n'en a pas, et rien ne se déclenche.
+- Une feature qui ne fait que réutiliser ne change aucune version.
+- Une fois la feature implémentée, son code est vérifié contre son `ui.md` et les liens vers le code sont mis à jour.
+
+### Rendus
+
+- Écrans et composants sont rendus en HTML avec les vrais tokens, sans valeur en dur.
+- Un écran montre tous ses états dans un seul fichier, avec un sélecteur d'état.
+- La vitrine est générée sans IA, à partir des fiches et de gabarits fixes : identique à chaque génération, elle montre chaque élément, ses variantes, ses états, ses usages et son lien vers le réel.
+- La vitrine affiche la version validée d'un écran et un lien vers le réel.
+
+### Review
+
+- La review design se fait dans une page HTML : OK ou pas OK par écran et par état, avec un commentaire.
+- Les verdicts sont enregistrés dans une fiche review, qui vit avec ce qu'elle revoit : `aidd_docs/ui/reviews/` pour une review du design system, le dossier de la tâche pour une review de feature. Quand la personne dit qu'elle a fini, l'IA lit la fiche et continue.
+- Une review partielle garde les écrans restants, et l'IA reprend là où elle s'est arrêtée.
+
+### i18n et accessibilité
+
+- `system.md` déclare les langues et les sens d'écriture.
+- Les rendus utilisent des propriétés logiques plutôt que physiques quand un sens droite-gauche est déclaré, et aucune largeur fixe sur du texte.
+- Dates et nombres suivent la langue.
+- Base d'accessibilité : WCAG 2.2 AA, mobile d'abord, tailles en `rem`, aucun comportement qui n'existe qu'au survol sur écran tactile.
+
+### Vérification
+
+- La structure se vérifie à chaque écriture dans le design system, quel que soit le skill qui écrit, et à la main, par des scripts déterministes, sans IA, qui tournent sur toute machine où tourne Node :
+ - format de chaque fiche et du fichier de tokens ;
+ - éléments utilisés et alias de tokens qui existent ;
+ - cycle de vie respecté ;
+ - liens vers le code valides, couverture des dossiers UI ;
+ - aucune valeur en dur dans les rendus ni dans le code ;
+ - versions en double dans un historique ;
+ - propriétés physiques quand un sens droite-gauche est déclaré.
+- L'IA juge le sens : le code fait-il ce que disent `ui.md` et les fiches ?
+- L'audit UI constate et ne corrige rien : élément sans code, code sans élément, écart entre le validé et le réel, doublons proches, textes trop longs dans la langue la plus longue, accessibilité.
+
+### Format
+
+- Les skills suivent le format lean de brainstorm, plan et implement.
+- Les artefacts ne dépendent d'aucune techno ; Figma et Claude Design se branchent, le contrat du projet fait foi.
+
+## Non-goals
+
+- Plusieurs design systems dans un projet, ou une app web et une app mobile avec deux systèmes.
+- Un composant réparti sur plusieurs fichiers.
+- Synchronisation dans les deux sens avec Figma ou Claude Design, et import de maquettes existantes.
+- Retour à une version précédente du design system.
+- Travail à plusieurs, et parcours pour un designer qui ne code pas.
+- Rendu du réel hors web.
+- Détection des valeurs en dur dans du code non web.
+
+## Done-when
+
+- Sur un projet vierge puis sur un projet existant, le flow passe de la marque jusqu'à tous les écrans voulus, chacun validé en review.
+- Les features générées ensuite sont liées au design system, sans dérive, et leur code est vérifié.
+- Un changement de token, de composant et d'écran produit chacun son rapport d'impact, ses régénérations et ses nouvelles versions, sans élément oublié.
+- Deux features parallèles sur le même élément aboutissent à une version en double signalée.
+- La vitrine générée deux fois de suite est identique.
+- Chaque règle de vérification a un cas qui la fait échouer.
+- Sur Gouvernail et Kairos, le design system est extrait du code existant.
+
+## Open Questions
+
+- TBD: quel projet pilote pour le cas vierge, sachant que Gouvernail et Kairos, pilotes du cas existant, ont déjà une identité ?
+
+## Context
+
+- Brief approuvé : [brainstorm.md](./brainstorm.md).
+- Découpage en pull requests : [roadmap.md](./roadmap.md).
From 9db5c887bc58093237dd16c9aa5fb6707b2a36d6 Mon Sep 17 00:00:00 2001
From: Baptiste LAFOURCADE
Date: Fri, 30 Oct 2026 14:50:05 +0100
Subject: [PATCH 03/26] docs(aidd-ui): plan the ui foundation validator
Co-Authored-By: Claude Opus 5.5
Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
---
.../2026_10_30_aidd-ui-foundation/phase-1.md | 122 ++++++++++++++++++
.../2026_10_30_aidd-ui-foundation/phase-2.md | 77 +++++++++++
.../2026_10_30_aidd-ui-foundation/phase-3.md | 64 +++++++++
.../2026_10_30_aidd-ui-foundation/phase-4.md | 88 +++++++++++++
.../2026_10_30_aidd-ui-foundation/plan.md | 56 ++++++++
5 files changed, 407 insertions(+)
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-1.md
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-2.md
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-3.md
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-4.md
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/plan.md
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-1.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-1.md
new file mode 100644
index 000000000..c760e59ce
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-1.md
@@ -0,0 +1,122 @@
+---
+status: pending
+---
+
+# Instruction: Records and history
+
+## Architecture projection
+
+> Tree of the final files. ✅ create · ✏️ modify · ❌ delete
+
+```txt
+.
+├── plugins/aidd-ui/hooks/lib/
+│ ├── markdown.cjs ✅
+│ ├── project.cjs ✅
+│ ├── records.cjs ✅
+│ └── history.cjs ✅
+└── scripts/__tests__/
+ ├── aidd-ui-records.test.js ✅
+ └── fixtures/
+ ├── README.md ✏️
+ └── aidd-ui/
+ └── project.js ✅
+```
+
+## Test Scope
+
+| Scenario | Action | Observable outcome | Actor |
+| ------------ | ----------------------- | -------------------- | ------------------------------- |
+| Setup | `writeProject(tmp)` from `fixtures/aidd-ui/project.js` | a complete valid project: every record kind, tokens, renders, code under `src/ui/` | system |
+| Happy path | `records.check(load(tmp))` and `history.check(load(tmp))` | both return `[]` | system |
+| Edge case | R1: a record without front matter, or a line that is neither `key: value` nor `key: [a, b]` | one problem naming the file and the line | system |
+| Edge case | R2: `kind: widget`, or an atom under `screens/` | one problem: unknown kind, or kind outside its folder | system |
+| Edge case | R3: a required key removed, per kind; `status: done`; `interactive: maybe`; asset `type: photo` | one problem naming the missing key or the bad value | system |
+| Edge case | R4: `id` differs from the file name; two records with the same `id` | one problem each | system |
+| Edge case | R5: `version: 0` or `v2` on an element; `version: 1.0` on `system.md` | one problem each: element integer from 1, system semver | system |
+| Edge case | R6: `uses` names an absent id; an atom uses an atom; a molecule uses a composition; a screen uses a screen | one problem each | system |
+| Edge case | R7: an interactive component without `hover`, `focus` or `disabled`; a component without `default`; a screen without `default`; an interactive component without `## Keyboard` | one problem each | system |
+| Edge case | R8: `status: coded` without `code` | one problem | system |
+| Edge case | R9: `deprecated` without `replaced-by`; `replaced-by` absent or deprecated; `replaced-by: none` without `## Deprecation` | one problem each | system |
+| Edge case | R10: a non-deprecated record uses a deprecated one | one problem naming both | system |
+| Edge case | R11: a screen breakpoint missing from `system.md` | one problem | system |
+| Edge case | R12: a journey step naming an absent screen | one problem | system |
+| Edge case | R13: a review missing a row for one screen state; `Verdict` not `ok`, `ko` or `pending` | one problem each | system |
+| Edge case | R14: `brand.md` without one of its seven headings | one problem naming the heading | system |
+| Edge case | R16: `system.md`, `brand.md` or a review with `status: coded` or `deprecated` | one problem: only `proposed` or `validated` | system |
+| Edge case | R15: an asset whose `file` is absent | one problem | system |
+| Edge case | H1: a versioned record without `## History` | one problem | system |
+| Edge case | H2: two rows for version 2, as after a merge of two branches | one problem: two changes claim version 2, renumber | system |
+| Edge case | H3: front matter `version` not the highest row; a gap from 1 to 3 | one problem each | system |
+| Edge case | H4: `Breaking` neither `yes` nor `no` | one problem | system |
+| Edge case | H5: a task with a breaking element row and no major bump in `system.md`; a task with only non-breaking rows whose `system.md` row raises nothing; a task in an element history with no `system.md` row | one problem each, naming the task | system |
+| Edge case | H6: a `deprecated` record whose last history row says `Breaking: no` | one problem | system |
+| Teardown | remove `tmp` | no file left | system |
+
+## Tasks to do
+
+### `1)` Fixture project
+
+> One complete valid project every phase mutates.
+
+1. Export `writeProject(dir)` writing:
+ - Every record holds `id`, `kind`, `status`, `version` and a `## History` table (Version, Change, Breaking, Task); every element's first row is task `ds-init`.
+ - `aidd_docs/ui/system.md`: `id: system`, `kind: system`, `status: validated`, `version: 2.0.0`, `platforms: [web]`, `breakpoints: [mobile, desktop]`, `themes: [light, dark]`, `locales: [fr, ar]`, `directions: [ltr, rtl]`, `code-roots: [src/ui]`, `ignore: [src/ui/tokens.css]`, `libraries: [@radix-ui/react-dialog]`; a `## Breakpoints` table; `## History` rows `1.0.0` for task `ds-init`, `2.0.0` for task `retire-old-button`.
+ - `aidd_docs/ui/brand.md`: `id: brand`, `kind: brand`, `status: validated`, `version: 1`; headings `## Project`, `## Users`, `## Domain`, `## Platforms`, `## Personality and tone`, `## References`, `## Anti-references`, optional `## Imposed charter`.
+ - `aidd_docs/ui/tokens.json`: `color.brand.primary` (srgb, dark theme extension), `color.text.default` aliasing it, `space.md` (rem), `border.thin` (`0.0625rem`), `motion.fast` (ms), `font.body` (family list), `font.weight.bold` (700).
+ - `aidd_docs/ui/assets/icon-search.md` with `icon-search.svg`.
+ - `aidd_docs/ui/components/`, each with `tokens`, `variants`, `states`, `role` and its `.html` render carrying a `data-variant` per variant, a `data-state` per state, tokens through `var(--...)` only, logical properties only:
+ - atom `button`: interactive, `role: button`, coded `src/ui/Button.tsx#Button`, variants `primary`, `secondary`, states `default`, `hover`, `focus`, `disabled`, `## Keyboard`.
+ - molecule `search-field`: interactive, `role: search`, validated, uses `button`, `icon-search`, no code, variants `default`, states `default`, `hover`, `focus`, `disabled`, `## Keyboard`.
+ - composition `dialog`: interactive, `role: dialog`, coded `package:@radix-ui/react-dialog#Root`, uses `button`, variants `default`, states `default`, `hover`, `focus`, `disabled`, `## Keyboard`.
+ - atom `old-button`: not interactive, `role: button`, variants `default`, states `default`, deprecated, `replaced-by: button`, history row 2 `Breaking: yes` for task `retire-old-button`.
+ - `aidd_docs/ui/screens/home.md` (coded, `src/ui/HomePage.tsx#HomePage`, states `default`, `empty`, `loading`, `error`, breakpoints `mobile`, `desktop`, route `/`) with `home.html`.
+ - `aidd_docs/ui/journeys/onboarding.md` (`## Steps` table: Screen, Action).
+ - `aidd_docs/ui/reviews/first-pass.md` (`status: proposed`, `scope: system`, `screens: [home]`, `## Verdicts` table: Screen, State, Verdict, Comment, one row per state, one `pending`: the remaining screens are the `pending` rows).
+ - `src/ui/Button.tsx`, `src/ui/HomePage.tsx`, `src/ui/tokens.css` (ignored, holds hex values).
+2. Add the fixture to `scripts/__tests__/fixtures/README.md`.
+
+### `2)` Markdown reading
+
+> Records read the same way everywhere.
+
+1. `markdown.cjs`: front matter between the first two `---` lines into `{key: string | string[]}`, a problem per malformed line; `## ` headings into sections; a section's first table into rows keyed by header.
+
+### `3)` Project loading
+
+> One read of the tree every check shares.
+
+1. `project.cjs`: `load(root)` returns `null` without `aidd_docs/ui/`, else every record with its file, folder, front matter and sections, the raw `tokens.json` text, and the render paths.
+
+### `4)` Record rules
+
+> R1 to R16 hold.
+
+1. `records.cjs`: `check(project)` returns `{file, message}` per broken rule, in rule order.
+2. Required keys: every record `id`, `kind`, `status`, `version`; `system.md` `platforms`, `breakpoints`, `themes`, `locales`, `directions`, `code-roots`, `ignore`, `libraries`; component `uses`, `tokens`, `variants`, `states`, `interactive`, `role`; screen `uses`, `states`, `breakpoints`, `route`; journey `persona`; asset `type`, `file`, `alt`; review `scope`, `screens`; `code` only when `coded`; `replaced-by` only when `deprecated`.
+3. Folders: `components/` holds atom, molecule, composition; `screens/` screen; `journeys/` journey; `assets/` asset; `reviews/` review; the root holds `system.md`, `brand.md`.
+
+### `5)` History rules
+
+> H1 to H6 hold.
+
+1. `history.cjs`: `check(project)` reads each `## History` table (Version, Change, Breaking, Task) and returns `{file, message}` per broken rule.
+2. Bumps: the system row of a task raises the major version over the previous row when any element row of that task says `yes`, else at least the minor.
+3. A `deprecated` record's last row says `Breaking: yes`.
+
+### `6)` Tests
+
+> Each rule has the mutation that turns its test red.
+
+1. `aidd-ui-records.test.js`: the Happy path, then one test per Edge case row, each asserting its own message.
+
+## Test acceptance criteria
+
+| Task | Acceptance criteria |
+| ---- | -------------------------------- |
+| 1 | `writeProject` output passes both checks; the fixture README lists it |
+| 2 | a malformed front matter line comes back as a problem with its line |
+| 3 | `load` returns `null` without `aidd_docs/ui/` and every record otherwise |
+| 4 | each of R1 to R16 has its own message |
+| 5 | each of H1 to H6 has its own message, H2 naming the claimed version |
+| 6 | reverting any one rule turns exactly its test red |
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-2.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-2.md
new file mode 100644
index 000000000..4fb53fa02
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-2.md
@@ -0,0 +1,77 @@
+---
+status: pending
+---
+
+# Instruction: Tokens and renders
+
+## Architecture projection
+
+> Tree of the final files. ✅ create · ✏️ modify · ❌ delete
+
+```txt
+.
+├── plugins/aidd-ui/hooks/lib/
+│ ├── tokens.cjs ✅
+│ └── renders.cjs ✅
+└── scripts/__tests__/
+ └── aidd-ui-tokens-renders.test.js ✅
+```
+
+## Test Scope
+
+| Scenario | Action | Observable outcome | Actor |
+| ------------ | ----------------------- | -------------------- | ------------------------------- |
+| Setup | `writeProject(tmp)` | the valid project | system |
+| Happy path | `tokens.check(load(tmp))`, `renders.check(load(tmp))` | both `[]` | system |
+| Edge case | T1: `tokens.json` not JSON | one problem | system |
+| Edge case | T2: a name starting with `$` that is not a reserved key; a name holding `.` | one problem each | system |
+| Edge case | T3: a token without `$value`; without any `$type`; with `$type: colour` | one problem each | system |
+| Edge case | T4: color `colorSpace: cmyk`; color with two components; `hex: #fff`; dimension `unit: em`; duration `unit: min`; fontWeight `1200`; cubicBezier x `1.5` | one problem each | system |
+| Edge case | T5: `{color.missing}`; `{color.brand}` naming a group | one problem each | system |
+| Edge case | T6: theme `sepia` absent from `system.md`; a theme value of the wrong shape | one problem each | system |
+| Edge case | T7: a component `tokens` entry naming no token | one problem | system |
+| Edge case | T8: a dimension token in `px` | one problem: sizes are in `rem` | system |
+| Edge case | V1: a component or screen without its `.html` | one problem | system |
+| Edge case | V2: a declared variant or state with no `data-variant` or `data-state` in the render | one problem each | system |
+| Edge case | V3: `var(--color-missing)` in a render | one problem | system |
+| Edge case | V4: `#336699`, `rgb(`, `hsl(` in a render | one problem each, with its line | system |
+| Edge case | V6: `16px`, `1.5rem` or `200ms` written in a render | one problem each: only tokens carry values | system |
+| Edge case | V5: `margin-left` in a render while `system.md` declares `rtl`; the same with only `ltr` | one problem; none | system |
+| Teardown | remove `tmp` | no file left | system |
+
+## Tasks to do
+
+### `1)` Token rules
+
+> T1 to T8 hold.
+
+1. `tokens.cjs`: walk the tree; a key starting with `$` is a property, any other is a group or a token, a token being an object with `$value`.
+2. Resolve `$type`: own, else the aliased token's, else the closest group's.
+3. Check primitive shapes per the 2025.10 module; for composite types, check only that `$value` exists.
+4. Read themes from `$extensions["dev.ai-driven.themes"]`; check names against `system.md` `themes`, values against the token's type.
+5. Require `rem` on every dimension token.
+6. Export the set of token paths and their CSS names for renders.
+
+### `2)` Render rules
+
+> V1 to V6 hold.
+
+1. `renders.cjs`: require `.html` beside each component and screen record.
+2. Find `data-variant="x"` and `data-state="x"` for each declared variant and state.
+3. Flag each `var(--x)` with no token, each colour literal (`#` with 3, 4, 6 or 8 hex digits, `rgb(`, `rgba(`, `hsl(`, `hsla(`) with its line, and, when `rtl` is declared, each `margin-left`, `margin-right`, `padding-left`, `padding-right`, `border-left`, `border-right`, `left:`, `right:`, `text-align: left`, `text-align: right`, `float: left`, `float: right`.
+4. Flag each number followed by `px`, `rem`, `em`, `ms` or `s` outside `var(...)`; `0` alone passes.
+5. Export the colour, unit and physical-property patterns for the code checks.
+
+### `3)` Tests
+
+> Each rule has its mutation.
+
+1. `aidd-ui-tokens-renders.test.js`: the Happy path, then one test per Edge case row.
+
+## Test acceptance criteria
+
+| Task | Acceptance criteria |
+| ---- | -------------------------------- |
+| 1 | each of T1 to T8 has its own message |
+| 2 | each of V1 to V6 has its own message; `ltr` alone allows physical properties |
+| 3 | reverting any one rule turns exactly its test red |
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-3.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-3.md
new file mode 100644
index 000000000..ba863f296
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-3.md
@@ -0,0 +1,64 @@
+---
+status: pending
+---
+
+# Instruction: Code link
+
+## Architecture projection
+
+> Tree of the final files. ✅ create · ✏️ modify · ❌ delete
+
+```txt
+.
+├── plugins/aidd-ui/hooks/lib/
+│ └── code.cjs ✅
+└── scripts/__tests__/
+ └── aidd-ui-code.test.js ✅
+```
+
+## Test Scope
+
+| Scenario | Action | Observable outcome | Actor |
+| ------------ | ----------------------- | -------------------- | ------------------------------- |
+| Setup | `writeProject(tmp)` | the valid project | system |
+| Happy path | `code.check(load(tmp))` | `[]` | system |
+| Edge case | C1: `code` path absent; export name absent from the file; `code` without `#` | one problem each | system |
+| Edge case | C2: `package:left-pad#Pad` not in `libraries` | one problem | system |
+| Edge case | C3: `src/ui/Orphan.tsx` linked by no record and under no `ignore` | one problem naming the file | system |
+| Edge case | C3: a `proposed` record whose `code` points at an existing file | no problem: the link is optional before `coded`, valid when present | system |
+| Edge case | C4: `color: #ff0000` in `src/ui/Button.tsx`; the same in `src/ui/tokens.css` | one problem with its line; none, the file is ignored | system |
+| Edge case | C4: `padding: 16px` in a `.css` file under `src/ui/`; the same in a `.tsx` file | one problem; none, units in script files are a stated limit | system |
+| Edge case | C5: two records with the same `code` | one problem naming both | system |
+| Edge case | C6: `margin-left` in a `.css` file under `src/ui/` while `rtl` is declared | one problem | system |
+| Teardown | remove `tmp` | no file left | system |
+
+## Tasks to do
+
+### `1)` Link rules
+
+> C1 and C2 hold.
+
+1. `code.cjs`: split `code` on its last `#`; a `package:` link needs its name in `system.md` `libraries`; any other needs the file under the project root and the export as a whole word in it.
+
+### `2)` Coverage and literals
+
+> C3 to C6 hold.
+
+1. Walk each `code-roots` prefix; flag each file no `code` names and no `ignore` prefix covers.
+2. In files with extension `.css`, `.scss`, `.js`, `.jsx`, `.ts`, `.tsx`, `.vue`, `.svelte`, `.html`, outside `ignore`, flag colour literals with their line, with the render pattern.
+3. In `.css` and `.scss` files only, flag unit literals and, when `rtl` is declared, physical properties, with the render patterns.
+4. Flag two records sharing one `code`.
+
+### `3)` Tests
+
+> Each rule has its mutation.
+
+1. `aidd-ui-code.test.js`: the Happy path, then one test per Edge case row.
+
+## Test acceptance criteria
+
+| Task | Acceptance criteria |
+| ---- | -------------------------------- |
+| 1 | an absent file, an absent export, a malformed link and an undeclared package each have their own message |
+| 2 | an orphan file, a colour literal, a unit literal, a shared link and a physical property each have their own message; an ignored file and a unit in a script file have none |
+| 3 | reverting any one rule turns exactly its test red |
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-4.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-4.md
new file mode 100644
index 000000000..b35d036fc
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/phase-4.md
@@ -0,0 +1,88 @@
+---
+status: pending
+---
+
+# Instruction: Entry, hook and docs
+
+## Architecture projection
+
+> Tree of the final files. ✅ create · ✏️ modify · ❌ delete
+
+```txt
+.
+├── docs/
+│ └── CATALOG.md ✏️
+├── plugins/aidd-ui/
+│ ├── CATALOG.md ✏️
+│ ├── README.md ✏️
+│ └── hooks/
+│ ├── hooks.json ✅
+│ ├── ui-hook.cjs ✅
+│ └── validate-ui.cjs ✅
+└── scripts/__tests__/
+ └── aidd-ui-validate.test.js ✅
+```
+
+## Test Scope
+
+| Scenario | Action | Observable outcome | Actor |
+| ------------ | ----------------------- | -------------------- | ------------------------------- |
+| Setup | `writeProject(tmp)` | the valid project | system |
+| Happy path | `node plugins/aidd-ui/hooks/validate-ui.cjs tmp` | `VALID`, exit 0 | cli |
+| Edge case | E1: the same on a project without `aidd_docs/ui/` | nothing printed, exit 0 | cli |
+| Edge case | E2: one mutation from each of phases 1, 2 and 3 | one `✗ : ` line each, exit 1 | cli |
+| Edge case | E3: `ui-hook.cjs` with a PostToolUse payload, `cwd` = `tmp`, `tool_input.file_path` under `aidd_docs/ui/`, after a mutation | the `✗` lines on stderr, exit 2 | system |
+| Edge case | E3: the same with `file_path` under `src/ui/` | the `✗` lines on stderr, exit 2 | system |
+| Edge case | E3: the same with `file_path` outside `aidd_docs/ui/` and every code root | silent, exit 0 | system |
+| Edge case | E3: the same on a valid project | silent, exit 0 | system |
+| Edge case | E4: SessionStart payload on a project with failures | stdout: the count then the `✗` lines, exit 0 | system |
+| Edge case | E4: SessionStart on a project without `aidd_docs/ui/` | silent, exit 0 | system |
+| Edge case | E5: PostToolUse payload without `tool_input.file_path`, as a host without matcher sends; empty or non-JSON stdin | silent, exit 0 | system |
+| Teardown | remove `tmp` | no file left | system |
+
+## Tasks to do
+
+### `1)` Manual entry
+
+> One command runs every check.
+
+1. `validate-ui.cjs`: root from the argument, else the working directory; `load`; nothing and exit 0 when `null`; else run `records`, `history`, `tokens`, `renders`, `code` in that order; print `VALID` or one `✗ : ` per problem; exit 1 on any; export `validate(root)` returning the problems.
+
+### `2)` Hook entry
+
+> The same checks on every write and at session start.
+
+1. `ui-hook.cjs`: read stdin JSON; anything else exits 0 silently; root from `cwd`.
+2. PostToolUse: run `validate(root)` only when `tool_input.file_path` is under `aidd_docs/ui/` or a `code-roots` prefix; on problems write the `✗` lines to stderr and exit 2.
+3. SessionStart: on problems write `aidd-ui: problems` then the `✗` lines to stdout; always exit 0.
+4. Any thrown error exits 0 silently: a broken check never blocks a session.
+5. `hooks.json`: `SessionStart` and `PostToolUse` matching `Write|Edit|MultiEdit`, each `node ${CLAUDE_PLUGIN_ROOT}/hooks/ui-hook.cjs`.
+
+### `3)` Tests
+
+> Each entry has its mutation.
+
+1. `aidd-ui-validate.test.js`: one test per Test Scope row, spawning `node` with the payload on stdin.
+
+### `4)` Docs
+
+> The README and catalogs match the tree.
+
+1. `plugins/aidd-ui/README.md`: status from `plugin.json`'s version; the `aidd_docs/ui/` tree and each record's keys; the hand command `node /hooks/validate-ui.cjs`; the limits: no `node`, no feedback in the turn outside Claude Code, Codex runs the hook once trusted, no composite token shape, no non-web code literal, no unit literal in script files, a word of hex letters after `#` counts as a colour; fixed widths on text and long translations are for the audit.
+2. Run `node scripts/sync-generated-docs.mjs` and `sh scripts/summarize-plugin-catalogs.sh`.
+
+### `5)` Contributor checks
+
+> The tree passes what a pull request requires.
+
+1. Run `make check` (`CONTRIBUTING.md`) and `node scripts/check-tests-leave-git-alone.js -- node --test 'scripts/__tests__/**/*.test.js'` (`aidd_docs/memory/testing.md`); fix until both exit 0.
+
+## Test acceptance criteria
+
+| Task | Acceptance criteria |
+| ---- | -------------------------------- |
+| 1 | the valid project prints `VALID`; each phase's mutation prints its line and exits 1 |
+| 2 | each Test Scope hook row gives its exit code and output |
+| 3 | reverting the path filter, the exit 2 or the silent catch turns its own test red |
+| 4 | the README holds the tree, the command and every limit; `docs/CATALOG.md` lists `hooks/ui-hook.cjs` under `SessionStart` and `PostToolUse`; `plugins/aidd-ui/CATALOG.md` lists the hook files |
+| 5 | both commands exit 0 |
diff --git a/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/plan.md b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/plan.md
new file mode 100644
index 000000000..c57f7a0da
--- /dev/null
+++ b/aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/plan.md
@@ -0,0 +1,56 @@
+---
+objective: "A deterministic validator, run by hand and by an aidd-ui hook on every write, rejects any UI record, token, render or code link that breaks the spec."
+status: pending
+---
+
+# Plan: aidd-ui foundation, every record and its validator
+
+Source: aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/spec.md, pull request 1 of aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-rework/roadmap.md.
+
+## Phases
+
+| # | Phase | File | Depends on |
+| --- | ------------ | ---------------------------- | ---------- |
+| 1 | Records and history | [`phase-1.md`](./phase-1.md) | none |
+| 2 | Tokens and renders | [`phase-2.md`](./phase-2.md) | 1 |
+| 3 | Code link | [`phase-3.md`](./phase-3.md) | 1 |
+| 4 | Entry, hook and docs | [`phase-4.md`](./phase-4.md) | 2, 3 |
+
+## External sources
+
+| URL | What it settled |
+| ----- | ----------------- |
+| https://www.designtokens.org/tr/2025.10/format/ | types: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, and composites strokeStyle, border, transition, shadow, gradient, typography; dimension `{value, unit: px or rem}`, duration `{value, unit: ms or s}`, fontWeight 1 to 1000 or a keyword, cubicBezier four numbers with x in 0..1; `$type` from the token, else the referenced token, else the closest parent group, else invalid; names never start with `$` nor hold `{`, `}`, `.`; a `{a.b}` alias targets a token, never a group; `$extensions` keys in reverse-domain notation; `$deprecated` true, false or a string; themes are not in the format module |
+| https://www.designtokens.org/tr/2025.10/color/ | color `$value` is `{colorSpace, components, alpha?, hex?}`, `colorSpace` one of srgb, srgb-linear, hsl, hwb, lab, lch, oklab, oklch, display-p3, a98-rgb, prophoto-rgb, rec2020, xyz-d65, xyz-d50, `components` three numbers or `none`, `hex` six digits |
+| https://code.claude.com/docs/en/hooks#posttooluse | PostToolUse reads `tool_input.file_path` on stdin; exit 2 hands stderr back to the agent |
+
+## Impact
+
+| Category | Verdict and evidence | Handled in |
+| -------------------------------------------------- | -------------------- | ------------------ |
+| runtime | the hook runs on the user's `node` with built-ins only: plugins ship without `node_modules` (`plugins/aidd-context/hooks/update_memory.js`). Kilo and opencode replay only `node ${CLAUDE_PLUGIN_ROOT}/hooks/` (`cli/src/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.ts:27`) and drop the hook's output (`:77`); Cursor and Copilot drop the matcher (`cli/src/contexts/tools/domain/formats/flat-hooks-merge.ts:109`); Codex runs a hook once trusted (`cli/src/contexts/tools/domain/profiles/codex/profile.ts:54`); a sibling `require` survives every translation (`plugins/aidd-telemetry/hooks/catch-up.cjs:2`). Tool names on hosts other than Claude Code: unverified, stated as a limit | 4 |
+| regression | low: no existing file changes behaviour; `01-hello` stays; golden snapshots read `cli/tests/fixtures/framework-real` (`cli/tests/golden/framework-build-golden.e2e.test.ts:17`). Safety-net phase: no | none |
+| architecture | aidd-ui gains its first hooks, `hooks/hooks.json` discovered without a manifest key (`plugins/aidd-context/.claude-plugin/plugin.json`). No skill reaches the validator by path: the hook runs it on every write | 4 |
+| documentation | `docs/CATALOG.md` hooks block and `plugins/aidd-ui/CATALOG.md` are regenerated at pre-commit (`scripts/sync-generated-docs.mjs:49`, `scripts/summarize-plugin-catalogs.sh`), checked by `scripts/__tests__/architecture-doc-matches-the-tree.test.js`; `plugins/aidd-ui/README.md` says `0.1.0-alpha.0`, `plugin.json` holds `0.2.1-alpha.0`; `scripts/__tests__/fixtures/README.md` lists every fixture | 1, 4 |
+
+## Rules
+
+| Rule | Why it applies |
+| ------ | -------------- |
+| A guard ships with the mutation that proves it (`aidd_docs/memory/coding-assertions.md`) | every rule below has one test that its one mutation turns red |
+| No code for an input never observed in real data (`aidd_docs/memory/coding-assertions.md`) | composite token values, alias cycles, globs and non-web code are stated limits, not code |
+| A plugin never holds its own tests (`aidd_docs/memory/testing.md`) | tests and their fixture go in `scripts/__tests__/` |
+| Run the scripts suite wrapped (`aidd_docs/memory/testing.md`) | `node scripts/check-tests-leave-git-alone.js -- node --test ...` |
+| A skill never links outside itself (`aidd_docs/memory/architecture.md`) | the validator lives in `hooks/`, reached by the hook, never by a skill path |
+| Bundled hooks run Node (`aidd_docs/memory/architecture.md`) | without `node` the hook is silent, stated in the README |
+
+## Decisions
+
+| Decision | Why |
+| ---------- | --- |
+| Front matter is flat: `key: value` or `key: [a, b]`, nothing nested; tables in the body carry what has rows | parses with built-ins, no YAML dependency, same reading for an agent and a script |
+| Keys and values are English; the spec's states map to `proposed`, `validated`, `coded`, `deprecated` | the plugin and its users' records share the repository's language |
+| Themes are a token extension `"$extensions": {"dev.ai-driven.themes": {"": }}` | the 2025.10 format module defines no themes; extensions are its sanctioned, preserved escape |
+| A token's CSS name is `--` plus its path joined by `-` | one rule both renders and the later `tokens.css` generator follow |
+| A code link is `path#Export` or `package:#Export` | one file and one export per element, a library component by its package |
+| The validator is `hooks/validate-ui.cjs` over modules in `hooks/lib/`, built one module per phase; `hooks/ui-hook.cjs` runs it for PostToolUse and SessionStart | one source of rules for the hand, the hook and every skill that writes |
From 4c350902c0ed231bdfdd6de4df71799d9c5c6a37 Mon Sep 17 00:00:00 2001
From: Baptiste LAFOURCADE
Date: Fri, 30 Oct 2026 15:15:59 +0100
Subject: [PATCH 04/26] feat(aidd-ui): validate ui records, tokens, renders and
code links on every write
Co-Authored-By: Claude Opus 5.5
Claude-Session: https://claude.ai/code/session_01XeK3mD4irAZumku9bknHhD
---
README.md | 2 +-
.../2026_10_30_aidd-ui-foundation/phase-1.md | 2 +-
.../2026_10_30_aidd-ui-foundation/phase-2.md | 2 +-
.../2026_10_30_aidd-ui-foundation/phase-3.md | 2 +-
.../2026_10_30_aidd-ui-foundation/phase-4.md | 2 +-
.../2026_10_30_aidd-ui-foundation/plan.md | 2 +-
.../2026_10_30_aidd-ui-foundation/run.md | 27 ++
docs/CATALOG.md | 11 +
plugins/aidd-ui/CATALOG.md | 7 +
plugins/aidd-ui/README.md | 61 +++-
plugins/aidd-ui/hooks/hooks.json | 27 ++
plugins/aidd-ui/hooks/lib/code.cjs | 114 ++++++
plugins/aidd-ui/hooks/lib/history.cjs | 138 +++++++
plugins/aidd-ui/hooks/lib/markdown.cjs | 94 +++++
plugins/aidd-ui/hooks/lib/project.cjs | 54 +++
plugins/aidd-ui/hooks/lib/records.cjs | 272 ++++++++++++++
plugins/aidd-ui/hooks/lib/renders.cjs | 95 +++++
plugins/aidd-ui/hooks/lib/tokens.cjs | 230 ++++++++++++
plugins/aidd-ui/hooks/ui-hook.cjs | 68 ++++
plugins/aidd-ui/hooks/validate-ui.cjs | 39 ++
scripts/__tests__/aidd-ui-code.test.js | 133 +++++++
scripts/__tests__/aidd-ui-records.test.js | 336 ++++++++++++++++++
.../__tests__/aidd-ui-tokens-renders.test.js | 208 +++++++++++
scripts/__tests__/aidd-ui-validate.test.js | 130 +++++++
scripts/__tests__/fixtures/README.md | 2 +
scripts/__tests__/fixtures/aidd-ui/project.js | 286 +++++++++++++++
26 files changed, 2337 insertions(+), 7 deletions(-)
create mode 100644 aidd_docs/tasks/2026_10/2026_10_30_aidd-ui-foundation/run.md
create mode 100644 plugins/aidd-ui/hooks/hooks.json
create mode 100644 plugins/aidd-ui/hooks/lib/code.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/history.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/markdown.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/project.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/records.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/renders.cjs
create mode 100644 plugins/aidd-ui/hooks/lib/tokens.cjs
create mode 100644 plugins/aidd-ui/hooks/ui-hook.cjs
create mode 100644 plugins/aidd-ui/hooks/validate-ui.cjs
create mode 100644 scripts/__tests__/aidd-ui-code.test.js
create mode 100644 scripts/__tests__/aidd-ui-records.test.js
create mode 100644 scripts/__tests__/aidd-ui-tokens-renders.test.js
create mode 100644 scripts/__tests__/aidd-ui-validate.test.js
create mode 100644 scripts/__tests__/fixtures/aidd-ui/project.js
diff --git a/README.md b/README.md
index 7868fb461..437922b16 100644
--- a/README.md
+++ b/README.md
@@ -185,7 +185,7 @@ Feature flow, issue-to-PR automation, backlog