@atlashub/smartstack-cli 3.31.0 → 3.32.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/.documentation/installation.html +7 -2
- package/README.md +7 -1
- package/dist/index.js +33 -37
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +547 -97
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/scripts/health-check.sh +2 -1
- package/templates/mcp-scaffolding/controller.cs.hbs +10 -7
- package/templates/mcp-scaffolding/entity-extension.cs.hbs +132 -124
- package/templates/mcp-scaffolding/frontend/api-client.ts.hbs +4 -4
- package/templates/mcp-scaffolding/tests/controller.test.cs.hbs +38 -15
- package/templates/mcp-scaffolding/tests/service.test.cs.hbs +20 -8
- package/templates/skills/apex/SKILL.md +7 -9
- package/templates/skills/apex/_shared.md +9 -2
- package/templates/skills/apex/references/code-generation.md +412 -0
- package/templates/skills/apex/references/post-checks.md +377 -37
- package/templates/skills/apex/references/smartstack-api.md +229 -5
- package/templates/skills/apex/references/smartstack-frontend.md +368 -11
- package/templates/skills/apex/references/smartstack-layers.md +54 -7
- package/templates/skills/apex/steps/step-00-init.md +1 -2
- package/templates/skills/apex/steps/step-01-analyze.md +45 -2
- package/templates/skills/apex/steps/step-02-plan.md +23 -2
- package/templates/skills/apex/steps/step-03-execute.md +195 -5
- package/templates/skills/apex/steps/step-04-examine.md +18 -5
- package/templates/skills/apex/steps/step-05-deep-review.md +9 -11
- package/templates/skills/apex/steps/step-06-resolve.md +5 -9
- package/templates/skills/apex/steps/step-07-tests.md +66 -1
- package/templates/skills/apex/steps/step-08-run-tests.md +12 -3
- package/templates/skills/application/references/provider-template.md +62 -39
- package/templates/skills/application/templates-backend.md +3 -3
- package/templates/skills/application/templates-frontend.md +12 -12
- package/templates/skills/application/templates-seed.md +14 -4
- package/templates/skills/business-analyse/SKILL.md +9 -6
- package/templates/skills/business-analyse/questionnaire/04-data.md +8 -0
- package/templates/skills/business-analyse/references/agent-module-prompt.md +84 -5
- package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +83 -19
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +6 -2
- package/templates/skills/business-analyse/references/team-orchestration.md +443 -110
- package/templates/skills/business-analyse/references/validation-checklist.md +5 -4
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +44 -0
- package/templates/skills/business-analyse/steps/step-03a2-analysis.md +72 -1
- package/templates/skills/business-analyse/steps/step-03c-compile.md +93 -7
- package/templates/skills/business-analyse/steps/step-03d-validate.md +34 -2
- package/templates/skills/business-analyse/steps/step-04b-analyze.md +40 -0
- package/templates/skills/controller/references/controller-code-templates.md +2 -2
- package/templates/skills/controller/templates.md +12 -12
- package/templates/skills/feature-full/steps/step-01-implementation.md +4 -4
- package/templates/skills/ralph-loop/references/category-rules.md +44 -2
- package/templates/skills/ralph-loop/references/compact-loop.md +37 -0
- package/templates/skills/ralph-loop/references/core-seed-data.md +51 -20
- package/templates/skills/review-code/references/owasp-api-top10.md +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
> **Loaded by:** step-02 when multi-module detected (`moduleOrder.length >= 2`)
|
|
4
4
|
> **Purpose:** Delegate module specification to autonomous agents with user review.
|
|
5
5
|
> **Rule:** Single module = NO team. Only create team for 2+ modules.
|
|
6
|
+
> **Execution:** Parallel by dependency layer — all modules in the same layer run simultaneously.
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
@@ -39,9 +40,9 @@ Store team context for the session:
|
|
|
39
40
|
const teamContext = {
|
|
40
41
|
teamName: actualTeamName, // ← RETURNED name, NOT "ba-{appName}"
|
|
41
42
|
moduleOrder: metadata.workflow.moduleOrder,
|
|
42
|
-
dependencyLayers: dependencyGraph.layers
|
|
43
|
-
currentModuleIdx: 0,
|
|
43
|
+
dependencyLayers: dependencyGraph.layers, // ← from step-02 topological sort
|
|
44
44
|
completedModules: [],
|
|
45
|
+
completedLayers: [],
|
|
45
46
|
mode: "propose-review"
|
|
46
47
|
};
|
|
47
48
|
```
|
|
@@ -51,33 +52,100 @@ const teamContext = {
|
|
|
51
52
|
|
|
52
53
|
---
|
|
53
54
|
|
|
54
|
-
## 2. Module Agent Spawn —
|
|
55
|
+
## 2. Module Agent Spawn — Parallel by Dependency Layer
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
Process modules **layer by layer**. Within each layer, spawn ALL agents **simultaneously**.
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
```
|
|
60
|
+
FOR each layer in dependencyGraph.layers:
|
|
61
|
+
Execute §2a → §2b → §2c → §2d → §2e → §3 → §4
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2a. Pre-Spawn Cross-Module Analysis
|
|
65
|
+
|
|
66
|
+
**ALWAYS executed for layers with 2+ modules.** Analyze the module definitions within this layer to identify cross-module touchpoints BEFORE spawning agents.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
IF layer.modules.length >= 2:
|
|
70
|
+
|
|
71
|
+
ULTRATHINK: Analyze module definitions for same-layer interactions:
|
|
72
|
+
|
|
73
|
+
1. Shared entity names
|
|
74
|
+
→ Do any modules reference the same entity? (e.g., both "Products" and "Inventory"
|
|
75
|
+
might reference a "Category" entity)
|
|
76
|
+
|
|
77
|
+
2. Potential FK overlaps
|
|
78
|
+
→ Do any modules anticipate creating entities that others might reference?
|
|
79
|
+
→ E.g., Products creates "Product" entity, Orders references "Product" via FK
|
|
80
|
+
|
|
81
|
+
3. Naming conventions
|
|
82
|
+
→ Will both modules use similar attribute names? (e.g., "Code", "Name", "Status")
|
|
83
|
+
→ Agree on a consistent naming pattern
|
|
84
|
+
|
|
85
|
+
4. Shared lookup data
|
|
86
|
+
→ Do any modules reference common reference tables?
|
|
87
|
+
→ E.g., both use a "Status" enum, a "Country" lookup, a "Currency" type
|
|
88
|
+
|
|
89
|
+
5. Permission path consistency
|
|
90
|
+
→ Verify permission paths won't collide:
|
|
91
|
+
{context}.{app}.{module1}.{entity}.{action}
|
|
92
|
+
{context}.{app}.{module2}.{entity}.{action}
|
|
93
|
+
|
|
94
|
+
Build coordinationNotes for EACH module in the layer:
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**coordinationNotes template** (injected into each agent's prompt):
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
## Same-Layer Coordination Notes
|
|
101
|
+
|
|
102
|
+
You are running IN PARALLEL with: {otherModuleCodes.join(", ")}
|
|
103
|
+
|
|
104
|
+
### Known Touchpoints
|
|
105
|
+
- {otherModule} will define entity "{EntityName}" — if you need to reference it,
|
|
106
|
+
use CROSS_MODULE_QUERY to get the exact attribute structure
|
|
107
|
+
- Naming convention: use {convention} for shared concepts (e.g., "Status" enum values)
|
|
108
|
+
- Shared lookups: {list any common reference data both modules might create}
|
|
109
|
+
|
|
110
|
+
### Your Responsibilities vs Theirs
|
|
111
|
+
- You own: {your entities — list}
|
|
112
|
+
- They own: {their entities — list}
|
|
113
|
+
- Contested/shared: {entities both might create — QUERY before defining}
|
|
114
|
+
|
|
115
|
+
### Cross-Module FK Convention
|
|
116
|
+
When referencing an entity owned by a same-layer module:
|
|
117
|
+
1. Send CROSS_MODULE_QUERY to team lead asking for the entity's attribute structure
|
|
118
|
+
2. WAIT for the answer before defining your FK field
|
|
119
|
+
3. Use the exact entity name and primary key type from the answer
|
|
120
|
+
```
|
|
59
121
|
|
|
60
|
-
|
|
122
|
+
> **IF layer has only 1 module:** Skip §2a entirely. No coordination notes needed.
|
|
123
|
+
|
|
124
|
+
### 2b. Prepare Agent Context (per module)
|
|
125
|
+
|
|
126
|
+
For EACH module in the layer, gather the context the agent needs:
|
|
61
127
|
|
|
62
128
|
```
|
|
63
129
|
1. ba-reader.readApplicationContext({feature_id})
|
|
64
130
|
→ Extract: appName, featureId, context, language
|
|
65
131
|
|
|
66
132
|
2. Read module decomposition data from master feature.json:
|
|
67
|
-
→ modules[
|
|
68
|
-
anticipatedSections, dependencies, detailTabs
|
|
133
|
+
→ modules[moduleCode]: code, name, description, featureType, entities,
|
|
134
|
+
anticipatedSections, dependencies, detailTabs, estimatedComplexity, priority
|
|
69
135
|
|
|
70
136
|
3. ba-reader.getCompletedModulesSummary({feature_id})
|
|
71
|
-
→ Compact summary of already-specified modules (max 100 lines)
|
|
137
|
+
→ Compact summary of already-specified modules from COMPLETED LAYERS (max 100 lines)
|
|
72
138
|
→ Includes: entity names, FK relationships, permission paths, shared types
|
|
73
139
|
```
|
|
74
140
|
|
|
75
|
-
###
|
|
141
|
+
### 2c. Spawn ALL Layer Agents Simultaneously
|
|
142
|
+
|
|
143
|
+
**For layers with 1 module** — single spawn (same as standard):
|
|
76
144
|
|
|
77
145
|
```javascript
|
|
78
146
|
Task({
|
|
79
147
|
subagent_type: "general-purpose",
|
|
80
|
-
team_name: teamContext.teamName,
|
|
148
|
+
team_name: teamContext.teamName,
|
|
81
149
|
name: "mod-{moduleCode}",
|
|
82
150
|
model: "opus",
|
|
83
151
|
mode: "bypassPermissions",
|
|
@@ -91,7 +159,10 @@ Task({
|
|
|
91
159
|
anticipatedSections: module.anticipatedSections,
|
|
92
160
|
dependencies: module.dependencies,
|
|
93
161
|
detailTabs: module.detailTabs,
|
|
162
|
+
estimatedComplexity: module.estimatedComplexity,
|
|
163
|
+
priority: module.priority,
|
|
94
164
|
completedModulesSummary,
|
|
165
|
+
coordinationNotes: "", // empty for single-module layer
|
|
95
166
|
language: metadata.language,
|
|
96
167
|
docsDir: "docs/business/{appName}/{moduleCode}/business-analyse/v{version}/"
|
|
97
168
|
}),
|
|
@@ -99,75 +170,220 @@ Task({
|
|
|
99
170
|
});
|
|
100
171
|
```
|
|
101
172
|
|
|
102
|
-
**
|
|
173
|
+
**For layers with 2+ modules** — spawn ALL in a **single message** (parallel):
|
|
103
174
|
|
|
104
|
-
|
|
175
|
+
```javascript
|
|
176
|
+
// CRITICAL: All Task() calls MUST be in ONE message for parallel execution.
|
|
177
|
+
// Do NOT await between them — they MUST be sent together.
|
|
105
178
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
179
|
+
// Agent 1:
|
|
180
|
+
Task({
|
|
181
|
+
subagent_type: "general-purpose",
|
|
182
|
+
team_name: teamContext.teamName,
|
|
183
|
+
name: "mod-{moduleCode1}",
|
|
184
|
+
model: "opus",
|
|
185
|
+
mode: "bypassPermissions",
|
|
186
|
+
prompt: BUILD_PROMPT(references/agent-module-prompt.md, {
|
|
187
|
+
...moduleContext1,
|
|
188
|
+
coordinationNotes: coordinationNotesForModule1, // ← NEW
|
|
189
|
+
}),
|
|
190
|
+
description: "Specify {moduleCode1}"
|
|
191
|
+
});
|
|
110
192
|
|
|
111
|
-
|
|
193
|
+
// Agent 2 (IN SAME MESSAGE):
|
|
194
|
+
Task({
|
|
195
|
+
subagent_type: "general-purpose",
|
|
196
|
+
team_name: teamContext.teamName,
|
|
197
|
+
name: "mod-{moduleCode2}",
|
|
198
|
+
model: "opus",
|
|
199
|
+
mode: "bypassPermissions",
|
|
200
|
+
prompt: BUILD_PROMPT(references/agent-module-prompt.md, {
|
|
201
|
+
...moduleContext2,
|
|
202
|
+
coordinationNotes: coordinationNotesForModule2, // ← NEW
|
|
203
|
+
}),
|
|
204
|
+
description: "Specify {moduleCode2}"
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ... repeat for all modules in this layer
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**BUILD_PROMPT**: Read `references/agent-module-prompt.md`, replace all `{placeholders}` with actual values (including the new `{coordinationNotes}`), and pass as the `prompt` parameter.
|
|
211
|
+
|
|
212
|
+
### 2d. Track Layer State
|
|
213
|
+
|
|
214
|
+
After spawning, initialize layer tracking:
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
const layerState = {
|
|
218
|
+
layerIndex: L,
|
|
219
|
+
modules: layer.modules, // ["Customers", "Products"]
|
|
220
|
+
pendingProposals: [...layer.modules], // agents not yet PROPOSAL_READY
|
|
221
|
+
receivedProposals: {}, // { moduleCode: proposalSummary }
|
|
222
|
+
approvedModules: [], // modules approved by user
|
|
223
|
+
crossModuleQueries: [], // log of queries handled
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 2e. Wait for Layer Completion — Message Handling Loop
|
|
112
228
|
|
|
113
|
-
After
|
|
229
|
+
After spawning all agents in the layer, the team lead enters a **message handling loop**.
|
|
114
230
|
Messages from teammates are delivered automatically — do NOT poll or re-spawn.
|
|
115
231
|
|
|
116
|
-
|
|
117
|
-
|
|
232
|
+
```
|
|
233
|
+
WHILE layerState.pendingProposals.length > 0:
|
|
234
|
+
|
|
235
|
+
Wait for next message from any agent in this layer.
|
|
236
|
+
|
|
237
|
+
CASE message matches "PROPOSAL_READY:{moduleCode}":
|
|
238
|
+
→ Remove moduleCode from pendingProposals
|
|
239
|
+
→ Store proposal in receivedProposals[moduleCode]
|
|
240
|
+
→ Display: "✓ Module {moduleCode} proposal received ({received}/{total})"
|
|
241
|
+
→ IF pendingProposals is now empty:
|
|
242
|
+
→ All agents in this layer have proposed
|
|
243
|
+
→ Proceed to §3 (Layer Review)
|
|
244
|
+
|
|
245
|
+
CASE message matches "CROSS_MODULE_QUERY:{targetModule}":
|
|
246
|
+
→ Handle per §2-bis (Cross-Module Coordination Protocol)
|
|
247
|
+
|
|
248
|
+
CASE message matches "CROSS_MODULE_ANSWER_RELAY:{requestingModule}":
|
|
249
|
+
→ Forward to requesting agent per §2-bis
|
|
250
|
+
|
|
251
|
+
CASE message matches "ERROR:{moduleCode}:{description}":
|
|
252
|
+
→ Handle per §8 (Error Recovery)
|
|
253
|
+
→ Remove from pendingProposals if module is skipped
|
|
254
|
+
→ IF pendingProposals is now empty → proceed to §3
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
> **This loop may take several minutes** as agents work autonomously.
|
|
258
|
+
> The team lead does nothing except handle cross-module queries during this time.
|
|
118
259
|
|
|
119
260
|
---
|
|
120
261
|
|
|
121
|
-
##
|
|
262
|
+
## 2-bis. Cross-Module Coordination Protocol (Runtime Relay)
|
|
263
|
+
|
|
264
|
+
When an agent sends `CROSS_MODULE_QUERY:{targetModule}`, the team lead routes the query based on the target module's state:
|
|
122
265
|
|
|
123
|
-
###
|
|
266
|
+
### Case 1: Target is in a COMPLETED layer
|
|
124
267
|
|
|
125
|
-
The module
|
|
268
|
+
The target module's specification is already written to feature.json.
|
|
126
269
|
|
|
127
270
|
```
|
|
128
|
-
|
|
271
|
+
→ Read target module's entities/attributes from completedModulesSummary
|
|
272
|
+
→ Send answer directly to requesting agent:
|
|
129
273
|
|
|
130
|
-
|
|
274
|
+
SendMessage({
|
|
275
|
+
type: "message",
|
|
276
|
+
recipient: "mod-{requestingModule}",
|
|
277
|
+
content: "CROSS_MODULE_ANSWER:{requestingModule}\nAnswer: {entity structure from completed module data}",
|
|
278
|
+
summary: "Answer from completed {targetModule}"
|
|
279
|
+
})
|
|
280
|
+
```
|
|
131
281
|
|
|
132
|
-
###
|
|
133
|
-
| Entity | Attributes | Relationships |
|
|
134
|
-
|--------|-----------|---------------|
|
|
135
|
-
| ... | ... | ... |
|
|
282
|
+
### Case 2: Target is in CURRENT layer AND has sent PROPOSAL_READY
|
|
136
283
|
|
|
137
|
-
|
|
138
|
-
| Section | Description | Resources |
|
|
139
|
-
|---------|-------------|-----------|
|
|
140
|
-
| ... | ... | ... |
|
|
284
|
+
The target agent has finished its proposal — we have its specification data.
|
|
141
285
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
- ...
|
|
286
|
+
```
|
|
287
|
+
→ Extract relevant entity/attribute info from receivedProposals[targetModule]
|
|
288
|
+
→ Send answer directly to requesting agent:
|
|
146
289
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
-
|
|
290
|
+
SendMessage({
|
|
291
|
+
type: "message",
|
|
292
|
+
recipient: "mod-{requestingModule}",
|
|
293
|
+
content: "CROSS_MODULE_ANSWER:{requestingModule}\nAnswer: {entity structure from proposal data}",
|
|
294
|
+
summary: "Answer from {targetModule} proposal"
|
|
295
|
+
})
|
|
296
|
+
```
|
|
150
297
|
|
|
151
|
-
###
|
|
152
|
-
- {context}.{app}.{module}.{action}
|
|
153
|
-
- ...
|
|
298
|
+
### Case 3: Target is in CURRENT layer AND still working (no PROPOSAL_READY yet)
|
|
154
299
|
|
|
155
|
-
|
|
156
|
-
- Modules: {count} | Sections: {count} | Resources: {count}
|
|
157
|
-
- Translations: {count} | Permissions: {count} | Role mappings: {count}
|
|
300
|
+
The target agent is still specifying — relay the question.
|
|
158
301
|
|
|
159
|
-
### Wireframes
|
|
160
|
-
- {section}: {1-line description}
|
|
161
|
-
- ...
|
|
162
302
|
```
|
|
303
|
+
→ Forward question to target agent:
|
|
304
|
+
|
|
305
|
+
SendMessage({
|
|
306
|
+
type: "message",
|
|
307
|
+
recipient: "mod-{targetModule}",
|
|
308
|
+
content: "CROSS_MODULE_QUERY_RELAY:{requestingModule}\nQuestion: {original question}",
|
|
309
|
+
summary: "Relay query from {requestingModule}"
|
|
310
|
+
})
|
|
163
311
|
|
|
164
|
-
|
|
312
|
+
→ Wait for target agent to respond with CROSS_MODULE_ANSWER_RELAY
|
|
313
|
+
→ Forward answer to requesting agent:
|
|
314
|
+
|
|
315
|
+
SendMessage({
|
|
316
|
+
type: "message",
|
|
317
|
+
recipient: "mod-{requestingModule}",
|
|
318
|
+
content: "CROSS_MODULE_ANSWER:{requestingModule}\nAnswer: {answer from target agent}",
|
|
319
|
+
summary: "Answer from {targetModule}"
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Case 4: Circular query (A asks about B, B asks about A simultaneously)
|
|
324
|
+
|
|
325
|
+
Both agents are blocked waiting for each other. The team lead MUST resolve this autonomously.
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
→ ULTRATHINK: Based on SmartStack conventions and module descriptions,
|
|
329
|
+
make a consistent design decision for BOTH modules.
|
|
330
|
+
→ Send CROSS_MODULE_ANSWER to BOTH agents with compatible entity structures.
|
|
331
|
+
→ Log resolution in layerState.crossModuleQueries[] for later review.
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
> **Every cross-module query is logged** in `layerState.crossModuleQueries[]` for display during §3 review.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 3. Layer Review — Quality-First Protocol
|
|
339
|
+
|
|
340
|
+
When ALL agents in a layer have sent PROPOSAL_READY, the team lead presents the results to the user.
|
|
341
|
+
|
|
342
|
+
### 3a. Cross-Module Interaction Analysis (layers with 2+ modules)
|
|
343
|
+
|
|
344
|
+
**ALWAYS displayed FIRST** for multi-module layers. This gives the user a bird's-eye view of how modules in this layer interact.
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
═══════════════════════════════════════════════════════════
|
|
348
|
+
Layer {L} — {N} modules terminés — Analyse croisée
|
|
349
|
+
═══════════════════════════════════════════════════════════
|
|
350
|
+
|
|
351
|
+
### Interactions cross-module détectées
|
|
352
|
+
|
|
353
|
+
| Module A | Module B | Type | Détail |
|
|
354
|
+
|----------|----------|------|--------|
|
|
355
|
+
| {mod1} | {mod2} | FK | {mod1}.{entity}.{field} → {mod2}.{entity} |
|
|
356
|
+
| {mod1} | {mod2} | Concept partagé | Les deux définissent "{concept}" |
|
|
357
|
+
| {mod1} | {mod2} | Lookup | {mod1} référence {mod2}.{entity} comme donnée de ref |
|
|
358
|
+
|
|
359
|
+
### Requêtes cross-module résolues pendant la spécification ({count})
|
|
360
|
+
{FOR each query in layerState.crossModuleQueries:}
|
|
361
|
+
- {requestingModule} → {targetModule}: {question summary} → {answer summary}
|
|
362
|
+
|
|
363
|
+
### Points d'attention
|
|
364
|
+
- {naming inconsistencies detected between module proposals}
|
|
365
|
+
- {potential permission path conflicts}
|
|
366
|
+
- {shared entity definition differences}
|
|
367
|
+
|
|
368
|
+
─────────────────────────────────────────────────────────
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
> **For single-module layers:** Skip §3a entirely — no cross-module analysis needed.
|
|
372
|
+
|
|
373
|
+
### 3b. Individual Module Review (ALWAYS — for quality)
|
|
374
|
+
|
|
375
|
+
Review each module's proposal individually. For multi-module layers, the user has already seen the cross-module context from §3a.
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
FOR each module in layer (respecting topologicalOrder within layer):
|
|
379
|
+
```
|
|
165
380
|
|
|
166
381
|
**Step 1:** Format and display the proposal:
|
|
167
382
|
|
|
168
383
|
```
|
|
169
384
|
═══════════════════════════════════════════════════════════
|
|
170
|
-
Proposition pour le module {moduleCode}
|
|
385
|
+
Proposition pour le module {moduleCode}
|
|
386
|
+
(Layer {L} — module {idx+1}/{layerTotal} — global {globalIdx+1}/{totalModules})
|
|
171
387
|
═══════════════════════════════════════════════════════════
|
|
172
388
|
|
|
173
389
|
{structured summary from agent — displayed as-is}
|
|
@@ -178,11 +394,11 @@ PROPOSAL_READY:{moduleCode}
|
|
|
178
394
|
**Step 2:** Ask the user via AskUserQuestion:
|
|
179
395
|
|
|
180
396
|
```
|
|
181
|
-
Validez-vous cette
|
|
397
|
+
Validez-vous cette spécification ?
|
|
182
398
|
Options:
|
|
183
399
|
1. "Valider" → approve as-is
|
|
184
400
|
2. "Modifier" → provide feedback for revision
|
|
185
|
-
3. "Voir
|
|
401
|
+
3. "Voir détail" → team lead reads module feature.json and displays full content
|
|
186
402
|
```
|
|
187
403
|
|
|
188
404
|
**Step 3 — IMMEDIATELY after AskUserQuestion returns, handle the response:**
|
|
@@ -197,7 +413,9 @@ SendMessage({
|
|
|
197
413
|
})
|
|
198
414
|
```
|
|
199
415
|
→ CRITICAL: You MUST send this message. Do NOT skip this step.
|
|
200
|
-
→ Then WAIT for the agent to send `MODULE_COMPLETE:{moduleCode}
|
|
416
|
+
→ Then WAIT for the agent to send `MODULE_COMPLETE:{moduleCode}`.
|
|
417
|
+
→ Add moduleCode to `layerState.approvedModules`.
|
|
418
|
+
→ Continue to next module in this layer.
|
|
201
419
|
|
|
202
420
|
**IF user selected "Modifier" (revision):**
|
|
203
421
|
→ Ask user for specific feedback via AskUserQuestion
|
|
@@ -210,9 +428,10 @@ SendMessage({
|
|
|
210
428
|
summary: "{moduleCode} revision requested"
|
|
211
429
|
})
|
|
212
430
|
```
|
|
213
|
-
→ Then WAIT for the agent to send a new `PROPOSAL_READY` →
|
|
431
|
+
→ Then WAIT for the agent to send a new `PROPOSAL_READY` → re-display this module's proposal.
|
|
432
|
+
→ Other modules in the layer are NOT blocked — their proposals remain in receivedProposals.
|
|
214
433
|
|
|
215
|
-
**IF user selected "Voir
|
|
434
|
+
**IF user selected "Voir détail":**
|
|
216
435
|
→ Read module feature.json via ba-reader.readSection({feature_id, section})
|
|
217
436
|
→ Display relevant sections in detail
|
|
218
437
|
→ Go back to Step 2 (re-ask the validation question)
|
|
@@ -221,58 +440,120 @@ SendMessage({
|
|
|
221
440
|
|
|
222
441
|
- Max **3 revision cycles** per module
|
|
223
442
|
- After 3 rejections: team lead asks user if they want to switch to **inline interactive mode** for this module
|
|
224
|
-
- If yes: team lead loads step-03a1-setup.md and executes interactively
|
|
443
|
+
- If yes: shutdown agent, team lead loads step-03a1-setup.md and executes interactively
|
|
225
444
|
- If no: mark module as "needs-review" and continue to next module
|
|
226
445
|
|
|
446
|
+
### 3d. Layer Consistency Check (layers with 2+ modules)
|
|
447
|
+
|
|
448
|
+
After ALL modules in a layer are approved, perform a final cross-module consistency verification:
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
IF layer.modules.length >= 2 AND all modules approved:
|
|
452
|
+
|
|
453
|
+
ULTRATHINK: Verify cross-module consistency:
|
|
454
|
+
|
|
455
|
+
1. FK references: Do FK field names match actual entity names across modules?
|
|
456
|
+
→ e.g., if Products.CategoryId references Categories.Category, names must match
|
|
457
|
+
|
|
458
|
+
2. Permission paths: Are paths consistent and non-colliding?
|
|
459
|
+
→ business.{app}.{module1}.{entity}.read vs business.{app}.{module2}.{entity}.read
|
|
460
|
+
|
|
461
|
+
3. i18n keys: Do keys follow consistent patterns? No collisions?
|
|
462
|
+
→ {module1}.labels.name vs {module2}.labels.name (OK — namespaced)
|
|
463
|
+
|
|
464
|
+
4. Seed data IDs: Are deterministic GUIDs unique across modules?
|
|
465
|
+
→ Check DeterministicGuid inputs don't collide
|
|
466
|
+
|
|
467
|
+
5. Entity attribute types: Are shared concepts typed consistently?
|
|
468
|
+
→ If both modules define "Status", is it the same enum type?
|
|
469
|
+
|
|
470
|
+
IF inconsistency found:
|
|
471
|
+
Display warning with specific issue:
|
|
472
|
+
"⚠ Incohérence détectée entre {mod1} et {mod2}: {description}"
|
|
473
|
+
|
|
474
|
+
AskUserQuestion:
|
|
475
|
+
question: "Corriger automatiquement cette incohérence ?"
|
|
476
|
+
options:
|
|
477
|
+
1. "Corriger" → send REVISION to affected agent(s) with fix instructions
|
|
478
|
+
2. "Ignorer" → proceed (will be caught in consolidation)
|
|
479
|
+
|
|
480
|
+
IF "Corriger":
|
|
481
|
+
→ Send REVISION:{moduleCode}\n{auto-fix instructions} to affected agent
|
|
482
|
+
→ Wait for new PROPOSAL_READY
|
|
483
|
+
→ Re-approve (no full re-review needed — only the fix)
|
|
484
|
+
|
|
485
|
+
IF no inconsistency found:
|
|
486
|
+
Display: "✓ Cohérence cross-module vérifiée pour le layer {L}"
|
|
487
|
+
```
|
|
488
|
+
|
|
227
489
|
---
|
|
228
490
|
|
|
229
|
-
## 4.
|
|
491
|
+
## 4. Layer Completion & Agent Shutdown
|
|
230
492
|
|
|
231
|
-
|
|
493
|
+
After ALL modules in a layer are approved AND consistency check passed:
|
|
232
494
|
|
|
233
|
-
### 4a.
|
|
495
|
+
### 4a. Shutdown ALL Layer Agents (MANDATORY — do NOT skip)
|
|
496
|
+
|
|
497
|
+
**IMMEDIATELY** after layer is fully approved, send shutdown_request to ALL agents in this layer:
|
|
234
498
|
|
|
235
499
|
```javascript
|
|
236
|
-
|
|
237
|
-
|
|
500
|
+
// Send shutdown to ALL layer agents
|
|
501
|
+
FOR each moduleCode in layer.modules:
|
|
502
|
+
SendMessage({
|
|
503
|
+
type: "shutdown_request",
|
|
504
|
+
recipient: "mod-{moduleCode}",
|
|
505
|
+
content: "Layer complete, shutting down"
|
|
506
|
+
})
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Wait for ALL agents to confirm shutdown (`shutdown_response approve: true`).
|
|
510
|
+
|
|
511
|
+
> **WARNING:** If you skip this step, agents will remain running indefinitely.
|
|
512
|
+
> Agents CANNOT self-terminate — they NEED shutdown_request from you.
|
|
238
513
|
|
|
239
|
-
|
|
240
|
-
ba-writer.updateModuleStatus({feature_id, moduleCode, status: "specified"});
|
|
514
|
+
### 4b. Update Layer Tracking
|
|
241
515
|
|
|
242
|
-
|
|
516
|
+
```javascript
|
|
517
|
+
FOR each moduleCode in layer.modules:
|
|
518
|
+
teamContext.completedModules.push(moduleCode);
|
|
519
|
+
ba-writer.updateModuleStatus({feature_id, moduleCode, status: "specified"});
|
|
520
|
+
|
|
521
|
+
teamContext.completedLayers.push(layerState.layerIndex);
|
|
522
|
+
|
|
523
|
+
Display:
|
|
524
|
+
"═══ Layer {L} complete — {layer.modules.length} modules specified ═══"
|
|
525
|
+
"═══ Progress: {completedModules.length}/{moduleOrder.length} modules ═══"
|
|
243
526
|
```
|
|
244
527
|
|
|
245
|
-
###
|
|
528
|
+
### 4c. Build Updated Context for Next Layer
|
|
246
529
|
|
|
247
|
-
|
|
530
|
+
Before spawning the next layer's agents, rebuild the `completedModulesSummary`:
|
|
248
531
|
|
|
249
532
|
```
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
})
|
|
533
|
+
ba-reader.getCompletedModulesSummary({feature_id})
|
|
534
|
+
→ Now includes ALL modules from completed layers
|
|
535
|
+
→ This summary is injected into next layer's agent prompts
|
|
536
|
+
→ Agents in the next layer will have full context of everything specified so far
|
|
255
537
|
```
|
|
256
538
|
|
|
257
|
-
|
|
258
|
-
**Wait for the agent to confirm shutdown** before spawning the next agent.
|
|
259
|
-
|
|
260
|
-
> **WARNING:** If you skip this step, the agent will remain running indefinitely.
|
|
261
|
-
> The agent CANNOT self-terminate — it NEEDS this shutdown_request from you.
|
|
539
|
+
### 4d. Next Layer or Consolidation
|
|
262
540
|
|
|
263
|
-
|
|
541
|
+
```
|
|
542
|
+
IF more layers remain in dependencyGraph.layers:
|
|
543
|
+
→ Go back to §2 for the next layer
|
|
264
544
|
|
|
265
|
-
|
|
266
|
-
|
|
545
|
+
IF all layers complete (all modules specified):
|
|
546
|
+
→ Proceed to §5 (Consolidation)
|
|
547
|
+
```
|
|
267
548
|
|
|
268
549
|
---
|
|
269
550
|
|
|
270
551
|
## 5. Consolidation Phase
|
|
271
552
|
|
|
272
|
-
After ALL modules are specified:
|
|
553
|
+
After ALL modules are specified (all layers complete):
|
|
273
554
|
|
|
274
555
|
```
|
|
275
|
-
Display: "═══ All modules specified — Starting consolidation ═══"
|
|
556
|
+
Display: "═══ All {moduleOrder.length} modules specified — Starting consolidation ═══"
|
|
276
557
|
```
|
|
277
558
|
|
|
278
559
|
### 5a. Spawn Consolidation Agent
|
|
@@ -295,6 +576,7 @@ Execute cross-module consolidation (steps 04a + 04b):
|
|
|
295
576
|
## Context
|
|
296
577
|
- Feature ID: {featureId}
|
|
297
578
|
- Modules: {moduleOrder.join(", ")}
|
|
579
|
+
- Dependency layers: {JSON.stringify(dependencyGraph.layers)}
|
|
298
580
|
- All modules have status "specified"
|
|
299
581
|
|
|
300
582
|
## Output
|
|
@@ -328,7 +610,7 @@ When CONSOLIDATION_READY received:
|
|
|
328
610
|
|
|
329
611
|
AskUserQuestion: "Approuvez-vous la consolidation ?"
|
|
330
612
|
- "Approuver" → send APPROVED to agent → agent writes consolidation to master feature.json
|
|
331
|
-
- "
|
|
613
|
+
- "Réviser" → send feedback → agent adjusts
|
|
332
614
|
|
|
333
615
|
After approval → shutdown consolidation agent → proceed to §6.
|
|
334
616
|
|
|
@@ -393,7 +675,7 @@ After handoff complete:
|
|
|
393
675
|
|
|
394
676
|
```javascript
|
|
395
677
|
// Safety net: shutdown ALL remaining agents (module agents + consolidation + handoff)
|
|
396
|
-
// Module agents should already be shut down in §
|
|
678
|
+
// Module agents should already be shut down in §4a, but this catches any missed ones.
|
|
397
679
|
const allAgents = [
|
|
398
680
|
...teamContext.moduleOrder.map(m => `mod-${m}`),
|
|
399
681
|
"consolidation",
|
|
@@ -422,28 +704,32 @@ Display: "═══ Business-analyse complete — Team cleaned up ═══"
|
|
|
422
704
|
|
|
423
705
|
## 8. Error Recovery
|
|
424
706
|
|
|
425
|
-
### Agent Crash
|
|
707
|
+
### Agent Crash in Parallel Layer
|
|
426
708
|
|
|
427
|
-
If an agent stops responding or sends ERROR:
|
|
709
|
+
If an agent stops responding or sends ERROR while other agents in the same layer are still working:
|
|
428
710
|
|
|
429
711
|
```javascript
|
|
430
|
-
// 1.
|
|
712
|
+
// 1. Do NOT disrupt other agents in the layer — they continue working
|
|
713
|
+
// 2. Check module status in feature.json
|
|
431
714
|
const moduleStatus = ba-reader.getModuleStatus({feature_id});
|
|
432
715
|
|
|
433
|
-
//
|
|
434
|
-
// → Spawn new agent for same module
|
|
716
|
+
// 3. If module has partial data (status = "in-progress"):
|
|
717
|
+
// → Spawn new agent for same module (joins existing layer)
|
|
435
718
|
// → New agent detects partial state and continues
|
|
436
719
|
// → Include in prompt: "Resume specification — partial data exists in feature.json"
|
|
437
720
|
|
|
438
|
-
//
|
|
721
|
+
// 4. Track retry count per module
|
|
439
722
|
if (retryCount[moduleCode] >= 3) {
|
|
440
723
|
Display: "Agent failed 3 times for module {moduleCode}."
|
|
441
724
|
AskUserQuestion: "Fallback to inline interactive mode for this module?"
|
|
442
|
-
// If yes:
|
|
725
|
+
// If yes: remove from pendingProposals, will handle inline after layer completes
|
|
443
726
|
// If no: skip module, mark as "needs-review"
|
|
444
727
|
}
|
|
445
728
|
```
|
|
446
729
|
|
|
730
|
+
> **Key difference from sequential mode:** Other agents in the layer keep running.
|
|
731
|
+
> The crashed module is retried independently without blocking the layer.
|
|
732
|
+
|
|
447
733
|
### Context Exhaustion on Team Lead
|
|
448
734
|
|
|
449
735
|
The team lead should stay under 30% context usage. If approaching limits:
|
|
@@ -459,9 +745,13 @@ If the entire session crashes:
|
|
|
459
745
|
1. User restarts `/business-analyse`
|
|
460
746
|
2. Step-00 detects existing feature.json with `status: "decomposed"` or partial modules
|
|
461
747
|
3. Reads `metadata.workflow.completedModules` to know which modules are done
|
|
462
|
-
4.
|
|
463
|
-
|
|
464
|
-
|
|
748
|
+
4. Determines which layer to resume from:
|
|
749
|
+
- Find the first layer where not all modules are in `completedModules`
|
|
750
|
+
- Modules already completed in that layer are skipped
|
|
751
|
+
5. **Cleans up old team/task data** (§1a cleanup step) before creating new team
|
|
752
|
+
6. Creates new team (§1b — captures actual team name)
|
|
753
|
+
7. Spawns agents ONLY for incomplete modules in the current layer
|
|
754
|
+
8. Continues normally (parallel within layer, sequential between layers)
|
|
465
755
|
|
|
466
756
|
---
|
|
467
757
|
|
|
@@ -471,25 +761,68 @@ If the entire session crashes:
|
|
|
471
761
|
|-----------|--------|
|
|
472
762
|
| 1 module | NO team, classic inline execution |
|
|
473
763
|
| 2+ modules | Team mode (Propose & Review) |
|
|
474
|
-
| Modules in same dependency layer
|
|
475
|
-
| Modules
|
|
476
|
-
|
|
|
764
|
+
| Modules in same dependency layer | Spawn ALL in parallel (single message) |
|
|
765
|
+
| Modules in different layers | Sequential — complete layer N before spawning layer N+1 |
|
|
766
|
+
| Layer with 1 module | Standard single-agent propose-review |
|
|
767
|
+
| Layer with 2+ modules | Pre-inject coordination notes + parallel spawn + batch review |
|
|
768
|
+
| Cross-module query (completed layer) | Answer from completedModulesSummary |
|
|
769
|
+
| Cross-module query (same layer, proposed) | Answer from receivedProposals |
|
|
770
|
+
| Cross-module query (same layer, working) | Relay to target agent |
|
|
771
|
+
| Circular cross-query (A↔B) | Team lead resolves autonomously |
|
|
772
|
+
| Agent error in parallel layer | Other agents continue; retry crashed module |
|
|
477
773
|
| User rejects 3 times | Offer fallback to inline interactive |
|
|
774
|
+
| Layer consistency check fails | Auto-fix via targeted REVISION |
|
|
478
775
|
| Context > 50% on team lead | Minimize presentation, suggest auto-approve |
|
|
479
|
-
| Session crash | Resume from feature.json
|
|
776
|
+
| Session crash | Resume from feature.json + completedModules state |
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## Message Protocol Summary
|
|
781
|
+
|
|
782
|
+
### Standard Messages (unchanged)
|
|
783
|
+
|
|
784
|
+
| Message | Direction | Purpose |
|
|
785
|
+
|---------|-----------|---------|
|
|
786
|
+
| `PROPOSAL_READY:{moduleCode}\n{summary}` | agent → lead | Specification complete |
|
|
787
|
+
| `APPROVED:{moduleCode}` | lead → agent | User approved |
|
|
788
|
+
| `REVISION:{moduleCode}\n{feedback}` | lead → agent | User wants changes |
|
|
789
|
+
| `MODULE_COMPLETE:{moduleCode}` | agent → lead | After approval confirmed |
|
|
790
|
+
| `CONSOLIDATION_READY:{appName}\n{report}` | agent → lead | Consolidation done |
|
|
791
|
+
| `HANDOFF_READY:{appName}\n{report}` | agent → lead | Handoff done |
|
|
792
|
+
| `ERROR:{moduleCode}:{description}` | agent → lead | Blocking error |
|
|
793
|
+
| `shutdown_request` / `shutdown_response` | lead ↔ agent | Termination |
|
|
794
|
+
|
|
795
|
+
### Cross-Module Messages (NEW — for parallel execution)
|
|
796
|
+
|
|
797
|
+
| Message | Direction | Purpose |
|
|
798
|
+
|---------|-----------|---------|
|
|
799
|
+
| `CROSS_MODULE_QUERY:{targetModule}\nQuestion:{q}\nContext:{ctx}` | agent → lead | Ask about same-layer module |
|
|
800
|
+
| `CROSS_MODULE_ANSWER:{requestingModule}\nAnswer:{a}` | lead → agent | Response to query |
|
|
801
|
+
| `CROSS_MODULE_QUERY_RELAY:{requestingModule}\nQuestion:{q}` | lead → target agent | Relay query to working agent |
|
|
802
|
+
| `CROSS_MODULE_ANSWER_RELAY:{requestingModule}\nAnswer:{a}` | target agent → lead | Response to relayed query |
|
|
480
803
|
|
|
481
804
|
---
|
|
482
805
|
|
|
483
806
|
## Token Budget Estimates
|
|
484
807
|
|
|
485
|
-
| Phase | Agent |
|
|
486
|
-
|
|
487
|
-
| Init + Cadrage + Decomposition | Team lead (inline) | 20-30% |
|
|
488
|
-
|
|
|
489
|
-
|
|
|
490
|
-
|
|
|
491
|
-
|
|
|
492
|
-
|
|
|
493
|
-
|
|
|
494
|
-
|
|
495
|
-
**
|
|
808
|
+
| Phase | Agent | Est. Context % | Notes |
|
|
809
|
+
|-------|-------|---------------|-------|
|
|
810
|
+
| Init + Cadrage + Decomposition | Team lead (inline) | 20-30% | Sequential, interactive |
|
|
811
|
+
| Pre-spawn analysis (per layer) | Team lead | +1-3% per layer | Cross-module touchpoint detection |
|
|
812
|
+
| Module specification (per module) | mod-{code} agent | 40-60% | Parallel within layer, fresh context |
|
|
813
|
+
| Cross-module relay (per query) | Team lead | +1-2% per query | Lightweight relay |
|
|
814
|
+
| Layer review (per layer) | Team lead | +3-5% per layer | Proposals + consistency check |
|
|
815
|
+
| Consolidation | consolidation agent | 30-40% | Cross-module validation |
|
|
816
|
+
| Handoff | handoff agent | 40-50% | Artifact generation |
|
|
817
|
+
| **Total team lead** | — | **30-50%** | Same budget, more throughput |
|
|
818
|
+
| **Total per module agent** | — | **40-60%** | Independent contexts |
|
|
819
|
+
|
|
820
|
+
**Key insight:** Team lead never exceeds 50% even with 10+ modules, because:
|
|
821
|
+
- Module specifications happen in separate parallel contexts
|
|
822
|
+
- Cross-module relay is lightweight (forward message, not re-analyze)
|
|
823
|
+
- Layer reviews are incremental (only current layer proposals)
|
|
824
|
+
|
|
825
|
+
**Wall-clock time improvement:**
|
|
826
|
+
- Layer with 3 independent modules: 1x (parallel) vs 3x (sequential) = **66% reduction**
|
|
827
|
+
- Typical 4-module app (2 layers of 2): ~50% wall-clock reduction
|
|
828
|
+
- Full benefit: apps with many independent foundation modules (layer 0)
|