@roomi-fields/grillhouse 0.23.1 → 0.24.1
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 +130 -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/frontieres.mjs +4 -2
- package/scripts/gardes-du-cadre.mjs +8 -6
- package/scripts/grillhouse-maj.mjs +113 -19
- 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 +274 -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
package/scripts/etapes.mjs
CHANGED
|
@@ -3,121 +3,81 @@
|
|
|
3
3
|
// list, which the circuit (scripts/circuit.mjs), the board (scripts/tableau.mjs), the bilan
|
|
4
4
|
// (scripts/bilan.mjs) and the texts read.
|
|
5
5
|
//
|
|
6
|
-
// - A step (ETAPES): its number (« 2 », «
|
|
6
|
+
// - A step (ETAPES): its number (« 2 », « 4.1 »), its title, who works there (`qui`: the role
|
|
7
7
|
// agents, or AUTO for a step the circuit leads itself; none for a step that only holds its
|
|
8
|
-
// sub-steps), its
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// a questioning, the reviews, the same stop come back after a RELANCE of the regulator. The
|
|
23
|
-
// circuit stops each loop at its maximum and writes its count in its state; the board shows
|
|
24
|
-
// « <label> <n>/<max> » on the ticket's line from the second pass.
|
|
25
|
-
// - The arbitrage of a stop (ARBITRAGE) stands out of the sequence, under the stopped step: the
|
|
26
|
-
// regulator settles the stop, and the questionneur asks its questions of his decision before it
|
|
27
|
-
// is applied, as Amazon's bar raiser and a cockpit's challenge and response; it has no number.
|
|
8
|
+
// sub-steps), its sub-steps (`sous`), and the step of the circuit's state it is (`etat`: the
|
|
9
|
+
// `etape` of `.claude/worktrees/<ticket>.circuit.json`, the final pass being the checks once
|
|
10
|
+
// `finale`). Every step runs once for the whole ticket, as a merge request has one author of
|
|
11
|
+
// its tests and one of its code, one CI on the whole and one review: one session of the
|
|
12
|
+
// testwriter (2) and one of the developpeur (3) carry the whole plan.
|
|
13
|
+
// The plan (1) is read elsewhere in the state: by the work on the plan under way
|
|
14
|
+
// (`questionnement`, the explorateur's or the questionneur's session) and by its stop (`arrets`).
|
|
15
|
+
// SUITE is the tree in its order, each step before its sub-steps.
|
|
16
|
+
// - A step carries as many bounded loops as it needs (`boucles`), each spanning the step and its
|
|
17
|
+
// sub-steps: each its key (`cle`, which keys its count in the state's `boucles`), its label and
|
|
18
|
+
// its maximum (`max`, the pass that stops it): the testwriter's sessions after a refused proof,
|
|
19
|
+
// the developpeur's sessions with their checks, the reviews. The circuit stops each loop at its
|
|
20
|
+
// maximum and writes its count in its state; the board shows « <label> <n>/<max> » on the
|
|
21
|
+
// ticket's line from the second pass.
|
|
28
22
|
// - The stops of the circuit, each by its name and its exit code (ARRETS): the circuit ends on one
|
|
29
23
|
// with its code, and its header says when.
|
|
30
|
-
// - The
|
|
24
|
+
// - The gestures of the circuit (GESTES, below): what it does itself on a stop a rule settles,
|
|
25
|
+
// with no session.
|
|
26
|
+
// - The question of each other stop (MONTEES, below): what goes up to the supervisor, and who
|
|
27
|
+
// must answer it.
|
|
31
28
|
import { A_REPASSER } from './vitest-config/pression.mjs';
|
|
32
29
|
|
|
33
30
|
// Who works at a step the circuit leads itself, with no agent.
|
|
34
31
|
export const AUTO = 'auto';
|
|
35
32
|
|
|
36
|
-
// The rounds of a questioning, of the plan at 1.2 and of a decision at the arbitrage.
|
|
37
|
-
const TOURS = { cle: 'questionnement', libelle: 'tour', max: 4 };
|
|
38
|
-
|
|
39
33
|
export const ETAPES = [
|
|
40
|
-
{ numero: '0', titre: 'Exploration', qui: ['explorateur'], etat: null },
|
|
41
34
|
{
|
|
42
35
|
numero: '1',
|
|
43
|
-
titre: '
|
|
44
|
-
qui: [],
|
|
36
|
+
titre: 'Plan',
|
|
37
|
+
qui: ['explorateur', 'questionneur'],
|
|
45
38
|
etat: null,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
numero: '1.1',
|
|
49
|
-
titre: 'Relevé des composants',
|
|
50
|
-
qui: [AUTO],
|
|
51
|
-
etat: null,
|
|
52
|
-
releve: true,
|
|
53
|
-
arrets: ['composants-manquants'],
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
numero: '1.2',
|
|
57
|
-
titre: 'Questionnement',
|
|
58
|
-
qui: ['questionneur', 'referent-technique'],
|
|
59
|
-
quiCourt: 'questionneur ⇄ référent',
|
|
60
|
-
etat: null,
|
|
61
|
-
questionnement: 'plan',
|
|
62
|
-
arrets: ['questionnement'],
|
|
63
|
-
boucles: [TOURS],
|
|
64
|
-
},
|
|
65
|
-
],
|
|
39
|
+
questionnement: 'plan',
|
|
40
|
+
arrets: ['questionnement'],
|
|
66
41
|
},
|
|
67
42
|
{
|
|
68
43
|
numero: '2',
|
|
69
|
-
titre: '
|
|
70
|
-
qui: [],
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{ cle: 'composant', libelle: 'composant', max: null },
|
|
75
|
-
{ cle: 'tests', libelle: 'essai', max: 3, sur: ['2.1', '2.2'] },
|
|
76
|
-
{ cle: 'code', libelle: 'essai', max: 3, sur: ['2.3', '2.4'] },
|
|
77
|
-
],
|
|
78
|
-
sous: [
|
|
79
|
-
{
|
|
80
|
-
numero: '2.1',
|
|
81
|
-
titre: 'Tests',
|
|
82
|
-
qui: ['testwriter'],
|
|
83
|
-
parComposant: true,
|
|
84
|
-
etat: 'testwriter',
|
|
85
|
-
},
|
|
86
|
-
{ numero: '2.2', titre: 'Preuve du rouge', qui: [AUTO], parComposant: true, etat: 'preuve' },
|
|
87
|
-
{
|
|
88
|
-
numero: '2.3',
|
|
89
|
-
titre: 'Code',
|
|
90
|
-
qui: ['developpeur'],
|
|
91
|
-
parComposant: true,
|
|
92
|
-
etat: 'developpeur',
|
|
93
|
-
},
|
|
94
|
-
{ numero: '2.4', titre: 'Contrôles', qui: [AUTO], parComposant: true, etat: 'controles' },
|
|
95
|
-
],
|
|
44
|
+
titre: 'Tests',
|
|
45
|
+
qui: ['testwriter'],
|
|
46
|
+
etat: 'testwriter',
|
|
47
|
+
boucles: [{ cle: 'tests', libelle: 'essai', max: 3 }],
|
|
48
|
+
sous: [{ numero: '2.1', titre: 'Preuve du rouge', qui: [AUTO], etat: 'preuve' }],
|
|
96
49
|
},
|
|
97
50
|
{
|
|
98
51
|
numero: '3',
|
|
99
|
-
titre: '
|
|
100
|
-
qui: [
|
|
101
|
-
etat: '
|
|
102
|
-
|
|
52
|
+
titre: 'Code',
|
|
53
|
+
qui: ['developpeur'],
|
|
54
|
+
etat: 'developpeur',
|
|
55
|
+
boucles: [{ cle: 'code', libelle: 'essai', max: 3 }],
|
|
56
|
+
sous: [{ numero: '3.1', titre: 'Contrôles', qui: [AUTO], etat: 'controles' }],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
numero: '4',
|
|
60
|
+
titre: 'Passe finale et relecture',
|
|
61
|
+
qui: [],
|
|
62
|
+
etat: null,
|
|
103
63
|
sous: [
|
|
64
|
+
{ numero: '4.1', titre: 'Passe finale', qui: [AUTO], etat: 'controles', finale: true },
|
|
104
65
|
{
|
|
105
|
-
numero: '
|
|
66
|
+
numero: '4.2',
|
|
106
67
|
titre: 'Régénération des références',
|
|
107
68
|
qui: [AUTO],
|
|
108
69
|
etat: 'references',
|
|
109
|
-
declaration: 'references',
|
|
110
70
|
arrets: ['references'],
|
|
111
71
|
},
|
|
72
|
+
{
|
|
73
|
+
numero: '4.3',
|
|
74
|
+
titre: 'Relecture',
|
|
75
|
+
qui: ['relecteur'],
|
|
76
|
+
etat: 'relecture',
|
|
77
|
+
boucles: [{ cle: 'relecture', libelle: 'tour', max: 3 }],
|
|
78
|
+
},
|
|
112
79
|
],
|
|
113
80
|
},
|
|
114
|
-
{
|
|
115
|
-
numero: '4',
|
|
116
|
-
titre: 'Relecture',
|
|
117
|
-
qui: ['relecteur'],
|
|
118
|
-
etat: 'relecture',
|
|
119
|
-
boucles: [{ cle: 'relecture', libelle: 'tour', max: 3 }],
|
|
120
|
-
},
|
|
121
81
|
{
|
|
122
82
|
numero: '5',
|
|
123
83
|
titre: 'Intégration',
|
|
@@ -133,29 +93,19 @@ export const ETAPES = [
|
|
|
133
93
|
// Every step and sub-step, in the order of the tree.
|
|
134
94
|
export const SUITE = ETAPES.flatMap(e => [e, ...(e.sous ?? [])]);
|
|
135
95
|
|
|
136
|
-
// The arbitrage of a stop, out of the sequence, under the stopped step.
|
|
137
|
-
export const ARBITRAGE = {
|
|
138
|
-
numero: null,
|
|
139
|
-
titre: "Arbitrage de l'arrêt",
|
|
140
|
-
qui: ['regulateur', 'questionneur'],
|
|
141
|
-
etat: null,
|
|
142
|
-
boucles: [{ cle: 'arret', libelle: 'arrêt', max: 3 }, TOURS],
|
|
143
|
-
};
|
|
144
|
-
|
|
145
96
|
// The bounded loop of key <cle>.
|
|
146
|
-
export const boucle = cle =>
|
|
147
|
-
[...SUITE, ARBITRAGE].flatMap(e => e.boucles ?? []).find(b => b.cle === cle) ?? null;
|
|
97
|
+
export const boucle = cle => SUITE.flatMap(e => e.boucles ?? []).find(b => b.cle === cle) ?? null;
|
|
148
98
|
|
|
149
|
-
// The loops that run at the step <etape>:
|
|
150
|
-
// each step that spans it, itself or its parent.
|
|
99
|
+
// The loops that run at the step <etape>: its own and its parent's.
|
|
151
100
|
export const bouclesDe = etape => {
|
|
152
|
-
if (etape === ARBITRAGE) return ARBITRAGE.boucles;
|
|
153
101
|
const parent = ETAPES.find(e => e === etape || e.sous?.includes(etape));
|
|
154
|
-
return [...new Set([parent, etape])]
|
|
155
|
-
.flatMap(e => e?.boucles ?? [])
|
|
156
|
-
.filter(b => (b.sur ? b.sur.includes(etape.numero) : true));
|
|
102
|
+
return [...new Set([parent, etape])].flatMap(e => e?.boucles ?? []);
|
|
157
103
|
};
|
|
158
104
|
|
|
105
|
+
// The agents who write the lot, the testwriter its tests and the developpeur its code: the roles a
|
|
106
|
+
// blocking finding of the reviewer names.
|
|
107
|
+
export const AGENTS_DU_LOT = ['testwriter', 'developpeur'];
|
|
108
|
+
|
|
159
109
|
// The exit code of each stop of the circuit.
|
|
160
110
|
export const ARRETS = {
|
|
161
111
|
lancement: 10,
|
|
@@ -166,46 +116,36 @@ export const ARRETS = {
|
|
|
166
116
|
'sans-livraison': 15,
|
|
167
117
|
'relecture-arret': 16,
|
|
168
118
|
integration: 17,
|
|
169
|
-
question: 18,
|
|
170
119
|
'hors-portee': 19,
|
|
171
120
|
besoin: 20,
|
|
172
|
-
'composants-manquants': 21,
|
|
173
121
|
questionnement: 22,
|
|
174
122
|
references: 23,
|
|
123
|
+
'hors-plan': 24,
|
|
175
124
|
'a-repasser': A_REPASSER,
|
|
176
125
|
};
|
|
177
126
|
|
|
178
|
-
// The role that
|
|
179
|
-
export const
|
|
127
|
+
// The role that writes the plan and answers its questions once, and the role that questions it.
|
|
128
|
+
export const EXPLORATEUR = 'explorateur';
|
|
180
129
|
export const QUESTIONNEUR = 'questionneur';
|
|
181
130
|
|
|
182
131
|
// A role in words.
|
|
183
|
-
const NOMS = {
|
|
184
|
-
'referent-technique': 'référent technique',
|
|
185
|
-
regulateur: 'régulateur',
|
|
186
|
-
developpeur: 'développeur',
|
|
187
|
-
};
|
|
132
|
+
const NOMS = { developpeur: 'développeur' };
|
|
188
133
|
export const nomDuRole = role => NOMS[role] ?? role;
|
|
189
134
|
|
|
190
|
-
// Who works at the step <e>, in words
|
|
191
|
-
|
|
192
|
-
export const quiDe = e => e.quiCourt ?? e.qui.map(nomDuRole).join(' ⇄ ');
|
|
135
|
+
// Who works at the step <e>, in words: its roles' names.
|
|
136
|
+
export const quiDe = e => e.qui.map(nomDuRole).join(' ⇄ ');
|
|
193
137
|
|
|
194
|
-
// The step <e> in words, «
|
|
138
|
+
// The step <e> in words, « 3 Code ».
|
|
195
139
|
export const libelle = e => `${e.numero} ${e.titre}`;
|
|
196
140
|
|
|
197
|
-
// The step of a circuit's state (`etape`, `finale`, its stop `raison`, its
|
|
198
|
-
// `questionnement`, an object or its `objet
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
export const etapeDuCircuit = ({ etape, finale, raison, questionnement, releve }) => {
|
|
141
|
+
// The step of a circuit's state (`etape`, `finale`, its stop `raison`, the work on its plan under
|
|
142
|
+
// way `questionnement`, an object or its `objet`), or null (« integre », an unknown step): the step
|
|
143
|
+
// whose stop or work on the plan it is, else the step of its `etape`.
|
|
144
|
+
export const etapeDuCircuit = ({ etape, finale, raison, questionnement }) => {
|
|
202
145
|
const objet = questionnement?.objet ?? questionnement ?? null;
|
|
203
146
|
return (
|
|
204
147
|
SUITE.find(
|
|
205
|
-
e =>
|
|
206
|
-
(raison && e.arrets?.includes(raison)) ||
|
|
207
|
-
(objet && e.questionnement === objet) ||
|
|
208
|
-
(!raison && !objet && releve && e.releve)
|
|
148
|
+
e => (raison && e.arrets?.includes(raison)) || (objet && e.questionnement === objet)
|
|
209
149
|
) ??
|
|
210
150
|
SUITE.find(
|
|
211
151
|
e =>
|
|
@@ -217,107 +157,102 @@ export const etapeDuCircuit = ({ etape, finale, raison, questionnement, releve }
|
|
|
217
157
|
);
|
|
218
158
|
};
|
|
219
159
|
|
|
220
|
-
// The step where the role agent <role> works,
|
|
221
|
-
// other agent.
|
|
160
|
+
// The step where the role agent <role> works, or null for any other agent.
|
|
222
161
|
export const etapeDuRole = role =>
|
|
223
|
-
role === AUTO ? null : (
|
|
224
|
-
|
|
225
|
-
// The step where a ticket's plan is questioned.
|
|
226
|
-
const QUESTIONNEMENT_DU_PLAN = SUITE.find(e => e.questionnement === 'plan');
|
|
162
|
+
role === AUTO ? null : (SUITE.find(e => e.qui.includes(role)) ?? null);
|
|
227
163
|
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
// sheriffs of Chromium quarantine a flaky test by a rule, not by a judgement. The circuit
|
|
236
|
-
// (scripts/circuit.mjs) tries its lines in their order on each stop, and on the regulator's
|
|
237
|
-
// decision: a gesture the table names, it applies itself, with no regulator; the regulator is
|
|
238
|
-
// launched for what no line settles, and for the line that sends to him. Each line: `genre`, the
|
|
239
|
-
// kind of stop as the circuit reads it in its structured results and its state; `geste`, what
|
|
240
|
-
// follows; `cas`, the case of BPScript 320.3 (2026-10-20) it would have settled, by its stop (A)
|
|
241
|
-
// or its decision (D) in the analysis of that ticket. The gestures (GESTES):
|
|
242
|
-
// - `superviseur`: the circuit ends on the stop, its reason saying why, for the supervisor, with
|
|
243
|
-
// no regulator, and the board shows it under its step after « ⤷ Arrêt · superviseur »;
|
|
244
|
-
// - `a-repasser`: the circuit ends at 75, which the supervisor plays again at rest;
|
|
245
|
-
// - `regulateur`: a session of the regulator settles the stop;
|
|
246
|
-
// - `developpeur-du-composant`: the red goes to the developpeur of the component that owns it,
|
|
247
|
-
// never to the one under way: it waits for that component's checks, or, at the final pass, the
|
|
248
|
-
// circuit relaunches that developpeur (the checks of scripts/circuit.mjs);
|
|
249
|
-
// - `testwriter`: the circuit plays the component again from its testwriter.
|
|
164
|
+
// The gestures of the circuit: what it does itself on a stop a rule settles, as a CI applies its
|
|
165
|
+
// rules (retry, regenerate, skip a job without object) without asking anyone, and as the sheriffs
|
|
166
|
+
// of Chromium quarantine a flaky test by a rule, not by a judgement. Each gesture: `genre`, its
|
|
167
|
+
// name as the circuit writes it at the ticket and in the log; `geste`, what the circuit does;
|
|
168
|
+
// `regle`, the rule that settles it; `cas`, the case of BPScript it settles (the analysis of 320.3,
|
|
169
|
+
// its stop A or its decision D, or that of 320.9). On each one, the circuit writes at the ticket
|
|
170
|
+
// `Circuit · geste : <genre> → <geste> (règle : <regle>)`, and the same line in the ticket's log.
|
|
250
171
|
export const GESTES = [
|
|
251
|
-
'superviseur',
|
|
252
|
-
'a-repasser',
|
|
253
|
-
'regulateur',
|
|
254
|
-
'developpeur-du-composant',
|
|
255
|
-
'testwriter',
|
|
256
|
-
];
|
|
257
|
-
|
|
258
|
-
export const TABLE_DES_ARRETS = [
|
|
259
172
|
{
|
|
260
|
-
// A component the survey of the ticket finds and its title misses (21): the circuit ends on
|
|
261
|
-
// it at 1.1, before any session.
|
|
262
|
-
genre: 'composants-manquants',
|
|
263
|
-
geste: 'superviseur',
|
|
264
|
-
cas: 'A3 : 020-loader mis au titre en cours de route ; A14 : 040-checker, nommé au critère 13 et absent du titre, rouge à la première passe finale',
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
// A questioning of the plan that does not converge at 1.2 (22), a disagreement or a fourth
|
|
268
|
-
// round still questioned.
|
|
269
|
-
genre: 'questionnement',
|
|
270
|
-
geste: 'superviseur',
|
|
271
|
-
cas: 'A14 : 040-checker nommé au critère 13 et absent du titre, que le plan questionné aurait relevé ; D15 : une consigne neuve sur le fond, hors du plan',
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
// The same stop (its name, step and component) after a RELANCE, the copy and the ticket's
|
|
275
|
-
// description unchanged since that decision.
|
|
276
|
-
genre: 'meme-arret-sans-fait-nouveau',
|
|
277
|
-
geste: 'superviseur',
|
|
278
|
-
cas: 'A8 → A9 : RELANCE --reprendre sans contexte, le même arrêt sur la même copie (D9) ; A11 → A13 : le même rouge de la passe finale trois fois (D13, D14)',
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
// Checks whose failures all depend on a duration under load (verifier's 75), the integration
|
|
282
|
-
// at 75, or the branch kept in the queue.
|
|
283
173
|
genre: 'a-repasser',
|
|
284
|
-
geste: '
|
|
285
|
-
|
|
174
|
+
geste: 'le circuit finit à 75, que le superviseur rejoue au repos par --reprendre',
|
|
175
|
+
regle: 'seul le code 75 du vérificateur dit la charge de la machine',
|
|
176
|
+
cas: 'A12, A17, A18 : un vrai rouge pris pour la charge du processeur (D14, D20, D21)',
|
|
286
177
|
},
|
|
287
178
|
{
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
cas: '
|
|
179
|
+
genre: 'rejeu',
|
|
180
|
+
geste: 'la commande joue une seconde fois',
|
|
181
|
+
regle:
|
|
182
|
+
'une commande des contrôles hors de la passe finale, ou l’intégration, à 75 rejoue une fois avant l’arrêt',
|
|
183
|
+
cas: 'A12 : un contrôle à 75, rejoué avant de conclure à la charge',
|
|
293
184
|
},
|
|
294
185
|
{
|
|
295
|
-
// A red that belongs to another component of the title than the one whose checks run.
|
|
296
|
-
genre: 'rouge-d-un-autre-composant',
|
|
297
|
-
geste: 'developpeur-du-composant',
|
|
298
|
-
cas: 'A4, A6, A8–A10 : la garde des mots de 030-binder rendue aux développeurs de 050, 130 et 900 (D5, D7, D9–D11)',
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
// A developpeur's sheet whose `renvoi` names the testwriter of a component of the title up to
|
|
302
|
-
// his own.
|
|
303
186
|
genre: 'renvoi-au-testwriter',
|
|
304
|
-
geste: 'testwriter',
|
|
187
|
+
geste: 'au testwriter, que la fiche du développeur nomme, puis la preuve et le développeur',
|
|
188
|
+
regle: 'le rouge qui reste est dans les tests du lot (`renvoi` de sa fiche)',
|
|
305
189
|
cas: 'A5, A7 : « Agent : testwriter » non lu, les tests périmés de 050 et de 130 (D6, D8) ; A2 (D2)',
|
|
306
190
|
},
|
|
307
191
|
{
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
192
|
+
genre: 'regeneration',
|
|
193
|
+
geste:
|
|
194
|
+
'à la régénération des références (4.2), puis la passe finale restreinte à ce qu’elle change',
|
|
195
|
+
regle:
|
|
196
|
+
'un rouge de la passe finale est celui d’une référence, même mêlé à d’autres : une que le projet déclare (`grillhouse.references`), ou un fichier que le cadre engendre (l’index des interfaces, les turbo.json, les rapports d’API) ; ou la passe abaisse la dette des gardes (`dette.mjs --abaisser`, depuis ses notes)',
|
|
197
|
+
cas: 'BP 320.9 : 292 min autour des références, dont 163 min d’attente pour régénérer à la main l’index des interfaces, le plafond et l’empreinte, des rouges de références mêlés à d’autres',
|
|
312
198
|
},
|
|
313
199
|
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
cas: '
|
|
200
|
+
genre: 'rien-a-livrer',
|
|
201
|
+
geste: 'aux contrôles, qui jugent le lot',
|
|
202
|
+
regle:
|
|
203
|
+
'un développeur qui ne change aucun fichier du plan n’a rien à livrer quand les contrôles sont verts ; rouges, l’arrêt monte (sans-livraison)',
|
|
204
|
+
cas: 'BP 320.9 : 995-tools n’a rien à livrer, 4 montées et 49 min (B5)',
|
|
319
205
|
},
|
|
320
206
|
];
|
|
321
207
|
|
|
322
|
-
// The
|
|
323
|
-
export const gesteDe = genre =>
|
|
208
|
+
// The gesture of name <genre>, or null.
|
|
209
|
+
export const gesteDe = genre => GESTES.find(g => g.genre === genre) ?? null;
|
|
210
|
+
|
|
211
|
+
// Who answers a question of the circuit: the supervisor, or the owner, whose question the
|
|
212
|
+
// supervisor carries.
|
|
213
|
+
export const SUPERVISEUR = 'superviseur';
|
|
214
|
+
export const RESPONSABLE = 'responsable';
|
|
215
|
+
|
|
216
|
+
// The commands by which the supervisor answers a question (scripts/circuit.mjs): resume, extend
|
|
217
|
+
// the plan, stop.
|
|
218
|
+
const REPONSES =
|
|
219
|
+
'Le superviseur répond par une commande du circuit : `--reprendre` (avec `--contexte`) ou `--depuis <testwriter|developpeur>` (avec `--contexte`), `--etendre <paquet>` (le plan gagne ce paquet, puis l’étape en cours reprend), ou `--arreter`.';
|
|
220
|
+
|
|
221
|
+
// The question of each stop no gesture settles, as a CI calls a person only for what no rule
|
|
222
|
+
// settles (the approval of a review): every stop of ARRETS but « a-repasser », a gesture. The
|
|
223
|
+
// circuit ends on the stop, its state carrying the question (`question`: `{ arret, fait, piece,
|
|
224
|
+
// question, qui }`: the fact, its piece, file:line or command and output, the question and who must
|
|
225
|
+
// answer it), for the supervisor, who answers by a command of the circuit and carries to the owner
|
|
226
|
+
// what is his (`qui` responsable: the reviewer's question on a real word of the language).
|
|
227
|
+
export const MONTEES = Object.fromEntries(
|
|
228
|
+
Object.entries({
|
|
229
|
+
lancement:
|
|
230
|
+
'Le lanceur s’arrête avant la séance : la machine se répare-t-elle, pour reprendre ?',
|
|
231
|
+
bloqué:
|
|
232
|
+
'La séance n’a plus bougé, et le circuit l’a arrêtée : reprendre l’étape, ou arrêter le circuit ?',
|
|
233
|
+
'sans-fiche':
|
|
234
|
+
'La séance finit deux fois sans fiche conforme : reprendre l’étape, ou arrêter le circuit ?',
|
|
235
|
+
preuve:
|
|
236
|
+
'La troisième preuve du rouge refuse le lot de tests : quel contexte donner au testwriter, ou le plan doit-il changer ?',
|
|
237
|
+
controles:
|
|
238
|
+
'Un rouge reste, que le circuit ne rend pas au développeur (hors du plan, sans fichier, à arbitrer), ou que trois séances n’ont pas levé : avec quel contexte le lever, ou le plan doit-il s’étendre ?',
|
|
239
|
+
'sans-livraison':
|
|
240
|
+
'Le développeur ne change rien et le rouge reste : avec quel contexte le lever, ou le plan doit-il changer ?',
|
|
241
|
+
'relecture-arret':
|
|
242
|
+
'La relecture ne rend pas le lot à un agent (un constat sans destinataire valide, un critère en cause, ou la troisième relecture rendue) : que devient le plan, et qui reprend ?',
|
|
243
|
+
integration:
|
|
244
|
+
'L’intégration refuse le lot, ou la file rouvre le ticket : que corrige le lot, et qui le reprend ?',
|
|
245
|
+
'hors-portee':
|
|
246
|
+
'L’agent se dit bloqué hors de sa portée : le plan s’étend-il au paquet qu’il nomme, ou un autre agent lève-t-il le reste ?',
|
|
247
|
+
besoin: 'Une réponse manque pour avancer : laquelle ?',
|
|
248
|
+
questionnement:
|
|
249
|
+
'Des questions du plan restent ouvertes après la réponse de l’explorateur : le plan change-t-il (`bd update`), ou reste-t-il tel quel ? `--reprendre` le fait passer tel qu’il est alors.',
|
|
250
|
+
references:
|
|
251
|
+
'La régénération des références change une référence du projet que le plan ne nomme pas, un fichier qu’aucune référence n’écrit, ou sa commande échoue : le plan les nomme-t-il, ou qui corrige le lot ?',
|
|
252
|
+
'hors-plan':
|
|
253
|
+
'La séance écrit hors du plan du ticket : le plan s’étend-il à ce paquet (`--etendre`), ou l’écriture est-elle refusée (`--reprendre` avec son contexte) ?',
|
|
254
|
+
}).map(([arret, question]) => [arret, { question: `${question} ${REPONSES}`, qui: SUPERVISEUR }])
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
// The question of the stop <arret>, `{ question, qui }`, or null for a gesture.
|
|
258
|
+
export const monteeDe = arret => MONTEES[arret] ?? null;
|
package/scripts/frontieres.mjs
CHANGED
|
@@ -47,8 +47,10 @@ import { trancher } from './dette.mjs';
|
|
|
47
47
|
|
|
48
48
|
export const CONFIGURATION = '.dependency-cruiser.cjs';
|
|
49
49
|
export const RACINES = ['src', 'packages'];
|
|
50
|
-
|
|
51
|
-
const
|
|
50
|
+
/** The test files, as a pattern of a path from the repository's root. */
|
|
51
|
+
export const TESTS = '(^|/)(test|tests|__tests__)/|[.](test|spec)[.][a-z]+$';
|
|
52
|
+
/** The code of `src/` (the root's, or a package's under `packages/`), as a pattern of such a path. */
|
|
53
|
+
export const CODE = '^src/|^packages/[^/]+/src/';
|
|
52
54
|
const REGLE_OUTILS = 'pas-d-outil-de-developpement-dans-le-code';
|
|
53
55
|
// The environment variable naming the file that holds the pattern of the published files.
|
|
54
56
|
const JUGES = 'GRILLHOUSE_JUGES';
|
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
// - Each red guard is named with its code at the end; the exit code is 1 when one guard is red,
|
|
10
10
|
// 0 when all are green.
|
|
11
11
|
// - While the run names its results directory (`GRILLHOUSE_RESULTATS`, scripts/resultats.mjs),
|
|
12
|
-
// each guard writes its findings there in SARIF; a red guard that wrote no finding
|
|
13
|
-
// written for it, without location, its name (its
|
|
14
|
-
// a red no reader can place.
|
|
12
|
+
// each guard writes its findings there in SARIF; a red guard that wrote no finding (a note of
|
|
13
|
+
// the debt, `a-elaguer`, is none) has one written for it, without location, its name (its
|
|
14
|
+
// script's, without extension) and its code: a red no reader can place.
|
|
15
15
|
// - The build is not among them: Turborepo builds before this task (turbo.json).
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
19
|
-
import { ecrireSarif, lireSarif, RESULTATS } from './resultats.mjs';
|
|
19
|
+
import { A_ELAGUER, ecrireSarif, lireSarif, RESULTATS } from './resultats.mjs';
|
|
20
20
|
|
|
21
21
|
// A script of the package, beside this one, by its name.
|
|
22
22
|
const ici = nom => fileURLToPath(new URL(nom, import.meta.url));
|
|
@@ -47,13 +47,15 @@ export function jouerLesGardes({
|
|
|
47
47
|
dire = l => process.stdout.write(`${l}\n`),
|
|
48
48
|
}) {
|
|
49
49
|
const rouges = [];
|
|
50
|
+
// The findings under the results directory, the notes of the debt left out.
|
|
51
|
+
const nombre = () => lireSarif(env[RESULTATS]).constats.filter(k => k.genre !== A_ELAGUER).length;
|
|
50
52
|
for (const garde of gardes) {
|
|
51
|
-
const avant = env[RESULTATS] ?
|
|
53
|
+
const avant = env[RESULTATS] ? nombre() : 0;
|
|
52
54
|
const r = spawnSync(process.execPath, garde, { cwd: racine, env, stdio: 'inherit' });
|
|
53
55
|
if (r.status === 0) continue;
|
|
54
56
|
const code = `code ${r.status ?? r.signal}`;
|
|
55
57
|
rouges.push(`${libelle(garde)} (${code})`);
|
|
56
|
-
if (env[RESULTATS] &&
|
|
58
|
+
if (env[RESULTATS] && nombre() === avant) {
|
|
57
59
|
ecrireSarif({
|
|
58
60
|
garde: nomDeGarde(garde),
|
|
59
61
|
racine,
|