@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.
- package/dist/mcp-entry.mjs +33 -11
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/ba-writer.md +46 -46
- package/templates/project/appsettings.json.template +4 -6
- package/templates/skills/apex/SKILL.md +1 -0
- package/templates/skills/apex/references/challenge-questions.md +17 -0
- package/templates/skills/apex/references/core-seed-data.md +27 -4
- package/templates/skills/apex/references/post-checks.md +330 -0
- package/templates/skills/apex/references/smartstack-layers.md +31 -0
- package/templates/skills/apex/steps/step-02-plan.md +9 -0
- package/templates/skills/apex/steps/step-03-execute.md +102 -4
- package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +33 -0
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +17 -0
- package/templates/skills/business-analyse/references/spec-auto-inference.md +12 -7
- package/templates/skills/business-analyse/steps/step-00-init.md +19 -9
- package/templates/skills/business-analyse/steps/step-02-structure.md +20 -6
- package/templates/skills/business-analyse/steps/step-03-specify.md +7 -0
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +2 -14
- package/templates/skills/controller/references/mcp-scaffold-workflow.md +20 -0
- package/templates/skills/derive-prd/references/handoff-file-templates.md +25 -1
- package/templates/skills/derive-prd/references/handoff-seeddata-generation.md +3 -1
- package/templates/skills/ralph-loop/references/category-completeness.md +125 -0
- package/templates/skills/ralph-loop/references/compact-loop.md +90 -3
- package/templates/skills/ralph-loop/references/module-transition.md +60 -0
- package/templates/skills/ralph-loop/steps/step-04-check.md +207 -12
- 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.
|
|
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
|
-
//
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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 (
|
|
83
|
-
|
|
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
|
-
|
|
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} |
|