@atlashub/smartstack-cli 3.17.0 → 3.18.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlashub/smartstack-cli",
3
- "version": "3.17.0",
3
+ "version": "3.18.0",
4
4
  "description": "SmartStack Claude Code automation toolkit - GitFlow, EF Core migrations, prompts and more",
5
5
  "author": {
6
6
  "name": "SmartStack",
@@ -209,7 +209,7 @@ When step-00 detects that the description matches an existing application:
209
209
  | 04c | `steps/step-04c-decide.md` | Opus | Final approval, write consolidation, proceed to handoff |
210
210
  | 05a | `steps/step-05a-handoff.md` | Sonnet | Handoff: file mapping (7 categories), BR-to-code mapping, API summary, write handoff |
211
211
  | 05b | `steps/step-05b-deploy.md` | Sonnet | Deploy: prd.json, progress.txt, manifest, ba-interactive.html |
212
- | 05c | `steps/step-05c-ralph-readiness.md` | Sonnet | Ralph readiness validation gate (optional but recommended) |
212
+ | 05c | `steps/step-05c-ralph-readiness.md` | Opus | ULTRATHINK quality review + ralph readiness gate (MANDATORY) |
213
213
  | 06 | `steps/step-06-review.md` | Opus | Apply review corrections, create new version, regenerate all artifacts |
214
214
 
215
215
  </step_files>
@@ -252,10 +252,10 @@ Load ONLY relevant categories based on feature type:
252
252
  | -------- | ----------------------------------- | ------------ |
253
253
  | schema | `schemas/feature-schema.json` | All steps |
254
254
  | spec | `templates/tpl-frd.md` | 02 |
255
- | handoff | `templates/tpl-handoff.md` | 04 |
255
+ | handoff | `templates/tpl-handoff.md` | 05a |
256
256
  | suggestions | `patterns/suggestion-catalog.md` | 01 |
257
- | interactive | `html/ba-interactive.html` | 03d (incremental), 05d (final deploy) |
258
- | mapping | `references/html-data-mapping.md` | 03d, 05d (FEATURE_DATA + EMBEDDED_ARTIFACTS mapping) |
257
+ | interactive | `html/ba-interactive.html` | 03d (incremental), 05b (final deploy) |
258
+ | mapping | `references/html-data-mapping.md` | 03d, 05b (FEATURE_DATA + EMBEDDED_ARTIFACTS mapping) |
259
259
 
260
260
  </template_files>
261
261
 
@@ -374,12 +374,30 @@ If initialization was interrupted:
374
374
 
375
375
  1. Check `.business-analyse/config.json` for currentFeature
376
376
  2. If feature ID exists, search for feature.json in `docs/business/`
377
- 3. If found, check `metadata.workflow.lastCompletedStep`:
378
- - If `"step-04-consolidation"` AND status = `"consolidated"`:
379
- Resume directly at `step-05a-handoff.md` (skip steps 00-04)
380
- → Display: "Resuming from consolidation — proceeding to handoff..."
377
+ 3. If found, check status and `metadata.workflow.lastCompletedStep`:
378
+
379
+ **Status-based resume routing (check in this order):**
380
+
381
+ - If status = `"handed-off"` AND `ba-interactive.html` missing:
382
+ → Resume at `step-05b-deploy.md` (deploy artifacts + HTML)
383
+ → Display: "Handoff complete but HTML/artifacts missing — deploying..."
384
+
381
385
  - If status = `"handed-off"` AND `.ralph/prd-*.json` files missing:
382
386
  → Resume at `step-05b-deploy.md` (only deploy artifacts needed)
383
- → Display: "Handoff complete but artifacts missing — deploying..."
387
+ → Display: "Handoff complete but PRD files missing — deploying..."
388
+
389
+ - If status = `"consolidated"` OR lastCompletedStep = `"step-04-consolidation"`:
390
+ → Resume directly at `step-05a-handoff.md` (skip steps 00-04)
391
+ → Display: "Resuming from consolidation — proceeding to handoff..."
392
+
393
+ - If status = `"specified"` AND `metadata.workflow.allModulesSpecified === true`:
394
+ → Resume at `step-04a-collect.md` (consolidation phase)
395
+ → Display: "All modules specified — resuming at consolidation..."
396
+
397
+ - If status = `"specified"` AND `metadata.workflow.completedModules.length > 0` AND `metadata.workflow.completedModules.length < metadata.workflow.moduleOrder.length`:
398
+ → Resume at `step-03a1-setup.md` (continue specifying remaining modules)
399
+ → Display: "Resuming module specification ({completedCount}/{totalCount})..."
400
+
384
401
  - Otherwise: offer to resume from last completed step
402
+
385
403
  4. If not found, create fresh feature.json
@@ -165,6 +165,24 @@ ELSE:
165
165
 
166
166
  ---
167
167
 
168
+ ### 9g. Anti-Premature-Completion Guard (MANDATORY)
169
+
170
+ > **CRITICAL — NEVER say "the analysis is complete" or "ready for /ralph-loop" at this point.**
171
+ > Step-03d is the END of SPECIFICATION, NOT the end of the BA workflow.
172
+ > Steps 04a → 04b → 04c (consolidation) + 05a → 05b → 05c (handoff) are STILL REQUIRED.
173
+ > Without handoff, /ralph-loop will generate an INCOMPLETE PRD (no frontend, no tests).
174
+
175
+ **FORBIDDEN phrases in step-03d output:**
176
+ - "L'analyse métier est complète" / "The business analysis is complete"
177
+ - "Prêt pour /ralph-loop" / "Ready for /ralph-loop"
178
+ - "Vous pouvez maintenant lancer /ralph-loop"
179
+ - Any variation suggesting the BA is finished or /ralph-loop can be invoked
180
+
181
+ **REQUIRED phrasing:**
182
+ - "Module {name} spécifié. {Remaining} modules restants." (if more modules)
183
+ - "Tous les modules spécifiés. Passage à la consolidation (étapes 04a-04c)..." (if last module)
184
+ - NEVER mention /ralph-loop — only step-05c (ralph readiness) validates the handoff
185
+
168
186
  ### 10. Module Summary with Roles & Permissions
169
187
 
170
188
  Display comprehensive summary:
@@ -286,8 +304,23 @@ IF currentModuleIndex < moduleOrder.length:
286
304
  Load: steps/step-03a1-setup.md
287
305
 
288
306
  IF currentModuleIndex >= moduleOrder.length:
289
- Display: "═══ Tous les modules spécifiés! Passage à la consolidation... ═══"
307
+ Display: "═══ Tous les modules spécifiés! Passage à la consolidation (04a→04c) puis handoff (05a→05c)... ═══"
308
+ Display: "⚠ NE PAS lancer /ralph-loop — la consolidation et le handoff sont encore nécessaires."
290
309
  ba-writer.updateStatus({feature_id}, "specified")
310
+
311
+ // CHECKPOINT: Save progress BEFORE transition (protects against context exhaustion)
312
+ ba-writer.enrichSection({
313
+ featureId: {feature_id},
314
+ section: "metadata.workflow",
315
+ data: {
316
+ lastCompletedStep: "step-03d-validate",
317
+ allModulesSpecified: true
318
+ }
319
+ })
320
+
321
+ // MANDATORY TRANSITION — DO NOT STOP HERE
322
+ // If context is near exhaustion, the checkpoint above ensures the user
323
+ // can resume with /business-analyse and it will route to step-04a automatically.
291
324
  Load: steps/step-04a-collect.md
292
325
  ```
293
326
 
@@ -360,10 +360,9 @@ Effort: {total_days} days ({total_hours} hours)
360
360
  1. Ouvrir ba-interactive.html dans le navigateur
361
361
  2. Partager avec les stakeholders pour validation
362
362
  3. Si retours --> relancer /business-analyse pour une nouvelle itération
363
- 4. Validation de la compatibilité ralph-loop (recommandé):
363
+ 4. Validation qualité ULTRATHINK (automatique):
364
364
 
365
- Continuez à step-05c-ralph-readiness.md pour valider
366
- la complétude et l'intégrité avant développement
365
+ Lancement automatique de step-05c-ralph-readiness.md...
367
366
 
368
367
  5. Une fois validé, lancer le développement:
369
368
 
@@ -376,16 +375,19 @@ Effort: {total_days} days ({total_hours} hours)
376
375
 
377
376
  ## NEXT STEP
378
377
 
379
- **RECOMMENDED:** Load `steps/step-05c-ralph-readiness.md` to run validation gate before /ralph-loop.
378
+ **MANDATORY:** Load `steps/step-05c-ralph-readiness.md` ULTRATHINK quality review & readiness gate.
379
+
380
+ > **This step is NON-NEGOTIABLE.** The BA skill MUST run step-05c before completing.
381
+ > DO NOT skip this step. DO NOT display a "done" message without running step-05c first.
380
382
 
381
383
  This validation ensures:
382
- - All module handoffs are complete
384
+ - ULTRATHINK deep quality review of the entire BA output
385
+ - All module handoffs are complete and content is coherent
383
386
  - PRD files are structurally valid
384
387
  - Cross-module references are resolvable
388
+ - Specification quality meets production standards
385
389
  - No blocking issues before development
386
390
 
387
- User can skip validation and proceed directly to /ralph-loop, but validation is strongly recommended to catch issues early.
388
-
389
391
  ---
390
392
 
391
393
  ## MODE SUPPORT & TROUBLESHOOTING
@@ -1,16 +1,17 @@
1
1
  ---
2
2
  name: step-05c-ralph-readiness
3
- description: Validation gate before ralph-loop - verify completeness, integrity, and readiness
4
- model: sonnet
3
+ description: ULTRATHINK quality review + validation gate before ralph-loop
4
+ model: opus
5
5
  next_step: null
6
6
  ---
7
7
 
8
8
  > **Context files:** `_shared.md`
9
9
 
10
- # Step 5c: Ralph Readiness Check
10
+ # Step 5c: ULTRATHINK Quality Review & Ralph Readiness Check
11
11
 
12
12
  ## MANDATORY EXECUTION RULES
13
13
 
14
+ - **ALWAYS** use ULTRATHINK mode for the quality review (section 0b)
14
15
  - **ALWAYS** run ALL validation checks (NEVER skip)
15
16
  - **BLOCKING RULE:** If ANY check fails → STOP, DO NOT proceed to ralph-loop
16
17
  - **ALWAYS** provide actionable fix instructions for failures
@@ -19,7 +20,7 @@ next_step: null
19
20
 
20
21
  ## YOUR TASK
21
22
 
22
- Perform comprehensive validation to ensure the business analysis is ready for implementation via /ralph-loop. This is a **BLOCKING** gate - all checks must pass before development can proceed.
23
+ Perform a deep ULTRATHINK quality review of the entire business analysis output, then run comprehensive structural validation to ensure readiness for /ralph-loop. This is a **BLOCKING** gate all checks must pass before development can proceed.
23
24
 
24
25
  ---
25
26
 
@@ -31,9 +32,177 @@ Display validation banner:
31
32
 
32
33
  ```
33
34
  ═══════════════════════════════════════════════════════════════
34
- RALPH READINESS CHECK - {application_name}
35
+ ULTRATHINK QUALITY REVIEW & RALPH READINESS CHECK
36
+ {application_name}
35
37
  ═══════════════════════════════════════════════════════════════
36
- Validating business analysis completeness before development...
38
+ Phase 1: Deep quality review (ULTRATHINK)...
39
+ Phase 2: Structural validation (8 checks)...
40
+ ```
41
+
42
+ ---
43
+
44
+ ### 0b. ULTRATHINK Deep Quality Review (MANDATORY)
45
+
46
+ > **This section MUST be executed in ULTRATHINK mode.**
47
+ > Take the time to deeply analyze the ENTIRE business analysis output.
48
+ > This is the last chance to catch quality issues before development begins.
49
+
50
+ **Objective:** Perform a thorough, deep-thinking review of the business analysis quality — not just structural checks, but semantic coherence, completeness, and production-readiness.
51
+
52
+ **Process:**
53
+
54
+ 1. **Read ALL module feature.json files** (master + each module)
55
+ 2. **Activate ULTRATHINK** and analyze the following 6 dimensions:
56
+
57
+ #### Dimension 1: Specification Coherence
58
+
59
+ ```
60
+ For EACH module:
61
+ - Do use cases (UCs) tell a coherent story?
62
+ - Are functional requirements (FRs) logically derived from UCs?
63
+ - Do business rules (BRs) cover all edge cases mentioned in UCs?
64
+ - Are gherkin scenarios testing the RIGHT behaviors (not trivial CRUD)?
65
+ - Do entity relationships make domain sense?
66
+
67
+ Flag: Orphan FRs (not linked to any UC), UCs with no FR coverage,
68
+ BRs that don't map to any entity/field
69
+ ```
70
+
71
+ #### Dimension 2: Permission & Security Model
72
+
73
+ ```
74
+ For EACH module:
75
+ - Is the permission hierarchy logical? (admin > manager > contributor > viewer)
76
+ - Are there actions that should be restricted but aren't?
77
+ - Do API endpoints all have permissions assigned?
78
+ - Are there over-permissive roles? (e.g., contributor with delete access)
79
+ - Cross-module: can a user in Module A access data in Module B through indirect routes?
80
+
81
+ Flag: Endpoints without permissions, roles with excessive access,
82
+ missing permission paths
83
+ ```
84
+
85
+ #### Dimension 3: Data Model Integrity
86
+
87
+ ```
88
+ For EACH module:
89
+ - Are all entity relationships bidirectional where needed?
90
+ - Are FK references correct (target entity exists, correct field type)?
91
+ - Are there missing audit fields (CreatedAt, UpdatedAt, CreatedBy)?
92
+ - Do lifecycle states cover all business scenarios?
93
+ - Are cascade delete/update rules safe? (no orphan risk)
94
+
95
+ Cross-module:
96
+ - Are shared entity references correct?
97
+ - Is the dependency graph honest? (no hidden dependencies)
98
+
99
+ Flag: Missing relationships, unsafe cascades, missing audit fields,
100
+ hidden cross-module dependencies
101
+ ```
102
+
103
+ #### Dimension 4: UI/UX Completeness
104
+
105
+ ```
106
+ For EACH module:
107
+ - Does every section have at least one wireframe?
108
+ - Do wireframes cover ALL use cases? (no UC without UI representation)
109
+ - Are navigation entries correct and complete?
110
+ - Do wireframe actions map to real API endpoints?
111
+ - Are form fields aligned with entity attributes?
112
+ - Are validation rules defined for all user-input fields?
113
+
114
+ Flag: UCs with no wireframe, wireframes with unmapped actions,
115
+ missing form validations, navigation gaps
116
+ ```
117
+
118
+ #### Dimension 5: i18n & Messages Quality
119
+
120
+ ```
121
+ For EACH module:
122
+ - Are all user-facing strings covered by i18n keys?
123
+ - Are error messages specific enough? (not generic "Error occurred")
124
+ - Do validation messages reference the field name?
125
+ - Are success/confirmation messages present for all write operations?
126
+ - Are there missing translations in any language?
127
+
128
+ Flag: Generic error messages, missing field-specific validations,
129
+ incomplete language coverage
130
+ ```
131
+
132
+ #### Dimension 6: Implementation Feasibility
133
+
134
+ ```
135
+ For EACH module:
136
+ - Is the handoff.filesToCreate list realistic? (no missing files, no impossible paths)
137
+ - Do brToCodeMapping entries have enough detail for generation?
138
+ - Are API endpoint paths following REST conventions?
139
+ - Are DTO structures aligned with entity attributes?
140
+ - Is the seed data sufficient for testing all use cases?
141
+ - Are there any features that would require infrastructure not in the stack?
142
+
143
+ Flag: Unrealistic file counts, vague BR mappings, non-RESTful routes,
144
+ missing seed data for critical test scenarios
145
+ ```
146
+
147
+ 3. **Produce Quality Verdict:**
148
+
149
+ ```
150
+ ═══════════════════════════════════════════════════════════════
151
+ ULTRATHINK QUALITY REVIEW - RESULTS
152
+ ═══════════════════════════════════════════════════════════════
153
+
154
+ | Dimension | Score | Issues |
155
+ |-----------|-------|--------|
156
+ | Specification Coherence | A/B/C/D | {count} issues |
157
+ | Permission & Security | A/B/C/D | {count} issues |
158
+ | Data Model Integrity | A/B/C/D | {count} issues |
159
+ | UI/UX Completeness | A/B/C/D | {count} issues |
160
+ | i18n & Messages | A/B/C/D | {count} issues |
161
+ | Implementation Feasibility | A/B/C/D | {count} issues |
162
+
163
+ Overall Quality: {A/B/C/D}
164
+ A = Production-ready (0 critical, ≤3 warnings)
165
+ B = Good (0 critical, >3 warnings)
166
+ C = Needs fixes (1-2 critical issues)
167
+ D = Major rework needed (>2 critical issues)
168
+ ```
169
+
170
+ 4. **Display Issues (if any):**
171
+
172
+ ```
173
+ Critical Issues (MUST fix before /ralph-loop):
174
+ ✗ [Dimension] Issue description
175
+ → Fix: Specific action to resolve
176
+
177
+ Warnings (SHOULD fix, not blocking):
178
+ ⚠ [Dimension] Issue description
179
+ → Recommendation: How to improve
180
+
181
+ Suggestions (nice-to-have):
182
+ ℹ [Dimension] Suggestion
183
+ ```
184
+
185
+ 5. **Decision:**
186
+
187
+ ```
188
+ IF overall quality = D:
189
+ BLOCKING ERROR: Major quality issues detected
190
+ → Return to appropriate step to fix critical issues
191
+ → DO NOT proceed to structural validation
192
+
193
+ IF overall quality = C:
194
+ Ask via AskUserQuestion:
195
+ question: "Des problèmes de qualité ont été détectés. Comment souhaitez-vous procéder ?"
196
+ header: "Qualité"
197
+ options:
198
+ - label: "Corriger les problèmes critiques"
199
+ description: "Retourner aux étapes concernées pour corriger"
200
+ - label: "Continuer malgré les problèmes"
201
+ description: "Accepter les risques et poursuivre la validation structurelle"
202
+
203
+ IF overall quality = A or B:
204
+ Display: "✓ Quality review passed — proceeding to structural validation..."
205
+ → Continue to section 1
37
206
  ```
38
207
 
39
208
  ---
@@ -394,10 +563,11 @@ Progress Tracker Validation:
394
563
 
395
564
  **Process:**
396
565
 
397
- 1. Aggregate all validation results
566
+ 1. Aggregate all validation results (quality review + 7 structural checks)
398
567
  2. Calculate readiness score:
399
568
  ```
400
569
  passedChecks / totalChecks * 100
570
+ Quality gate: overall quality must be A or B
401
571
  ```
402
572
 
403
573
  3. Display final report:
@@ -407,17 +577,23 @@ Progress Tracker Validation:
407
577
  RALPH READINESS CHECK - COMPLETE
408
578
  ═══════════════════════════════════════════════════════════════
409
579
 
410
- Validation Summary:
411
- Module status validation: PASS (5/5 modules)
412
- ✓ PRD files validation: PASS (5/5 files)
413
- Dependency graph validation: PASS (4 edges)
414
- ✓ Cross-module references validation: PASS (4 references)
415
- ✓ Handoff completeness check: PASS (5/5 modules)
416
- i18n keys validation: WARNING (1 missing translation)
580
+ ULTRATHINK Quality Review:
581
+ Quality Score: {A/B} {Production-ready / Good}
582
+ Dimensions: {6/6 reviewed}
583
+ Critical issues: {0}
584
+ Warnings: {count}
585
+
586
+ Structural Validation Summary:
587
+ ✓ Module status validation: PASS ({n}/{n} modules)
588
+ ✓ PRD files validation: PASS ({n}/{n} files)
589
+ ✓ Dependency graph validation: PASS ({n} edges)
590
+ ✓ Cross-module references validation: PASS ({n} references)
591
+ ✓ Handoff completeness check: PASS ({n}/{n} modules)
592
+ ⚠ i18n keys validation: WARNING ({n} missing translation)
417
593
  ✓ Master feature validation: PASS
418
594
  ✓ Progress tracker validation: PASS
419
595
 
420
- Readiness Score: 100% (7/7 critical checks passed, 1 warning)
596
+ Readiness Score: 100% (8/8 checks passed, {n} warnings)
421
597
 
422
598
  ═══════════════════════════════════════════════════════════════
423
599
 
@@ -425,7 +601,7 @@ Status: READY FOR DEVELOPMENT ✓
425
601
 
426
602
  Next Steps:
427
603
  1. Address warnings (recommended but not blocking):
428
- - Add missing DE translation for "timeEntry.validation.overlapping" in TimeTracking module
604
+ - {list warnings from quality review + structural checks}
429
605
 
430
606
  2. Review progress tracker: .ralph/progress.txt
431
607
 
@@ -434,14 +610,14 @@ Next Steps:
434
610
  /ralph-loop -r
435
611
 
436
612
  4. Ralph-loop will:
437
- - Process modules in topological order: [Projects, TimeTracking, LeaveManagement, AbsenceManagement, Reporting]
438
- - Generate 183 files across 7 layers
439
- - Execute 247 tasks tracked in progress.txt
613
+ - Process modules in topological order: [{module list}]
614
+ - Generate {n} files across 7 layers
615
+ - Execute {n} tasks tracked in progress.txt
440
616
 
441
617
  ═══════════════════════════════════════════════════════════════
442
618
  ```
443
619
 
444
- **IF readiness score < 100% (critical checks failed):**
620
+ **IF readiness score < 100% OR quality = C/D (critical checks failed):**
445
621
 
446
622
  ```
447
623
  ═══════════════════════════════════════════════════════════════
@@ -450,21 +626,24 @@ Next Steps:
450
626
 
451
627
  Status: NOT READY FOR DEVELOPMENT ✗
452
628
 
453
- Critical Issues Found:
454
- Module status validation: FAIL (1/5 modules incomplete)
455
- - Reporting module status is "specified", must be "handed-off"
456
- - Fix: Return to step-05a-handoff.md for Reporting module
629
+ {IF quality = C/D:}
630
+ Quality Issues Found:
631
+ ULTRATHINK quality review: {C/D} {Needs fixes / Major rework}
632
+ - {List critical quality issues from section 0b}
633
+ - Fix: Return to appropriate step (see quality review details above)
457
634
 
458
- PRD files validation: FAIL (1/5 files invalid)
459
- - prd-Reporting.json has wrong structure (filesToCreate at root level)
460
- - Fix: Re-run ss derive-prd --feature docs/business/HumanResources/Reporting/business-analyse/v1.0/feature.json --output .ralph/prd-Reporting.json
635
+ {IF structural checks failed:}
636
+ Structural Issues Found:
637
+ {check name}: FAIL ({details})
638
+ - {specific issue}
639
+ - Fix: {specific action}
461
640
 
462
641
  Required Actions:
463
642
  1. Fix all critical issues listed above
464
643
  2. Re-run validation: load step-05c-ralph-readiness.md
465
- 3. Only proceed to /ralph-loop when all critical checks pass
644
+ 3. Only proceed to /ralph-loop when all checks pass AND quality ≥ B
466
645
 
467
- DO NOT PROCEED TO /ralph-loop UNTIL ALL CRITICAL CHECKS PASS
646
+ DO NOT PROCEED TO /ralph-loop UNTIL ALL CHECKS PASS
468
647
  ═══════════════════════════════════════════════════════════════
469
648
  ```
470
649
 
@@ -474,22 +653,25 @@ DO NOT PROCEED TO /ralph-loop UNTIL ALL CRITICAL CHECKS PASS
474
653
 
475
654
  Before displaying final report, VERIFY:
476
655
 
477
- 1. **ALL validation checks executed** (never skip)
478
- 2. **Results clearly marked** (PASS/FAIL/WARNING)
479
- 3. **Actionable fixes provided** for all failures
480
- 4. **Readiness score calculated** correctly
481
- 5. **Next steps displayed** with exact commands
482
- 6. **Blocking errors prevent progression** (no false positives)
656
+ 1. **ULTRATHINK quality review executed** (6 dimensions analyzed)
657
+ 2. **Quality verdict displayed** with scores per dimension
658
+ 3. **ALL 8 structural validation checks executed** (never skip)
659
+ 4. **Results clearly marked** (PASS/FAIL/WARNING)
660
+ 5. **Actionable fixes provided** for all failures
661
+ 6. **Readiness score calculated** correctly
662
+ 7. **Next steps displayed** with exact commands
663
+ 8. **Blocking errors prevent progression** (no false positives)
483
664
 
484
665
  ---
485
666
 
486
667
  ## SUCCESS CRITERIA
487
668
 
488
- - All 7 critical validation checks executed
669
+ - ULTRATHINK quality review completed with overall score A or B
670
+ - All 8 critical validation checks executed (quality review + 7 structural)
489
671
  - Clear PASS/FAIL/WARNING status for each check
490
672
  - Readiness score displayed (100% = all critical checks passed)
491
673
  - Actionable fix instructions for all failures
492
- - User can proceed to /ralph-loop only if readiness score = 100%
674
+ - User can proceed to /ralph-loop only if readiness score = 100% AND quality ≥ B
493
675
  - Warnings documented but not blocking
494
676
 
495
677
  ---
@@ -498,6 +680,7 @@ Before displaying final report, VERIFY:
498
680
 
499
681
  **Why this gate matters:**
500
682
 
683
+ - **ULTRATHINK catches semantic issues** that structural checks miss (orphan UCs, incoherent permissions, missing UI flows)
501
684
  - Prevents incomplete handoffs from reaching development
502
685
  - Catches structural issues early (PRD validation)
503
686
  - Verifies cross-module integrity before code generation
@@ -506,8 +689,7 @@ Before displaying final report, VERIFY:
506
689
 
507
690
  **When to run this gate:**
508
691
 
509
- - Automatically at end of step-05b-deploy.md (recommended)
510
- - Manually before /ralph-loop if user wants to verify
692
+ - **Automatically at end of step-05b-deploy.md (MANDATORY)**
511
693
  - After fixing any handoff issues to re-validate
512
694
 
513
695
  **What happens if checks fail:**
@@ -515,4 +697,4 @@ Before displaying final report, VERIFY:
515
697
  - Development is BLOCKED until issues are fixed
516
698
  - User returns to appropriate step to fix issues
517
699
  - Re-run validation after fixes
518
- - Only proceed when all critical checks pass
700
+ - Only proceed when all critical checks pass AND quality review passes
@@ -95,8 +95,41 @@ LOAD → GENERATE → COMPILE → TEST → [FAIL?] → FIX → RE-TEST → [PASS
95
95
  - `scaffold_tests` — test generation
96
96
  </mcp_requirements>
97
97
 
98
+ <execution_guarantee>
99
+
100
+ ## EXECUTION GUARANTEE — READ THIS FIRST
101
+
102
+ **Ralph-loop executes ALL tasks from start to finish. No exceptions.**
103
+
104
+ When the user invokes `/ralph-loop`, they are giving you the instruction to:
105
+ 1. Initialize the loop (step-00)
106
+ 2. Load ALL tasks (step-01)
107
+ 3. Execute the FIRST task (step-02)
108
+ 4. Commit (step-03)
109
+ 5. Enter the COMPACT LOOP (step-04 → compact-loop.md)
110
+ 6. **Execute ALL remaining tasks autonomously** (compact loop repeats)
111
+ 7. Generate the final report (step-05)
112
+
113
+ **You MUST NOT:**
114
+ - Stop after the first task to "ask for confirmation"
115
+ - Set `max_iterations = 1` or any reduced value
116
+ - Ask the user to choose between supervised/autonomous mode
117
+ - Ask the user to choose a completion promise
118
+ - Wait for user input between iterations
119
+ - Delegate the loop to sub-agents (except team mode)
120
+
121
+ **The ONLY valid stop conditions are:**
122
+ - ALL tasks completed (→ step-05 report)
123
+ - `max_iterations` reached (user set via `-m N`)
124
+ - Dead-end (all remaining blocked/failed)
125
+ - User Ctrl+C
126
+
127
+ **If you stop for any other reason, you have VIOLATED this guarantee.**
128
+
129
+ </execution_guarantee>
130
+
98
131
  <entry_point>
99
- **FIRST ACTION:** Load `steps/step-00-init.md`
132
+ **FIRST ACTION:** Load `steps/step-00-init.md` — then execute ALL steps through to step-05 without stopping.
100
133
  </entry_point>
101
134
 
102
135
  <step_files>
@@ -134,6 +167,13 @@ LOAD → GENERATE → COMPILE → TEST → [FAIL?] → FIX → RE-TEST → [PASS
134
167
 
135
168
  <execution_rules>
136
169
 
170
+ ### NON-NEGOTIABLE — Autonomous Full Execution
171
+ - **EXECUTE ALL TASKS** — from first to last, no user interaction, no pause, no confirmation
172
+ - **NEVER ask the user** — no mode selection, no completion promise choice, no "shall I continue?"
173
+ - **NEVER stop after first task** — the first task is just the beginning, NOT the end
174
+ - **NEVER set max_iterations = 1** — unless the user explicitly passed `-m 1`
175
+
176
+ ### Loop Mechanics
137
177
  - **Single module:** Main agent runs compact loop (NEVER delegate to sub-agent)
138
178
  - **Multi-module (2+):** Team lead + module workers via TeamCreate (see references/team-orchestration.md)
139
179
  - **Load step files ONCE** — after first iteration, use compact-loop.md
@@ -141,13 +141,86 @@ Rules:
141
141
  - DTOs separate from domain entities
142
142
  - Service interfaces in Application, implementations in Infrastructure
143
143
 
144
- **Tenant isolation (BLOCKING):**
144
+ **Tenant isolation (BLOCKING — SECURITY CRITICAL):**
145
+
146
+ > **ROOT CAUSE (test-v4-005):** Services were generated WITHOUT TenantId filtering,
147
+ > creating cross-tenant data leakage on ALL 70+ CRUD endpoints.
148
+ > This is an OWASP A01 (Broken Access Control) vulnerability.
149
+
145
150
  - ALL queries on tenant entities MUST include `.Where(x => x.TenantId == _currentUser.TenantId)`
146
151
  - ALL entity creation MUST pass `_currentUser.TenantId` as first parameter to `Entity.Create(tenantId, ...)`
147
152
  - NEVER use `new Entity { }` without `TenantId =` — always prefer factory method `Entity.Create()`
148
153
  - NEVER use `Guid.Empty` as a placeholder for userId, tenantId, or any business identifier
149
154
  - Service constructor MUST inject `ICurrentUserService _currentUser` to access TenantId
150
155
 
156
+ **MANDATORY Service Template (use as skeleton for ALL services):**
157
+
158
+ ```csharp
159
+ public class {Entity}Service : I{Entity}Service
160
+ {
161
+ private readonly IExtensionsDbContext _db;
162
+ private readonly ICurrentUserService _currentUser;
163
+
164
+ public {Entity}Service(IExtensionsDbContext db, ICurrentUserService currentUser)
165
+ {
166
+ _db = db;
167
+ _currentUser = currentUser;
168
+ }
169
+
170
+ public async Task<PagedResult<{Entity}Response>> GetAllAsync(/* filters */, CancellationToken ct)
171
+ {
172
+ var tenantId = _currentUser.TenantId;
173
+ var query = _db.{Entities}
174
+ .Where(x => x.TenantId == tenantId) // ← MANDATORY tenant filter
175
+ .AsQueryable();
176
+ // ... apply filters, pagination, projection to Response DTO
177
+ }
178
+
179
+ public async Task<{Entity}Response?> GetByIdAsync(Guid id, CancellationToken ct)
180
+ {
181
+ var tenantId = _currentUser.TenantId;
182
+ var entity = await _db.{Entities}
183
+ .Where(x => x.TenantId == tenantId) // ← MANDATORY tenant filter
184
+ .FirstOrDefaultAsync(x => x.Id == id, ct);
185
+ // ...
186
+ }
187
+
188
+ public async Task<{Entity}Response> CreateAsync(Create{Entity}Dto dto, CancellationToken ct)
189
+ {
190
+ var entity = {Entity}.Create(_currentUser.TenantId, /* dto fields */);
191
+ // ← TenantId as FIRST parameter
192
+ _db.{Entities}.Add(entity);
193
+ await _db.SaveChangesAsync(ct);
194
+ return MapToResponse(entity);
195
+ }
196
+
197
+ public async Task<{Entity}Response> UpdateAsync(Guid id, Update{Entity}Dto dto, CancellationToken ct)
198
+ {
199
+ var entity = await _db.{Entities}
200
+ .Where(x => x.TenantId == _currentUser.TenantId) // ← MANDATORY
201
+ .FirstOrDefaultAsync(x => x.Id == id, ct)
202
+ ?? throw new NotFoundException(nameof({Entity}), id);
203
+ // ... update fields
204
+ }
205
+
206
+ public async Task DeleteAsync(Guid id, CancellationToken ct)
207
+ {
208
+ var entity = await _db.{Entities}
209
+ .Where(x => x.TenantId == _currentUser.TenantId) // ← MANDATORY
210
+ .FirstOrDefaultAsync(x => x.Id == id, ct)
211
+ ?? throw new NotFoundException(nameof({Entity}), id);
212
+ // ...
213
+ }
214
+
215
+ private static {Entity}Response MapToResponse({Entity} entity) => new()
216
+ {
217
+ // Map entity fields to response DTO
218
+ };
219
+ }
220
+ ```
221
+
222
+ **POST-CHECK after writing ANY service:** Grep the file for `TenantId`. If 0 occurrences → FAIL, rewrite with tenant filtering.
223
+
151
224
  **Lifecycle-aware services:**
152
225
  - Services operating on entities with a `lifeCycle` (status field) MUST validate entity state before mutations
153
226
  - Example: `if (entity.Status == EmployeeStatus.Terminated) throw new BusinessException("Cannot update terminated employee")`
@@ -161,6 +234,22 @@ Rules:
161
234
  - DependencyInjection.cs MUST NOT be empty or contain only TODO comments
162
235
  - After writing validators, VERIFY DI registration exists — if missing, add it immediately
163
236
 
237
+ **POST-CHECK after writing validators:**
238
+ ```bash
239
+ # Count Create validators vs Update validators
240
+ CREATE_COUNT=$(find . -path "*/Validators/*" -name "Create*Validator.cs" | wc -l)
241
+ UPDATE_COUNT=$(find . -path "*/Validators/*" -name "Update*Validator.cs" | wc -l)
242
+ if [ "$CREATE_COUNT" -ne "$UPDATE_COUNT" ]; then
243
+ echo "VALIDATOR MISMATCH: $CREATE_COUNT Create vs $UPDATE_COUNT Update → MUST be equal"
244
+ # List missing UpdateValidators and CREATE them
245
+ fi
246
+ ```
247
+
248
+ **Mapper pattern (DRY):**
249
+ - Each service MUST include a `private static {Entity}Response MapToResponse({Entity} entity)` method
250
+ - For complex mappings with related entities, use an extension method in `Application/Mappings/{Module}Mappings.cs`
251
+ - NEVER duplicate mapping logic between GetAll, GetById, Create, Update — always call MapToResponse
252
+
164
253
  **FORBIDDEN:**
165
254
  - Empty DependencyInjection.cs with `// TODO` placeholder
166
255
  - CreateValidator without matching UpdateValidator
@@ -169,6 +258,7 @@ Rules:
169
258
  - `new Entity { }` without TenantId assignment
170
259
  - `Guid.Empty` as a business value in services or controllers
171
260
  - Entity.Create() without tenantId as first parameter
261
+ - Duplicated mapping logic (entity→response) in multiple methods
172
262
 
173
263
  ---
174
264
 
@@ -280,9 +370,13 @@ useXxx with raw axios inside hooks → hooks MUST use the shared apiCl
280
370
 
281
371
  **MCP:** `scaffold_tests`, `analyze_test_coverage`
282
372
 
373
+ > **CRITICAL:** Test generation is a MANDATORY category. If the PRD has no test tasks,
374
+ > the category completeness check (step-01 section 4b) will inject a guardrail task.
375
+ > Test projects MUST be created as the FIRST action in this category — before generating any test files.
376
+
283
377
  **Execution sequence:**
284
378
 
285
- 1. **Ensure test projects exist:**
379
+ 1. **Ensure test projects exist (FIRST — before any test generation):**
286
380
  ```bash
287
381
  # Unit test project
288
382
  UNIT_TEST_PROJECT="tests/${PROJECT_NAME}.Tests.Unit"
@@ -1,8 +1,15 @@
1
1
  # Compact Loop — Inline Execution
2
2
 
3
3
  > **Loaded by:** step-04 section 5 (after first full iteration)
4
- > **Purpose:** Execute all subsequent iterations inline without re-reading step files.
5
- > **Rule:** NEVER stop the loop. NEVER wait for user input. NEVER re-read step files.
4
+ > **Purpose:** Execute ALL remaining tasks autonomously without stopping.
5
+ > **EXECUTION GUARANTEE:** This loop runs until ALL tasks are done, max iterations, or dead-end.
6
+ > **ABSOLUTE RULES:**
7
+ > - NEVER stop the loop
8
+ > - NEVER wait for user input
9
+ > - NEVER ask for confirmation
10
+ > - NEVER re-read step files
11
+ > - NEVER pause between iterations
12
+ > - Execute A → B → C → D → back to step-04 section 1 → repeat
6
13
 
7
14
  ---
8
15
 
@@ -208,10 +215,49 @@ Batch: {batch.length} [{firstCategory}] → {batch.map(t => `[${t.id}] ${t.descr
208
215
 
209
216
  ## C. Commit Batch
210
217
 
218
+ ### C1. Update PRD Status (MANDATORY — BEFORE git commit)
219
+
220
+ > **CRITICAL:** PRD status MUST be updated BEFORE committing.
221
+ > In test-v4-005, the compact loop executed 44 tasks but NEVER updated prd.json status.
222
+ > This broke ALL downstream guardrails (module completeness check never triggered).
223
+
224
+ ```javascript
225
+ const now = new Date().toISOString();
226
+ const COMMIT_HASH_PENDING = 'pending-commit'; // Updated after git commit
227
+
228
+ for (const task of batch) {
229
+ if (task.status !== 'failed') task.status = 'completed';
230
+ task.completed_at = now;
231
+ task.iteration = prd.config.current_iteration;
232
+ task.commit_hash = COMMIT_HASH_PENDING;
233
+ }
234
+ prd.config.current_iteration++;
235
+ prd.updated_at = now;
236
+ writeJSON('.ralph/prd.json', prd);
237
+ ```
238
+
239
+ ### C2. Update Progress File (MANDATORY)
240
+
241
+ ```javascript
242
+ const completed = prd.tasks.filter(t => t.status === 'completed').length;
243
+ const total = prd.tasks.length;
244
+ const moduleName = prd.project?.module || 'unknown';
245
+
246
+ // Append to progress.txt (NOT overwrite)
247
+ appendFile('.ralph/progress.txt',
248
+ `Iteration ${prd.config.current_iteration - 1}: ${batch.map(t => t.id).join('/')} COMPLETED — ` +
249
+ `${batch[0].category} (${batch.length} tasks). ${completed}/${total} done.\n` +
250
+ ` Files: ${batch.reduce((acc, t) => acc + (t.files_changed?.created?.length || 0), 0)} created\n`
251
+ );
252
+ ```
253
+
254
+ ### C3. Git Commit
255
+
211
256
  ```bash
212
257
  # Stage all changed files from batch
213
258
  git add {all_files_from_batch}
214
- git add .ralph/prd.json
259
+ git add .ralph/prd.json .ralph/progress.txt
260
+ [ -f .ralph/modules-queue.json ] && git add .ralph/modules-queue.json
215
261
 
216
262
  git commit -m "$(cat <<'EOF'
217
263
  feat({scope}): [{category}] {batch.length} tasks — {short summary}
@@ -227,44 +273,59 @@ EOF
227
273
  COMMIT_HASH=$(git rev-parse --short HEAD)
228
274
  ```
229
275
 
230
- **Finalize tasks in prd.json:**
276
+ ### C4. Finalize PRD with Commit Hash
277
+
231
278
  ```javascript
232
- const now = new Date().toISOString();
279
+ // Update commit hash now that we have the real one
233
280
  for (const task of batch) {
234
- if (task.status !== 'failed') task.status = 'completed';
235
- task.completed_at = now;
236
- task.iteration = prd.config.current_iteration;
237
- task.commit_hash = COMMIT_HASH;
281
+ if (task.commit_hash === 'pending-commit') task.commit_hash = COMMIT_HASH;
238
282
  }
239
283
  prd.history.push({
240
- iteration: prd.config.current_iteration,
284
+ iteration: prd.config.current_iteration - 1,
241
285
  task_ids: batch.map(t => t.id),
242
286
  action: 'batch-completed',
243
287
  timestamp: now,
244
288
  commit_hash: COMMIT_HASH,
245
289
  notes: "{summary}"
246
290
  });
247
- prd.config.current_iteration++;
248
- prd.updated_at = now;
249
291
  writeJSON('.ralph/prd.json', prd);
250
292
  ```
251
293
 
252
- **Commit progress:**
253
- ```bash
254
- git add .ralph/prd.json .ralph/progress.txt
255
- [ -f .ralph/modules-queue.json ] && git add .ralph/modules-queue.json
256
- git commit -m "chore(ralph): progress — iteration {iteration}"
294
+ ### C5. PRD Sync Verification (HARD CHECK)
295
+
296
+ > **MANDATORY:** Verify prd.json reflects reality before looping back.
297
+
298
+ ```javascript
299
+ const prdCheck = readJSON('.ralph/prd.json');
300
+ const batchIds = batch.map(t => t.id);
301
+ const actuallyCompleted = prdCheck.tasks.filter(t => batchIds.includes(t.id) && t.status === 'completed');
302
+
303
+ if (actuallyCompleted.length !== batch.filter(t => t.status !== 'failed').length) {
304
+ console.error('PRD SYNC ERROR: Tasks executed but not marked completed in prd.json');
305
+ console.error(`Expected: ${batch.filter(t => t.status !== 'failed').length} completed, Got: ${actuallyCompleted.length}`);
306
+ // Force re-write
307
+ for (const task of batch) {
308
+ const prdTask = prdCheck.tasks.find(t => t.id === task.id);
309
+ if (prdTask && task.status === 'completed') prdTask.status = 'completed';
310
+ if (prdTask) prdTask.commit_hash = COMMIT_HASH;
311
+ }
312
+ writeJSON('.ralph/prd.json', prdCheck);
313
+ console.log('PRD SYNC REPAIRED');
314
+ }
257
315
  ```
258
316
 
259
317
  ---
260
318
 
261
- ## D. Loop Back
319
+ ## D. Loop Back (MANDATORY — NO PAUSE)
262
320
 
263
321
  **IMMEDIATELY return to step-04 section 1 (Read Current State).**
264
- DO NOT stop. DO NOT wait for user. DO NOT re-read step files.
265
322
 
266
- The only exit conditions:
267
- - ALL tasks complete (all modules if multi-module)
268
- - Max iterations reached
269
- - Dead-end (all remaining blocked/failed)
270
- - User Ctrl+C
323
+ DO NOT stop. DO NOT wait for user. DO NOT ask "should I continue?". DO NOT re-read step files.
324
+ DO NOT display a summary and pause. DO NOT output partial results and wait.
325
+ **Go directly to step-04 section 1. NOW.**
326
+
327
+ The ONLY exit conditions (enforced by step-04 sections 2-4):
328
+ - ALL tasks complete (all modules if multi-module) → step-05
329
+ - Max iterations reached → step-05
330
+ - Dead-end (all remaining blocked/failed) → step-05
331
+ - User Ctrl+C (external interrupt)
@@ -8,9 +8,12 @@ next_step: steps/step-01-task.md
8
8
 
9
9
  ## MANDATORY RULES:
10
10
 
11
+ - **FULLY AUTONOMOUS** — execute ALL tasks without stopping or asking the user
11
12
  - NEVER skip MCP verification
12
13
  - ALWAYS parse ALL flags before any action
13
14
  - ONLY check resume if -r flag is set
15
+ - **NEVER ask the user** to choose a mode, confirm execution, or select options
16
+ - **NEVER set max_iterations = 1** — unless the user explicitly passed `-m 1`
14
17
  - CONTEXT BUDGET: Keep output COMPACT
15
18
  - **NEVER DELEGATE** the main Ralph loop to a sub-agent (single module)
16
19
  - **Multi-module (2+ modules):** Use Agent Teams for parallel execution
@@ -48,69 +51,36 @@ mcp__context7__resolve-library-id: libraryName: "test" → {mcp_context7} = tru
48
51
 
49
52
  If ANY fails: show error, suggest `smartstack check-mcp`, STOP.
50
53
 
51
- ## 3. Human-in-the-Loop Checkpoint (RECOMMENDED)
54
+ ## 3. Execution Mode (FULLY AUTONOMOUS)
52
55
 
53
- > **Best Practice:** Commencer en mode supervisé avant le mode autonome complet.
56
+ > **CRITICAL:** Ralph-loop is FULLY AUTONOMOUS by default.
57
+ > It executes ALL tasks from start to finish WITHOUT stopping.
58
+ > The user launched `/ralph-loop` — this IS the instruction to execute everything.
54
59
 
55
- ### Why HITL First?
60
+ **DO NOT** ask the user to confirm, choose a mode, or approve execution.
61
+ **DO NOT** set `max_iterations = 1` or any reduced value.
62
+ **DO NOT** stop after the first task to "check quality".
56
63
 
57
- Ralph-loop est puissant mais peut diverger si :
58
- - Les requirements sont ambigus
59
- - Les tests sont lents (>30s)
60
- - Le code généré ne compile pas immédiatement
61
-
62
- **Stratégie recommandée :**
63
-
64
- 1. **Première itération supervisée** - Lancer manuellement la première tâche pour vérifier :
65
- - La qualité du code généré
66
- - Le temps d'exécution des tests
67
- - La clarté des messages d'erreur
68
-
69
- 2. **Mode autonome limité** - Si première itération OK, relancer avec `--max-iterations 5-10`
70
-
71
- 3. **Mode autonome complet** - Une fois confiant, augmenter à `--max-iterations 50`
72
-
73
- ### Checkpoint Prompt (Optional)
74
-
75
- Si vous détectez que c'est la première utilisation de ralph-loop sur ce projet (pas de `.ralph/logs/`), proposer :
64
+ The loop runs autonomously until:
65
+ - ALL tasks are completed (success)
66
+ - `max_iterations` is reached (user explicitly set via `-m N`)
67
+ - Dead-end detected (all remaining tasks blocked/failed)
68
+ - User Ctrl+C (external interrupt)
76
69
 
77
70
  ```javascript
78
- if (!dirExists('.ralph/logs') && !resume_mode) {
79
- AskUserQuestion({
80
- questions: [{
81
- question: "Premier usage de ralph-loop détecté. Démarrer en mode supervisé ou autonome ?",
82
- header: "Mode",
83
- multiSelect: false,
84
- options: [
85
- { label: "Supervisé (recommandé)", description: "Exécuter 1 tâche, puis demander confirmation" },
86
- { label: "Autonome limité", description: "Max 10 itérations automatiques" },
87
- { label: "Autonome complet", description: "Jusqu'à 50 itérations (mode AFK)" }
88
- ]
89
- }]
90
- });
91
-
92
- if (answer === "Supervisé") {
93
- max_iterations = 1;
94
- console.log("Mode supervisé : 1 tâche sera exécutée. Relancez avec -r pour continuer.");
95
- } else if (answer === "Autonome limité") {
96
- max_iterations = Math.min(max_iterations, 10);
97
- }
98
- }
71
+ // NO user prompt. NO mode selection. JUST EXECUTE.
72
+ // max_iterations is already set from flags (default: 50).
73
+ // If user wants fewer iterations, they use -m N explicitly.
74
+ console.log(`Mode: AUTONOMOUS | Max iterations: ${max_iterations}`);
99
75
  ```
100
76
 
101
- ### Feedback Speed Warning
102
-
103
- ⚠️ **IMPORTANT :** Si vos tests prennent >30 secondes, ralph-loop peut devenir inefficace.
77
+ ### Speed Warning (informational only — does NOT block)
104
78
 
79
+ If tests are slow (>30s detected in previous logs), display a one-line warning but **continue execution**:
105
80
  ```
106
- Temps test recommandés :
107
- - Unitaires : <5s
108
- - Intégration : <15s
109
- - E2E : <30s (à exécuter en dehors du loop)
81
+ Slow tests detected. Consider disabling E2E during ralph-loop.
110
82
  ```
111
83
 
112
- Si tests lents détectés (via logs), avertir l'utilisateur et suggérer de désactiver tests E2E pendant le loop.
113
-
114
84
  ## 4. Resume Mode
115
85
 
116
86
  If `{resume_mode} = true`:
@@ -213,9 +183,15 @@ if (PRD_COUNT > 1) {
213
183
  }
214
184
  ```
215
185
 
216
- ## 5. Completion Promise
186
+ ## 5. Completion Promise (auto-set)
217
187
 
218
- If `{completion_promise}` is null: ask user to choose (COMPLETE, ALL TESTS PASS, DONE, or custom).
188
+ ```javascript
189
+ // Auto-set if not provided — NEVER ask the user
190
+ if (!completion_promise) {
191
+ completion_promise = "COMPLETE";
192
+ }
193
+ // The promise is output ONLY when ALL tasks are done. No user interaction needed.
194
+ ```
219
195
 
220
196
  ## 6. Collect Metadata
221
197
 
@@ -94,11 +94,62 @@ If `.ralph/prd.json` exists:
94
94
  2. **v3 FAST PATH:** If `$version === "3.0.0"` AND `tasks[]` exists:
95
95
  - Inject runtime fields if missing (status, config, feature, created, updated_at, history)
96
96
  - Write back to `.ralph/prd.json`
97
+ - **Run CATEGORY COMPLETENESS CHECK (section 4b) before proceeding**
97
98
  - Skip directly to section 5 (find next task)
98
99
  3. **v2 legacy:** If `$version === "2.0.0"` → find next eligible task (section 5), skip to section 5
99
100
  4. **FORMAT A (deprecated):** If `.project && .requirements && !.$version` → run `transformPrdJsonToRalphV2()` → section 5
100
101
 
101
- If `.ralph/prd.json` does not exist: continue to section 2.
102
+ If `.ralph/prd.json` does not exist: continue to section 1b.
103
+
104
+ ### 1b. BA Handoff Quality Gate (BLOCKING)
105
+
106
+ > **CRITICAL:** Before generating ANY tasks, verify the BA handoff is complete.
107
+ > A missing handoff means no frontend files, no test plan, no BR-to-code mapping.
108
+ > Generating tasks without handoff produces an INCOMPLETE PRD (backend-only).
109
+
110
+ ```javascript
111
+ // Find the source feature.json for the current module
112
+ const sourceFeatureJson = prd?.metadata?.sourceFeatureJson
113
+ || findFile('docs/business/**/business-analyse/**/feature.json');
114
+
115
+ if (sourceFeatureJson) {
116
+ const feature = readJSON(sourceFeatureJson);
117
+ const handoff = feature.handoff || {};
118
+
119
+ // CHECK 1: Handoff status must be "handed-off"
120
+ if (handoff.status !== 'handed-off') {
121
+ console.error(`
122
+ ╔══════════════════════════════════════════════════════════════╗
123
+ ║ BLOCKING: BA HANDOFF INCOMPLETE ║
124
+ ║ ║
125
+ ║ feature.json handoff.status = "${handoff.status || 'missing'}"
126
+ ║ Expected: "handed-off" ║
127
+ ║ ║
128
+ ║ The /business-analyse did not complete steps 04a→05c. ║
129
+ ║ Without handoff, the PRD will be MISSING: ║
130
+ ║ - Frontend tasks (pages, components, routes) ║
131
+ ║ - Test tasks (unit, integration, security) ║
132
+ ║ - BR-to-code mappings ║
133
+ ║ - API endpoint summary ║
134
+ ║ ║
135
+ ║ ACTION: Run /business-analyse to complete the handoff, ║
136
+ ║ then re-run /ralph-loop. ║
137
+ ╚══════════════════════════════════════════════════════════════╝`);
138
+ STOP;
139
+ }
140
+
141
+ // CHECK 2: filesToCreate must have all 7 categories
142
+ const filesToCreate = handoff.filesToCreate || {};
143
+ const requiredCategories = ['domain', 'application', 'infrastructure', 'api', 'frontend', 'seedData', 'tests'];
144
+ const missingInHandoff = requiredCategories.filter(c => !filesToCreate[c] || filesToCreate[c].length === 0);
145
+
146
+ if (missingInHandoff.length > 0) {
147
+ console.warn(`⚠ Handoff has empty categories: ${missingInHandoff.join(', ')}`);
148
+ console.warn('PRD generation may produce incomplete tasks. Consider re-running /business-analyse step-05a.');
149
+ // WARNING only — allow proceeding if handoff.status is correct
150
+ }
151
+ }
152
+ ```
102
153
 
103
154
  ## 2. Analyze Task Description
104
155
 
@@ -128,6 +179,56 @@ Initialize `.ralph/progress.txt`:
128
179
  - Dependency references are valid (exist, no forward/circular)
129
180
  - Task count 3-30
130
181
 
182
+ ### 4b. Category Completeness Check (BLOCKING)
183
+
184
+ > **CRITICAL:** The PRD MUST contain tasks for ALL required categories.
185
+ > A PRD with only backend categories (domain, infrastructure, application, api) is INCOMPLETE.
186
+ > This check prevents the "no frontend generated" failure mode.
187
+
188
+ ```javascript
189
+ const REQUIRED_CATEGORIES = ['domain', 'infrastructure', 'application', 'api', 'frontend', 'test'];
190
+ const presentCategories = new Set(prd.tasks.map(t => t.category));
191
+ const missingCategories = REQUIRED_CATEGORIES.filter(c => !presentCategories.has(c));
192
+
193
+ if (missingCategories.length > 0) {
194
+ console.warn(`⚠ PRD MISSING CATEGORIES: ${missingCategories.join(', ')}`);
195
+
196
+ // AUTO-INJECT guardrail tasks for missing categories
197
+ let maxIdNum = Math.max(...prd.tasks.map(t => {
198
+ const num = parseInt(t.id.replace(/[^0-9]/g, ''), 10);
199
+ return isNaN(num) ? 0 : num;
200
+ }));
201
+ const prefix = prd.tasks[0]?.id?.replace(/[0-9]+$/, '') || 'GUARD-';
202
+ const lastBackendTask = prd.tasks.filter(t => t.category === 'api').pop()?.id || prd.tasks[prd.tasks.length - 1]?.id;
203
+
204
+ for (const cat of missingCategories) {
205
+ maxIdNum++;
206
+ const taskId = `${prefix}${String(maxIdNum).padStart(3, '0')}`;
207
+ const guardrailTask = {
208
+ id: taskId,
209
+ description: `[GUARDRAIL] Generate ${cat} layer for ${prd.project?.module || 'module'}`,
210
+ status: 'pending',
211
+ category: cat,
212
+ dependencies: cat === 'test' ? [lastBackendTask] : (cat === 'frontend' ? [lastBackendTask] : []),
213
+ acceptance_criteria: [
214
+ cat === 'frontend' ? 'React pages created via MCP scaffold_api_client + scaffold_routes, wired to App.tsx' :
215
+ cat === 'test' ? 'Unit + Integration test projects created, scaffold_tests MCP called, dotnet test passes' :
216
+ `${cat} layer fully implemented per category-rules.md`
217
+ ],
218
+ started_at: null, completed_at: null, iteration: null,
219
+ commit_hash: null, files_changed: [], validation: null, error: null
220
+ };
221
+ prd.tasks.push(guardrailTask);
222
+ console.log(` → Injected guardrail: [${taskId}] ${cat}`);
223
+ }
224
+
225
+ writeJSON('.ralph/prd.json', prd);
226
+ console.log(`PRD updated: ${prd.tasks.length} tasks (${missingCategories.length} guardrails added)`);
227
+ }
228
+ ```
229
+
230
+ **Why this matters:** In test-v4-005, the PRD was generated with only backend categories (domain, infrastructure, application, api, seedData, validation). The frontend and test categories were entirely absent, resulting in 0 frontend pages and 0 tests generated across 3 modules.
231
+
131
232
  ## 5. Find Current Task
132
233
 
133
234
  ```javascript
@@ -71,6 +71,68 @@ if [ -f "web/package.json" ] || [ -f "package.json" ]; then
71
71
  fi
72
72
  ```
73
73
 
74
+ ### 1.7. Category Completeness Check (RUNS EVERY ITERATION)
75
+
76
+ > **CRITICAL:** This check runs REGARDLESS of allDone status.
77
+ > In test-v4-005, allDone was never true (PRD status not updated), so the
78
+ > module completeness check in section 3b never triggered, and missing
79
+ > frontend/test categories were never detected.
80
+
81
+ ```javascript
82
+ const presentCategories = new Set(prd.tasks.map(t => t.category));
83
+ const REQUIRED_CATEGORIES = ['domain', 'infrastructure', 'application', 'api', 'frontend', 'test'];
84
+ const missingFromPrd = REQUIRED_CATEGORIES.filter(c => !presentCategories.has(c));
85
+
86
+ if (missingFromPrd.length > 0) {
87
+ console.warn(`⚠ PRD MISSING CATEGORIES: ${missingFromPrd.join(', ')}`);
88
+
89
+ // Inject guardrail tasks for missing categories
90
+ let maxIdNum = Math.max(...prd.tasks.map(t => parseInt(t.id.replace(/[^0-9]/g, ''), 10) || 0));
91
+ const prefix = prd.tasks[0]?.id?.replace(/[0-9]+$/, '') || 'GUARD-';
92
+ const lastApiTask = prd.tasks.filter(t => t.category === 'api').pop()?.id;
93
+
94
+ for (const cat of missingFromPrd) {
95
+ maxIdNum++;
96
+ const taskId = `${prefix}${String(maxIdNum).padStart(3, '0')}`;
97
+ prd.tasks.push({
98
+ id: taskId,
99
+ description: `[GUARDRAIL] Generate missing ${cat} layer for ${prd.project?.module || 'module'}`,
100
+ status: 'pending', category: cat,
101
+ dependencies: lastApiTask ? [lastApiTask] : [],
102
+ acceptance_criteria: [
103
+ cat === 'frontend' ? 'React pages + routes wired to App.tsx (standard + tenant blocks)' :
104
+ cat === 'test' ? 'Unit + integration test projects with passing dotnet test' :
105
+ `${cat} layer complete`
106
+ ],
107
+ started_at: null, completed_at: null, iteration: null,
108
+ commit_hash: null, files_changed: [], validation: null, error: null
109
+ });
110
+ console.log(` → Injected [${taskId}] ${cat} guardrail`);
111
+ }
112
+ writeJSON('.ralph/prd.json', prd);
113
+
114
+ // Re-count after injection
115
+ const newPending = prd.tasks.filter(t => t.status === 'pending').length;
116
+ console.log(`PRD updated: +${missingFromPrd.length} guardrails, ${newPending} pending tasks`);
117
+ }
118
+
119
+ // Also check: artifact existence for categories with completed tasks
120
+ const completedCats = new Set(prd.tasks.filter(t => t.status === 'completed').map(t => t.category));
121
+ const artifactChecks = {
122
+ 'frontend': () => glob.sync('**/src/pages/**/*.tsx').length > 0,
123
+ 'test': () => glob.sync('tests/**/*Tests.cs').length > 0,
124
+ 'api': () => glob.sync('src/*/Controllers/**/*Controller.cs').length > 0
125
+ };
126
+ for (const [cat, check] of Object.entries(artifactChecks)) {
127
+ if (completedCats.has(cat) && !check()) {
128
+ console.warn(`ARTIFACT MISSING: ${cat} tasks marked completed but no files found — resetting`);
129
+ prd.tasks.filter(t => t.category === cat && t.status === 'completed')
130
+ .forEach(t => { t.status = 'pending'; t.error = 'Artifacts missing — re-execute'; t.completed_at = null; });
131
+ writeJSON('.ralph/prd.json', prd);
132
+ }
133
+ }
134
+ ```
135
+
74
136
  ## 2. Check Iteration Limit
75
137
 
76
138
  If `current_iteration > max_iterations`:
@@ -82,6 +144,13 @@ Set `prd.status = 'partial'` → step-05.
82
144
 
83
145
  ## 3. Check All Tasks Complete
84
146
 
147
+ **Re-read state after section 1.7 (categories may have been injected):**
148
+ ```javascript
149
+ const tasksCompletedNow = prd.tasks.filter(t => t.status === 'completed').length;
150
+ const tasksTotalNow = prd.tasks.length;
151
+ const allDone = (tasksCompletedNow + prd.tasks.filter(t => t.status === 'skipped').length) === tasksTotalNow;
152
+ ```
153
+
85
154
  If `allDone`:
86
155
 
87
156
  ### 3a. Team Mode (multi-module with Agent Teams)
@@ -107,42 +176,15 @@ if (fileExists(queuePath)) {
107
176
  const queue = readJSON(queuePath);
108
177
  const currentModule = queue.modules[queue.currentIndex];
109
178
 
110
- // MODULE COMPLETENESS CHECK: verify all expected layers AND their artifacts
179
+ // MODULE COMPLETENESS CHECK (lightweight heavy check already done in section 1.7)
180
+ // Verify all expected layers have completed tasks
111
181
  const completedCats = new Set(prd.tasks.filter(t => t.status === 'completed').map(t => t.category));
112
182
  const expected = ['domain', 'infrastructure', 'application', 'api', 'frontend', 'test'];
113
183
  const missing = expected.filter(c => !completedCats.has(c));
114
184
 
115
- // ARTIFACT EXISTENCE CHECK: categories with completed tasks must have real files
116
- const artifactChecks = {
117
- 'infrastructure': () => fs.existsSync('src/*/Persistence/Migrations') && fs.readdirSync('src/*/Persistence/Migrations').length > 0,
118
- 'test': () => fs.existsSync(`tests/${projectName}.Tests.Unit`) && glob.sync('tests/**/*Tests.cs').length > 0,
119
- 'api': () => glob.sync('src/*/Controllers/**/*Controller.cs').length > 0,
120
- 'frontend': () => glob.sync('**/src/pages/**/*.tsx').length > 0
121
- };
122
- for (const [cat, check] of Object.entries(artifactChecks)) {
123
- if (completedCats.has(cat) && !check()) {
124
- // Tasks marked completed but artifacts missing — reset to pending
125
- prd.tasks.filter(t => t.category === cat && t.status === 'completed')
126
- .forEach(t => { t.status = 'pending'; t.error = 'Artifacts missing — re-execute'; t.completed_at = null; });
127
- missing.push(cat);
128
- console.log(`ARTIFACT RESET: ${cat} tasks reset to pending (no files found)`);
129
- }
130
- }
131
-
132
185
  if (missing.length > 0) {
133
- // Inject guardrail tasks for missing layers
134
- let maxId = Math.max(...prd.tasks.map(t => t.id));
135
- for (const cat of missing) {
136
- maxId++;
137
- prd.tasks.push({
138
- id: maxId, description: `[${cat}] GUARDRAIL: Generate missing ${cat} for ${currentModule.code}`,
139
- status: 'pending', category: cat, dependencies: [],
140
- acceptance_criteria: `${cat} layer fully implemented`, started_at: null, completed_at: null,
141
- iteration: null, commit_hash: null, files_changed: { created: [], modified: [] },
142
- validation: null, error: null, module: currentModule.code
143
- });
144
- }
145
- writeJSON('.ralph/prd.json', prd);
186
+ // Section 1.7 should have injected guardrails already — fall through to compact loop
187
+ console.log(`Module ${currentModule.code}: missing categories ${missing.join(', ')} — continuing loop`);
146
188
  // Fall through to section 5 (compact loop)
147
189
  } else {
148
190
  // Module complete — advance
@@ -198,28 +240,33 @@ DEAD-END: {completed} done, {failed} failed, {blocked} blocked
198
240
  ```
199
241
  Set `prd.status = 'failed'` → step-05.
200
242
 
201
- ## 5. Compact Loop (CRITICAL)
243
+ ## 5. Compact Loop (MANDATORY — EXECUTE IMMEDIATELY)
202
244
 
203
- > **MANDATORY:** After first full iteration, ALL subsequent iterations use this inline loop.
204
- > DO NOT stop. DO NOT wait for user. DO NOT re-read step files.
205
- > **Read `references/compact-loop.md` and execute inline.**
245
+ > **THIS IS NOT OPTIONAL.** If there are pending tasks, you MUST enter the compact loop NOW.
246
+ > DO NOT stop. DO NOT wait for user. DO NOT ask for confirmation. DO NOT re-read step files.
247
+ > **Read `references/compact-loop.md` and execute ALL sections inline.**
248
+ > **Stopping here is a VIOLATION of the execution guarantee.**
206
249
 
207
250
  If `hasPending && iteration < max`:
208
251
 
209
252
  1. Read `references/compact-loop.md`
210
- 2. Execute sections A → B → C → D inline
211
- 3. Return to section 1 of THIS step
253
+ 2. Execute sections A → B → C → D inline (find tasks → execute batch → commit → loop back)
254
+ 3. **IMMEDIATELY** return to section 1 of THIS step (do NOT pause)
255
+ 4. Repeat until ALL tasks are complete, max iterations reached, or dead-end
212
256
 
213
257
  ---
214
258
 
215
- ## CRITICAL RULES:
259
+ ## CRITICAL RULES — EXECUTION GUARANTEE:
216
260
 
217
261
  - **NEVER** output completion promise unless ALL tasks done (all modules if multi)
218
262
  - **NEVER** delegate the loop to sub-agents (except team mode for multi-module)
219
- - **NEVER** stop between iterations
263
+ - **NEVER** stop between iterations — this is the CORE PROMISE of ralph-loop
264
+ - **NEVER** ask the user "should I continue?" or "is this OK?" — JUST CONTINUE
265
+ - **NEVER** pause to show intermediate results and wait for feedback
220
266
  - **BATCH** same-category tasks (max 5)
221
267
  - **MODULE COMPLETENESS:** All layers must have completed tasks before advancing
222
- - Only valid stop: all complete, max iterations, dead-end, or user Ctrl+C
268
+ - **Only valid stop conditions:** all complete, max iterations, dead-end, or user Ctrl+C
269
+ - **If you stop for any other reason, you have VIOLATED the execution guarantee.**
223
270
 
224
271
  ---
225
272