@atlashub/smartstack-cli 4.26.0 → 4.28.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 (27) hide show
  1. package/dist/mcp-entry.mjs +33 -11
  2. package/dist/mcp-entry.mjs.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/agents/ba-writer.md +46 -46
  5. package/templates/project/appsettings.json.template +4 -6
  6. package/templates/skills/apex/SKILL.md +1 -0
  7. package/templates/skills/apex/references/challenge-questions.md +17 -0
  8. package/templates/skills/apex/references/core-seed-data.md +27 -4
  9. package/templates/skills/apex/references/post-checks.md +330 -0
  10. package/templates/skills/apex/references/smartstack-layers.md +31 -0
  11. package/templates/skills/apex/steps/step-02-plan.md +9 -0
  12. package/templates/skills/apex/steps/step-03-execute.md +102 -4
  13. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +33 -0
  14. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +17 -0
  15. package/templates/skills/business-analyse/references/spec-auto-inference.md +12 -7
  16. package/templates/skills/business-analyse/steps/step-00-init.md +19 -9
  17. package/templates/skills/business-analyse/steps/step-02-structure.md +20 -6
  18. package/templates/skills/business-analyse/steps/step-03-specify.md +7 -0
  19. package/templates/skills/business-analyse/steps/step-04-consolidate.md +2 -14
  20. package/templates/skills/controller/references/mcp-scaffold-workflow.md +20 -0
  21. package/templates/skills/derive-prd/references/handoff-file-templates.md +25 -1
  22. package/templates/skills/derive-prd/references/handoff-seeddata-generation.md +3 -1
  23. package/templates/skills/ralph-loop/references/category-completeness.md +125 -0
  24. package/templates/skills/ralph-loop/references/compact-loop.md +90 -3
  25. package/templates/skills/ralph-loop/references/module-transition.md +60 -0
  26. package/templates/skills/ralph-loop/steps/step-04-check.md +207 -12
  27. package/templates/skills/ralph-loop/steps/step-05-report.md +205 -14
@@ -63,24 +63,136 @@ if (fileExists(queuePath)) {
63
63
  }
64
64
  ```
65
65
 
66
- ### 1d. Artifact Verification (Post-Execution Validation)
66
+ ### 1d. Handoff Reconciliation (Post-Execution Validation)
67
+
68
+ > **LESSON LEARNED (audit ba-002):** Simple "missing files" warnings were ignored.
69
+ > Structured reconciliation tables make gaps impossible to miss.
67
70
 
68
71
  ```javascript
69
- // Verify key artifacts exist on disk
70
- const allFiles = prd.implementation?.filesToCreate || {};
71
- const missingFiles = [];
72
- for (const cat of Object.keys(allFiles)) {
73
- for (const file of allFiles[cat] || []) {
74
- if (!fileExists(file.path)) missingFiles.push(file.path);
72
+ // === RECONCILIATION 1: Handoff File Coverage ===
73
+ const filesToCreate = prd.implementation?.filesToCreate || {};
74
+ const handoffReconciliation = { categories: [], totalDeclared: 0, totalPresent: 0, missingFiles: [] };
75
+
76
+ for (const [cat, files] of Object.entries(filesToCreate)) {
77
+ let declared = 0, present = 0;
78
+ for (const file of (files || [])) {
79
+ declared++;
80
+ const filePath = file.path || file;
81
+ if (fileExists(filePath)) {
82
+ present++;
83
+ } else {
84
+ handoffReconciliation.missingFiles.push({ category: cat, path: filePath });
85
+ }
75
86
  }
87
+ handoffReconciliation.categories.push({
88
+ category: cat, declared, present, missing: declared - present,
89
+ coverage: declared > 0 ? Math.round((present / declared) * 100) : 100
90
+ });
91
+ handoffReconciliation.totalDeclared += declared;
92
+ handoffReconciliation.totalPresent += present;
76
93
  }
77
- if (missingFiles.length > 0) {
78
- console.warn(`WARNING: ${missingFiles.length} files declared in PRD but not found on disk`);
79
- for (const f of missingFiles.slice(0, 10)) {
80
- console.warn(` MISSING: ${f}`);
94
+
95
+ const totalHandoffCoverage = handoffReconciliation.totalDeclared > 0
96
+ ? Math.round((handoffReconciliation.totalPresent / handoffReconciliation.totalDeclared) * 100)
97
+ : 100;
98
+
99
+ // === RECONCILIATION 2: Business Rule Coverage ===
100
+ const brMapping = prd.implementation?.brToCodeMapping || [];
101
+ const brReconciliation = { total: brMapping.length, implemented: 0, missing: [], notTested: [] };
102
+
103
+ for (const br of brMapping) {
104
+ const componentFile = br.component || br.file;
105
+ const methodName = br.method || br.function;
106
+
107
+ if (!componentFile || !fileExists(componentFile)) {
108
+ brReconciliation.missing.push({ id: br.id, rule: br.rule, reason: 'file not found' });
109
+ continue;
110
+ }
111
+ if (methodName) {
112
+ const content = readFile(componentFile);
113
+ if (!content.includes(methodName)) {
114
+ brReconciliation.missing.push({ id: br.id, rule: br.rule, reason: `method ${methodName} not found` });
115
+ continue;
116
+ }
117
+ }
118
+ brReconciliation.implemented++;
119
+
120
+ if (br.testFile && !fileExists(br.testFile)) {
121
+ brReconciliation.notTested.push({ id: br.id, rule: br.rule });
122
+ }
123
+ }
124
+
125
+ // === RECONCILIATION 3: API Endpoint Coverage ===
126
+ const apiEndpoints = prd.implementation?.apiEndpointSummary || [];
127
+ const apiReconciliation = { total: apiEndpoints.length, found: 0, missing: [] };
128
+
129
+ const ctrlFilesForReconciliation = glob('src/**/Controllers/**/*Controller.cs');
130
+ for (const ep of apiEndpoints) {
131
+ const opName = ep.operation || ep.name;
132
+ let found = false;
133
+ for (const f of ctrlFilesForReconciliation) {
134
+ const content = readFile(f);
135
+ if (content.includes(opName)) { found = true; break; }
81
136
  }
82
- if (missingFiles.length > 10) {
83
- console.warn(` ... and ${missingFiles.length - 10} more`);
137
+ if (found) {
138
+ apiReconciliation.found++;
139
+ } else {
140
+ apiReconciliation.missing.push({ operation: opName, method: ep.method, path: ep.path });
141
+ }
142
+ }
143
+
144
+ // Log summary
145
+ console.log(`Handoff files: ${handoffReconciliation.totalPresent}/${handoffReconciliation.totalDeclared} (${totalHandoffCoverage}%)`);
146
+ console.log(`Business rules: ${brReconciliation.implemented}/${brReconciliation.total} implemented`);
147
+ console.log(`API endpoints: ${apiReconciliation.found}/${apiReconciliation.total} found`);
148
+ ```
149
+
150
+ ### 1e. Final Build & Test Verification (TRUTH CHECK)
151
+
152
+ > **LESSON LEARNED (audit ba-002):** "92/92 COMPLETE" + "Build PASS" was reported but the code
153
+ > had compilation errors and critical security flaws. The report MUST reflect actual build/test
154
+ > state, not just PRD task statuses.
155
+
156
+ ```bash
157
+ # REAL build verification — overrides any previous "Build PASS" claim
158
+ dotnet build --no-restore --verbosity quiet
159
+ FINAL_BUILD_RC=$?
160
+
161
+ FINAL_TEST_RC=-1
162
+ if [ $FINAL_BUILD_RC -eq 0 ]; then
163
+ dotnet test --no-build --verbosity quiet
164
+ FINAL_TEST_RC=$?
165
+ fi
166
+ ```
167
+
168
+ ```javascript
169
+ // Override PRD-based build/test status with REAL results
170
+ const buildStatus = FINAL_BUILD_RC === 0 ? 'PASS' : 'FAIL';
171
+ const testStatus = FINAL_TEST_RC === 0 ? 'PASS' : (FINAL_TEST_RC === -1 ? 'SKIPPED (build failed)' : 'FAIL');
172
+
173
+ // CRITICAL: If build fails despite all tasks "completed", flag this prominently
174
+ if (FINAL_BUILD_RC !== 0 && stats.tasks.completed === stats.tasks.total) {
175
+ console.error('INTEGRITY WARNING: All tasks marked COMPLETE but build FAILS');
176
+ console.error('This indicates phantom task completion — review code quality');
177
+ stats.buildIntegrityWarning = true;
178
+ }
179
+ ```
180
+
181
+ ### 1f. MCP Security Scan (Final Gate)
182
+
183
+ ```javascript
184
+ // Quick MCP security validation on the final codebase
185
+ const securityScan = await mcp__smartstack__validate_security();
186
+ const conventionScan = await mcp__smartstack__validate_conventions();
187
+
188
+ // Check for write endpoints with Read permissions (semantic permission check)
189
+ const permissionWarnings = [];
190
+ const ctrlFiles = glob('src/**/Controllers/**/*Controller.cs');
191
+ for (const f of ctrlFiles) {
192
+ const content = readFile(f);
193
+ const writeWithRead = content.matchAll(/\[(HttpPost|HttpPut|HttpDelete|HttpPatch)[^\]]*\][^[]*\[RequirePermission\([^\)]*\.Read\)\]/gs);
194
+ for (const m of writeWithRead) {
195
+ permissionWarnings.push(`${f}: ${m[1]} uses Read permission`);
84
196
  }
85
197
  }
86
198
  ```
@@ -138,7 +250,86 @@ Write to `.ralph/reports/{feature-slug}.md`:
138
250
 
139
251
  {end if}
140
252
 
141
- ## Test Metrics
253
+ {if handoffReconciliation.totalDeclared > 0:}
254
+ ## Handoff Reconciliation
255
+
256
+ ### File Coverage by Category
257
+ | Category | Declared | Present | Missing | Coverage |
258
+ |----------|----------|---------|---------|----------|
259
+ {for each cat in handoffReconciliation.categories:}
260
+ | {category} | {declared} | {present} | {missing} | {coverage}% |
261
+ {end for}
262
+
263
+ **Total: {totalPresent}/{totalDeclared} ({totalHandoffCoverage}%)**
264
+
265
+ {if handoffReconciliation.missingFiles.length > 0:}
266
+ ### Missing Files
267
+ {for each mf in handoffReconciliation.missingFiles:}
268
+ - **{mf.category}**: `{mf.path}`
269
+ {end for}
270
+ {end if}
271
+ {end if}
272
+
273
+ {if brReconciliation.total > 0:}
274
+ ### Business Rule Coverage
275
+ | Metric | Value |
276
+ |--------|-------|
277
+ | Total Rules | {brReconciliation.total} |
278
+ | Implemented | {brReconciliation.implemented} |
279
+ | Missing | {brReconciliation.missing.length} |
280
+ | Not Tested | {brReconciliation.notTested.length} |
281
+
282
+ {if brReconciliation.missing.length > 0:}
283
+ **Missing BR implementations:**
284
+ {for each br in brReconciliation.missing:}
285
+ - `{br.id}`: {br.rule} — {br.reason}
286
+ {end for}
287
+ {end if}
288
+ {end if}
289
+
290
+ {if apiReconciliation.total > 0:}
291
+ ### API Endpoint Coverage
292
+ | Metric | Value |
293
+ |--------|-------|
294
+ | Total Endpoints | {apiReconciliation.total} |
295
+ | Found | {apiReconciliation.found} |
296
+ | Missing | {apiReconciliation.missing.length} |
297
+
298
+ {if apiReconciliation.missing.length > 0:}
299
+ **Missing API endpoints:**
300
+ {for each ep in apiReconciliation.missing:}
301
+ - `{ep.method} {ep.path}` — operation: `{ep.operation}`
302
+ {end for}
303
+ {end if}
304
+ {end if}
305
+
306
+ ## Build & Test Verification (Actual)
307
+
308
+ > These results come from REAL `dotnet build` and `dotnet test` execution,
309
+ > not from PRD task statuses.
310
+
311
+ | Check | Result |
312
+ |-------|--------|
313
+ | `dotnet build` | {buildStatus} |
314
+ | `dotnet test` | {testStatus} |
315
+ | MCP validate_security | {securityScan.status} |
316
+ | MCP validate_conventions | {conventionScan.status} |
317
+ | Permission semantic check | {permissionWarnings.length === 0 ? 'PASS' : `${permissionWarnings.length} issues`} |
318
+
319
+ {if stats.buildIntegrityWarning:}
320
+ > **INTEGRITY WARNING:** All tasks marked COMPLETE but the build FAILS.
321
+ > This means some generated code references types or methods that don't exist.
322
+ > Review the build output and fix before considering this feature done.
323
+ {end if}
324
+
325
+ {if permissionWarnings.length > 0:}
326
+ > **PERMISSION WARNINGS:** Write endpoints using Read permissions detected:
327
+ {for each warning:}
328
+ > - {warning}
329
+ {end for}
330
+ {end if}
331
+
332
+ ## Test Metrics (PRD-based)
142
333
  | Metric | Value |
143
334
  |--------|-------|
144
335
  | Test Tasks | {testTasks.length} |