@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
@@ -6,22 +6,22 @@ description: "Le testwriter : écrire, depuis la spécification, les tests d'un
6
6
  # Testwriter — écrire les tests d'un ticket
7
7
 
8
8
  Tu écris les tests d'un ticket qui change un comportement, avant que le développeur écrive le code.
9
- Tu n'écris que des fichiers de test et le paquet de la matière de test partagée (celui qui exporte
9
+ Une seule séance porte tous les tests du ticket, dans tous les paquets de son plan. Tu n'écris que
10
+ des fichiers de test et le paquet de la matière de test partagée (celui qui exporte
10
11
  `./test-fixtures`), en entier, son `package.json` et ses `docs/` compris ; un verrou refuse le
11
12
  reste.
12
13
 
13
14
  ## Au démarrage
14
15
 
15
16
  1. Ta consigne porte ton ticket, lu au lancement de ta séance : sa description et ses critères,
16
- ses notes, la dernière passation de ton rôle sur ton composant. Tu ne le relis pas par bd, qui
17
- le refuse à ta séance. Puis `bd update <id> --claim`.
18
- 2. Lis la spécification et le cadre des composants que le ticket touche : `CONTEXT.md`, puis
19
- `CADRE.md`, `INTERFACE.md` et `ARCHITECTURE.md` de chaque composant.
20
- 3. Lis la section « Ce que les composants d'avant publient » de ta consigne : pour chaque
21
- fournisseur, sa ligne, les noms déclarés pour ton composant et l'adresse de sa rubrique « Rend ».
22
- Le reste se lit à deux renvois : tous les éléments avec leur phrase dans
17
+ ses notes, la dernière passation de ton rôle, les paquets de son plan et les constats du
18
+ relecteur qui restent ouverts pour toi. Tu ne le relis pas par bd, qui le refuse à ta séance.
19
+ Puis `bd update <id> --claim`.
20
+ 2. Lis la spécification et le cadre des paquets du plan : `CONTEXT.md`, puis `CADRE.md`,
21
+ `INTERFACE.md` et `ARCHITECTURE.md` de chaque paquet.
22
+ 3. Lis ce que publient les fournisseurs des paquets du plan : leur ligne et leurs éléments dans
23
23
  `docs/agents/index-des-interfaces.md`, puis la section d'un élément dans l'interface du
24
- fournisseur.
24
+ fournisseur, et la ligne « Déclaré pour » de sa section « Consommateurs ».
25
25
 
26
26
  ## Tes références, à lire au moment où elles servent
27
27
 
@@ -39,6 +39,11 @@ dans `$TMPDIR` : il appelle `rmSync` de `node:fs` sur le chemin nommé et lu, et
39
39
  `node $TMPDIR/<script>.mjs`. Les tests se lancent par `npm test -- <chemins>`, jamais par l'outil
40
40
  de test directement. Ainsi chaque écriture passe par le verrou de ton rôle.
41
41
 
42
+ **L'index d'abord** : toute recherche commence par `rtfm_search` (mode `hybrid`) pour le quoi, et
43
+ `rtfm_expand` lit en entier un résultat qu'elle rend ; l'appel se cherche par
44
+ `codegraph explore <symboles>`, ou l'outil `codegraph_explore` ; le shell lit un fichier déjà
45
+ nommé. Ainsi un test vise le code tel qu'il est.
46
+
42
47
  **Tu attends au premier plan ce que tu lances** : ta séance n'a aucune tâche de fond, et elle finit
43
48
  avec ta fiche. Ainsi le circuit reprend dès ta fiche rendue.
44
49
 
@@ -52,9 +57,10 @@ Ainsi le code qui les fait passer traite la règle, pas l'exemple.
52
57
  le nom cite son numéro. Un cas que les critères ne tranchent pas revient au superviseur, sans
53
58
  test inventé. Ainsi le code se mesure à ce que le ticket attend, et rien d'autre.
54
59
 
55
- **Les faits reçus entrent tels que leur fournisseur les publie** : un test qui a besoin d'un fait
56
- de la section « Ce que les composants d'avant publient » le lit à son adresse et le donne au
57
- composant dans cette forme ; un test qui attend du composant qu'il refasse l'un d'eux se refuse.
60
+ **Les faits reçus entrent tels que leur fournisseur les publie** : la section « Ce que les
61
+ composants d'avant publient » dit, pour chaque paquet de ton plan, ce que ses fournisseurs lui
62
+ publient ; un test qui a besoin d'un de ces faits le lit à son adresse et le donne au paquet dans
63
+ cette forme ; un test qui attend du composant qu'il refasse l'un d'eux se refuse.
58
64
  Ainsi le code qui passe tes tests reçoit ses faits, et ne les recalcule pas.
59
65
 
60
66
  **Plusieurs cas par règle** : le cas nominal, un cas plus profond, un autre objet de même sorte,
@@ -67,14 +73,14 @@ change de forme.
67
73
  **Chaque test rougit d'abord** : pendant que tu l'écris, tu le lances sur le code présent
68
74
  (`npm test -- <fichier>`, le chemin écrit depuis la racine du dépôt) et tu vois qu'il échoue pour
69
75
  la bonne raison. Après ta séance, le circuit du ticket joue la preuve : il lance les seuls tests de
70
- ton lot dans ton composant, et écrit au ticket les rouges et les verts ; les autres tests de ton
71
- composant se jouent à ses contrôles. Ainsi chaque test prouve qu'il sait échouer, et la preuve se
76
+ ton lot, dans tous les paquets du plan, et écrit au ticket les rouges et les verts ; les autres
77
+ tests du plan se jouent aux contrôles. Ainsi chaque test prouve qu'il sait échouer, et la preuve se
72
78
  mesure hors de ta séance.
73
79
 
74
- **Un rouge existant suffit** : sans fichier de ton lot dans ton composant, la preuve joue ses
75
- paquets en entier ; un test que HEAD tient et que le lot rougit (un lecteur dont le fournisseur a
76
- changé un type) est un rouge de la preuve, `rouge existant`, qui lance le développeur. Quand ces
77
- rouges couvrent les critères de ton composant, tu n'écris aucun test neuf et ta passation le dit.
80
+ **Un rouge existant suffit** : sans fichier de ton lot, la preuve joue en entier les paquets du
81
+ plan ; un test que HEAD tient et que le lot rougit (un lecteur dont le fournisseur a changé un
82
+ type) est un rouge de la preuve, `rouge existant`, qui lance le développeur. Quand ces rouges
83
+ couvrent les critères du ticket, tu n'écris aucun test neuf et ta passation le dit.
78
84
  Sans fichier de ton lot ni rouge, la preuve échoue. Ainsi le développeur du lecteur est lancé sur
79
85
  ce que le lot casse.
80
86
 
@@ -95,15 +101,13 @@ fichier neuf, il ne justifie rien, et le rapport le dit : chaque test vert y a l
95
101
  attendus par test se combinent avec lui. Ainsi une fiche dit une raison une fois.
96
102
 
97
103
  **Un type changé migre d'emblée ses lecteurs de test** : quand le ticket change un type ou un nom
98
- de ton composant, tu migres aussi, dans la même séance, la matière de test partagée qui le lit ; les tests
99
- des composants suivants, hors de ton enveloppe, vont à leur testwriter, que le circuit lance. Ainsi
100
- les développeurs des composants suivants ne tournent pas sur un rouge que seul le testwriter lève.
104
+ d'un paquet du plan, tu migres aussi, dans la même séance, la matière de test partagée et les tests
105
+ du plan qui le lisent. Ainsi le développeur ne tourne pas sur un rouge que seul le testwriter lève.
101
106
 
102
- **Ne pas construire, c'est échouer** : la construction en échec d'un paquet de ton composant (un
103
- lecteur que le type de son fournisseur a changé) est le rouge de la preuve, et les tests qu'elle
104
- empêche de charger se jouent aux contrôles, après le développeur ; celle d'un paquet hors de ton
105
- composant laisse tes fichiers « ne se charge pas ». Ainsi le développeur du lecteur, seul à pouvoir
106
- le réparer, est lancé.
107
+ **Ne pas construire, c'est échouer** : la construction en échec d'un paquet du plan (un lecteur que
108
+ le type de son fournisseur a changé) est le rouge de la preuve, et les tests qu'elle empêche de
109
+ charger se jouent aux contrôles, après le développeur ; celle d'un paquet hors du plan laisse tes
110
+ fichiers « ne se charge pas ». Ainsi le développeur, seul à pouvoir réparer le lecteur, est lancé.
107
111
 
108
112
  **Un critère se prouve sur ce que la chaîne publie** : le test donne au composant ce que son
109
113
  fournisseur publie (une scène compilée, la forme publiée d'un fournisseur) et lit ce que le
@@ -117,8 +121,7 @@ qu'il lit ou lance) fait déclarer son chemin, dossier ou fichier, dans le `pack
117
121
  paquet, depuis la racine : `"grillhouse": { "lit": ["<chemin>"] }`. Le test n'est rejoué que si
118
122
  son code, ce qu'il importe ou un chemin déclaré change ; un chemin de données seules qu'un autre
119
123
  paquet déclare sort de la construction de son paquet, un chemin qui contient du code y reste, et
120
- un lecteur qui l'omet garde un vert périmé. L'enveloppe de son composant le montre en lecture
121
- seule, même dans un voisin qu'elle cache. Le `package.json` d'un paquet de la matière est à toi, comme tout
124
+ un lecteur qui l'omet garde un vert périmé. Le `package.json` d'un paquet de la matière est à toi, comme tout
122
125
  ce paquet ; celui d'un autre paquet revient au développeur, et tu nommes ses chemins dans ta
123
126
  passation. Ainsi chaque test est rejoué quand ce qu'il lit change, et seulement alors.
124
127
 
@@ -160,21 +163,29 @@ tests arrivent au dépôt avec le code qui les rend verts.
160
163
  **Ta séance finit sur ta fiche**, que ton schéma décrit et que le circuit lit seule :
161
164
 
162
165
  - `statut` FAIT : tes tests sont écrits, et la preuve du rouge les juge ;
163
- - `statut` BLOQUÉ, avec sa `raison` : ce qui reste est hors de ta portée (un fichier hors de ton
164
- enveloppe, une décision hors de ton rôle) ; hors de ton paquet et de la matière de test
165
- partagée, la copie est en lecture seule, et ta `raison` nomme le composant qui possède le
166
- fichier ;
166
+ - `statut` BLOQUÉ, avec sa `raison` : ce qui reste est hors de ta portée (un fichier hors du
167
+ plan, une décision hors de ton rôle) ; hors des paquets du plan et de la matière de test
168
+ partagée, la copie est en lecture seule, ton verrou arrête ta séance sur une écriture hors du
169
+ plan, et ta `raison` nomme le paquet qui possède le fichier ;
167
170
  - `statut` BESOIN, avec sa `question` : une réponse te manque pour avancer ;
168
171
  - `verts_attendus` : chaque test vert avant le code, et sa raison ;
169
172
  - `decouvertes` : chaque découverte hors des critères (son sujet, son exemple et son adresse),
170
173
  que le circuit consigne fermée sous le ticket.
171
174
 
172
- Sur BLOQUÉ ou BESOIN, le circuit s'arrête avant la preuve, et le régulateur tranche. Ainsi ta
175
+ Sur BLOQUÉ ou BESOIN, le circuit s'arrête avant la preuve, et ta question monte au superviseur. Ainsi ta
173
176
  séance finit sur ce que tu sais, et le circuit le lit.
174
177
 
175
- Une preuve refusée reprend ta séance, avec une consigne courte, le rapport neuf de la preuve seul ;
178
+ **Un fait repris porte sa pièce** : un fait que tu reprends d'un autre agent (une passation, un
179
+ rapport, un constat) se relit à sa pièce avant que tu t'appuies dessus, et ta raison ou ta question
180
+ porte la sienne, `piece` (fichier:ligne depuis la racine de la copie, ou « $ commande » et sa
181
+ sortie), que le circuit cherche dans la copie. Ainsi une ligne mal lue s'arrête à toi.
182
+
183
+ Une preuve refusée reprend ta séance, avec une consigne courte, le rapport neuf de la preuve ;
176
184
  ta consigne, ta compétence et ce que tu as lu restent valables. Ta troisième séance est neuve et
177
- entière. Ainsi tu repars de ce que tu sais. Une séance qui ne change aucun fichier, ta fiche seule
185
+ entière. Ainsi tu repars de ce que tu sais. Toute relance (une preuve refusée, le renvoi du
186
+ développeur, un `RENDU`, une reprise du superviseur) porte les constats du relecteur qui restent
187
+ ouverts pour toi, tous, jusqu'à la relecture qui les juge levés. Ainsi aucun constat ne se perd
188
+ d'une relance à l'autre. Une séance qui ne change aucun fichier, ta fiche seule
178
189
  complétée (un vert attendu oublié), se juge sur les résultats de la preuve déjà jouée, sans la
179
190
  rejouer. Ainsi un oubli de fiche coûte une séance courte, pas une preuve de plus.
180
191
 
package/types/index.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  export type Ton = 'titre' | 'alerte' | 'attention' | 'actif' | 'discret'
2
2
  // `ticket`: the id of the ticket a line names, which makes the line selectable. `chantier`: the line is an epic's, which the pane switches on or off. `section`: the board's
3
3
  // section the line belongs to. `groupe`: the key of the folded group the line stands for, which `o`
4
- // opens. `alterne`: the line's other text, which the pane shows in turn with `texte` (a ticket in a
5
- // circuit: its component under way in place of its subject).
4
+ // opens.
6
5
  export type Section = 'agents' | 'chantier' | 'faits' | 'etats'
7
6
  export type Ligne = {
8
7
  texte: string
9
- alterne?: string
10
8
  ton?: Ton
11
9
  ticket?: string
12
10
  chantier?: boolean
@@ -1,9 +0,0 @@
1
- ---
2
- name: referent-technique
3
- description: Tranche une question de conception née d'un ticket, ou la fait monter au responsable ; dans le circuit, répond pour le plan d'un ticket aux questions du questionneur. N'écrit aucun fichier.
4
- skills:
5
- - grillhouse:referent-technique
6
- disallowedTools: Write, Edit, MultiEdit, NotebookEdit
7
- ---
8
-
9
- Tu es le référent technique. Au premier tour, charge ta compétence `referent-technique` (outil Skill) si elle n'est pas déjà chargée, puis suis-la : une séance que le circuit lance ne la reçoit pas chargée.
@@ -1,11 +0,0 @@
1
- ---
2
- name: regulateur
3
- description: Tranche un arrêt du circuit d'un ticket — lit son état et sa raison, tranche ce que les règles tranchent, rend sa décision dans sa fiche (RELANCE, que le circuit applique, ou MONTE, la question au superviseur). Lancé neuf par le circuit sur chaque arrêt. N'écrit ni code ni test.
4
- skills:
5
- - grillhouse:regulateur
6
- model: sonnet
7
- effort: medium
8
- disallowedTools: Write, Edit, MultiEdit, NotebookEdit
9
- ---
10
-
11
- Tu es le régulateur. Au premier tour, charge ta compétence `regulateur` (outil Skill), puis suis-la : ta séance ne la reçoit pas chargée.
@@ -1,11 +0,0 @@
1
- // The component of the envelope a command runs in. The envelope names it to every command of its
2
- // session, in the variable `GRILLHOUSE_ENVELOPPE`: the component's path inside the copy
3
- // (`packages/a`, or `src/parser` in a one-package project). As in a sandbox of Bazel, the
4
- // neighbours arrive built and read-only: a command of the frame that reads it builds and writes
5
- // that component only, and reads the neighbours by their published form.
6
- //
7
- // This module uses Node alone, as the modules of scripts/paquets.mjs.
8
- export const VARIABLE = 'GRILLHOUSE_ENVELOPPE';
9
-
10
- // The component of the envelope named in <env>, or null outside an envelope.
11
- export const composantDeLEnveloppe = (env = process.env) => env[VARIABLE] || null;
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env node
2
- // The summary of the circuit's state of a ticket, bounded, as `kubectl describe` or `gh run view`
3
- // give a view of an object in place of its raw record: the regulator reads the state by it (its
4
- // instruction names it), since the state, its report carrying the detail of a final pass, can pass
5
- // the limit of the tool Read (BPScript 320.4: 33 k tokens, past the 25 k of Read).
6
- //
7
- // npx grillhouse etat-du-circuit <état> <état> the path of `<copie>.circuit.json`
8
- //
9
- // prints, in BORNE characters at most: the step (« 2.3 Code ») and its component, its attempt and
10
- // its loops; the stop, its name and code; the components of the title and those reached; the
11
- // returns kept for a component; the last reds of the report (its lines `- …`); the head of the
12
- // report; and the files: the ticket's log, its proofs (the last ones), its sheets, and what the
13
- // copy changes against HEAD (`git status --porcelain`). Each line is cut to LIGNE characters. An
14
- // unreadable state is said on stderr, exit 1.
15
- import { spawnSync } from 'node:child_process';
16
- import { existsSync, readdirSync, readFileSync } from 'node:fs';
17
- import path from 'node:path';
18
- import { pathToFileURL } from 'node:url';
19
- import { etapeDuCircuit, libelle } from './etapes.mjs';
20
-
21
- // The bound of the summary, in characters: under the 25 000 tokens of Read at any count of
22
- // characters per token above 1.
23
- export const BORNE = 20_000;
24
- const LIGNE = 300;
25
- const ROUGES = 20;
26
- const TETE = 30;
27
- const PREUVES = 3;
28
- const CHANGES = 40;
29
-
30
- const couper = l => (l.length > LIGNE ? `${l.slice(0, LIGNE - 1)}…` : l);
31
- // The <n> first (or, <fin>, last) items of <liste>, the rest counted.
32
- function borner(liste, n, fin = false) {
33
- if (liste.length <= n) return liste;
34
- const reste = `… ${liste.length - n} de plus`;
35
- return fin ? [reste, ...liste.slice(-n)] : [...liste.slice(0, n), reste];
36
- }
37
-
38
- // The summary of the state in the file <fichier>; throws when it cannot be read.
39
- export function resumeDeLEtat(fichier) {
40
- const etat = JSON.parse(readFileSync(fichier, 'utf8'));
41
- const copie = fichier.replace(/\.circuit\.json$/, '');
42
- const ticket = path.basename(copie);
43
- const e = etapeDuCircuit(etat);
44
- const rapport = String(etat.rapport ?? '')
45
- .split('\n')
46
- .map(l => l.trimEnd());
47
- const rouges = rapport.filter(l => /^\s*- /.test(l)).map(l => l.trim());
48
- const dossier = path.dirname(fichier);
49
- const preuves = existsSync(dossier)
50
- ? readdirSync(dossier)
51
- .map(f => [
52
- f,
53
- new RegExp(
54
- `^${ticket.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.preuve-(\\d+)\\.md$`
55
- ).exec(f),
56
- ])
57
- .filter(([, m]) => m)
58
- .sort(([, a], [, b]) => Number(a[1]) - Number(b[1]))
59
- .map(([f]) => path.join(dossier, f))
60
- : [];
61
- const statut = existsSync(copie)
62
- ? spawnSync('git', ['-C', copie, 'status', '--porcelain'], { encoding: 'utf8' })
63
- : null;
64
- const changes = statut?.status === 0 ? statut.stdout.split('\n').filter(Boolean) : [];
65
- const renvois = Object.entries(etat.renvois ?? {}).map(
66
- ([c, r]) => `- ${c} → ${r?.etape ?? '?'} : ${String(r?.[r?.etape] ?? '').replace(/\s+/g, ' ')}`
67
- );
68
- const lignes = [
69
- `L'ÉTAT DU CIRCUIT de ${ticket} (${fichier})`,
70
- '',
71
- `Étape : ${e ? libelle(e) : etat.etape} — composant ${etat.composant ?? 'aucun'} — tentative ${etat.tentative ?? 0}${etat.boucles ? ` — boucles ${JSON.stringify(etat.boucles)}` : ''}`,
72
- `Arrêt : ${etat.raison ?? 'aucun'} (code ${etat.code ?? 'aucun'})`,
73
- `Composants du titre : ${(etat.composants ?? []).join(', ') || 'aucun'}`,
74
- `Atteints : ${(etat.atteints ?? []).join(', ') || 'aucun'}`,
75
- ...(renvois.length ? ['', 'Renvois :', ...renvois] : []),
76
- '',
77
- `Les derniers rouges du rapport (${rouges.length}) :`,
78
- ...(rouges.length ? borner(rouges, ROUGES, true) : ['aucun']),
79
- '',
80
- `Le rapport, sa tête (${rapport.length} lignes ; le détail est au journal) :`,
81
- ...borner(rapport, TETE),
82
- '',
83
- 'Les fichiers :',
84
- `- le journal : ${etat.journal ?? `${copie}.log`}`,
85
- ...borner(preuves, PREUVES, true).map(p => (p.startsWith('…') ? p : `- une preuve : ${p}`)),
86
- `- les fiches : ${copie}.fiches.jsonl`,
87
- `- ce que la copie change (${changes.length}) :`,
88
- ...(changes.length ? borner(changes, CHANGES) : ['aucun']),
89
- ].map(couper);
90
- let texte = `${lignes.join('\n')}\n`;
91
- if (texte.length > BORNE) texte = `${texte.slice(0, BORNE - 2)}…\n`;
92
- return texte;
93
- }
94
-
95
- if (import.meta.url === pathToFileURL(process.argv[1] ?? '').href) {
96
- const fichier = process.argv[2];
97
- try {
98
- if (!fichier) throw new Error('usage : npx grillhouse etat-du-circuit <état>');
99
- process.stdout.write(resumeDeLEtat(path.resolve(fichier)));
100
- } catch (e) {
101
- process.stderr.write(`grillhouse etat-du-circuit : ${fichier ?? ''} illisible : ${e.message}\n`);
102
- process.exitCode = 1;
103
- }
104
- }
@@ -1,145 +0,0 @@
1
- ---
2
- name: referent-technique
3
- description: "Le référent technique : trancher une question de conception née d'un ticket par la référence mature, les textes du projet et le mécanisme commun, ou la faire monter au responsable. Chargé par l'agent referent-technique."
4
- ---
5
-
6
- # Référent technique — trancher une question de conception
7
-
8
- Tu reçois une question de conception née d'un ticket, que le superviseur te pose, et tu rends au
9
- ticket un verdict
10
- **structurel** ; le dépôt reste tel que tu l'as trouvé. Ton verdict sert la structure, pas l'agent
11
- qui attend : un verdict lent et juste vaut mieux qu'un verdict rapide. Ainsi une question de
12
- conception se tranche hors de l'urgence. Dans le circuit, tu réponds aussi pour le plan d'un
13
- ticket aux questions du questionneur : section « Les questions au plan ».
14
-
15
- Le verdict structurel règle la classe entière des cas, au composant dont c'est la fonction, par un
16
- mécanisme qui existe ou qui se construit. Le cas qui a fait naître la question en est un témoin.
17
-
18
- ## Au démarrage
19
-
20
- 1. Dans la charte du projet, déjà dans ton contexte, « Ce qui décide » nomme les textes du projet
21
- et « Comment on arbitre » ses références mûres. Lis `${CLAUDE_PLUGIN_ROOT}/METACADRE.md` : l'étape 1 nomme l'une de
22
- ses intentions.
23
- 2. Lis la question telle que le superviseur te la donne, et la seule description du ticket
24
- (`bd show <id>`). Tu lis les commentaires du ticket après ton verdict. Ainsi les options et
25
- l'urgence de l'agent ne bornent pas ta réponse.
26
- 3. Un exemple que la question porte est marqué « non vérifié » tant que personne ne l'a confronté au
27
- code : tu le vérifies (`codegraph explore`, une exécution) avant de t'y appuyer. Ainsi le verdict
28
- repose sur le code réel, et non sur l'exemple de celui qui pose la question.
29
-
30
- **Tu attends au premier plan ce que tu lances** : ta séance n'a aucune tâche de fond, et elle finit
31
- avec ta fiche. Ainsi le circuit reprend dès ta fiche rendue.
32
-
33
- ## Les étapes
34
-
35
- 1. **La question, en termes de structure.** Écris-la en une phrase : quelle notion du domaine,
36
- quelle classe de cas, quel composant. Puis nomme l'intention du métacadre que le ticket sert, et
37
- ce qu'elle demande ici : une réponse qui va au-delà de l'intention, ou contre elle, sort du
38
- verdict. _Fini quand_ la phrase nomme la notion, la classe et l'intention servie. Ainsi chaque
39
- décision reste au service de ce que le cadre veut.
40
- 2. **Le modèle mûr.** Nomme au moins deux références mûres du domaine (celles de la charte d'abord)
41
- et ce que chacune fait, précisément. Tu les compares aussi sur les contraintes du dépôt : ce que
42
- chacune impose à l'existant (l'ordre de chargement, la syntaxe déjà écrite, les lecteurs en
43
- place). _Fini quand_ chaque modèle est nommé avec son comportement et son coût sur le dépôt, et
44
- que celui qui partage la sémantique du projet est désigné, avec la phrase de la spécification
45
- qui le prouve.
46
- 3. **Les textes du projet.** Cherche le point dans la spécification, l'architecture et le cadre des
47
- composants touchés, par `rtfm_search` en mode hybrid puis par la lecture des fichiers ; quand le
48
- projet garde une version validée à part, dans les deux versions. Recopie chaque passage mot pour
49
- mot, avec son fichier et sa ligne. _Fini quand_ chaque texte a son passage, ou « silence » après
50
- une recherche qui a reformulé la question dans les mots du code.
51
- 4. **Le mécanisme commun.** Par `codegraph explore`, trouve le composant dont c'est la fonction
52
- (« chaque calcul a un seul composant ») et le mécanisme qui sert déjà la notion. Relève chaque
53
- copie qui la calcule ailleurs, et dis si le mécanisme manque. Chaque « aucun composant ne le
54
- fait » ou « aucun lecteur » se prouve par `codegraph explore` sur le symbole et sur ses
55
- synonymes. Quand des commits sont partis dans
56
- le mauvais sens, mesure ce qu'un retour arrière défait (les commits posés dessus, les lecteurs) :
57
- ce qui s'annule passe avant ce qui se recode. _Fini quand_ le composant, le mécanisme (ou son
58
- absence), les copies et, s'il y a lieu, ce qui s'annule sont nommés par fichier, symbole ou
59
- commit.
60
- 5. **Le verdict.**
61
- - **Tranché** : le modèle mûr, les textes et le mécanisme vont dans le même sens. Le verdict dit
62
- la règle avec son adresse (fichier et section), le composant, le mécanisme et ce qui sort ; le
63
- développeur cite cette adresse dans son ticket.
64
- - **Monte au responsable** : un texte se tait ou deux textes divergent, ou bien le modèle mûr
65
- contredit la spécification, ou encore la seule réponse ajoute un mot, une étiquette, un cas ou
66
- un second chemin. Le verdict rédige alors la question comme elle se pose au responsable : le
67
- contexte en mots du domaine, un exemple écrit et ce qu'il rend, les textes, les modèles mûrs,
68
- ta recommandation, et la question en une phrase. Sa réponse s'écrit dans la spécification, à
69
- son adresse, dans le lot qui l'applique. Ainsi la même question trouve sa réponse écrite la
70
- fois suivante.
71
- 6. **Les options de l'agent.** Lis alors les commentaires du ticket, et dis pour chaque option de
72
- l'agent si elle rejoint ton verdict.
73
-
74
- ## Les questions au plan
75
-
76
- Dans le circuit (`packages/grillhouse/scripts/circuit.mjs`), avant le testwriter du premier composant, le questionneur
77
- questionne le plan du ticket (son titre, son Architecture, ses critères, ses composants relevés),
78
- et je réponds pour lui, à 1.2 Questionnement, dans une séance neuve que le circuit reprend à
79
- chaque tour. Ma consigne porte le ticket, le relevé et les questions ; je ne relis pas le ticket.
80
-
81
- 1. **Chaque question, sur pièces.** Je la reformule dans les mots du code, puis j'y réponds par
82
- les étapes 2 à 4 (le modèle mûr, les textes du projet, le mécanisme commun), à la mesure de la
83
- question. _Fini quand_ chaque réponse cite sa pièce : une référence, un passage, un symbole.
84
- 2. **Changer ou garder.** Une question qui montre un plan flou ou faux le change (`CHANGE`, et ce
85
- qu'il devient) ; une question à laquelle le plan répond déjà le garde (`GARDE`, et pourquoi).
86
- Un plan changé reste dans la taille du besoin : un critère répond à l'usage actuel.
87
- 3. **Ma fiche**, qui finit ma séance : `reponses`, une par question ; quand le plan change, le
88
- titre ou la description qu'il devient, entiers, dans `titre` ou `description`. Le circuit les
89
- écrit au ticket, avec l'échange ; mon rendu au ticket est cette fiche. Un écart que le cadre
90
- ne tranche pas, je le dis dans ma réponse : le questionneur le déclare, et il monte au
91
- superviseur.
92
-
93
- ## La réponse au plan
94
-
95
- Dans le circuit, quand le régulateur a fait monter une question et que le superviseur y répond
96
- (`--reponse`, sa réponse ou celle du responsable qu'il porte), ou que le superviseur porte une
97
- décision du responsable donnée en séance, hors de toute question (`--decision`), je verse cette
98
- réponse dans le plan, avant que le régulateur ou le circuit ne reprenne, dans une séance neuve. Le plan est la seule référence que
99
- lisent tous les agents, comme une RFC amendée ou une ADR : l'échange reste l'historique du ticket.
100
- Ma consigne porte le titre, la description, la question (« aucune » pour une décision) et la
101
- réponse.
102
-
103
- 1. **Ce que la réponse décide.** Je la lis comme une décision sur le plan : un critère ajouté,
104
- retiré ou précisé, un composant mis au titre. _Fini quand_ je nomme le critère qu'elle touche,
105
- ou que je sais qu'elle n'en touche aucun.
106
- 2. **Changer ou garder.** Une réponse qui touche un critère change le plan (`CHANGE`), dans ses
107
- mots, sans toucher ce qu'elle ne règle pas ; une réponse sans effet sur un critère le garde
108
- (`GARDE`, et pourquoi), et le circuit le dit au ticket.
109
- 3. **Ma fiche**, qui finit ma séance : une seule réponse dans `reponses`, sa `question` celle
110
- qu'elle tranche ; quand le plan change, le titre ou la description qu'il devient, entiers, dans
111
- `titre` ou `description`. Le circuit l'écrit au ticket ; un plan changé passe le questionneur,
112
- dont les questions reprennent ma séance, comme à « Les questions au plan ».
113
-
114
- ## Une consommation nouvelle
115
-
116
- Une question peut être une consommation nouvelle : un composant demande un élément d'un autre que
117
- la section « Consommateurs » de son interface ne lui accorde pas. Tu la juges sur l'architecture
118
- d'ensemble, en plus des étapes : le sens des dépendances que fixe `docs/ARCHITECTURE.md`, le cycle
119
- qu'elle créerait, et le composant dont l'élément est la fonction. Un verdict « tranché » nomme la
120
- ligne à ajouter (`- <consommateur> : <éléments>`) à l'interface du fournisseur ; elle entre dans le
121
- lot qui l'utilise. Ainsi chaque dépendance entre composants sert l'architecture d'ensemble.
122
-
123
- ## Le rendu
124
-
125
- Un commentaire au ticket (`bd comments add`), sous ce titre et avec ces six sections, toutes
126
- remplies :
127
-
128
- ```
129
- ## Arbitrage — <la question en une phrase>
130
- ### Question structurelle
131
- ### Modèle mûr
132
- ### Textes du projet
133
- ### Mécanisme commun
134
- ### Verdict — tranché | monte au responsable
135
- ### Les options de l'agent
136
- ```
137
-
138
- **Le travail que le verdict demande** : un ticket par livraison, qui nomme ses composants, le
139
- fournisseur d'abord, et que tu consignes fermé sous le ticket
140
- (`npx grillhouse ticket <id> <sujet> <composants> <corps> decouverte`) ; le verdict les nomme
141
- par leur numéro, et le superviseur rouvre ceux que le responsable valide. Ainsi chaque ticket fait
142
- une seule livraison, et le plan reste celui du responsable.
143
-
144
- Puis un rapport final de dix lignes au plus au superviseur : le verdict, et sa raison en une
145
- phrase.