@roomi-fields/grillhouse 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/METACADRE.md +1 -1
  3. package/agents/explorateur.md +4 -2
  4. package/agents/questionneur.md +1 -1
  5. package/bin/grillhouse.mjs +3 -58
  6. package/cadre/templates/projet/CLAUDE.md +5 -1
  7. package/cadre/templates/projet/docs/agents/issue-tracker.md +4 -4
  8. package/charte.md +23 -6
  9. package/docs/ARCHITECTURE.md +127 -1
  10. package/hooks/register.tsx +3 -13
  11. package/package.json +13 -1
  12. package/scripts/bilan.mjs +134 -88
  13. package/scripts/circuit.mjs +1547 -2248
  14. package/scripts/composants-affectes.mjs +27 -108
  15. package/scripts/consommateurs-arbitres.mjs +15 -21
  16. package/scripts/consommateurs.d.ts +8 -0
  17. package/scripts/consommateurs.mjs +5 -1
  18. package/scripts/dette.d.ts +23 -0
  19. package/scripts/dette.mjs +76 -13
  20. package/scripts/droits.mjs +38 -44
  21. package/scripts/elements-du-lot.mjs +246 -0
  22. package/scripts/enveloppe/enveloppe.mjs +105 -232
  23. package/scripts/enveloppe/lancer.sh +79 -49
  24. package/scripts/enveloppe/paquets-du-plan.mjs +49 -0
  25. package/scripts/etapes.mjs +148 -213
  26. package/scripts/gardes-du-cadre.mjs +8 -6
  27. package/scripts/grillhouse-maj.mjs +31 -9
  28. package/scripts/index-interfaces.mjs +21 -1
  29. package/scripts/integration/integrer.mjs +2 -2
  30. package/scripts/interfaces-contre-code.mjs +25 -17
  31. package/scripts/migrations/0.23.0-config-vitest.mjs +26 -23
  32. package/scripts/migrations/0.23.2-copies-du-cadre.mjs +201 -0
  33. package/scripts/migrations/0.24.0-circuit-simplifie.mjs +231 -0
  34. package/scripts/migrations.mjs +41 -6
  35. package/scripts/paquets.d.ts +5 -0
  36. package/scripts/paquets.mjs +3 -0
  37. package/scripts/references-par-les-types.mjs +55 -36
  38. package/scripts/registre.mjs +7 -15
  39. package/scripts/resultats.mjs +283 -142
  40. package/scripts/resumes.mjs +1 -1
  41. package/scripts/session-start.sh +1 -2
  42. package/scripts/sortie.mjs +1 -1
  43. package/scripts/sources.mjs +28 -0
  44. package/scripts/sous-commandes.mjs +62 -0
  45. package/scripts/tableau.mjs +85 -191
  46. package/scripts/tests.mjs +19 -17
  47. package/scripts/verifier.mjs +5 -4
  48. package/scripts/verrou-de-machine.mjs +131 -24
  49. package/scripts/verrous/verrou.mjs +66 -5
  50. package/skills/developpeur/SKILL.md +60 -50
  51. package/skills/explorateur/SKILL.md +90 -64
  52. package/skills/grill/SKILL.md +1 -1
  53. package/skills/mesure/SKILL.md +2 -1
  54. package/skills/pitmaster/SKILL.md +132 -118
  55. package/skills/pitmaster/references/consigne-agent.md +54 -148
  56. package/skills/questionneur/SKILL.md +18 -18
  57. package/skills/relecteur/SKILL.md +69 -23
  58. package/skills/testwriter/SKILL.md +46 -35
  59. package/types/index.d.ts +1 -3
  60. package/agents/referent-technique.md +0 -9
  61. package/agents/regulateur.md +0 -11
  62. package/scripts/enveloppe/composant.mjs +0 -11
  63. package/scripts/etat-du-circuit.mjs +0 -104
  64. package/skills/referent-technique/SKILL.md +0 -145
  65. package/skills/regulateur/SKILL.md +0 -220
@@ -5,5 +5,5 @@
5
5
  "author": {
6
6
  "name": "Romain Peyrichou"
7
7
  },
8
- "version": "0.23.0"
8
+ "version": "0.24.0"
9
9
  }
package/METACADRE.md CHANGED
@@ -21,7 +21,7 @@ intentions sort du cadre.
21
21
  5. **Des agents cadrés** : chaque ticket part à un agent neuf, dans le cadre écrit, et un autre que
22
22
  lui relit sa fermeture. Ainsi le travail des agents reste dans l'architecture ; sans cadre, ils
23
23
  font systématiquement le contraire.
24
- 6. **Le responsable tranche l'essentiel** : ce qu'une règle écrite tranche, le régulateur ou
24
+ 6. **Le responsable tranche l'essentiel** : ce qu'une règle écrite tranche, le circuit ou
25
25
  le superviseur le tranche. Le responsable reçoit les décisions qu'aucune règle ne couvre, avec leur contexte et une
26
26
  recommandation. Ainsi son temps va aux vraies décisions.
27
27
 
@@ -1,9 +1,11 @@
1
1
  ---
2
2
  name: explorateur
3
- description: "Mène un ticket d'exploration : relève l'état réel, liste les décisions à prendre, propose les tickets de réalisation. N'écrit aucun fichier."
3
+ description: "Écrit le plan d'un ticket à l'étape 1 de son circuit (ses critères, les paquets à toucher, ses questions ouvertes) et répond une fois au questionneur ; mène aussi un ticket d'exploration : relève l'état réel, liste les décisions à prendre, propose les tickets de réalisation. N'écrit aucun fichier ni rien au ticket."
4
4
  skills:
5
5
  - grillhouse:explorateur
6
+ model: sonnet
7
+ effort: medium
6
8
  disallowedTools: Write, Edit, MultiEdit, NotebookEdit
7
9
  ---
8
10
 
9
- Tu es l'explorateur. Ta compétence `explorateur` est chargée : suis-la.
11
+ Tu es l'explorateur. Au premier tour, charge ta compétence `explorateur` (outil Skill), puis suis-la : ta séance ne la reçoit pas chargée.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: questionneur
3
- description: Questionne une proposition qu'il n'a pas écrite (le plan d'un ticket, une décision du régulateur, un plan du superviseur) là où elle lui paraît floue, à la lumière du cadre ; ne décide rien, ne propose pas sa solution, n'écrit aucun fichier ni rien au ticket.
3
+ description: Questionne une proposition qu'il n'a pas écrite (le plan d'un ticket, un plan du superviseur) là où elle lui paraît floue, à la lumière du cadre ; ne décide rien, ne propose pas sa solution, n'écrit aucun fichier ni rien au ticket.
4
4
  skills:
5
5
  - grillhouse:questionneur
6
6
  model: sonnet
@@ -9,10 +9,7 @@
9
9
  // after it): no second Node starts, which a hook of Claude Code called at each tool pays. A `.sh`
10
10
  // runs by bash, its standard streams this process's, its exit code this command's, and a script
11
11
  // ended by a signal gives 128 plus the signal's number, as a shell gives it.
12
- // - A subcommand is named after its script, without directory nor extension (`verifier`,
13
- // `circuit`, `tableau`); `maj` runs `grillhouse-maj.mjs`, whose name already says the frame's;
14
- // `hooks` (`crochets.mjs`, which places the git hooks) and `hook` (`crochet.mjs`, which runs one)
15
- // take Husky's names, which a project's `prepare` and its git hooks call.
12
+ // - The subcommands and their scripts are the table of scripts/sous-commandes.mjs.
16
13
  // - A subcommand missing or unknown writes the usage and the list of the subcommands on the error
17
14
  // stream, and the exit code is 2.
18
15
  // - A script finds its neighbours by its own directory, and the project by the working directory
@@ -20,60 +17,8 @@
20
17
  import { spawn } from 'node:child_process';
21
18
  import { realpathSync } from 'node:fs';
22
19
  import { constants } from 'node:os';
23
- import path from 'node:path';
24
- import { fileURLToPath, pathToFileURL } from 'node:url';
25
-
26
- const SCRIPTS = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'scripts');
27
-
28
- // Each subcommand and its script, under `scripts/`.
29
- export const SOUS_COMMANDES = {
30
- bilan: 'bilan.mjs',
31
- circuit: 'circuit.mjs',
32
- 'code-mort': 'code-mort.mjs',
33
- commande: 'verrous/commande.mjs',
34
- 'composants-affectes': 'composants-affectes.mjs',
35
- consommateurs: 'consommateurs.mjs',
36
- 'consommateurs-arbitres': 'consommateurs-arbitres.mjs',
37
- droits: 'droits.mjs',
38
- enveloppe: 'enveloppe/enveloppe.mjs',
39
- 'etat-du-circuit': 'etat-du-circuit.mjs',
40
- file: 'integration/file.mjs',
41
- frontieres: 'frontieres.mjs',
42
- 'gardes-du-cadre': 'gardes-du-cadre.mjs',
43
- greffons: 'greffons.mjs',
44
- hook: 'crochet.mjs',
45
- hooks: 'crochets.mjs',
46
- 'index-interfaces': 'index-interfaces.mjs',
47
- init: 'init.mjs',
48
- integrer: 'integration/integrer.mjs',
49
- 'interfaces-contre-code': 'interfaces-contre-code.mjs',
50
- lancer: 'enveloppe/lancer.sh',
51
- 'ligne-etat': 'ligne-etat/ligne-etat.mjs',
52
- maj: 'grillhouse-maj.mjs',
53
- nuit: 'nuit.sh',
54
- pression: 'vitest-config/pression.mjs',
55
- registre: 'registre.mjs',
56
- resultats: 'resultats.mjs',
57
- resumes: 'resumes.mjs',
58
- 'retirer-copie': 'retirer-copie.sh',
59
- 'session-start': 'session-start.sh',
60
- sortie: 'sortie.mjs',
61
- 'sous-modules': 'sous-modules.sh',
62
- 'structure-guard': 'structure-guard.sh',
63
- superviseur: 'superviseur.mjs',
64
- tableau: 'tableau.mjs',
65
- tests: 'tests.mjs',
66
- ticket: 'ticket.sh',
67
- 'ticket-du-sous-agent': 'verrous/ticket-du-sous-agent.mjs',
68
- 'turbo-des-paquets': 'turbo-des-paquets.mjs',
69
- verifier: 'verifier.mjs',
70
- verrou: 'verrous/verrou.mjs',
71
- };
72
-
73
- // The absolute path of the script of the subcommand <nom>; null for a name the table lacks.
74
- export function scriptDe(nom) {
75
- return Object.hasOwn(SOUS_COMMANDES, nom) ? path.join(SCRIPTS, SOUS_COMMANDES[nom]) : null;
76
- }
20
+ import { pathToFileURL } from 'node:url';
21
+ import { scriptDe, SOUS_COMMANDES } from '../scripts/sous-commandes.mjs';
77
22
 
78
23
  // The usage and the list of the subcommands, as the error stream receives them.
79
24
  const usage = () =>
@@ -31,7 +31,8 @@ d'abord », « une personne maintient le projet »…).
31
31
 
32
32
  ## Ce qui monte au superviseur
33
33
 
34
- Le fonctionnel que le régulateur ne tranche jamais seul : <le langage, le moteur audio, une
34
+ Une question qu'aucun geste du circuit ne tranche monte au superviseur, avec sa pièce. Il monte au
35
+ responsable le fonctionnel, qu'il ne tranche jamais seul : <le langage, le moteur audio, une
35
36
  interface publiée…>. Le cadre et l'architecture montent toujours (charte commune).
36
37
 
37
38
  ## Commandes
@@ -44,3 +45,6 @@ interface publiée…>. Le cadre et l'architecture montent toujours (charte comm
44
45
  - Les sous-modules partagés : la clé `grillhouse.partage` du `package.json` (les chemins des
45
46
  sous-modules qu'aucun ticket n'écrit ; chaque copie les lit dans le dépôt principal, en lecture
46
47
  seule, au lieu d'en recevoir un exemplaire).
48
+ - La plage de nuit : la clé `grillhouse.plageDeNuit` du `package.json` (`{ "debut": 23, "fin": 8 }`
49
+ par défaut : les heures, à l'heure locale, où l'attente d'une réponse compte au bilan comme nuit,
50
+ à part de l'attente du superviseur et de celle du responsable).
@@ -11,16 +11,16 @@ Issues for this repo live in Beads, a git-backed tracker: data under `.beads/`,
11
11
  - One ticket, one delivery: a goal whose split is unknown opens an exploration ticket (no code, agent `explorateur`), which closes on the realisation tickets it proposes, recorded closed and labelled `decouverte`; the supervisor reopens those the owner validates. A realisation ticket names the components it touches (« Numéros et titres ») and enters in one commit, under its own number alone; the `commit-msg` hook refuses a second commit for a closed ticket whose delivery stands, and lets a ticket reopened after its delivery (open in Beads) take correction commits; a revert (`Revert "…"`, `Reapply "…"`) passes and withdraws the delivery it names.
12
12
  - An open ticket is born of the owner's word, or of a direct need of a project that uses the frame (a defect it meets). A discovery during work is recorded, with its example and address, in a closed ticket under the ticket that found it, labelled `decouverte` (see « Numéros et titres »); it reopens on the owner's word. A discovery that blocks stops the agent, and its handoff names it. The supervisor brings to the owner the discoveries that touch a real use.
13
13
  - Types: `epic` (a chantier, always at the root: an epic has no mother), `task`, `bug`, `decision`. A mother under a chantier is a `task`; the session start lists an epic that has a mother. Priority `0`-`4`, 0 highest.
14
- - Comments carry progress and handoffs: `bd comments add <id> "<text>"`. In a ticket's circuit, each comment carries its author: the circuit launches each session with `BEADS_ACTOR` naming its role (`testwriter <composant>`, `developpeur <composant>`, `relecteur`, `regulateur`), writes its own lines (`Circuit · …`) as `circuit` and the reviewer's verdict as `relecteur`; the queue (`packages/grillhouse/scripts/integration/file.mjs`) writes as `file`; a verdict is a comment of the author `relecteur` whose first word is `ACCEPTÉ` or `RENDU`. An agent does not change its author: its rights refuse bd's `--actor`, `-a`/`--author` and the variable `BEADS_ACTOR`.
15
- - Labels used by the skills: `a-valider` (proposed, waits for the owner), `decouverte` (a discovery recorded closed; it reopens on the owner's word), `circuit` (the owner said to launch it: the ticket is in the flow, and only such a ticket waits in the pane's AGENTS), `attend-responsable` (a rule waits for the owner's word), `arbitrage` (a design question went to the `referent-technique` agent; the lot enters only with its verdict).
14
+ - Comments carry progress and handoffs: `bd comments add <id> "<text>"`. In a ticket's circuit, each comment carries its author: the circuit launches each session with `BEADS_ACTOR` naming its role (`explorateur`, `questionneur`, `testwriter`, `developpeur`, `relecteur`), writes its own lines (`Circuit · …`) as `circuit` and the reviewer's verdict as `relecteur`; the queue (`packages/grillhouse/scripts/integration/file.mjs`) writes as `file`; a verdict is a comment of the author `relecteur` whose first word is `ACCEPTÉ` or `RENDU`. An agent does not change its author: its rights refuse bd's `--actor`, `-a`/`--author` and the variable `BEADS_ACTOR`.
15
+ - Labels used by the skills: `a-valider` (proposed, waits for the owner), `decouverte` (a discovery recorded closed; it reopens on the owner's word), `circuit` (the owner said to launch it: the ticket is in the flow, and only such a ticket waits in the pane's AGENTS), `attend-responsable` (a rule waits for the owner's word), `arbitrage` (a design question the supervisor settles, his « ## Arbitrage » comment at the ticket; the lot enters only with its verdict).
16
16
 
17
17
  ## Numéros et titres
18
18
 
19
19
  - A chantier is an `epic` at the root; under it, every subject has a mother ticket (a `task`), open while work remains under it. Every ticket is created under its mother, so Beads numbers it natively: `320.1`, `320.2`, `320.2.1`.
20
- - The title reads `<number> — <subject> — <components>`, the number being the id without the whole prefix of the project (`bd config get issue_prefix`, which may hold dashes: `bp-mono-`). The components are the ones the ticket touches, separated by commas, the provider first, then its readers (charte, « Un ticket de réalisation nomme ses composants »): `320.5.2 — Publie l'objet de la scène — 020-loader, 050-emitter`. A mother takes `parent` as its component. The survey of the components (`npx grillhouse composants-affectes --description <file>` on a draft, `npx grillhouse composants-affectes <id>` on a ticket) gives that list from the elements the Architecture section and the criteria name: for each, its provider and its readers (the consumers its INTERFACE.md declares, the packages that import it, the tests of other packages that name it). A component it finds that the ticket does not change is admitted out of the title, with its reason, once the ticket exists: `npx grillhouse composants-affectes <id> --admettre <component> --raison "<reason>"`, a line at the ticket. The circuit runs the survey again before the first testwriter, and stops at `composants-manquants` (21) on a component it finds that the title misses and no admission covers.
20
+ - The title reads `<number> — <subject> — <components>`, the number being the id without the whole prefix of the project (`bd config get issue_prefix`, which may hold dashes: `bp-mono-`). The components are the ones the ticket touches, separated by commas, the provider first, then its readers (charte, « Un ticket de réalisation nomme ses composants »): `320.5.2 — Publie l'objet de la scène — 020-loader, 050-emitter`. A mother takes `parent` as its component. The survey of the components (`npx grillhouse composants-affectes --description <file>` on a draft, `npx grillhouse composants-affectes <id>` on a ticket) gives that list from the elements the Architecture section and the criteria name: for each, its provider and its readers (the consumers its INTERFACE.md declares, the packages that import it, the tests of other packages that name it). The title names the readers the ticket changes. In a ticket's circuit, the explorer runs the survey when it writes the plan (1 Plan), and the circuit writes the packages of its plan as the title's components.
21
21
  - Creating one: `npx grillhouse ticket <mother> <subject> <components> <body> [label]` prints its id; the label is `a-valider` by default, and `decouverte` creates it closed (« découverte consignée »).
22
22
 
23
- - A ticket goes through the tree of its circuit, the « auto » steps included (`packages/grillhouse/scripts/etapes.mjs`, the one list): 0 Exploration (`explorateur`); 1 Ouverture: 1.1 Relevé des composants, 1.2 Questionnement (`questionneur` ⇄ `referent-technique`); 2 Composants, for each component: 2.1 Tests (`testwriter`), 2.2 Preuve du rouge, 2.3 Code (`developpeur`), 2.4 Contrôles; 3 Passe finale; 4 Relecture (`relecteur`); 5 Intégration: 5.1 Commit, 5.2 File : main, poussée, CI. Out of the sequence, under the stopped step, the Arbitrage de l'arrêt (`regulateur` ⇄ `questionneur`). The `referent-technique` also settles a design question the supervisor asks him. One says « 320.2.1, step 2.3 »; the pane shows each ticket at its step.
23
+ - A ticket goes through the tree of its circuit, the « auto » steps included (`packages/grillhouse/scripts/etapes.mjs`, the one list): 1 Plan (`explorateur` writes the plan, `questionneur` reads it once, the explorer answers once); 2 Tests (`testwriter`), 2.1 Preuve du rouge; 3 Code (`developpeur`), 3.1 Contrôles; 4 Passe finale et relecture: 4.1 Passe finale, 4.2 Régénération des références, 4.3 Relecture (`relecteur`); 5 Intégration: 5.1 Commit, 5.2 File : main, poussée, CI. Every step is one for the whole ticket: one testwriter and one developpeur, each on every package of its plan. The circuit makes its mechanical gestures itself; any other stop goes up to the supervisor, its question in the circuit's state. One says « 320.2.1, step 3 »; the pane shows each ticket at its step.
24
24
 
25
25
  ## When a skill says "publish to the issue tracker"
26
26
 
package/charte.md CHANGED
@@ -29,7 +29,9 @@ professionnel.
29
29
  le correctif va dans ce mécanisme. Ainsi tout correctif passe par l'architecture.
30
30
  3. Une décision reste à prendre : `mattpocock-skills:grilling` avant d'écrire, ses questions dans
31
31
  le ticket. Ainsi la décision est prise et écrite avant le code.
32
- 4. Le plan va dans le ticket (`bd update <id> -d`). Un travail qui change un comportement est un
32
+ 4. Le plan va dans le ticket : dans le circuit, l'explorateur l'écrit (ses critères, les paquets à
33
+ toucher, ses questions ouvertes), le questionneur le lit une fois, l'explorateur répond une
34
+ fois, et ce qui reste ouvert monte au superviseur. Un travail qui change un comportement est un
33
35
  seul ticket : les tests d'abord (agent `testwriter`), puis le code qui les rend verts (agent
34
36
  `developpeur`). Ainsi le code se mesure à des tests qu'il n'a pas écrits. Un critère répond à
35
37
  un besoin réel de l'usage actuel. Ainsi le ticket garde la taille du besoin.
@@ -42,13 +44,26 @@ professionnel.
42
44
  la fiche le circuit.
43
45
 
44
46
  Un ticket parcourt les étapes de son circuit (`etapes.mjs`, la seule liste), chacune tenue par un
45
- rôle, agent du cadre, sous ses droits. Ainsi chaque agent travaille dans son cadre, et le numéro
46
- d'une étape dit où en est chaque ticket.
47
+ rôle, agent du cadre, sous ses droits : 1 Plan, l'explorateur puis le questionneur ; 2 Tests, une
48
+ séance du testwriter, et 2.1 Preuve du rouge ; 3 Code, une séance du développeur, et
49
+ 3.1 Contrôles ; 4 Passe finale et relecture : la passe finale, la régénération des références,
50
+ puis le relecteur, qui rend une ligne de conformité par élément que le lot ajoute, change ou
51
+ supprime ; 5 Intégration. Ainsi chaque agent travaille dans son cadre,
52
+ et le numéro d'une étape dit où en est chaque ticket.
53
+
54
+ **Le circuit fait les gestes, une vraie question monte** : le circuit fait lui-même les gestes
55
+ mécaniques que la liste des étapes écrit (rejouer, régénérer, juger un lot sans rien à livrer) ;
56
+ tout autre arrêt monte au superviseur avec sa pièce, et il monte au responsable ce qui lui
57
+ revient. Ainsi aucune séance ne juge ce qu'une règle tranche.
47
58
 
48
59
  **Tous les agents jugent sur le plan** : une décision du responsable entre dans la description du
49
60
  ticket, comme une RFC amendée ; les commentaires restent l'historique. Ainsi chaque agent lit la
50
61
  même décision.
51
62
 
63
+ **Un fait repris se relit à sa pièce** (fichier:ligne depuis la racine de la copie, ou
64
+ « $ commande » et sa sortie) avant qu'un agent s'appuie dessus, et un fait transmis porte la
65
+ sienne. Ainsi une ligne mal lue s'arrête au premier qui la relit.
66
+
52
67
  **Un ticket de réalisation nomme ses composants** dans son titre (« numéro — sujet — composant,
53
68
  composant ») et sa section « Architecture », le fournisseur d'abord ; il fait une seule livraison,
54
69
  en un seul commit, et se crée sous sa mère (`docs/agents/issue-tracker.md`). Un objectif dont le
@@ -98,9 +113,11 @@ Une découverte d'agent se consigne dans un ticket fermé, sous le ticket qui l'
98
113
  Ainsi chaque rouge a son ticket.
99
114
  - **L'index d'abord** : toute recherche commence par `rtfm_search` (mode `hybrid`) pour le quoi, et
100
115
  par `codegraph explore` (ou l'outil `codegraph_explore`) pour l'appel ; le shell lit un fichier
101
- déjà nommé. Dans son enveloppe, un agent lit son paquet, les interfaces de ses voisins, la
102
- matière de test partagée et ce que ses tests déclarent lire (`grillhouse.lit`). Ainsi une
103
- affirmation sur le code repose sur ce que le code contient.
116
+ déjà nommé. Ainsi une affirmation sur le code repose sur ce que le code contient.
117
+ - **Tout se lit, le plan s'écrit** : dans son enveloppe, un agent lit tout le dépôt, index compris,
118
+ et n'écrit que les paquets que le plan de son ticket nomme. Une écriture hors du plan l'arrête,
119
+ et le superviseur étend le plan ou refuse. Ainsi l'agent lit ce dont il a besoin, et les gardes
120
+ tiennent l'architecture.
104
121
  - Tickets : Beads (`bd`), sous le préfixe du projet, voir `docs/agents/issue-tracker.md`.
105
122
  - Le greffon `mattpocock-skills` s'appelle avec son préfixe ; un document pour un agent s'écrit
106
123
  avec `mattpocock-skills:writing-for-agents`.
@@ -29,6 +29,112 @@ chemin que ses tests déclarent lire, `grillhouse.lit`) ; sans vert connu, la pa
29
29
  complète, et `npm run verifier -- --tout` la joue pour de vrai, comme la nuit. Ainsi un test ne
30
30
  tourne qu'une fois tant que rien ne change, et corriger un test ne rejoue que lui.
31
31
 
32
+ **Tout se lit, le plan s'écrit** : un agent de rôle travaille dans l'enveloppe de sa copie
33
+ (`packages/grillhouse/scripts/enveloppe/`, un bac à sable bubblewrap) ; il lit toute la copie,
34
+ index compris (`.codegraph`, `.rtfm`), et n'écrit que les paquets que le plan de son ticket nomme
35
+ (les paquets du titre), la base des tickets et le cache de Turborepo ; `.git` reste en lecture
36
+ seule, et la matière de test partagée s'écrit par le seul testwriter. Un chemin du plan hors des
37
+ paquets écrit la racine, toute la copie. `GRILLHOUSE_ENVELOPPE` porte la liste aux commandes du
38
+ cadre, qui construisent, jugent et écrivent ses seuls paquets. Une écriture hors du plan échoue
39
+ au montage, et le verrou de l'agent arrête sa séance en nommant le paquet ; le circuit s'arrête à
40
+ « hors-plan », une question pour le superviseur, qui étend le plan (`--etendre`) ou refuse. Comme la visibilité de Bazel et
41
+ les frontières de modules de Nx, la règle refuse et le code reste lisible ; comme
42
+ `bwrap --ro-bind / --bind`, le bac à sable n'ouvre en écriture que ce qu'il lie. Ainsi l'agent
43
+ lit ce dont il a besoin, et les gardes tiennent l'architecture (BP 320.9 : la lecture cloisonnée
44
+ causait l'essentiel des pertes).
45
+
46
+ **Le circuit fait les gestes, une vraie question monte** : comme une CI applique ses règles
47
+ (rejouer, régénérer, sauter une tâche sans objet) sans demander et n'appelle une personne que pour
48
+ ce qu'aucune règle ne tranche (l'approbation d'une revue), le circuit d'un ticket
49
+ (`packages/grillhouse/scripts/circuit.mjs`) fait lui-même, sans séance, les gestes que la liste des
50
+ étapes écrit (`GESTES` de `packages/grillhouse/scripts/etapes.mjs`) : une commande à 75 rejouée une
51
+ fois, la fin à 75, le renvoi au testwriter que la fiche du développeur nomme, la régénération des
52
+ références, un développeur sans rien à livrer jugé par les contrôles ; chaque geste s'écrit au ticket et au
53
+ journal avec sa règle. Tout autre arrêt finit le circuit sur une question au superviseur (`MONTEES`),
54
+ que l'état du circuit porte : le fait, sa pièce (`fichier:ligne`, ou la commande et sa sortie), la
55
+ question, et qui doit répondre, le superviseur ou le responsable ; le superviseur répond par une
56
+ commande du circuit (`--reprendre`, `--depuis`, `--etendre <paquet>`, `--arreter`). Ainsi aucune
57
+ séance ne juge un geste qu'une règle tranche (BP 320.9 : 67 séances d'arbitrage et de réponse
58
+ au plan, 14 montées qui étaient des gestes).
59
+
60
+ **La régénération d'office** : comme les genrules de Bazel et `--update-snapshots`, un fichier
61
+ engendré se réécrit par sa commande, puis le circuit rejoue seulement ce qui en dépend. Une passe
62
+ finale dont un rouge est celui d'une référence, mêlé ou non à d'autres, régénère les références
63
+ qu'il nomme (4.2), puis rejoue la passe finale restreinte à ce que la régénération change ; les
64
+ autres rouges restent, chacun à son propriétaire. Les références sont celles que le projet déclare
65
+ (`grillhouse.references`) et celles du cadre, dans chaque projet (`REFERENCES_DU_CADRE` de
66
+ `circuit.mjs`) : l'index des interfaces, les `turbo.json` des paquets et les rapports d'API, chacun
67
+ réécrit par son générateur sans que le plan le nomme, et la dette des gardes. Le circuit ne lit pas
68
+ le code de sortie d'un générateur du cadre, qui juge aussi les rouges qu'il laisse (`npm run api`
69
+ refuse à côté d'eux) : il juge la régénération sur ce qu'elle écrit, puis sur la passe restreinte
70
+ qui suit, et seule une vraie panne l'arrête (la commande introuvable, ou tuée par un signal). La dette s'abaisse depuis les notes de la passe finale (une note
71
+ `a-elaguer` du SARIF d'une garde, chaque clé inscrite au-dessus de ce qu'elle trouve), par
72
+ `dette.mjs --abaisser`, sans rejouer les gardes. Un plafond ne monte jamais : un lot qui le dépasse
73
+ reste rouge. Ainsi aucun fichier engendré n'attend une main (BP 320.9 : 292 min autour des
74
+ références, dont 163 d'attente).
75
+
76
+ **L'explorateur écrit le plan, questionné une fois** : comme l'auteur d'une RFC l'écrit après
77
+ avoir relevé l'existant, qu'une revue la lit une fois, que l'auteur répond une fois et que ce qui
78
+ reste ouvert va à qui décide, l'étape 1 du circuit (1 Plan) lance l'explorateur hors de
79
+ l'enveloppe ; il relève les composants (`npx grillhouse composants-affectes <ticket>`) et finit sur
80
+ sa fiche : les critères, les paquets à toucher, ses questions ouvertes avec leur pièce. Le circuit
81
+ écrit le plan au ticket : les paquets finissent son titre, la seule liste que lit l'enveloppe de
82
+ chaque séance d'après. Le questionneur le lit une fois ; l'explorateur, sa séance
83
+ reprise, répond une fois, CHANGE ou GARDE par question ; ce qui reste ouvert monte au superviseur
84
+ (« questionnement »), sinon le circuit passe aux tests. Ainsi les questions utiles se posent avant
85
+ le plan, et le plan ne tourne pas en rond (BP 320.9 : 132 tours de questions, 29 critères dont 2
86
+ utiles).
87
+
88
+ **Le relecteur juge chaque élément qui change** : comme API Extractor fait relire son rapport
89
+ ligne par ligne et qu'une revue mûre exige un avis par fichier changé, le circuit donne au
90
+ relecteur la liste de chaque fonction, classe, type, interface, constante de tête et export que
91
+ le lot ajoute, change ou supprime (`scripts/elements-du-lot.mjs`), avec son paquet, son
92
+ `fichier:ligne` et s'il est exporté : le service de langage de `references-par-les-types.mjs` lit
93
+ les déclarations et les exports, le texte de chaque déclaration avant et après le lot dit ce qui
94
+ change, le diff des rapports d'API (`docs/INTERFACE.api.md`) les exports qui changent. Sa fiche
95
+ rend une ligne par élément (`conformite`), conforme ou non, la règle citée (`document` CADRE,
96
+ INTERFACE ou ARCHITECTURE, et sa `reference`) ; un export neuf cite son entrée dans l'INTERFACE.
97
+ Le schéma de la fiche refuse une ligne sans document ni référence (`resultats.mjs`), et le
98
+ circuit une fiche à laquelle il manque un élément (`conformiteDuLot`) ; un « non » rend le lot à
99
+ son destinataire. En relecture bornée, comme une revue ne décoche « vu » que sur les fichiers
100
+ changés depuis, la consigne marque chaque élément : à rejuger quand la différence le touche,
101
+ repris sinon avec sa ligne d'avant, que la fiche porte encore. Ainsi rien de neuf n'entre sans
102
+ avoir été jugé contre l'architecture (Romain, 2026-10-23 : « il faut que le relecteur valide
103
+ vraiment la conformité à l'architecture de tout ce qu'il y a de nouveau/changé »).
104
+
105
+ **Un circuit par ticket** : comme une demande de fusion (un auteur, une série de tests et de
106
+ code, une CI sur l'ensemble, une revue), le circuit lance un seul testwriter et un seul
107
+ développeur pour tout le ticket, chacun dans l'enveloppe de tous les paquets du plan, puis la
108
+ passe finale et le relecteur sur l'ensemble ; aucun composant n'est une unité du circuit. Les
109
+ étapes (`packages/grillhouse/scripts/etapes.mjs`) : 1 Plan · 2 Tests · 2.1 Preuve du rouge ·
110
+ 3 Code · 3.1 Contrôles · 4 Passe finale et relecture (4.1 Passe finale, 4.2 Régénération des
111
+ références, 4.3 Relecture) · 5 Intégration. `--depuis <testwriter|developpeur>` rejoue le
112
+ ticket entier depuis cette étape ; `--etendre <paquet>` ajoute un paquet au plan, puis reprend
113
+ l'étape en cours. Un constat bloquant du relecteur va droit à l'agent qu'il nomme et reste ouvert
114
+ d'une relance à l'autre, comme un fil de revue non résolu, jusqu'à ce que le relecteur le dise
115
+ levé ou accepte le lot. Le bilan compte par étape et par rôle. Ainsi un type change avec ses
116
+ lecteurs en une seule séance, et un constat n'est jamais perdu (BP 320.9 : seize composants
117
+ joués l'un après l'autre, 118 min d'étapes vertes rejouées, un constat sur `exemplar` perdu six
118
+ fois).
119
+
120
+ **Le bilan sépare les attentes** : comme le « lead time » de DORA sépare l'attente de revue du
121
+ temps de travail, chaque montée dit qui doit répondre, et le bilan répartit l'attente entre celle
122
+ du superviseur, celle du responsable et la nuit, la plage horaire que le projet déclare
123
+ (`grillhouse.plageDeNuit` de son `package.json`, 23 h – 8 h par défaut). Son texte donne le mur,
124
+ le mur hors nuit d'attente (une nuit de travail y reste) et le perdu hors attentes. Ainsi le temps perdu se lit sans la nuit ni l'attente
125
+ d'une réponse (BP 320.9 : 500 min de nuit mêlées à l'attente du responsable et à celle du
126
+ superviseur).
127
+
128
+ **Un fait porte sa pièce** : comme une revue de code cite la ligne qu'elle juge, chaque constat,
129
+ question ou montée d'une fiche porte sa `piece`, un seul format (`lirePiece` de `resultats.mjs`) :
130
+ `fichier:ligne` ou `fichier:ligne-ligne` depuis la racine de la copie, ou `$ commande` et sa
131
+ sortie. Le circuit cherche chaque pièce `fichier:ligne` dans la copie, le fichier présent et sa
132
+ ligne (ou la fin de l'intervalle) dedans ; une pièce
133
+ introuvable refuse la fiche, redemandée une fois comme tout autre manque. L'agent qui reprend le
134
+ fait relit sa pièce avant de s'appuyer dessus. Ainsi une ligne mal lue s'arrête au premier qui la
135
+ relit (BP 320.9 : une question née d'une ligne mal lue, `native.ts:234`, recopiée par cinq agents
136
+ jusqu'au responsable).
137
+
32
138
  **Une passe écrit sous sa base** : chaque lancement de Vitest, `npm test`, `npm run verifier`,
33
139
  un circuit, une intégration et une enveloppe ouvrent leur base dans le dossier temporaire, la
34
140
  nomment dans `TMPDIR` à ce qu'ils lancent (les dossiers d'essai des tests, celui de Vitest, celui
@@ -60,6 +166,13 @@ celui qui attend est un blocage : l'attente le dit tout de suite et s'arrête, r
60
166
  borne ses tâches côte à côte à la moitié des cœurs. Ainsi une mesure rend le résultat du code, et
61
167
  non celui d'une autre mesure à côté, et aucune passe ne reste figée sans le dire.
62
168
 
169
+ **Le projet passe avant le cadre** : une mesure jouée dans le dépôt du cadre lui-même (le paquet
170
+ en développement, ses copies d'agents comprises) est de second rang ; celle d'un projet, de
171
+ premier rang. Une mesure de second rang ne prend pas le verrou, même libre, tant qu'une mesure de
172
+ premier rang attend ; l'attente dit son rang et qui elle attend, sous la même borne. Ainsi le
173
+ circuit d'un projet n'attend pas les vérifications du cadre, comme le serveur de tâches de GNU
174
+ make sert sa construction et Bazel ordonne ses tests par priorité.
175
+
63
176
  **Une passe automatique montre son avancement** : chaque passe automatique écrit ses fichiers
64
177
  de tests faits sur prévus (la file, les étapes de sa CI), que le panneau affiche avec le temps
65
178
  depuis son dernier signe, « ⚠ figée » au-delà de 5 min, comme le compteur d'actions de Bazel.
@@ -83,8 +196,21 @@ comme un paquet d'ESLint porte son greffon. La place de marché `roomi-fields`
83
196
  `grillhouse@roomi-fields` (`npx grillhouse maj`). Ce qui est propre à un projet (sa charte, ses
84
197
  réglages, sa version du paquet) vit dans le projet, jamais dans ce qui se publie. Une version de
85
198
  npm vaut pour les deux ; l'ouverture de séance nomme un greffon chargé à une autre version que
86
- le paquet du projet, avec la commande qui les remet d'accord. Un projet n'en garde aucune copie ; sans le paquet installé, l'ouverture de séance dit « lance `npm install` », et les autres crochets
199
+ le paquet du projet, avec la commande qui les remet d'accord. Un projet n'en garde aucune copie
200
+ (`npx grillhouse maj` retire, à leur empreinte, celles que posait la 0.22) ; sans le paquet installé, l'ouverture de séance dit « lance `npm install` », et les autres crochets
87
201
  sortent sans effet. Les crochets git du cadre suivent le modèle de Husky : le `prepare` du
88
202
  projet lance `grillhouse hooks`, qui les pose à côté des sections de Beads, et chacun appelle
89
203
  `grillhouse hook <nom>`, sans effet sans le paquet. Ainsi chaque projet suit la version du cadre qu'il installe, sans fichier à
90
204
  recopier.
205
+
206
+ **Le paquet publie ses entrées nommées, son interface** : un projet importe le paquet par son
207
+ nom et l'une de ses entrées (le champ `exports`), jamais par l'adresse d'un fichier, comme
208
+ `eslint/use-at-your-own-risk` publie les outils d'ESLint. Chaque entrée sort du module qui porte
209
+ la fonction, sans réexport, avec sa déclaration de types à côté (`scripts/<module>.d.ts`) :
210
+ `@roomi-fields/grillhouse/dette` (`trancher`, la dette connue d'une garde du projet),
211
+ `@roomi-fields/grillhouse/consommateurs` (`matieres`, les paquets de la matière de test
212
+ partagée), `@roomi-fields/grillhouse/paquets` (`horsCadre`, les paquets hors cadre), et la
213
+ configuration de base de Vitest, `@roomi-fields/grillhouse/vitest-config` et
214
+ `@roomi-fields/grillhouse/vitest-config/mesure`. Une entrée s'ajoute ou se retire avec ce
215
+ paragraphe, que `tests/unit/paquet-publie.spec.ts` confronte au champ `exports`. Ainsi une
216
+ version du paquet dit ce qu'un projet peut importer, et ce qu'elle lui retire.
@@ -170,12 +170,6 @@ export const ouvrirGroupe = (s: Etat, groupe: string | undefined): Etat =>
170
170
  ? { ...s, vue: 'groupe', groupe, element: null, grand: false }
171
171
  : s
172
172
 
173
- // A line's text and its other text (`alterne`) take turns, ALTERNANCE ms each: the text shown at
174
- // the turn `tour` of the pane's clock (its other text at an odd turn), its text when it has no other.
175
- export const ALTERNANCE = 5_000
176
- export const texteDe = (l: Ligne, tour: number) =>
177
- l.alterne !== undefined && tour % 2 === 1 ? l.alterne : l.texte
178
-
179
173
  // While the board shows a line of progress (`avancement`: an automatic pass, « il y a 8 s »), it is
180
174
  // measured again every AVANCEMENT ms instead of every PERIODE: `aMesurer` says when, at the pane's
181
175
  // clock.
@@ -190,8 +184,6 @@ export const couleur = (ton: Ligne['ton']) =>
190
184
  // The session's project, and whether the board applies to it.
191
185
  let cwd = ''
192
186
  let actif = false
193
- // The turns of the alternation of the lines' texts, one per ALTERNANCE.
194
- let tour = 0
195
187
  // The pane's window: its first line, the element it last followed, and the rows and focus it was
196
188
  // last drawn with. The wheel moves it; the ring moving to another line makes it follow.
197
189
  let fenetre = 0
@@ -314,11 +306,9 @@ export const register: Register = on => {
314
306
  })
315
307
  void rafraichir($)
316
308
  $.clock.every(PERIODE, () => void rafraichir($))
317
- // A line with another text turns at each ALTERNANCE: the pane is drawn again, while one shows.
318
- $.clock.every(ALTERNANCE, () => {
319
- tour++
309
+ // A line of progress has the board measured again, by the clock of half its period.
310
+ $.clock.every(AVANCEMENT / 2, () => {
320
311
  void read($, etat).then(s => {
321
- if (lignesDe(s).some(l => l.alterne !== undefined)) $.ui.invalidate('ui.render')
322
312
  if (aMesurer(s, Date.now())) void rafraichir($)
323
313
  })
324
314
  })
@@ -508,7 +498,7 @@ export const register: Register = on => {
508
498
  {liste.slice(premier, premier + rangs).map(({ l, cle }) => {
509
499
  const texte = (
510
500
  <Text bold={l.ton === 'titre'} dimColor={l.ton === 'discret'} color={couleur(l.ton)} wrap="truncate-end">
511
- {texteDe(l, tour) || ' '}
501
+ {l.texte || ' '}
512
502
  </Text>
513
503
  )
514
504
  if (cle && l.groupe) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roomi-fields/grillhouse",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Roomi's Grillhouse: the frame's scripts, called by one command, grillhouse <sous-commande>",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,6 +30,18 @@
30
30
  },
31
31
  "exports": {
32
32
  "./package.json": "./package.json",
33
+ "./consommateurs": {
34
+ "types": "./scripts/consommateurs.d.ts",
35
+ "default": "./scripts/consommateurs.mjs"
36
+ },
37
+ "./dette": {
38
+ "types": "./scripts/dette.d.ts",
39
+ "default": "./scripts/dette.mjs"
40
+ },
41
+ "./paquets": {
42
+ "types": "./scripts/paquets.d.ts",
43
+ "default": "./scripts/paquets.mjs"
44
+ },
33
45
  "./vitest-config": {
34
46
  "types": "./scripts/vitest-config/base.d.ts",
35
47
  "default": "./scripts/vitest-config/base.mjs"