@atlashub/smartstack-cli 4.48.0 → 4.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.documentation/testing-ba-e2e.md +76 -24
  2. package/package.json +1 -1
  3. package/templates/agents/gitflow/init.md +26 -0
  4. package/templates/skills/apex/references/parallel-execution.md +22 -4
  5. package/templates/skills/apex/steps/step-00-init.md +38 -0
  6. package/templates/skills/apex/steps/step-03a-layer0-domain.md +21 -0
  7. package/templates/skills/apex/steps/step-03b-layer1-seed.md +60 -0
  8. package/templates/skills/apex/steps/step-03c-layer2-backend.md +124 -13
  9. package/templates/skills/apex/steps/step-03d-layer3-frontend.md +32 -0
  10. package/templates/skills/application/references/backend-controller-hierarchy.md +14 -4
  11. package/templates/skills/business-analyse/patterns/suggestion-catalog.md +2 -0
  12. package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +2 -0
  13. package/templates/skills/business-analyse/schemas/application-schema.json +36 -1
  14. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +19 -0
  15. package/templates/skills/business-analyse/steps/step-00-init.md +64 -14
  16. package/templates/skills/business-analyse/steps/step-01-cadrage.md +49 -2
  17. package/templates/skills/business-analyse/steps/step-02-structure.md +41 -17
  18. package/templates/skills/business-analyse/steps/step-04-consolidate.md +171 -0
  19. package/templates/skills/business-analyse-develop/references/quality-gates.md +91 -1
  20. package/templates/skills/business-analyse-develop/steps/step-01-task.md +147 -1
  21. package/templates/skills/business-analyse-handoff/references/acceptance-criteria.md +53 -1
  22. package/templates/skills/business-analyse-handoff/references/handoff-file-templates.md +42 -0
  23. package/templates/skills/business-analyse-handoff/references/handoff-mappings.md +15 -1
  24. package/templates/skills/business-analyse-handoff/references/prd-generation.md +59 -0
  25. package/templates/skills/business-analyse-handoff/steps/step-01-transform.md +25 -1
  26. package/templates/skills/business-analyse-handoff/steps/step-02-export.md +32 -4
  27. package/templates/skills/business-analyse-html/html/ba-interactive.html +80 -11
  28. package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +4 -2
  29. package/templates/skills/business-analyse-html/html/src/scripts/02-navigation.js +16 -2
  30. package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +19 -4
  31. package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +1 -1
  32. package/templates/skills/business-analyse-html/html/src/styles/03-navigation.css +2 -2
  33. package/templates/skills/business-analyse-html/html/src/styles/05-modules.css +38 -0
  34. package/templates/skills/business-analyse-html/references/data-build.md +4 -1
  35. package/templates/skills/business-analyse-html/references/data-mapping.md +4 -1
  36. package/templates/skills/business-analyse-html/steps/step-02-build-data.md +113 -1
  37. package/templates/skills/business-analyse-html/steps/step-04-verify.md +17 -1
  38. package/templates/skills/controller/references/mcp-scaffold-workflow.md +8 -4
  39. package/templates/skills/controller/steps/step-05-validate.md +2 -2
  40. package/templates/skills/controller/templates.md +4 -3
  41. package/templates/skills/feature-full/steps/step-01-implementation.md +18 -5
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Vue d'ensemble
4
4
 
5
- Infrastructure de tests E2E pour valider le pipeline complet **Business Analyse → Handoff → PRD extraction → Ralph Loop**.
5
+ Infrastructure de tests E2E pour valider le pipeline complet **Business Analyse → Handoff → PRD extraction → `/business-analyse-develop`**.
6
6
 
7
7
  **Garanties :**
8
8
  - ✅ Validation déterministe du handoff
@@ -25,11 +25,15 @@ tests/ba/
25
25
  │ ├── Products/
26
26
  │ └── Orders/
27
27
 
28
- └── e2e/ # Test suites E2E
28
+ ├── chain-integrity.test.ts # Intégrité chaîne BA → Handoff → PRD (55 tests)
29
+
30
+ └── e2e/ # Test suites E2E
29
31
  ├── handoff-validation.test.ts # Validation handoff section
30
32
  ├── prd-extraction-simple.test.ts # Extraction module simple
31
33
  ├── prd-extraction-medium.test.ts # Extraction module lifecycle
32
- └── full-pipeline.test.ts # Pipeline complet BA → Ralph Loop
34
+ ├── full-pipeline.test.ts # Pipeline complet BA → PRD → develop
35
+ ├── task-generation.test.ts # Génération de tâches depuis PRD
36
+ └── unified-prd.test.ts # Extraction PRD unifié (dual-mode v2/v3)
33
37
  ```
34
38
 
35
39
  ---
@@ -140,7 +144,7 @@ tests/ba/
140
144
 
141
145
  ### 4. full-pipeline.test.ts
142
146
 
143
- **Objectif:** Tester pipeline complet BA → Ralph Loop.
147
+ **Objectif:** Tester pipeline complet BA → Handoff → PRD → `/business-analyse-develop`.
144
148
 
145
149
  **Scénarios:**
146
150
 
@@ -148,10 +152,10 @@ tests/ba/
148
152
  1. Load feature.json (status = "handed-off")
149
153
  2. Validate handoff section complet
150
154
  3. Extract prd.json déterministe
151
- 4. Write prd.json to .ralph/
155
+ 4. Write prd.json to .prd/
152
156
  5. Read back prd.json (verify integrity)
153
- 6. Verify all required sections for Ralph Loop
154
- 7. Verify prd.json meets Ralph Loop requirements (7 categories, BR mappings, CORE seedData)
157
+ 6. Verify all required sections for `/business-analyse-develop`
158
+ 7. Verify prd.json meets requirements (8 categories incl. `documentation`, BR mappings, CORE seedData)
155
159
 
156
160
  **Medium Module Pipeline with Lifecycle:**
157
161
  1. Load medium feature with lifecycle
@@ -159,7 +163,7 @@ tests/ba/
159
163
  3. Extract prd.json with lifecycle preserved
160
164
  4. Verify lifecycle transitions mapped to BR
161
165
  5. Verify lifecycle states match seedData
162
- 6. Write prd.json to .ralph/
166
+ 6. Write prd.json to .prd/
163
167
 
164
168
  **Reproducibility Test:**
165
169
  - Multiple extractions = identical prd.json (sans timestamp)
@@ -168,11 +172,56 @@ tests/ba/
168
172
  - Missing optional namespace handled gracefully
169
173
  - Empty arrays handled gracefully
170
174
 
171
- **Integration with Ralph Loop:**
175
+ **Integration with `/business-analyse-develop`:**
172
176
  - All required information present (entities, UCs, BRs, endpoints, permissions, filesToCreate, BR mappings, CORE seedData)
173
177
  - Use cases linked to API endpoints
174
178
  - Business rules linked to use cases
175
179
 
180
+ ### 5. chain-integrity.test.ts
181
+
182
+ **Objectif:** Valider l'intégrité de la chaîne complète BA → Handoff → PRD.
183
+
184
+ **Scénarios (55 tests, 9 parties):**
185
+ - Part 1: Fichiers skill BA existent et sont structurés correctement
186
+ - Part 2: Fichiers skill handoff existent et sont structurés correctement
187
+ - Part 3: Cohérence des références inter-steps (next_step valides)
188
+ - Part 4: Schémas JSON valides et présents
189
+ - Part 5: POST-CHECKs exécutables dans les steps critiques
190
+ - Part 6: Références aux fonctions d'extraction (extractPrd, extractUnifiedPrd)
191
+ - Part 7: Cohérence fixtures ↔ schéma feature-json
192
+ - Part 8: Imports et exports du module prd-extractor
193
+ - Part 9: Silent failure guards (détection parse-error avant fallback)
194
+
195
+ ### 6. task-generation.test.ts
196
+
197
+ **Objectif:** Tester la génération de tâches depuis le PRD.
198
+
199
+ **Scénarios (26 tests):**
200
+ - Génération de tâches depuis PRD simple (module Orders)
201
+ - Génération de tâches depuis PRD medium (module Invoices avec lifecycle)
202
+ - Validation intégrité des tâches (`validateTaskIntegrity()`)
203
+ - Tâches couvrent toutes les entités
204
+ - Tâches couvrent tous les use cases
205
+ - Tâches ont des dépendances valides (pas de cycles)
206
+ - Ordre topologique respecté
207
+ - Tâches lifecycle incluent les transitions
208
+
209
+ ### 7. unified-prd.test.ts
210
+
211
+ **Objectif:** Tester `extractUnifiedPrd()` — extraction PRD dual-mode v2/v3.
212
+
213
+ **Scénarios (24 tests):**
214
+ - Extraction PRD v3.0 (task-oriented) depuis feature simple
215
+ - Extraction PRD v3.0 depuis feature medium avec lifecycle
216
+ - Structure v3.0 : `$version: "3.0.0"`, tâches intégrées
217
+ - `validatePrdCompleteness()` : PRD complet passe
218
+ - `validatePrdCompleteness()` : PRD incomplet signale erreurs
219
+ - `getPrdFileCounts()` : comptage correct par catégorie
220
+ - Fallback v2.0 quand extractPrd() appelé directement
221
+ - Cohérence entre v2 et v3 (mêmes données source)
222
+ - Metadata préservé (application, module, namespace)
223
+ - Traçabilité source (extractedAt, featureJsonPath)
224
+
176
225
  ---
177
226
 
178
227
  ## Exécution des Tests
@@ -302,7 +351,7 @@ describe('My Test Suite', () => {
302
351
  const feature = await fs.readJson(join(fixturesDir, 'my-feature.json')) as ModuleFeatureJson;
303
352
  const prd = extractPrd(feature, 'my-feature.json', 'MyCompany.MyApp');
304
353
 
305
- expect(prd.version).toBe('2.0.0');
354
+ expect(prd.version).toBeDefined();
306
355
  expect(prd.project.module).toBe('MyModule');
307
356
  // ... more assertions
308
357
  });
@@ -377,14 +426,18 @@ jobs:
377
426
 
378
427
  | Fichier | Couverture Cible |
379
428
  |---------|-----------------|
380
- | `src/utils/prd-extractor.ts` | 100% |
381
- | `src/commands/derive-prd.ts` | 90% |
429
+ | `src/utils/prd-extractor.ts` — `extractPrd()` | 100% |
430
+ | `src/utils/prd-extractor.ts` — `extractUnifiedPrd()` | 100% |
431
+ | `src/utils/prd-extractor.ts` — `validatePrdCompleteness()` | 100% |
432
+ | `src/utils/prd-extractor.ts` — `validateTaskIntegrity()` | 100% |
433
+ | `src/utils/prd-extractor.ts` — `getPrdFileCounts()` | 100% |
434
+ | `src/commands/business-analyse-handoff.ts` | 90% |
382
435
  | `templates/skills/business-analyse/**/*.md` | N/A (documentation) |
383
436
 
384
437
  ### KPIs Tests
385
438
 
386
- - **Total tests:** ~60 scénarios
387
- - **Temps d'exécution:** < 10s
439
+ - **Total tests:** 168 scénarios (7 test suites)
440
+ - **Temps d'exécution:** < 2s
388
441
  - **Fixtures:** 3 (simple/medium/complex)
389
442
  - **Couverture code:** > 95% sur extraction pipeline
390
443
 
@@ -435,22 +488,20 @@ export default defineConfig({
435
488
  ### Phase 1 ✅ (Implémenté)
436
489
  - Infrastructure Vitest
437
490
  - 3 fixtures (simple/medium/complex)
438
- - 4 test suites (handoff-validation, prd-extraction x2, full-pipeline)
491
+ - 7 test suites (handoff-validation, prd-extraction x2, full-pipeline, chain-integrity, task-generation, unified-prd)
439
492
  - Scripts npm
440
493
  - Documentation
441
494
 
442
- ### Phase 2 (Futur)
495
+ ### Phase 2 (À planifier)
443
496
  - Tests pour mode `--application` (extraction multi-modules)
444
- - Tests pour mode `--strict`
445
- - Tests pour cross-module dependencies
497
+ - Tests pour flag `--v4` (PRD spec-oriented)
498
+ - Tests pour `extractUnifiedPrd()` edge cases
446
499
  - Performance benchmarks (extraction < 100ms)
447
- - Tests pour ba-interactive.html extraction
448
500
 
449
501
  ### Phase 3 (Futur)
450
- - Tests E2E Ralph Loop integration (mock Ralph Loop server)
451
- - Tests pour step-05-handoff.md (génération handoff)
452
- - Tests pour derive-prd CLI (end-to-end avec fs.existsSync)
453
- - Tests pour validation schema (feature-schema.json)
502
+ - Tests E2E `/business-analyse-develop` integration (mock `/apex -d`)
503
+ - Tests pour `/business-analyse-handoff` CLI (end-to-end avec fs)
504
+ - Tests pour validation schema v5.0 (`feature-schema.json`)
454
505
 
455
506
  ---
456
507
 
@@ -459,4 +510,5 @@ export default defineConfig({
459
510
  - [prd-json v2.0.0 Reference](./prd-json-v2.0.0.md)
460
511
  - [Feature JSON Schema](../templates/skills/business-analyse/schemas/feature-schema.json)
461
512
  - [Business Analyse Skill](../templates/skills/business-analyse/SKILL.md)
462
- - [Ralph Loop Documentation](../templates/skills/ralph-loop/SKILL.md)
513
+ - [Business Analyse Develop](../templates/skills/business-analyse-develop/SKILL.md)
514
+ - [Business Analyse Handoff](../templates/skills/business-analyse-handoff/SKILL.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlashub/smartstack-cli",
3
- "version": "4.48.0",
3
+ "version": "4.50.0",
4
4
  "description": "SmartStack Claude Code automation toolkit - GitFlow, EF Core migrations, prompts and more",
5
5
  "author": {
6
6
  "name": "SmartStack",
@@ -240,6 +240,28 @@ Check the result. If FAIL, report to user and suggest manual intervention.
240
240
 
241
241
  ---
242
242
 
243
+ ## STEP 3b: DETECT PROJECT VERSION
244
+
245
+ Read `references/init-version-detection.md` and execute the version detection script.
246
+
247
+ The script detects the project version with this priority:
248
+ 1. `*.csproj` `<Version>` tag
249
+ 2. `Directory.Build.props` `<Version>` tag
250
+ 3. `package.json` `"version"` field
251
+ 4. `VERSION` file
252
+ 5. Latest git tag (stripped of `v` prefix)
253
+ 6. Fallback: `0.0.0`
254
+
255
+ Store the result as `{VERSION}`.
256
+
257
+ **CRITICAL:** `{VERSION}` is the PROJECT version (e.g., "0.0.0", "1.2.3").
258
+ It is NOT the config schema version ("2.1.0" on line 1 of config.json).
259
+ These are two different things:
260
+ - `"version": "2.1.0"` = config file format version (FIXED, do not change)
261
+ - `"versioning.current": "{VERSION}"` = project semver version (DETECTED)
262
+
263
+ ---
264
+
243
265
  ## STEP 4: WRITE CONFIG
244
266
 
245
267
  Write `.claude/gitflow/config.json` in develop worktree using the Write tool.
@@ -257,6 +279,10 @@ MAIN_DIR = organized → "01-Main" | simple → "main" | disabled → "."
257
279
  DEVELOP_DIR = organized → "02-Develop" | simple → "develop" | disabled → "."
258
280
  ```
259
281
 
282
+ > **TWO DIFFERENT VERSIONS:** `"version": "2.1.0"` below is the CONFIG SCHEMA version (always 2.1.0).
283
+ > `"versioning.current": "{VERSION}"` is the PROJECT version (detected in step 3b).
284
+ > Do NOT confuse them. Do NOT use "2.1.0" as the project version.
285
+
260
286
  ```json
261
287
  {
262
288
  "version": "2.1.0",
@@ -91,12 +91,28 @@ Agent principal aggregates all results after all agents complete.
91
91
 
92
92
  ```
93
93
  Layer 2 (Backend) — if multiple entities:
94
+ # AGENT BOUNDARY: Snipper agents do NOT have access to MCP tools.
95
+ # Services, DTOs, controllers MUST be scaffolded by the principal agent via MCP.
96
+ # Snipper agents handle ONLY: business logic, validators, code-gen wiring.
97
+
98
+ # PHASE A — Sequential: MCP scaffolding (principal agent)
99
+ For each entity:
100
+ mcp__smartstack__scaffold_extension(type: "dto", name: "{Entity}", options: { navRoute: "..." })
101
+ mcp__smartstack__scaffold_extension(type: "controller", name: "{Entity}", options: { navRoute: "..." })
102
+ Verify NavRoute on generated controller (bash)
103
+
104
+ # PHASE B — Parallel: post-scaffold adjustments (Snipper agents)
94
105
  Agent(subagent_type='Snipper', model='opus',
95
- prompt='Execute Layer 2 backend for {Entity1}: service, DTO, controller, validators...')
106
+ prompt='Adjust Layer 2 backend for {Entity1}: service logic, validators, code-gen wiring.
107
+ DO NOT regenerate controller/DTO — already created by MCP.')
96
108
  Agent(subagent_type='Snipper', model='opus',
97
- prompt='Execute Layer 2 backend for {Entity2}: service, DTO, controller, validators...')
109
+ prompt='Adjust Layer 2 backend for {Entity2}: service logic, validators, code-gen wiring.
110
+ DO NOT regenerate controller/DTO — already created by MCP.')
98
111
  # Launched in parallel in a single message
99
112
 
113
+ # PHASE C — Sequential: DI registration (principal agent)
114
+ # Register all services + validators in DependencyInjection.cs (single pass, no conflicts)
115
+
100
116
  Layer 3 (Frontend) — if multiple entities:
101
117
  # ⛔ AGENT BOUNDARY: Snipper agents do NOT have access to Skill().
102
118
  # Pages (.tsx) MUST be generated by the principal agent via Skill("ui-components").
@@ -138,7 +154,9 @@ Each agent has an **isolated scope**: handles one entity end-to-end within the l
138
154
  2. Build gate: dotnet build → MUST PASS
139
155
  3. Layer 1: agent principal executes (seed data — sequential, no parallel agents)
140
156
  4. Build gate: dotnet build → MUST PASS
141
- 5. Layer 2: launch Snipper agents per entity (if multi-entity) OR agent principal (if single)
157
+ 5. Layer 2 Phase A: principal scaffolds ALL entities via MCP (dto + controller per entity)
158
+ 5b. Layer 2 Phase B: launch Snipper agents for post-scaffold adjustments (parallel)
159
+ 5c. Layer 2 Phase C: principal registers all DI in DependencyInjection.cs (single pass)
142
160
  6. Build gate: dotnet build → MUST PASS
143
161
  7. Backend tests inline (scaffold + run + fix max 3)
144
162
  8. Layer 3 Phase A: launch Snipper agents for infra (api-client, routes, i18n) — NOT pages
@@ -163,7 +181,7 @@ There is no idle state to manage — the agent principal simply waits for result
163
181
  |-----------|--------|
164
182
  | economy_mode = true | NO parallel agents, all sequential |
165
183
  | Single entity (any layer) | NO parallel agents, agent principal handles all |
166
- | Multiple entities, Layer 2 | Parallel: one Snipper agent per entity (service + controller) |
184
+ | Multiple entities, Layer 2 | Phase A: principal scaffolds via MCP (sequential). Phase B: Snipper for business logic (parallel). Phase C: principal DI registration (sequential) |
167
185
  | Multiple entities, Layer 3 | Parallel: Snipper agents for infra (api-client, routes, i18n) — pages by principal via Skill("ui-components") |
168
186
  | Layer 0, Layer 1, Layer 4 | NO parallel agents (sequential by nature) |
169
187
  | Analysis phase (step-01) | Parallel: 2-3 Explore agents (backend + frontend + context) |
@@ -57,6 +57,43 @@ When `-d {prd_path}` is used, extract all context from PRD file and skip section
57
57
  - `{needs_migration}` = any tasks with _migrationMeta
58
58
  - `{has_dependencies}` = prd.tasks.some(t => t.dependencies.length > 0) ? "references" : "none"
59
59
 
60
+ **Fallback extraction (if prd.project is absent — e.g. PRD v3.0.0 with metadata format):**
61
+ - `{app_name}` = prd.metadata?.applicationCode || prd.project?.application
62
+ - `{module_code}` = prd.metadata?.moduleCode || prd.project?.module
63
+ - `{entities}` = prd.implementation?.filesToCreate?.domain?.filter(f => f.type === 'Entity').map(f => extractEntityName(f.path)) || domain tasks fallback
64
+ - `{sections}` = prd.implementation?.filesToCreate?.seedData?.filter(f => f.path.includes('NavigationSectionSeedData')).length > 0 ? extractSectionsFromSeedDataPaths(prd) : []
65
+ - `{needs_seed_data}` = (prd.implementation?.filesToCreate?.seedData?.length || 0) > 0
66
+ - `{needs_migration}` = (prd.implementation?.filesToCreate?.infrastructure?.length || 0) > 0
67
+
68
+ **Specification Files Loading (if prd.specificationFiles present):**
69
+
70
+ ```javascript
71
+ if (prd.specificationFiles) {
72
+ const specsDir = path.dirname(delegate_prd_path); // .ralph/
73
+ const specFiles = prd.specificationFiles;
74
+
75
+ // Store loading plan for layer-specific consumption
76
+ specification_loading_plan = {
77
+ layer0_domain: [specFiles.entities],
78
+ layer1_seed: [specFiles.entities, specFiles.permissions],
79
+ layer2_backend: [specFiles.rules, specFiles.usecases],
80
+ layer3_frontend: [specFiles.screens, specFiles.usecases]
81
+ };
82
+
83
+ // Verify all companion files exist
84
+ for (const [layer, files] of Object.entries(specification_loading_plan)) {
85
+ for (const file of files) {
86
+ const filePath = path.join(specsDir, file);
87
+ if (!fileExists(filePath)) {
88
+ console.warn(`WARNING: Companion file missing for ${layer}: ${filePath}`);
89
+ }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ Each layer step (step-03a through step-03d) will load its companion files at the start. This provides full BA specifications (entity attributes, BR formulas, UC steps, screen columns) without loading the entire spec corpus.
96
+
60
97
  **Jump to:** section 3 (MCP verify) → section 6 (determine needs) → section 9 (summary)
61
98
 
62
99
  ---
@@ -231,6 +268,7 @@ Hierarchy: {app_name} → {module_code} → {sections[].code}
231
268
  Entities: {entities} | Complexity: {module_complexity} | Deps: {has_dependencies}
232
269
  Code: {code_patterns summary} | PRD: {prd_path||none} | Feature: {feature_path||none}
233
270
  Flags: {active_flags} | MCP: {available|degraded} | Needs: {migration/seed/workflow/notification}
271
+ Specs: {specification_loading_plan ? 'companion files available (layer-specific loading)' : 'none'}
234
272
  NEXT STEP: step-01-analyze
235
273
  ```
236
274
 
@@ -9,6 +9,27 @@ parent_step: steps/step-03-execute.md
9
9
 
10
10
  ## Layer 0 — Domain + Infrastructure (sequential, agent principal)
11
11
 
12
+ ### Companion Specs Loading (delegate mode)
13
+
14
+ ```javascript
15
+ if (delegate_mode && specification_loading_plan) {
16
+ const specsDir = path.dirname(delegate_prd_path);
17
+ // Layer 0 loads: entities companion
18
+ for (const file of specification_loading_plan.layer0_domain) {
19
+ const specPath = path.join(specsDir, file);
20
+ if (fileExists(specPath)) {
21
+ const specData = readJSON(specPath);
22
+ // specData.entities[] contains full attribute definitions:
23
+ // { name, type, required, validation, defaultValue, relationships[] }
24
+ // Use these for entity scaffolding instead of just entity names
25
+ console.log(`Loaded ${specPath}: ${(specData.entities || []).length} entities with full attributes`);
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ > When companion specs are loaded, use `specData.entities[].attributes[]` for entity property definitions (type, required, validation, defaultValue) instead of inferring from task descriptions. This ensures oneshot generation with correct types and constraints.
32
+
12
33
  ### Task Progress
13
34
  TaskUpdate(taskId: layer0_task_id, status: "in_progress")
14
35
  TaskUpdate(taskId: progress_tracker_id,
@@ -9,6 +9,31 @@ parent_step: steps/step-03-execute.md
9
9
 
10
10
  ## Layer 1 — Seed Data (DEDICATED LAYER — sequential, agent principal)
11
11
 
12
+ ### Companion Specs Loading (delegate mode)
13
+
14
+ ```javascript
15
+ if (delegate_mode && specification_loading_plan) {
16
+ const specsDir = path.dirname(delegate_prd_path);
17
+ // Layer 1 loads: entities + permissions companions
18
+ for (const file of specification_loading_plan.layer1_seed) {
19
+ const specPath = path.join(specsDir, file);
20
+ if (fileExists(specPath)) {
21
+ const specData = readJSON(specPath);
22
+ if (specData.entities) {
23
+ // Use entities[].seedValues[] for business seed data generation
24
+ console.log(`Loaded entities: ${specData.entities.length} entities`);
25
+ }
26
+ if (specData.permissionPaths || specData.roles) {
27
+ // Use full permission structure for PermissionsSeedData and RolesSeedData
28
+ console.log(`Loaded permissions: ${(specData.permissionPaths || []).length} paths, ${(specData.roles || []).length} roles`);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ > When companion specs are loaded, use `specData.permissionPaths[]` for exact permission paths and `specData.roles[]` for role definitions instead of generating from conventions. This ensures permission seed data matches BA specifications exactly.
36
+
12
37
  ### Task Progress
13
38
  TaskUpdate(taskId: layer1_task_id, status: "in_progress")
14
39
  TaskUpdate(taskId: progress_tracker_id,
@@ -157,6 +182,39 @@ Generate all files from scratch using `references/core-seed-data.md` templates:
157
182
 
158
183
  ---
159
184
 
185
+ ### Startup Pipeline Wiring (ONCE per project)
186
+
187
+ > **CRITICAL:** Seed data files are useless without startup execution.
188
+ > Reference: SmartStack.app `SmartStackExtensions.cs` → `InitializeSmartStackAsync()` → `RunClientSeedDataProvidersAsync()`
189
+
190
+ ```
191
+ Glob("**/Program.cs") → Read Program.cs
192
+
193
+ IF Program.cs calls `InitializeSmartStackAsync()`:
194
+ → Seed data pipeline is already wired ✅
195
+
196
+ ELSE IF Program.cs ONLY calls `MigrateAsync()` without seed data execution:
197
+ → Add seed data provider execution AFTER MigrateAsync():
198
+
199
+ After `await extDb.Database.MigrateAsync();`:
200
+ var seedProviders = scope.ServiceProvider
201
+ .GetServices<IClientSeedDataProvider>()
202
+ .OrderBy(s => s.Order).ToList();
203
+ foreach (var provider in seedProviders)
204
+ {
205
+ var coreDb = scope.ServiceProvider.GetRequiredService<ICoreDbContext>();
206
+ await provider.SeedNavigationAsync(coreDb, CancellationToken.None);
207
+ await provider.SeedRolesAsync(coreDb, CancellationToken.None);
208
+ await provider.SeedPermissionsAsync(coreDb, CancellationToken.None);
209
+ await provider.SeedRolePermissionsAsync(coreDb, CancellationToken.None);
210
+ }
211
+
212
+ Add using: SmartStack.Application.Common.Interfaces.Seeding
213
+ → ONE-TIME wiring. Future modules just add DI registrations.
214
+ ```
215
+
216
+ ---
217
+
160
218
  ### Post-Layer 1 Verification Checklist
161
219
 
162
220
  > **Before the build gate, verify ALL new scope elements are covered:**
@@ -169,6 +227,8 @@ For each section in {sections} from step-00:
169
227
  ✓ PermissionsSeedData has HasData() for each permission
170
228
  ✓ RolesSeedData maps all 4 roles to section permissions
171
229
  ✓ {App}SeedDataProvider references all seed data classes
230
+ ✓ Program.cs executes seed data providers after MigrateAsync()
231
+ ✓ DI registers: services.AddScoped<IClientSeedDataProvider, {App}SeedDataProvider>()
172
232
 
173
233
  IF any check fails → fix BEFORE build gate
174
234
  ```
@@ -9,6 +9,37 @@ parent_step: steps/step-03-execute.md
9
9
 
10
10
  ## Layer 2 — Backend (Services + Controllers)
11
11
 
12
+ ### Companion Specs Loading (delegate mode)
13
+
14
+ ```javascript
15
+ if (delegate_mode && specification_loading_plan) {
16
+ const specsDir = path.dirname(delegate_prd_path);
17
+ // Layer 2 loads: rules + usecases companions
18
+ for (const file of specification_loading_plan.layer2_backend) {
19
+ const specPath = path.join(specsDir, file);
20
+ if (fileExists(specPath)) {
21
+ const specData = readJSON(specPath);
22
+ if (specData.rules) {
23
+ // Full rule definitions: statement, example, formula, conditions
24
+ // Use for: Validator rules (BR-VAL-*), calculation logic (BR-CALC-*), workflow guards (BR-WF-*)
25
+ console.log(`Loaded rules: ${specData.rules.length} business rules with full definitions`);
26
+ }
27
+ if (specData.useCases || specData.usecases) {
28
+ const ucs = specData.useCases || specData.usecases;
29
+ // Full UC definitions: steps[], preconditions[], result, alternativeFlows
30
+ // Use for: Service method implementation, controller actions, error handling
31
+ console.log(`Loaded usecases: ${ucs.length} use cases with steps and preconditions`);
32
+ }
33
+ }
34
+ }
35
+ }
36
+ ```
37
+
38
+ > When companion specs are loaded:
39
+ > - **BR-VAL-*** rules: use `rule.statement` + `rule.conditions[]` to implement FluentValidation rules with exact business logic
40
+ > - **BR-CALC-*** rules: use `rule.formula` to implement calculation methods with the exact formula
41
+ > - **Use cases**: use `uc.steps[]` to implement service methods following the exact flow, and `uc.preconditions[]` for guard clauses
42
+
12
43
  ### Task Progress
13
44
  TaskUpdate(taskId: layer2_task_id, status: "in_progress")
14
45
  TaskUpdate(taskId: progress_tracker_id,
@@ -22,6 +53,28 @@ TaskUpdate(taskId: progress_tracker_id,
22
53
  > - DateOnly vs string for DTO date fields
23
54
  > - Code generation patterns (ICodeGenerator<T> registration, see references/code-generation.md)
24
55
 
56
+ ### HARD RULE — MCP scaffold_extension is NON-NEGOTIABLE for backend generation
57
+
58
+ > **VIOLATION CHECK:** If ANY service, controller, or DTO file was created by Write tool
59
+ > WITHOUT a prior MCP scaffold_extension call in this execution, the backend layer is INVALID.
60
+ >
61
+ > **You MUST NOT:**
62
+ > - Generate service/controller/DTO code in Agent prompts and dispatch to Snipper agents
63
+ > - Write controller content directly via the Write tool
64
+ > - Copy-paste controller templates from your knowledge
65
+ >
66
+ > **You MUST:**
67
+ > - Call MCP scaffold_extension for each entity (service, DTO, controller)
68
+ > - Let MCP generate all files with correct NavRoute, permissions, conventions
69
+ >
70
+ > **Why this matters:** Without MCP, controllers get both [Route] and [NavRoute] (causes 404s),
71
+ > NavRoute typos, incorrect permission scoping, and missing convention compliance.
72
+ >
73
+ > **Agent boundary rule:** Snipper sub-agents DO NOT have access to MCP tools.
74
+ > Therefore, MCP scaffolding MUST NEVER be delegated to Snipper agents.
75
+ > MCP calls are ALWAYS executed by the principal agent.
76
+ > Snipper agents handle: DI registration, business logic adjustments, validator customization.
77
+
25
78
  ### Backend Tasks (sequential or parallel within layer)
26
79
 
27
80
  - Services/DTOs: MCP scaffold_extension
@@ -63,32 +116,65 @@ For each entity where {code_patterns} defines strategy != "manual":
63
116
  | /notification | In-app or email notifications | trigger, recipients, template |
64
117
  | /workflow | Automated workflows | trigger, steps, conditions |
65
118
 
66
- ### If NOT economy_mode AND multiple entities: Parallel Agents (within layer)
119
+ ### If NOT economy_mode AND multiple entities: Phased Execution
67
120
 
68
121
  > **Protocol:** See `references/parallel-execution.md`
122
+ > **AGENT BOUNDARY:** Snipper agents do NOT have access to MCP tools or Bash.
123
+ > MCP scaffolding and bash validation MUST be executed by the principal agent.
124
+
125
+ #### Phase A — Sequential: MCP scaffolding (principal agent)
126
+
127
+ For each entity, the principal agent calls MCP directly:
69
128
 
70
129
  ```
71
130
  IF NOT economy_mode AND entities.length > 1:
131
+
132
+ FOR EACH entity in entities:
133
+ 1. mcp__smartstack__scaffold_extension(type: "dto", name: "{Entity}", options: { navRoute: "{navRoute}" })
134
+ 2. mcp__smartstack__scaffold_extension(type: "controller", name: "{Entity}", options: { navRoute: "{navRoute}" })
135
+
136
+ # Immediate NavRoute verification (principal has Bash access)
137
+ 3. Verify: [NavRoute] present, [Route] absent, segment count >= 2
138
+ If [Route] found alongside [NavRoute] → remove [Route] immediately
139
+ If [NavRoute] missing → add it with correct value
140
+ ```
141
+
142
+ #### Phase B — Parallel: post-scaffold adjustments (Snipper agents)
143
+
144
+ After ALL Phase A scaffolding completes, launch Snipper agents in parallel:
145
+
146
+ ```
72
147
  For each entity, launch in parallel (single message):
73
148
  Agent(subagent_type='Snipper', model='opus',
74
- prompt='Execute Layer 2 backend for {EntityName}:
75
- - Application service/DTO: MCP scaffold_extension
76
- - Controller: /controller skill or MCP scaffold_extension
77
- - IMPORTANT: GetAll endpoint MUST support ?search= parameter
78
- - Validators: FluentValidation + DI registration
149
+ prompt='Adjust Layer 2 backend for {EntityName}:
150
+ - Service: implement business logic in {EntityName}Service (FK patterns, search, inline Select)
151
+ - Validator: customize FluentValidation rules for Create{EntityName}Dto and Update{EntityName}Dto
79
152
  - CODE GENERATION: {code_patterns[EntityName] summary — e.g., "strategy: sequential, prefix: emp, digits: 5" or "manual"}
80
153
  If strategy != "manual": read references/code-generation.md, then:
81
- Register ICodeGenerator<{EntityName}> in DI (DependencyInjection.cs) with CodePatternConfig matching {code_patterns}
82
- Inject ICodeGenerator<{EntityName}> in {EntityName}Service, use _codeGenerator.NextCodeAsync(ct) in CreateAsync
83
- → Remove Code from Create{EntityName}Dto (auto-generated, not user-provided)
84
- → Keep Code in {EntityName}ResponseDto
154
+ Inject ICodeGenerator<{EntityName}> in {EntityName}Service constructor
155
+ Use _codeGenerator.NextCodeAsync(ct) in CreateAsync
156
+ → Remove Code from Create{EntityName}Dto, keep in {EntityName}ResponseDto
85
157
  → Create{EntityName}Validator: NO Code rule. Update{EntityName}Validator: Code rule with regex ^[a-z0-9_-]+$
86
158
  - Your task ID is {task_id}. Call TaskUpdate(status: "in_progress") before starting.
87
- - Call TaskUpdate(status: "completed", metadata: { files_created: [...] }) when done.')
159
+ - Call TaskUpdate(status: "completed", metadata: { files_created: [...] }) when done.
160
+
161
+ DO NOT regenerate controller or DTO files — already created by MCP in Phase A.
162
+ DO NOT add [Route] attribute — NavRoute is already set correctly.
163
+ Files already created: {list of paths from Phase A}')
88
164
  # All agents launched in parallel
165
+ ```
166
+
167
+ #### Phase C — Sequential: shared file edits (principal agent)
168
+
169
+ After ALL Phase B agents complete, the principal agent handles shared-file edits:
170
+
171
+ ```
172
+ 1. DependencyInjection.cs: register ALL services + validators in a single pass
173
+ → Avoids concurrent edit conflicts on shared file
174
+ 2. Code-generation DI: register ICodeGenerator<T> for each entity with strategy != "manual"
89
175
 
90
176
  ELSE:
91
- # Agent principal handles all entities sequentially
177
+ # Agent principal handles all entities sequentially (economy_mode or single entity)
92
178
  ```
93
179
 
94
180
  ### Parallel Agents + TaskCreate Integration
@@ -105,7 +191,7 @@ When launching agents for multi-entity layers:
105
191
 
106
192
  After controller generation, verify `[NavRoute]` attribute is present on every controller:
107
193
  - Expected: `[NavRoute("{app_name}.{module_code}.{section_code}")]` on the controller class
108
- - If missing: Add it manually above `[Authorize]`
194
+ - If missing: Add it manually above `[Microsoft.AspNetCore.Authorization.Authorize]`
109
195
  - When calling `scaffold_extension(type: "controller")`, always pass `navRoute` in options
110
196
  - This is REQUIRED for `scaffold_routes` to auto-detect routes in Layer 3
111
197
 
@@ -121,6 +207,9 @@ After controller generation, verify `[NavRoute]` attribute is present on every c
121
207
  - **If a controller is in a section subfolder** (e.g., `Controllers/{App}/Employees/ContractsController.cs`) **but has only 2 segments** → the API route will be wrong → 404. It MUST have 3 segments.
122
208
  - 0 dots = INVALID → BLOCK
123
209
 
210
+ > **Execution context:** These bash scripts run from the PRINCIPAL AGENT after Phase C.
211
+ > Snipper agents cannot execute Bash. Do NOT include these checks in Snipper prompts.
212
+
124
213
  ```bash
125
214
  # Quick validation
126
215
  CTRL_FILES=$(find src/ -path "*/Controllers/*" -name "*Controller.cs" 2>/dev/null)
@@ -149,6 +238,9 @@ for f in $CTRL_FILES; do
149
238
  if ! grep -q "\[NavRoute" "$f" && grep -q "\[Route" "$f"; then
150
239
  echo "WARNING: $f has [Route] but no [NavRoute] — add [NavRoute] for route auto-detection"
151
240
  fi
241
+ if grep -q "\[NavRoute" "$f" && grep -q "\[Route(" "$f"; then
242
+ echo "WARNING: $f has BOTH [Route] and [NavRoute] — remove [Route] (causes 404s)"
243
+ fi
152
244
  done
153
245
  ```
154
246
 
@@ -181,6 +273,25 @@ for ENTITY in $ENTITIES; do
181
273
  echo "BLOCKING: $CTRL has NO route attribute at all"
182
274
  echo "Fix: Add [NavRoute(\"{app}.{module}.{section}\")] from naming rules"
183
275
  fi
276
+
277
+ if [ "$HAS_NAVROUTE" -gt 0 ] && [ "$HAS_ROUTE" -gt 0 ]; then
278
+ echo "BLOCKING: $CTRL has BOTH [Route] and [NavRoute] — causes 404s"
279
+ echo "Fix: Remove [Route(\"...\")], keep only [NavRoute(\"...\")]"
280
+ fi
281
+ done
282
+
283
+ # Check NavRoute uniqueness across generated controllers
284
+ ALL_NAVROUTES=""
285
+ for ENTITY in $ENTITIES; do
286
+ CTRL=$(find src/ -path "*/Controllers/*" -name "${ENTITY}*Controller.cs" 2>/dev/null | head -1)
287
+ [ -z "$CTRL" ] && continue
288
+ NR=$(grep -oP '\[NavRoute\("\K[^"]+' "$CTRL" 2>/dev/null || true)
289
+ [ -z "$NR" ] && continue
290
+ if echo "$ALL_NAVROUTES" | grep -qx "$NR"; then
291
+ echo "BLOCKING: Duplicate NavRoute '$NR' on $CTRL — each controller needs a unique NavRoute"
292
+ fi
293
+ ALL_NAVROUTES="$ALL_NAVROUTES
294
+ $NR"
184
295
  done
185
296
  ```
186
297