@atlashub/smartstack-cli 3.10.0 → 3.13.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 (35) hide show
  1. package/dist/index.js +2544 -2461
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +479 -6185
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +2 -2
  6. package/templates/agents/db-reader.md +149 -0
  7. package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +9 -19
  8. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +12 -2
  9. package/templates/skills/business-analyse/references/deploy-data-build.md +36 -25
  10. package/templates/skills/business-analyse/references/detection-strategies.md +424 -0
  11. package/templates/skills/business-analyse/references/html-data-mapping.md +4 -0
  12. package/templates/skills/business-analyse/references/prd-generation.md +258 -0
  13. package/templates/skills/business-analyse/references/validate-incremental-html.md +47 -4
  14. package/templates/skills/business-analyse/references/validation-checklist.md +281 -0
  15. package/templates/skills/business-analyse/steps/step-00-init.md +50 -221
  16. package/templates/skills/business-analyse/steps/step-01-cadrage.md +8 -22
  17. package/templates/skills/business-analyse/steps/step-03a-data.md +20 -446
  18. package/templates/skills/business-analyse/steps/step-03a1-setup.md +356 -0
  19. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +143 -0
  20. package/templates/skills/business-analyse/steps/step-03b-ui.md +3 -0
  21. package/templates/skills/business-analyse/steps/step-03c-compile.md +1 -1
  22. package/templates/skills/business-analyse/steps/step-03d-validate.md +21 -262
  23. package/templates/skills/business-analyse/steps/step-04-consolidation.md +21 -606
  24. package/templates/skills/business-analyse/steps/step-04a-collect.md +304 -0
  25. package/templates/skills/business-analyse/steps/step-04b-analyze.md +239 -0
  26. package/templates/skills/business-analyse/steps/step-04c-decide.md +186 -0
  27. package/templates/skills/business-analyse/steps/step-05b-deploy.md +21 -0
  28. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +27 -35
  29. package/templates/skills/debug/SKILL.md +156 -53
  30. package/templates/skills/debug/references/team-protocol.md +232 -0
  31. package/templates/skills/ralph-loop/references/category-rules.md +46 -0
  32. package/templates/skills/ralph-loop/references/compact-loop.md +32 -2
  33. package/templates/skills/ralph-loop/references/core-seed-data.md +60 -0
  34. package/templates/skills/ralph-loop/steps/step-00-init.md +64 -1
  35. package/templates/skills/ralph-loop/steps/step-04-check.md +27 -2
@@ -0,0 +1,424 @@
1
+ # Detection Strategies - New vs Update vs Review
2
+
3
+ Source: business-analyse step-00-init.md
4
+
5
+ This document describes the algorithms used in step-00-init.md to automatically detect the workflow type (new application, update, or review mode) and match user intent against existing business analyses.
6
+
7
+ ---
8
+
9
+ ## 1. Review Mode Detection
10
+
11
+ **Trigger:** `{feature_description}` starts with `-review` (with or without extra text)
12
+
13
+ ### Algorithm
14
+
15
+ ```javascript
16
+ function detectReviewMode(feature_description) {
17
+ const isReviewMode = feature_description.trim().startsWith('-review');
18
+
19
+ if (!isReviewMode) {
20
+ return { mode: null };
21
+ }
22
+
23
+ // Scan docs/business/ for most recent application
24
+ const applications = glob('docs/business/*/business-analyse/*/feature.json')
25
+ .map(path => ({
26
+ path,
27
+ metadata: readJSON(path).metadata,
28
+ updatedAt: readJSON(path).metadata.updatedAt
29
+ }))
30
+ .sort((a, b) => b.updatedAt - a.updatedAt);
31
+
32
+ if (applications.length === 0) {
33
+ return {
34
+ mode: 'review',
35
+ error: 'NO_APPLICATIONS_FOUND',
36
+ fix: 'Create an application first using /business-analyse'
37
+ };
38
+ }
39
+
40
+ const latestApp = applications[0];
41
+ const versionDir = path.dirname(latestApp.path);
42
+ const reviewFilePath = path.join(versionDir, 'ba-review.json');
43
+
44
+ if (!fs.existsSync(reviewFilePath)) {
45
+ return {
46
+ mode: 'review',
47
+ error: 'NO_REVIEW_FILE',
48
+ applicationName: latestApp.metadata.application,
49
+ expectedPath: reviewFilePath,
50
+ fix: `
51
+ To create ba-review.json:
52
+ 1. Open ba-interactive.html in your browser
53
+ 2. Make your corrections
54
+ 3. Click "Sauvegarder corrections" button
55
+ 4. Save the downloaded ba-review.json in: ${versionDir}/
56
+ 5. Run /business-analyse -review again
57
+ `
58
+ };
59
+ }
60
+
61
+ return {
62
+ mode: 'review',
63
+ reviewJsonPath: reviewFilePath,
64
+ applicationName: latestApp.metadata.application,
65
+ docsDir: versionDir,
66
+ nextStep: 'step-06-review.md'
67
+ };
68
+ }
69
+ ```
70
+
71
+ ### Decision Matrix
72
+
73
+ | Condition | Action |
74
+ |-----------|--------|
75
+ | `{feature_description}` starts with `-review` | Activate review mode detection |
76
+ | ba-review.json found | Skip to step-06-review.md |
77
+ | ba-review.json NOT found | Display error with fix instructions, STOP |
78
+ | No applications exist | Display error, STOP |
79
+
80
+ ### Error Messages
81
+
82
+ **Error 1: No Applications Found**
83
+ ```
84
+ ERROR: No existing applications found in docs/business/
85
+
86
+ You must create an application first using:
87
+ /business-analyse
88
+
89
+ Then generate ba-interactive.html, make corrections, and export ba-review.json.
90
+ ```
91
+
92
+ **Error 2: No Review File**
93
+ ```
94
+ ERROR: No ba-review.json found in docs/business/{app}/business-analyse/v{version}/
95
+
96
+ To create one:
97
+ 1. Open the ba-interactive.html in your browser
98
+ 2. Make your corrections
99
+ 3. Click "Sauvegarder corrections" button
100
+ 4. Save the downloaded ba-review.json in the version folder
101
+ 5. Run /business-analyse -review again
102
+
103
+ Expected path: {expectedPath}
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 2. Existing Applications Scanner
109
+
110
+ **Objective:** Build a catalog of existing business analyses for comparison.
111
+
112
+ ### Scan Algorithm
113
+
114
+ ```javascript
115
+ function scanExistingApplications() {
116
+ const featureFiles = glob('docs/business/*/business-analyse/*/feature.json');
117
+
118
+ const existingApps = featureFiles.map(path => {
119
+ const feature = readJSON(path);
120
+ return {
121
+ app: feature.metadata.application,
122
+ featureId: feature.id,
123
+ description: feature.metadata.featureDescription,
124
+ version: extractVersion(path), // e.g., "1.0" from "v1.0"
125
+ path: path,
126
+ updatedAt: feature.metadata.updatedAt,
127
+ modules: feature.modules?.map(m => m.code) || [],
128
+ status: feature.status
129
+ };
130
+ });
131
+
132
+ // Sort by most recent first
133
+ existingApps.sort((a, b) => b.updatedAt - a.updatedAt);
134
+
135
+ return existingApps;
136
+ }
137
+ ```
138
+
139
+ ### Output Schema
140
+
141
+ ```typescript
142
+ interface ExistingApp {
143
+ app: string; // "HumanResources"
144
+ featureId: string; // "FEAT-001"
145
+ description: string; // "Gestion des projets et absences"
146
+ version: string; // "1.0", "1.1", "2.0"
147
+ path: string; // "docs/business/HumanResources/..."
148
+ updatedAt: string; // ISO timestamp
149
+ modules: string[]; // ["Projects", "TimeTracking", "Reporting"]
150
+ status: string; // "draft", "consolidated", "handed-off"
151
+ }
152
+ ```
153
+
154
+ ### Edge Cases
155
+
156
+ | Case | Handling |
157
+ |------|----------|
158
+ | No feature.json files found | Return empty array → triggers "new application" mode |
159
+ | Corrupted feature.json | Skip file, log warning, continue scan |
160
+ | Multiple versions of same app | Include all, sorted by updatedAt |
161
+ | Incomplete applications (status="draft") | Include but flag in description |
162
+
163
+ ---
164
+
165
+ ## 3. New vs Update Detection
166
+
167
+ **Objective:** Determine if user wants to create a new application or update an existing one.
168
+
169
+ ### Similarity Analysis Algorithm
170
+
171
+ ```javascript
172
+ function analyzeSimilarity(feature_description, existingApps) {
173
+ const scores = existingApps.map(app => ({
174
+ app,
175
+ score: calculateSimilarityScore(feature_description, app)
176
+ }));
177
+
178
+ // Sort by highest score first
179
+ scores.sort((a, b) => b.score - a.score);
180
+
181
+ return scores;
182
+ }
183
+
184
+ function calculateSimilarityScore(description, existingApp) {
185
+ let score = 0;
186
+
187
+ // 1. Application name match (50 points)
188
+ if (description.toLowerCase().includes(existingApp.app.toLowerCase())) {
189
+ score += 50;
190
+ }
191
+
192
+ // 2. Module name match (30 points)
193
+ for (const module of existingApp.modules) {
194
+ if (description.toLowerCase().includes(module.toLowerCase())) {
195
+ score += 30;
196
+ break;
197
+ }
198
+ }
199
+
200
+ // 3. Update keywords (40 points)
201
+ const updateKeywords = [
202
+ 'ajouter', 'modifier', 'changer', 'enrichir', 'mettre à jour',
203
+ 'add', 'modify', 'change', 'update', 'extend'
204
+ ];
205
+ for (const keyword of updateKeywords) {
206
+ if (description.toLowerCase().includes(keyword)) {
207
+ score += 40;
208
+ break;
209
+ }
210
+ }
211
+
212
+ // 4. Domain overlap (20 points)
213
+ // Check if description and existing app share domain terms
214
+ const domainTerms = extractDomainTerms(existingApp.description);
215
+ for (const term of domainTerms) {
216
+ if (description.toLowerCase().includes(term.toLowerCase())) {
217
+ score += 5; // Up to 20 points (4 terms)
218
+ }
219
+ }
220
+
221
+ return score;
222
+ }
223
+
224
+ function extractDomainTerms(text) {
225
+ // Extract nouns/domain entities (simplified)
226
+ const words = text.toLowerCase().split(/\s+/);
227
+ return words.filter(w => w.length > 4); // Filter short words
228
+ }
229
+ ```
230
+
231
+ ### Decision Tree
232
+
233
+ ```
234
+ ┌─────────────────────────────────────┐
235
+ │ existing_apps.length === 0? │
236
+ └──┬─────────────────────────┬────────┘
237
+ │ YES │ NO
238
+ │ │
239
+ v v
240
+ ┌──────────────┐ ┌──────────────────────┐
241
+ │ workflow_type │ │ Calculate similarity │
242
+ │ = "new" │ │ scores for all apps │
243
+ └──────────────┘ └──────┬───────────────┘
244
+
245
+ v
246
+ ┌─────────────────────┐
247
+ │ Top score >= 80? │
248
+ └──┬─────────────┬────┘
249
+ │ YES │ NO
250
+ │ │
251
+ v v
252
+ ┌──────────────┐ ┌──────────────┐
253
+ │ Suggest │ │ Show all │
254
+ │ update to │ │ options with │
255
+ │ matched app │ │ "New app" as │
256
+ │ as first │ │ first option │
257
+ │ option │ │ │
258
+ └───────────────┘ └──────────────┘
259
+ │ │
260
+ v v
261
+ ┌────────────────────────┐
262
+ │ Ask via │
263
+ │ AskUserQuestion │
264
+ └─────────┬──────────────┘
265
+
266
+ ┌──────────────┴──────────────┐
267
+ │ │
268
+ v v
269
+ ┌──────────────────┐ ┌──────────────────┐
270
+ │ User selects │ │ User selects │
271
+ │ "Update {app}" │ │ "New app" │
272
+ └────────┬─────────┘ └────────┬─────────┘
273
+ │ │
274
+ v v
275
+ ┌──────────────────┐ ┌──────────────────┐
276
+ │ workflow_type = │ │ workflow_type = │
277
+ │ "update" │ │ "new" │
278
+ │ existing_feature │ │ │
279
+ │ = app.featureId │ │ │
280
+ └──────────────────┘ └──────────────────┘
281
+ ```
282
+
283
+ ### AskUserQuestion Format
284
+
285
+ **When similarity score >= 80 (strong match):**
286
+ ```javascript
287
+ AskUserQuestion({
288
+ question: "J'ai trouvé une analyse existante similaire. Que souhaitez-vous faire ?",
289
+ header: "Mode",
290
+ options: [
291
+ {
292
+ label: `Mise à jour de ${matchedApp.app} (${matchedApp.featureId})`,
293
+ description: `Enrichir ou modifier l'application existante (crée v${nextVersion})`
294
+ },
295
+ {
296
+ label: "Nouvelle application",
297
+ description: "Créer une nouvelle analyse complète"
298
+ }
299
+ ]
300
+ });
301
+ ```
302
+
303
+ **When multiple apps but no strong match:**
304
+ ```javascript
305
+ AskUserQuestion({
306
+ question: "J'ai trouvé des analyses existantes. Que souhaitez-vous faire ?",
307
+ header: "Mode",
308
+ options: [
309
+ {
310
+ label: "Nouvelle application",
311
+ description: "Créer une nouvelle analyse complète"
312
+ },
313
+ ...existingApps.slice(0, 3).map(app => ({
314
+ label: `Mise à jour de ${app.app} (${app.featureId})`,
315
+ description: `Enrichir ${app.app} — modules: ${app.modules.join(', ')}`
316
+ }))
317
+ ]
318
+ });
319
+ ```
320
+
321
+ ### Update Mode Flow
322
+
323
+ When user selects an existing app for update:
324
+
325
+ ```javascript
326
+ function initiateUpdateMode(existingApp) {
327
+ // 1. Call ba-writer to create new version
328
+ const newVersion = ba_writer.createVersion(
329
+ existingApp.featureId,
330
+ feature_description
331
+ );
332
+
333
+ // 2. Copy previous version data as baseline
334
+ const previousFeature = readJSON(existingApp.path);
335
+ const newFeature = {
336
+ ...previousFeature,
337
+ id: existingApp.featureId, // Keep same feature ID
338
+ version: newVersion.version, // Increment version (e.g., "1.0" → "1.1")
339
+ status: "draft",
340
+ metadata: {
341
+ ...previousFeature.metadata,
342
+ featureDescription: feature_description, // New description
343
+ workflowType: "update",
344
+ previousVersion: extractVersion(existingApp.path),
345
+ updatedAt: new Date().toISOString()
346
+ }
347
+ };
348
+
349
+ // 3. Write new version feature.json
350
+ const newPath = `docs/business/${existingApp.app}/business-analyse/v${newVersion.version}/feature.json`;
351
+ writeJSON(newPath, newFeature);
352
+
353
+ return {
354
+ workflow_type: "update",
355
+ existing_feature_id: existingApp.featureId,
356
+ version: newVersion.version,
357
+ application_name: existingApp.app,
358
+ docs_dir: path.dirname(newPath)
359
+ };
360
+ }
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Similarity Scoring Reference
366
+
367
+ | Match Type | Score | Example |
368
+ |-----------|-------|---------|
369
+ | **Application name exact** | 50 | "HumanResources" in description → matches HumanResources app |
370
+ | **Module name exact** | 30 | "Projects" in description → matches app with Projects module |
371
+ | **Update keyword** | 40 | "ajouter", "modifier", "mettre à jour" |
372
+ | **Domain term overlap** | 5 per term (max 20) | "project", "absence", "employee" |
373
+
374
+ **Total possible:** 140 points
375
+
376
+ **Thresholds:**
377
+ - **>= 80:** Strong match → suggest update as first option
378
+ - **50-79:** Moderate match → show as option but list "New app" first
379
+ - **< 50:** Weak match → show in list but deprioritize
380
+
381
+ ---
382
+
383
+ ## State Variables After Detection
384
+
385
+ After detection completes, these variables are set:
386
+
387
+ ```typescript
388
+ interface DetectionResult {
389
+ workflow_type: "new" | "update" | "review";
390
+ existing_feature_id: string | null; // Set only if workflow_type = "update"
391
+ version: string; // "1.0" (new) or "1.1"+ (update)
392
+ application_name: string;
393
+ review_json_path?: string; // Set only if workflow_type = "review"
394
+ docs_dir: string;
395
+ }
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Testing Detection Logic
401
+
402
+ **Test Case 1: New Application (No Existing Apps)**
403
+ - Input: `"Créer une application de gestion des congés"`
404
+ - Expected: `workflow_type = "new"`, no prompt shown
405
+
406
+ **Test Case 2: Strong Match for Update**
407
+ - Input: `"Ajouter module de reporting à HumanResources"`
408
+ - Existing: `HumanResources (FEAT-001)` with modules `[Projects, TimeTracking]`
409
+ - Expected: Prompt with "Update HumanResources" as first option, score ~120
410
+
411
+ **Test Case 3: Ambiguous (Multiple Matches)**
412
+ - Input: `"Gérer les projets"`
413
+ - Existing: `HumanResources (FEAT-001)` with Projects module, `ProjectManagement (FEAT-002)`
414
+ - Expected: Prompt with "New app" first, both existing apps listed
415
+
416
+ **Test Case 4: Review Mode**
417
+ - Input: `"-review"`
418
+ - Existing: `HumanResources` with ba-review.json present
419
+ - Expected: Load ba-review.json, skip to step-06-review.md
420
+
421
+ **Test Case 5: Review Mode - File Missing**
422
+ - Input: `"-review"`
423
+ - Existing: `HumanResources` but no ba-review.json
424
+ - Expected: Display error with fix instructions, STOP
@@ -196,6 +196,10 @@ Default: "contributor"
196
196
 
197
197
  ## EMBEDDED_ARTIFACTS Mapping
198
198
 
199
+ > **FIELD RENAME WARNING:** feature.json stores wireframes with `mockupFormat` and `mockup` fields.
200
+ > The HTML renderer reads `format` and `content`. You MUST rename: `mockupFormat` → `format`, `mockup` → `content`.
201
+ > Failure to rename = empty mockup display in the browser.
202
+
199
203
  Build a JSON object containing ALL visual artifacts from feature.json:
200
204
 
201
205
  ```javascript
@@ -0,0 +1,258 @@
1
+ # PRD v3.0 Structure & Validation Rules
2
+
3
+ Source: business-analyse step-05c-ralph-readiness.md
4
+
5
+ ## PRD File Format v3.0
6
+
7
+ ### File Location
8
+
9
+ ```
10
+ .ralph/prd-{moduleCode}.json
11
+ ```
12
+
13
+ Example: `.ralph/prd-Projects.json`, `.ralph/prd-TimeTracking.json`
14
+
15
+ ---
16
+
17
+ ## Structure Requirements
18
+
19
+ ### 1. Version Field (MANDATORY)
20
+
21
+ ```json
22
+ {
23
+ "$version": "3.0.0"
24
+ }
25
+ ```
26
+
27
+ **Validation:**
28
+ - MUST be exactly `"3.0.0"`
29
+ - BLOCKING if missing or wrong version
30
+
31
+ **Common Error:**
32
+ ```
33
+ BLOCKING_ERROR: PRD version must be 3.0.0, got: 2.1.0
34
+ Fix: Re-run ss derive-prd with latest version
35
+ ```
36
+
37
+ ---
38
+
39
+ ### 2. Implementation Section (MANDATORY)
40
+
41
+ **CRITICAL:** `filesToCreate` MUST be under `implementation`, NOT at root level.
42
+
43
+ **Correct Structure:**
44
+ ```json
45
+ {
46
+ "$version": "3.0.0",
47
+ "implementation": {
48
+ "filesToCreate": {
49
+ "domain": [...],
50
+ "application": [...],
51
+ "infrastructure": [...],
52
+ "api": [...],
53
+ "frontend": [...],
54
+ "seedData": [...],
55
+ "tests": [...]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ **Wrong Structure (v2.x legacy):**
62
+ ```json
63
+ {
64
+ "$version": "3.0.0",
65
+ "filesToCreate": { // ❌ WRONG - at root level
66
+ "domain": [...]
67
+ }
68
+ }
69
+ ```
70
+
71
+ **Validation:**
72
+ - IF `prd.filesToCreate` exists at root level → BLOCKING ERROR
73
+ - IF `prd.implementation.filesToCreate` missing → BLOCKING ERROR
74
+
75
+ **Fix Command:**
76
+ ```bash
77
+ ss derive-prd --feature {path} --output .ralph/prd-{moduleCode}.json
78
+ ```
79
+
80
+ ---
81
+
82
+ ### 3. Seven Categories (MANDATORY)
83
+
84
+ All PRD files MUST include these 7 categories under `implementation.filesToCreate`:
85
+
86
+ | Category | Description | Examples |
87
+ |----------|-------------|----------|
88
+ | **domain** | Domain entities, value objects, domain services | `Project.cs`, `ProjectStatus.cs` |
89
+ | **application** | Application services, DTOs, interfaces | `ProjectService.cs`, `CreateProjectDto.cs` |
90
+ | **infrastructure** | Data access, repositories, EF Core config | `ProjectRepository.cs`, `ProjectConfiguration.cs` |
91
+ | **api** | Controllers, API endpoints | `ProjectsController.cs` |
92
+ | **frontend** | React pages, components, hooks | `ProjectsPage.tsx`, `useProjects.ts` |
93
+ | **seedData** | Seed data classes | `ProjectSeedData.cs` |
94
+ | **tests** | Unit tests, integration tests | `ProjectServiceTests.cs`, `ProjectsControllerTests.cs` |
95
+
96
+ **Validation:**
97
+ ```javascript
98
+ const categories = ['domain', 'application', 'infrastructure', 'api', 'frontend', 'seedData', 'tests'];
99
+ const missingCategories = categories.filter(cat => !prd.implementation.filesToCreate[cat]);
100
+
101
+ if (missingCategories.length > 0) {
102
+ BLOCKING_ERROR(`Missing categories: ${missingCategories.join(', ')}`);
103
+ }
104
+ ```
105
+
106
+ **Common Errors:**
107
+ - Missing `tests` category → often forgotten
108
+ - Missing `seedData` category → sometimes omitted for modules without seed data
109
+ - Empty arrays allowed (e.g., `"seedData": []`) if genuinely no files needed
110
+
111
+ ---
112
+
113
+ ### 4. File Count Consistency (MANDATORY)
114
+
115
+ **Validation:** PRD file counts MUST match feature.json handoff counts.
116
+
117
+ ```javascript
118
+ const featureHandoff = moduleFeature.handoff.filesToCreate;
119
+ const categories = ['domain', 'application', 'infrastructure', 'api', 'frontend', 'seedData', 'tests'];
120
+
121
+ for (const cat of categories) {
122
+ const prdCount = prd.implementation.filesToCreate[cat]?.length ?? 0;
123
+ const featureCount = featureHandoff[cat]?.length ?? 0;
124
+
125
+ if (prdCount !== featureCount) {
126
+ BLOCKING_ERROR(`${cat}: prd has ${prdCount} files but feature.json has ${featureCount}`);
127
+ }
128
+ }
129
+ ```
130
+
131
+ **Why this matters:**
132
+ - Ensures PRD was derived from the correct feature.json
133
+ - Catches stale PRD files (derived from old version)
134
+ - Validates handoff integrity before ralph-loop
135
+
136
+ **Fix:**
137
+ - Re-derive PRD from latest feature.json
138
+ - Check that feature.json handoff section is complete
139
+
140
+ ---
141
+
142
+ ### 5. File Entry Schema
143
+
144
+ Each file entry in a category array must have:
145
+
146
+ ```json
147
+ {
148
+ "path": "src/SmartStack.HumanResources.Domain/Projects/Project.cs",
149
+ "type": "Entity",
150
+ "module": "Projects"
151
+ }
152
+ ```
153
+
154
+ **Required Fields:**
155
+ - `path` (string): Absolute or relative path where file will be created
156
+ - `type` (string): File type hint (Entity, Service, Controller, Page, Test, etc.)
157
+ - `module` (string): Module code this file belongs to
158
+
159
+ **Optional Fields:**
160
+ - `description` (string): Brief description of what the file does
161
+ - `dependencies` (array): Other files this depends on
162
+
163
+ ---
164
+
165
+ ## Validation Checklist
166
+
167
+ Use this checklist when validating PRD files:
168
+
169
+ | Check | Validation | Status |
170
+ |-------|-----------|--------|
171
+ | **Version** | `$version === "3.0.0"` | PASS/FAIL |
172
+ | **Structure** | `implementation.filesToCreate` exists (not root) | PASS/FAIL |
173
+ | **Categories** | All 7 categories present | PASS/FAIL |
174
+ | **File Counts** | PRD counts match feature.json handoff | PASS/FAIL |
175
+ | **File Schemas** | All files have path, type, module | PASS/FAIL |
176
+
177
+ **All checks must PASS before proceeding to /ralph-loop**
178
+
179
+ ---
180
+
181
+ ## Common Errors & Fixes
182
+
183
+ ### Error 1: Wrong Version
184
+ ```
185
+ BLOCKING_ERROR: PRD version must be 3.0.0, got: 2.1.0
186
+ ```
187
+ **Fix:** Re-run `ss derive-prd` with latest SmartStack.mcp version
188
+
189
+ ### Error 2: filesToCreate at Root Level
190
+ ```
191
+ BLOCKING_ERROR: filesToCreate is at ROOT level (wrong structure)
192
+ ```
193
+ **Fix:** Re-run `ss derive-prd --feature {path} --output .ralph/prd-{moduleCode}.json`
194
+
195
+ ### Error 3: Missing Categories
196
+ ```
197
+ BLOCKING_ERROR: Missing categories: seedData, tests
198
+ ```
199
+ **Fix:**
200
+ - Check feature.json handoff.filesToCreate has all 7 categories
201
+ - Re-derive PRD after fixing feature.json
202
+ - If genuinely no files needed, use empty array: `"seedData": []`
203
+
204
+ ### Error 4: File Count Mismatch
205
+ ```
206
+ BLOCKING_ERROR: api: prd has 8 files but feature.json has 12
207
+ ```
208
+ **Fix:**
209
+ - PRD is stale (derived from old feature.json)
210
+ - Re-derive PRD from latest feature.json: `ss derive-prd --feature {path} --output .ralph/prd-{moduleCode}.json`
211
+
212
+ ---
213
+
214
+ ## Generation Command Reference
215
+
216
+ **Derive PRD from feature.json:**
217
+ ```bash
218
+ ss derive-prd \
219
+ --feature docs/business/{App}/{Module}/business-analyse/v1.0/feature.json \
220
+ --output .ralph/prd-{ModuleCode}.json
221
+ ```
222
+
223
+ **Example:**
224
+ ```bash
225
+ ss derive-prd \
226
+ --feature docs/business/HumanResources/Projects/business-analyse/v1.0/feature.json \
227
+ --output .ralph/prd-Projects.json
228
+ ```
229
+
230
+ **Batch generation for all modules:**
231
+ ```bash
232
+ # Typically done in step-05a-handoff.md
233
+ for module in $(modules); do
234
+ ss derive-prd --feature {module_feature_path} --output .ralph/prd-${module}.json
235
+ done
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Why PRD Validation Matters
241
+
242
+ | Risk | Without Validation | With Validation |
243
+ |------|-------------------|-----------------|
244
+ | **Wrong structure** | ralph-loop fails mid-execution | Caught before development starts |
245
+ | **Stale PRD** | Generates code from old spec | Detects version mismatch |
246
+ | **Missing files** | Incomplete implementation | Ensures all layers covered |
247
+ | **Count mismatch** | Silent data loss | Guarantees integrity |
248
+
249
+ **Bottom line:** Ralph-loop depends on correct PRD structure. Validating upfront saves hours of debugging.
250
+
251
+ ---
252
+
253
+ ## Related Files
254
+
255
+ - `step-05a-handoff.md`: Generates PRD files via `ss derive-prd`
256
+ - `step-05c-ralph-readiness.md`: Validates PRD structure before ralph-loop
257
+ - `feature-schema.json`: Schema for feature.json (source of PRD)
258
+ - `/ralph-loop` skill: Consumes PRD files for implementation