@atlashub/smartstack-cli 3.4.1 → 3.6.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 (46) hide show
  1. package/dist/index.js +160 -5
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +4 -3
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/skills/_shared.md +1 -1
  7. package/templates/skills/application/steps/step-04-backend.md +4 -4
  8. package/templates/skills/application/templates-backend.md +4 -4
  9. package/templates/skills/business-analyse/SKILL.md +26 -15
  10. package/templates/skills/business-analyse/_architecture.md +4 -4
  11. package/templates/skills/business-analyse/_elicitation.md +1 -1
  12. package/templates/skills/business-analyse/_module-loop.md +4 -4
  13. package/templates/skills/business-analyse/html/ba-interactive.html +39 -10
  14. package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
  15. package/templates/skills/business-analyse/questionnaire.md +2 -2
  16. package/templates/skills/business-analyse/react/components.md +1 -1
  17. package/templates/skills/business-analyse/react/schema.md +1 -1
  18. package/templates/skills/business-analyse/references/html-data-mapping.md +4 -3
  19. package/templates/skills/business-analyse/schemas/feature-schema.json +1 -1
  20. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  21. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +1 -0
  22. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  23. package/templates/skills/business-analyse/steps/step-00-init.md +29 -0
  24. package/templates/skills/business-analyse/steps/step-01-cadrage.md +166 -6
  25. package/templates/skills/business-analyse/steps/step-02-decomposition.md +4 -4
  26. package/templates/skills/business-analyse/steps/{step-03a-specify.md → step-03a-data.md} +10 -359
  27. package/templates/skills/business-analyse/steps/step-03b-ui.md +414 -0
  28. package/templates/skills/business-analyse/steps/step-03c-compile.md +343 -0
  29. package/templates/skills/business-analyse/steps/{step-03b-compile.md → step-03d-validate.md} +26 -308
  30. package/templates/skills/business-analyse/steps/step-04-consolidation.md +2 -2
  31. package/templates/skills/business-analyse/steps/step-05a-handoff.md +49 -292
  32. package/templates/skills/business-analyse/steps/step-05b-mapping.md +302 -0
  33. package/templates/skills/business-analyse/steps/step-05c-deploy.md +296 -0
  34. package/templates/skills/business-analyse/steps/step-05d-html.md +326 -0
  35. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  36. package/templates/skills/business-analyse/templates/tpl-handoff.md +6 -6
  37. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +1 -1
  38. package/templates/skills/business-analyse/templates/tpl-progress.md +1 -1
  39. package/templates/skills/controller/steps/step-03-generate.md +2 -1
  40. package/templates/skills/ralph-loop/SKILL.md +17 -2
  41. package/templates/skills/ralph-loop/references/core-seed-data.md +538 -0
  42. package/templates/skills/ralph-loop/steps/step-00-init.md +2 -0
  43. package/templates/skills/ralph-loop/steps/step-01-task.md +273 -7
  44. package/templates/skills/ralph-loop/steps/step-02-execute.md +39 -15
  45. package/templates/skills/ralph-loop/steps/step-04-check.md +87 -4
  46. package/templates/skills/business-analyse/steps/step-05b-deploy.md +0 -432
@@ -0,0 +1,414 @@
1
+ ---
2
+ name: step-03b-ui
3
+ description: Per-module specification - state machines, wireframes, layouts, dashboards (UI & visualization phase)
4
+ model: opus
5
+ next_step: steps/step-03c-compile.md
6
+ ---
7
+
8
+ > **Context files:** `_shared.md` | `_module-loop.md`
9
+
10
+ # Step 3b: Specification - UI & Visualization
11
+
12
+ ## MANDATORY EXECUTION RULES
13
+
14
+ - ALWAYS use ULTRATHINK mode
15
+ - This step is EXECUTED ONCE PER MODULE, after step-03a-data.md
16
+ - **WIREFRAME RULE:** Every section MUST have a wireframe in `specification.uiWireframes[]`. No section without a validated mockup.
17
+ - **ID NAMING RULE (MANDATORY, NO EXCEPTION):**
18
+ All IDs MUST include a module prefix to guarantee application-wide uniqueness.
19
+ The prefix is derived from the module code initials (2-4 chars):
20
+ UserManagement → UM | VehicleManagement → VM | PartsInventory → PI
21
+ RepairManagement → RM | MaintenanceSchedule → MS | DataSync → DS
22
+ Notifications → NT | Dashboard → DB | Orders → OR | Customers → CU
23
+
24
+ Patterns:
25
+ UC-{PREFIX}-{NNN} → UC-RM-001, UC-PI-003
26
+ BR-{CAT}-{PREFIX}-{NNN} → BR-VAL-RM-001, BR-CALC-PI-002
27
+ FR-{PREFIX}-{NNN} → FR-RM-001
28
+ OBJ-{PREFIX}-{NNN} → OBJ-RM-001
29
+ AC-{PREFIX}-{NNN} → AC-RM-001
30
+ RISK-{PREFIX}-{NNN} → RISK-RM-001
31
+
32
+ NEVER use bare IDs (UC-001, BR-VAL-001) in multi-module mode.
33
+ - **SCHEMA CONFORMITY RULE:**
34
+ ALL data MUST fit within the defined feature-schema.json structure.
35
+ NEVER create custom top-level fields (KPIDefinitions, ChartConfigurations, etc.)
36
+ Dashboard modules MUST use specification.dashboards[] (it exists in the schema).
37
+ If truly needed, use specification.extensions: {} (additionalProperties: true).
38
+
39
+ ## YOUR TASK
40
+
41
+ Define the UI layer for the current module: state machines for entities with status fields, wireframes for every section, component mapping, structural layouts, and dashboards.
42
+
43
+ ---
44
+
45
+ ## EXECUTION SEQUENCE
46
+
47
+ ### 3a-state. Define Entity State Machine (Full Depth)
48
+
49
+ > **For full depth modules with entities that have a status/enum field, define the complete state machine.**
50
+ > **This drives conditional actions, badges, and transition effects throughout the UI.**
51
+
52
+ For each entity with a status-like attribute:
53
+
54
+ 1. **Identify states** from the enum values or business rules:
55
+ ```
56
+ Ask client: "Quels sont les états possibles pour {Entity}.{statusField} ?"
57
+ ```
58
+
59
+ 2. **Define transitions** - for each state, ask:
60
+ ```
61
+ Ask client: "Depuis l'état {state}, quelles transitions sont possibles ?"
62
+ ```
63
+
64
+ 3. **For each transition**, capture:
65
+ - `action`: verb label (submit, approve, reject, cancel, archive)
66
+ - `permission`: which permission is required
67
+ - `guards`: which BR must pass (reference existing BR-XXX from analysis)
68
+ - `effects`: what happens after (notification, email, field update)
69
+ - `confirm`: does the user need to confirm?
70
+
71
+ 4. **Assign colors** to states for badge rendering:
72
+ - Draft/New → gray
73
+ - In Progress/Submitted → blue
74
+ - Approved/Active → green
75
+ - Warning/Pending → yellow
76
+ - Error/Rejected → red
77
+ - Archived/Cancelled → purple
78
+
79
+ 5. **Store** in `specification.lifeCycles[]`:
80
+ ```json
81
+ {
82
+ "entity": "{Entity}",
83
+ "field": "status",
84
+ "initialState": "{firstState}",
85
+ "states": [
86
+ { "id": "draft", "displayName": "Brouillon", "color": "gray", "allowedTransitions": ["submitted"], "isTerminal": false }
87
+ ],
88
+ "transitions": [
89
+ {
90
+ "from": "draft", "to": "submitted", "action": "submit",
91
+ "permission": "business.{app}.{module}.submit",
92
+ "guards": ["BR-VAL-{PREFIX}-001"],
93
+ "effects": [{ "type": "notification", "target": "role:manager", "template": "{module}-submitted" }],
94
+ "confirm": true
95
+ }
96
+ ]
97
+ }
98
+ ```
99
+
100
+ 6. **Cross-validate:** Every `allowedTransitions` entry must have a matching `transitions[]` entry.
101
+
102
+ ### 3a-bis. Structure Sections with Resources (Levels 4 & 5)
103
+
104
+ > **DEPTH GATE:** Execute this section for **full** depth, or for individual sections flagged for customization in **override** depth. For **convention** depth, sections are auto-generated by 3a-infer — skip to 3b.
105
+
106
+ For EACH section confirmed in 3a, build the `specification.sections[]` structure:
107
+
108
+ 1. For each resource in the section, determine:
109
+ - The SmartStack component type (SmartTable, SmartForm, DetailCard, KpiPanel, Chart, Map, Timeline, etc.)
110
+ - The entity it operates on
111
+ - Columns/fields based on entity attributes
112
+ - Permission (inherit from section or more specific)
113
+ - Available actions
114
+
115
+ 2. Link use cases to sections:
116
+ - Each UC MUST belong to exactly ONE section
117
+ - Map UC to section based on the primary action (list → UC-XX-001, create → UC-XX-003, etc.)
118
+
119
+ 3. Link business rules to sections:
120
+ - Each BR can belong to one or more sections
121
+ - Map BR based on where it's enforced (validation BR → create/edit section, calc BR → detail section)
122
+
123
+ 4. Build the section object:
124
+
125
+ > **STRUCTURE CARD: specification.sections[]** — Resources MUST include full depth definitions.
126
+ > ```json
127
+ > {
128
+ > "code": "list",
129
+ > "labels": { "fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste" },
130
+ > "route": "/business/{app}/{module}/list",
131
+ > "icon": "list",
132
+ > "permission": "business.{app}.{module}.read",
133
+ > "wireframe": "{module}-list",
134
+ > "useCases": ["UC-{PREFIX}-001", "UC-{PREFIX}-002"],
135
+ > "businessRules": ["BR-VAL-{PREFIX}-001"],
136
+ > "resources": [
137
+ > {
138
+ > "code": "{module}-grid",
139
+ > "type": "SmartTable",
140
+ > "entity": "{MainEntity}",
141
+ > "permission": "business.{app}.{module}.read",
142
+ > "columns": ["name", "status", "createdAt"],
143
+ > "columnDefs": [
144
+ > { "field": "code", "label": {"fr": "Code", "en": "Code"}, "format": "text", "sortable": true, "filterable": true, "clickAction": "navigate:detail" },
145
+ > { "field": "name", "label": {"fr": "Nom", "en": "Name"}, "format": "text", "sortable": true, "filterable": true },
146
+ > { "field": "status", "label": {"fr": "Statut", "en": "Status"}, "format": "badge", "sortable": true, "filterable": true, "colorMap": "stateMachine:{Entity}" },
147
+ > { "field": "createdAt", "label": {"fr": "Créé le", "en": "Created"}, "format": "date-relative", "sortable": true }
148
+ > ],
149
+ > "actions": ["view", "edit", "delete"],
150
+ > "rowActions": [
151
+ > { "action": "view", "icon": "eye", "permission": "business.{app}.{module}.read" },
152
+ > { "action": "edit", "icon": "edit", "permission": "business.{app}.{module}.update", "showWhen": {"status": ["draft"]} },
153
+ > { "action": "delete", "icon": "trash", "permission": "business.{app}.{module}.delete", "confirm": true }
154
+ > ],
155
+ > "filters": ["status", "dateRange"],
156
+ > "defaultSort": { "field": "createdAt", "direction": "desc" },
157
+ > "defaultPageSize": 20,
158
+ > "emptyState": { "icon": "inbox", "message": {"fr": "Aucun enregistrement", "en": "No records"}, "createAction": true }
159
+ > }
160
+ > ]
161
+ > }
162
+ > ```
163
+ >
164
+ > **SmartForm resource example (for create/edit sections):**
165
+ > ```json
166
+ > {
167
+ > "code": "{module}-form",
168
+ > "type": "SmartForm",
169
+ > "entity": "{MainEntity}",
170
+ > "permission": "business.{app}.{module}.create",
171
+ > "fields": [
172
+ > { "name": "code", "component": "Input", "required": true, "validation": "Unique, auto-generated" },
173
+ > { "name": "name", "component": "Input", "required": true },
174
+ > { "name": "type", "component": "Select", "required": true, "source": "EntityTypeEnum" },
175
+ > { "name": "description", "component": "TextArea", "required": false },
176
+ > { "name": "parentId", "component": "EntitySelect", "source": "ParentEntity", "required": true },
177
+ > { "name": "startDate", "component": "DatePicker", "required": true },
178
+ > { "name": "isActive", "component": "Toggle", "default": true }
179
+ > ],
180
+ > "formLayout": {
181
+ > "type": "tabs",
182
+ > "tabs": [
183
+ > { "code": "general", "label": {"fr": "Général", "en": "General"}, "fields": ["code", "name", "type", "description"] },
184
+ > { "code": "details", "label": {"fr": "Détails", "en": "Details"}, "fields": ["parentId", "startDate", "isActive"] }
185
+ > ]
186
+ > }
187
+ > }
188
+ > ```
189
+ > **MANDATORY for SmartTable:** `columnDefs`, `rowActions`, `defaultSort`, `emptyState`
190
+ > **MANDATORY for SmartForm:** `fields` with `component` type, `formLayout`
191
+
192
+ 5. Write `specification.sections[]` via ba-writer.enrichSection()
193
+
194
+ **VALIDATION:** Every UC must appear in exactly one section.useCases[]. No orphan UCs.
195
+
196
+ ### 3b. For Each Section: Generate MANDATORY ASCII Mockup
197
+
198
+ > **BLOCKING RULE:** Every section MUST have a wireframe. No section proceeds to entity definition (step 6) without a validated mockup stored in `specification.uiWireframes[]`.
199
+ > **HTML INTEGRATION:** These wireframes are also rendered in the interactive HTML document (`ba-interactive.html`) deployed at handoff. The client can review and annotate mockups directly in their browser.
200
+
201
+ For each confirmed section, generate an ASCII mockup and validate with client:
202
+
203
+ Example for a list section:
204
+
205
+ ```
206
+ ╔═══════════════════════════════════════════════════════════╗
207
+ ║ {Module} > Liste [+ Nouveau] ║
208
+ ╠═══════════════════════════════════════════════════════════╣
209
+ ║ 🔍 Rechercher... │ Statut: [Tous ▾] │ Date: [Ce mois ▾] ║
210
+ ╠═══════════════════════════════════════════════════════════╣
211
+ ║ # │ {Field1} │ {Field2} │ {Field3} │ Statut │ ··· ║
212
+ ║ 1 │ VAL-001 │ Exemple 1 │ 12'500.- │ ● Brouillon │ ⋮ ║
213
+ ║ 2 │ VAL-002 │ Exemple 2 │ 8'300.- │ ● Envoyé │ ⋮ ║
214
+ ╠═══════════════════════════════════════════════════════════╣
215
+ ║ 1-25 de 142 │ ◀ 1 2 3 ··· 6 ▶ ║
216
+ ╚═══════════════════════════════════════════════════════════╝
217
+ ```
218
+
219
+ Store in specification.uiWireframes[] (**MANDATORY** for every section):
220
+
221
+ > **STRUCTURE CARD: specification.uiWireframes[]** — ALL fields below are MANDATORY.
222
+ > ```json
223
+ > {
224
+ > "screen": "{module}-{section}",
225
+ > "section": "{section}",
226
+ > "description": "Description of the screen",
227
+ > "mockupFormat": "ascii",
228
+ > "mockup": "╔═══...",
229
+ > "elements": ["DataGrid", "FilterBar", "Pagination", "CreateButton"],
230
+ > "actions": ["filter", "sort", "create", "view-detail"],
231
+ > "permissionsRequired": ["business.{app}.{module}.read"],
232
+ > "componentMapping": [
233
+ > { "wireframeElement": "DataGrid", "reactComponent": "SmartTable" },
234
+ > { "wireframeElement": "FilterBar", "reactComponent": "SmartFilter" },
235
+ > { "wireframeElement": "CreateButton", "reactComponent": "Button" }
236
+ > ],
237
+ > "layout": {
238
+ > "type": "page",
239
+ > "regions": [
240
+ > { "id": "toolbar", "position": "top", "components": [
241
+ > { "type": "FilterBar", "resourceRef": "{module}-filters" },
242
+ > { "type": "ActionMenu", "resourceRef": "{module}-actions", "permission": "business.{app}.{module}.create" }
243
+ > ]},
244
+ > { "id": "content", "position": "main", "span": 12, "components": [
245
+ > { "type": "SmartTable", "resourceRef": "{module}-grid" }
246
+ > ]}
247
+ > ]
248
+ > }
249
+ > }
250
+ > ```
251
+ > **REQUIRED fields:** `screen`, `mockup`, `elements`, `section`, `componentMapping`, `layout` are ALL mandatory.
252
+ > A wireframe without `componentMapping` or `layout` will FAIL validation in step 9.
253
+ > **layout.regions[].components[].resourceRef** MUST match a `sections[].resources[].code`.
254
+
255
+ Ask client to validate each mockup via AskUserQuestion (batch 2-3 mockups at once if possible).
256
+
257
+ > **IF client rejects a mockup:** Revise and re-propose until validated. Do NOT proceed without client approval on the layout.
258
+
259
+ ### 3b-bis. Wireframe-to-Component Mapping
260
+
261
+ After client validates the mockup, map each wireframe element to a SmartStack React component:
262
+
263
+ | Wireframe Element | SmartStack Component | Notes |
264
+ |-------------------|---------------------|-------|
265
+ | DataGrid | `SmartTable` or `EntityCard` grid | Use EntityCard for card layouts |
266
+ | FilterBar | `SmartFilter` | Integrated with SmartTable |
267
+ | SearchInput | `SearchInput` | Debounced search |
268
+ | Pagination | Built into `SmartTable` | Server-side pagination |
269
+ | ActionButton | `Button` + `RequirePermission` | Always wrapped in permission check |
270
+ | StatusBadge | `StatusBadge` | Uses entity lifecycle states |
271
+ | DetailCard | `EntityDetailCard` | Standard detail layout |
272
+ | Form | `SmartForm` | FluentValidation-backed |
273
+ | KpiCard | `StatCard` (Recharts) | Dashboard KPI display |
274
+ | Chart:bar/line/pie | Recharts `BarChart`/`LineChart`/`PieChart` | CSS variables for colors |
275
+
276
+ Store the component mapping alongside the wireframe to ensure downstream skills use the correct components.
277
+
278
+ ### 3b-ter. Generate Structural Layout
279
+
280
+ For EACH wireframe generated in 3b, generate a `layout` object alongside the ASCII mockup:
281
+
282
+ 1. From the ASCII mockup, extract the visual regions (header, toolbar, main content, sidebar, etc.)
283
+ 2. For each region, map the visual elements to SmartStack component types
284
+ 3. Build the layout structure:
285
+ ```json
286
+ {
287
+ "type": "page",
288
+ "regions": [
289
+ { "id": "toolbar", "position": "top", "components": [
290
+ { "type": "FilterBar", "resourceRef": "{module}-filters" },
291
+ { "type": "ActionMenu", "resourceRef": "{module}-actions", "permission": "business.{app}.{module}.create" }
292
+ ]},
293
+ { "id": "content", "position": "main", "span": 12, "components": [
294
+ { "type": "SmartTable", "resourceRef": "{module}-grid" }
295
+ ]}
296
+ ]
297
+ }
298
+ ```
299
+ 4. Cross-validate: each component in layout.regions[].components[] MUST have a corresponding resource in sections[].resources[]
300
+ 5. Write layout alongside mockup in uiWireframes[]
301
+
302
+ **RULE:** The layout is the source of truth for ralph-loop. The mockup is for human validation only.
303
+
304
+ ### 3c. Identify Resources per Section
305
+
306
+ For each section, identify what resources/components are needed:
307
+
308
+ - List section → DataGrid, FilterBar, SearchInput, ExportButton
309
+ - Detail section → DetailCard, StatusBadge, ActionButtons, Timeline
310
+ - Create section → Form, ValidationMessages, SubmitButton
311
+ - Approve section → StatusTransitionPanel, CommentBox, ApproveRejectButtons
312
+ - Dashboard section → StatCard, RechartsChart (Bar/Line/Pie/Area), DashboardGrid, FilterBar
313
+
314
+ ### 3d. Dashboard Specification (if section = dashboard)
315
+
316
+ When a "dashboard" section is selected, capture structured KPI and chart data **in addition** to the standard ASCII mockup.
317
+
318
+ 1. **Ask client for KPIs** via AskUserQuestion (batch):
319
+ - KPI name and metric description
320
+ - Visualization type: `kpi-card`, `bar`, `line`, `pie`, `area`, `donut`, `stacked-bar`
321
+ - Data source entity
322
+ - Format: `number`, `currency`, `percent`, `duration`
323
+ - Thresholds (warning/critical) if applicable
324
+
325
+ 2. **Ask client for filters:**
326
+ - Date range filter? Default period? (day/week/month/quarter/year)
327
+ - Entity-based filters? (status, category, etc.)
328
+
329
+ 3. **Ask client for refresh mode:**
330
+ - Static (load on page open)
331
+ - Polling (periodic refresh)
332
+ - SignalR (real-time push)
333
+
334
+ 4. **Store in specification.dashboards[]:**
335
+
336
+ ```json
337
+ {
338
+ "code": "{module}-dashboard",
339
+ "title": "{Module} Dashboard",
340
+ "description": "Vue d'ensemble des métriques {module}",
341
+ "linkedUCs": ["UC-XXX"],
342
+ "refreshMode": "static",
343
+ "defaultPeriod": "month",
344
+ "kpis": [
345
+ {
346
+ "code": "total-items",
347
+ "label": "Total Items",
348
+ "metric": "COUNT(entity)",
349
+ "format": "number",
350
+ "visualization": "kpi-card",
351
+ "dataSource": "Entity",
352
+ "thresholds": { "warning": 100, "critical": 50 }
353
+ },
354
+ {
355
+ "code": "items-by-status",
356
+ "label": "Items by Status",
357
+ "metric": "COUNT(entity) GROUP BY status",
358
+ "format": "number",
359
+ "visualization": "pie",
360
+ "dataSource": "Entity",
361
+ "dimensions": ["status"]
362
+ }
363
+ ],
364
+ "filters": [
365
+ { "field": "dateRange", "type": "dateRange", "label": "Période" },
366
+ { "field": "status", "type": "multiselect", "label": "Statut" }
367
+ ],
368
+ "permissionsRequired": ["business.{app}.{module}.read"]
369
+ }
370
+ ```
371
+
372
+ 5. **ALSO generate the standard ASCII mockup** for the dashboard with KPI cards + chart placeholders:
373
+
374
+ ```
375
+ ╔═══════════════════════════════════════════════════════════════╗
376
+ ║ {Module} > Dashboard Période: [Ce mois ▾] ║
377
+ ╠═══════════════════════════════════════════════════════════════╣
378
+ ║ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ║
379
+ ║ │ KPI #1 │ │ KPI #2 │ │ KPI #3 │ │ KPI #4 │ ║
380
+ ║ │ 1,234 │ │ 567 │ │ 89.2% │ │ 12,400 │ ║
381
+ ║ │ ↑ +12% │ │ ↓ -3% │ │ → 0% │ │ ↑ +5% │ ║
382
+ ║ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ║
383
+ ╠═══════════════════════════════════════════════════════════════╣
384
+ ║ ┌─────────────────────────┐ ┌─────────────────────────┐ ║
385
+ ║ │ [Bar Chart] │ │ [Pie Chart] │ ║
386
+ ║ │ Items by Month │ │ Items by Status │ ║
387
+ ║ │ ████ │ │ ████████ │ ║
388
+ ║ │ ████ ████ │ │ ███ ███ │ ║
389
+ ║ │ ████ ████ ████ │ │ ██ 42% ██ │ ║
390
+ ║ └─────────────────────────┘ └─────────────────────────┘ ║
391
+ ╚═══════════════════════════════════════════════════════════════╝
392
+ ```
393
+
394
+ Store the mockup in specification.wireframes[] AS WELL (for visual reference).
395
+
396
+ ---
397
+
398
+ ## SELF-VERIFICATION (MANDATORY before loading step-03c-compile)
399
+
400
+ Before proceeding to step-03c-compile.md, VERIFY:
401
+
402
+ 1. **Wireframes exist for all sections** in `specification.uiWireframes[]`
403
+ 2. **All wireframes have componentMapping** with smarter mapping rules
404
+ 3. **All wireframes have layout** with regions and resourceRef references
405
+ 4. **All resource references** in layout.regions[].components[].resourceRef exist in sections[].resources[]
406
+ 5. **State machines defined** (if module has status fields) in `specification.lifeCycles[]`
407
+
408
+ **IF any check fails → FIX before proceeding.** Do NOT load step-03c-compile with incomplete data.
409
+
410
+ ---
411
+
412
+ ## NEXT STEP
413
+
414
+ Load: `steps/step-03c-compile.md`