@roomi-fields/grillhouse 0.23.1 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/METACADRE.md +1 -1
- package/agents/explorateur.md +4 -2
- package/agents/questionneur.md +1 -1
- package/bin/grillhouse.mjs +3 -58
- package/cadre/templates/projet/CLAUDE.md +5 -1
- package/cadre/templates/projet/docs/agents/issue-tracker.md +4 -4
- package/charte.md +23 -6
- package/docs/ARCHITECTURE.md +127 -1
- package/hooks/register.tsx +3 -13
- package/package.json +13 -1
- package/scripts/bilan.mjs +134 -88
- package/scripts/circuit.mjs +1547 -2248
- package/scripts/composants-affectes.mjs +27 -108
- package/scripts/consommateurs-arbitres.mjs +15 -21
- package/scripts/consommateurs.d.ts +8 -0
- package/scripts/consommateurs.mjs +5 -1
- package/scripts/dette.d.ts +23 -0
- package/scripts/dette.mjs +76 -13
- package/scripts/droits.mjs +38 -44
- package/scripts/elements-du-lot.mjs +246 -0
- package/scripts/enveloppe/enveloppe.mjs +105 -232
- package/scripts/enveloppe/lancer.sh +79 -49
- package/scripts/enveloppe/paquets-du-plan.mjs +49 -0
- package/scripts/etapes.mjs +148 -213
- package/scripts/gardes-du-cadre.mjs +8 -6
- package/scripts/grillhouse-maj.mjs +31 -9
- package/scripts/index-interfaces.mjs +21 -1
- package/scripts/integration/integrer.mjs +2 -2
- package/scripts/interfaces-contre-code.mjs +25 -17
- package/scripts/migrations/0.23.0-config-vitest.mjs +26 -23
- package/scripts/migrations/0.23.2-copies-du-cadre.mjs +201 -0
- package/scripts/migrations/0.24.0-circuit-simplifie.mjs +231 -0
- package/scripts/migrations.mjs +41 -6
- package/scripts/paquets.d.ts +5 -0
- package/scripts/paquets.mjs +3 -0
- package/scripts/references-par-les-types.mjs +55 -36
- package/scripts/registre.mjs +7 -15
- package/scripts/resultats.mjs +283 -142
- package/scripts/resumes.mjs +1 -1
- package/scripts/session-start.sh +1 -2
- package/scripts/sources.mjs +28 -0
- package/scripts/sous-commandes.mjs +62 -0
- package/scripts/tableau.mjs +85 -191
- package/scripts/tests.mjs +19 -17
- package/scripts/verifier.mjs +5 -4
- package/scripts/verrou-de-machine.mjs +131 -24
- package/scripts/verrous/verrou.mjs +66 -5
- package/skills/developpeur/SKILL.md +60 -50
- package/skills/explorateur/SKILL.md +90 -64
- package/skills/grill/SKILL.md +1 -1
- package/skills/mesure/SKILL.md +2 -1
- package/skills/pitmaster/SKILL.md +132 -118
- package/skills/pitmaster/references/consigne-agent.md +54 -148
- package/skills/questionneur/SKILL.md +18 -18
- package/skills/relecteur/SKILL.md +69 -23
- package/skills/testwriter/SKILL.md +46 -35
- package/types/index.d.ts +1 -3
- package/agents/referent-technique.md +0 -9
- package/agents/regulateur.md +0 -11
- package/scripts/enveloppe/composant.mjs +0 -11
- package/scripts/etat-du-circuit.mjs +0 -104
- package/skills/referent-technique/SKILL.md +0 -145
- 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
|
-
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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** :
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
71
|
-
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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é.
|
|
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
|
|
164
|
-
|
|
165
|
-
partagée, la copie est en lecture seule,
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
package/agents/regulateur.md
DELETED
|
@@ -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.
|