---
name: step-03d-validate
description: Per-module validation, write feature.json, incremental HTML deploy, loop decision
model: sonnet
next_step: steps/step-03a1-setup.md OR steps/step-04a-collect.md (conditional)
---

> **Context files:** `_shared.md` | `_module-loop.md`

# Step 3d: Validation & Loop

## MANDATORY EXECUTION RULES

- ALWAYS use ULTRATHINK mode
- This step VALIDATES the specification from step-03c, writes it to feature.json, and decides loop continuation
- ALWAYS verify specification completeness before writing
- ALL communication in `{language}`
- **ID NAMING RULE (MANDATORY, NO EXCEPTION):**
  All IDs MUST include a module prefix to guarantee application-wide uniqueness.
  The prefix is derived from the module code initials (2-4 chars):
    UserManagement → UM | VehicleManagement → VM | PartsInventory → PI
    RepairManagement → RM | MaintenanceSchedule → MS | DataSync → DS
    Notifications → NT | Dashboard → DB | Orders → OR | Customers → CU

  NEVER use bare IDs (UC-001, BR-VAL-001) in multi-module mode.

## YOUR TASK

Validate the module specification for completeness and consistency, write to feature.json, deploy incremental HTML, and decide whether to loop to the next module or proceed to consolidation.

---

### 9. Per-Module Validation

#### 9a. Completeness Checks

| Section | Minimum | Status |
|---------|---------|--------|
| actors | 2 | PASS/FAIL |
| useCases | 2 | PASS/FAIL |
| functionalRequirements | 4 | PASS/FAIL |
| permissionMatrix | 1 resource × 2 roles | PASS/FAIL |
| entities | 1 | PASS/FAIL |
| entitySchemaFormat | attributes[] not fields[] (BLOCKING) | PASS/FAIL |
| wireframes | 1 per section (BLOCKING) | PASS/FAIL |
| wireframeSchema | All required fields present (BLOCKING) | PASS/FAIL |
| gherkinScenarios | 2 per UC | PASS/FAIL |
| validations | 1 | PASS/FAIL |
| messages | 4 | PASS/FAIL |
| lifeCycles | 1 (if entity has status) | PASS/FAIL |
| seedDataCore | 7 sections present | PASS/FAIL (BLOCKING) |

#### 9b. Consistency Checks

- Every UC has ≥1 linked FR
- Every FR has ≥1 linked BR
- All BR references exist in analysis.businessRules
- All actors appear in permissionMatrix
- Permission paths use full format: `business.{app}.{module}.{resource}.{action}`
- rolePermissions paths match permissions paths
- API routes use consistent prefix

#### 9c. Convention Checks

- UC-NNN format
- FR-NNN format
- BR-{CATEGORY}-NNN format
- Entity names PascalCase
- Field names camelCase
- Entity attribute format: `attributes[]` with {name, description}, NOT `fields[]` with {name, type} — entities must NOT have tableName or primaryKey
- Wireframe structure: `screen` (not `name`), `componentMapping` is array of {wireframeElement, reactComponent} (not plain key-value object), `layout` is object with regions (not string)
- Permission paths dot-separated lowercase

#### 9d. Decision

IF validation PASS:
  Display summary, ask client for confirmation

IF validation FAIL:
  Display errors, offer:
  ```
  options:
    - label: "Auto-corriger"
      description: "Corriger automatiquement les erreurs détectées"
    - label: "Réviser manuellement"
      description: "Revenir aux sections problématiques"
    - label: "Forcer la validation"
      description: "Accepter malgré les erreurs (risqué)"
  ```

#### 9e. Write Module Validation Section (MANDATORY)

> **The module feature.json MUST have a `validation` section recording the results of steps 9a-9d.**

```
ba-writer.enrichSection({
  featureId: {module_feature_id},
  section: "validation",
  data: {
    validatedAt: "{ISO timestamp}",
    completenessChecks: [
      { "section": "useCases", "count": {count}, "minimum": 2, "status": "PASS|FAIL" },
      { "section": "functionalRequirements", "count": {count}, "minimum": 4, "status": "PASS|FAIL" },
      { "section": "wireframes", "count": {count}, "minimum": {section_count}, "status": "PASS|FAIL" },
      { "section": "seedDataCore", "count": 7, "minimum": 7, "status": "PASS|FAIL" }
    ],
    consistencyChecks: [
      { "check": "UC-FR linkage", "passed": {n}, "warnings": {n}, "errors": {n}, "status": "PASS|FAIL" },
      { "check": "BR references valid", "passed": {n}, "warnings": {n}, "errors": {n}, "status": "PASS|FAIL" },
      { "check": "Permission path format", "passed": {n}, "warnings": {n}, "errors": {n}, "status": "PASS|FAIL" }
    ],
    conventionChecks: [
      { "check": "ID naming with module prefix", "status": "PASS|FAIL", "details": "..." },
      { "check": "Entity names PascalCase", "status": "PASS|FAIL", "details": "..." }
    ],
    semanticChecks: [
      { "check": "orphan-permissions", "module": "{currentModule}", "status": "PASS|WARNING|ERROR", "details": "...", "autoFixed": false },
      { "check": "uc-sans-fr", "module": "{currentModule}", "status": "PASS|WARNING|ERROR", "details": "...", "autoFixed": false },
      { "check": "missing-wireframes", "module": "{currentModule}", "status": "PASS|WARNING|ERROR", "details": "...", "autoFixed": false }
    ],
    warnings: ["List of non-blocking warnings"],
    decision: {
      "approved": true,
      "reason": "All checks passed",
      "approvalMode": "standard",
      "approvedBy": "Client",
      "approvedAt": "{ISO timestamp}"
    }
  }
})
```

#### 9f. Module Specification Checklist (BLOCKING)

> **CRITICAL:** This checklist MUST be FULLY COMPLETED before marking module status = "specified".

**Execute the comprehensive validation checklist:**

Run the 27-check validation process across 10 categories:
- Data Model (4 checks) | Business Rules (3 checks) | Use Cases & FRs (4 checks)
- Permissions (3 checks) | UI & Navigation (4 checks) | I18N & Messages (3 checks)
- Seed Data (2 checks) | API Endpoints (2 checks) | Validations (1 check) | Gherkin (1 check)

```javascript
const blockingFailures = checks.filter(c => c.blocking && c.status === "FAIL");

IF blockingFailures.length > 0:
  // CONDITIONAL LOAD: Only load detailed checklist on validation failure
  Read references/validation-checklist.md
  Display:
    - Full validation logic for FAILED checks
    - Exact requirements (minimums, patterns, formats)
    - Fix recommendations for each failure

  BLOCKING ERROR: Module specification incomplete
  → Fix all failures before proceeding

ELSE:
  All blocking checks passed ✓
  Display: "{warnings_count} warnings (non-blocking)"
  → Proceed to mark module as "specified"
```

**Optimization:** The detailed 280-line validation-checklist.md is loaded **only when validation fails** (saves ~10,000 tokens on success path).

---

### 10. Module Summary with Roles & Permissions

Display comprehensive summary:

```
═══════════════════════════════════════════════════════════
  MODULE SPÉCIFIÉ: {currentModule} ({currentModuleIndex + 1}/{total})
═══════════════════════════════════════════════════════════

| Aspect | Valeur |
|--------|--------|
| Entités | {count} ({entity names}) |
| Business Rules | {count} (VAL: X, CALC: Y, WF: Z) |
| Use Cases | {count} (UC-001 → UC-NNN) |
| Exigences | {count} FRs |
| Sections | {count} ({section names}) |
| Maquettes | {count} wireframes |
| Permissions | {count} paths |
| Tests Gherkin | {count} scénarios |
| Messages | {count} |

### Rôles & Permissions pour {currentModule}
| Rôle | Permissions |
|------|------------|
| {App} Admin | business.{app}.{module}.* |
| {App} Manager | read, create, update, assign |
| {App} Contributor | read, create, update |
| {App} Viewer | read |

→ Validation: {PASS/FAIL}
═══════════════════════════════════════════════════════════
```

Ask via AskUserQuestion:

```
question: "Le module {currentModule} est-il correctement spécifié ?"
header: "Module"
options:
  - label: "Validé"
    description: "Passer au module suivant"
  - label: "Réviser"
    description: "Modifier des éléments du module"
```

---

### 11. Write Module Feature.json

```
// Write analysis section with ALL subsections
ba-writer.enrichSection({
  featureId: {module_feature_id},
  section: "analysis",
  data: {
    objectives: [{id, objective, metric, target}],       // from 6a
    entities: [{name, description, attributes, relationships}],  // from 6b — SCHEMA FORMAT
    businessRules: [{id, name, category, statement, priority, conditions, examples, testability}],  // from 7 — SCHEMA FORMAT
    processFlow: {entryPoints, mainFlow, decisionPoints, alternativeFlows},  // from 6c
    dataLifecycle: {retentionPeriod, archiveStrategy, gdprCompliance, states}  // from 6d
  }
})

// Write specification section with ALL subsections
ba-writer.enrichSection({
  featureId: {module_feature_id},
  section: "specification",
  data: {
    actors: [{role, description, permissions}],                   // 8a
    useCases: [{id, name, primaryActor, permission, mainScenario, linkedRules}],  // 8b
    functionalRequirements: [{id, statement, priority, linkedRules, linkedUseCases, acceptanceCriteria}],  // 8c
    permissionMatrix: {permissions: [], roleAssignments: []},     // 8d
    navigation: {entries: []},                                    // 8e
    seedDataCore: {navigationModules, navigationSections, navigationResources, navigationTranslations, permissions, rolePermissions, permissionConstants},  // 8f (7 arrays)
    gherkinScenarios: [{feature, scenarios: [{name, tags, given, when, then}]}],  // 8g
    validations: [{entity, field, rules, errorMessageKey}],       // 8h
    messages: [{code, type, title, message, i18nKey}],            // 8i
    lifeCycles: [{entity, field, initialState, states: [{id, displayName, color, allowedTransitions, isTerminal}], transitions}],  // 8j
    apiEndpoints: [{method, path, permission, requestDto, responseDto, description}],  // 8k
    i18nKeys: {...},                                              // 8l
    sections: [{code, labels, route, icon, permission, wireframe, useCases, businessRules, resources}],  // from 3a-bis
    dashboards: [{code, title, kpis, filters, refreshMode}],     // from 3d
    uiWireframes: [{screen, section, mockup, elements, actions, componentMapping, layout}]  // from 3b
  }
})

// Write validation results from step 9
// (Already written in step 9e above)

ba-writer.updateStatus({module_feature_id}, "specified")

// Update master
ba-writer.updateModuleStatus({feature_id}, {currentModule.code}, "specified")
```

---

### 11-bis. Deploy Incremental Interactive HTML (MANDATORY)

> **After each module is specified, deploy/update the interactive HTML document with all available data.**
> The client can review completed modules while the next module is being specified.

See [references/validate-incremental-html.md](../references/validate-incremental-html.md) for the complete deployment process (read sources, build FEATURE_DATA, replace placeholders, write HTML).

Uses the **same mapping** as step-05b-deploy.md — only difference is `moduleSpecs` only includes completed modules.

---

### 12. Loop Decision

```
ba-writer.advanceModuleLoop({feature_id})
→ Increments currentModuleIndex
→ Updates completedModules
→ Updates currentModule

IF currentModuleIndex < moduleOrder.length:
  Display: "→ Module suivant: {nextModule} ({currentModuleIndex + 1}/{total})"
  Load: steps/step-03a1-setup.md

IF currentModuleIndex >= moduleOrder.length:
  Display: "═══ Tous les modules spécifiés! Passage à la consolidation... ═══"
  ba-writer.updateStatus({feature_id}, "specified")
  Load: steps/step-04a-collect.md
```

---

## SELF-VERIFICATION (MANDATORY before loading next step)

Before proceeding to step-03a (next module) or step-04 (consolidation), VERIFY:

1. **Module feature.json has specification section** with ALL sub-sections (actors, useCases, functionalRequirements, permissionMatrix, navigation, seedDataCore, gherkinScenarios, validations, messages, lifeCycles, apiEndpoints, i18nKeys, sections, uiWireframes)
2. **Module feature.json status** = "specified" (set by section 11)
3. **Master modules[].status** for this module = "specified" (set by section 11)
4. **ba-interactive.html exists** and includes data for this module (set by section 11-bis)

**IF any check fails → FIX before proceeding.** Do NOT advance the module loop with incomplete data.

---

## SINGLE-MODULE MODE

When only 1 module in moduleOrder:

- Same full validation flow
- Skip cross-module references (section 5)
- After validation → direct to step-04a-collect.md (auto-consolidation)

---

## RESUME SUPPORT

IF the step is resumed (e.g., after interruption):

```
Read metadata.workflow.currentModuleIndex
Read metadata.workflow.currentModule
→ Resume at the correct module
→ If module has partial data, show what exists and continue from there
```

---

## CONTEXT MANAGEMENT

| Loaded | Not Loaded |
|--------|------------|
| _shared.md | Other module feature.json (full) |
| feature-schema.json | Questionnaires not needed |
| Questionnaires for this module | Templates |
| Completed modules summary (100 lines max) | React viewer files |

---

## STATE VARIABLES

| Variable | Description |
|----------|-------------|
| `{currentModule}` | Current module being specified |
| `{currentModuleIndex}` | Index in moduleOrder |
| `{completedModules}` | Array of already specified module codes |
| `{module_feature_id}` | Feature ID for the module-level feature.json |

---

## SUCCESS METRICS

- Module specification validation PASS
- Per-module validation results recorded in feature.json
- Client confirmed module specification
- Module feature.json written with all sections
- Master updated with module status
- Interactive HTML deployed/updated with completed module data (incremental)
- Loop advanced correctly or consolidation phase initiated

---

## FAILURE MODES

- Validation FAIL → offer auto-correct / manual revise / force
- Client rejects → revise specific sections via step-03a or step-03b
- Cross-module reference error → clarify with client
- Interruption → resumable via workflow state

---

## NEXT STEP

Conditional:

- IF modules remaining → Load `steps/step-03a1-setup.md`
- IF all modules done → Load `steps/step-04a-collect.md`
