clavix 4.7.0 → 4.8.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/cli/commands/execute.js +29 -9
- package/dist/cli/commands/verify.d.ts +28 -0
- package/dist/cli/commands/verify.js +347 -0
- package/dist/core/basic-checklist-generator.d.ts +35 -0
- package/dist/core/basic-checklist-generator.js +344 -0
- package/dist/core/checklist-parser.d.ts +48 -0
- package/dist/core/checklist-parser.js +238 -0
- package/dist/core/prompt-manager.d.ts +7 -0
- package/dist/core/prompt-manager.js +47 -22
- package/dist/core/verification-hooks.d.ts +67 -0
- package/dist/core/verification-hooks.js +309 -0
- package/dist/core/verification-manager.d.ts +106 -0
- package/dist/core/verification-manager.js +422 -0
- package/dist/templates/slash-commands/_canonical/execute.md +72 -1
- package/dist/templates/slash-commands/_canonical/verify.md +292 -0
- package/dist/templates/slash-commands/_components/agent-protocols/verification-methods.md +184 -0
- package/dist/types/verification.d.ts +204 -0
- package/dist/types/verification.js +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clavix v4.8: Verification Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages verification state, execution flow, and persistence.
|
|
5
|
+
* Coordinates between checklist parsing, hook execution, and result storage.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { ChecklistParser } from './checklist-parser.js';
|
|
10
|
+
import { VerificationHooks } from './verification-hooks.js';
|
|
11
|
+
import { PromptManager } from './prompt-manager.js';
|
|
12
|
+
/**
|
|
13
|
+
* Verification Manager
|
|
14
|
+
*/
|
|
15
|
+
export class VerificationManager {
|
|
16
|
+
promptManager;
|
|
17
|
+
checklistParser;
|
|
18
|
+
verificationHooks;
|
|
19
|
+
outputDir;
|
|
20
|
+
constructor(baseDir) {
|
|
21
|
+
this.outputDir = baseDir || path.join(process.cwd(), '.clavix', 'outputs', 'prompts');
|
|
22
|
+
this.promptManager = new PromptManager(this.outputDir);
|
|
23
|
+
this.checklistParser = new ChecklistParser();
|
|
24
|
+
this.verificationHooks = new VerificationHooks();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize verification for a prompt
|
|
28
|
+
*/
|
|
29
|
+
async initializeVerification(promptId) {
|
|
30
|
+
// Load prompt
|
|
31
|
+
const promptData = await this.promptManager.loadPrompt(promptId);
|
|
32
|
+
if (!promptData) {
|
|
33
|
+
throw new Error(`Prompt not found: ${promptId}`);
|
|
34
|
+
}
|
|
35
|
+
// Parse checklist from prompt content
|
|
36
|
+
const checklist = this.checklistParser.parse(promptData.content);
|
|
37
|
+
// Get all items
|
|
38
|
+
const items = [...checklist.validationItems, ...checklist.edgeCases, ...checklist.risks];
|
|
39
|
+
// Detect available hooks
|
|
40
|
+
const detectedHooks = await this.verificationHooks.detectHooks();
|
|
41
|
+
// Create initial report
|
|
42
|
+
const report = {
|
|
43
|
+
version: '1.0',
|
|
44
|
+
promptId,
|
|
45
|
+
source: promptData.metadata.source,
|
|
46
|
+
startedAt: new Date().toISOString(),
|
|
47
|
+
status: items.length > 0 ? 'pending' : 'completed',
|
|
48
|
+
items,
|
|
49
|
+
results: items.map((item) => ({
|
|
50
|
+
itemId: item.id,
|
|
51
|
+
status: 'pending',
|
|
52
|
+
method: item.verificationType === 'automated' ? 'automated' : 'manual',
|
|
53
|
+
confidence: 'low',
|
|
54
|
+
verifiedAt: '',
|
|
55
|
+
})),
|
|
56
|
+
summary: this.calculateSummary([]),
|
|
57
|
+
detectedHooks,
|
|
58
|
+
};
|
|
59
|
+
// Save initial report
|
|
60
|
+
await this.saveReport(report);
|
|
61
|
+
return report;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get verification report path for a prompt
|
|
65
|
+
*/
|
|
66
|
+
getReportPath(promptId, source) {
|
|
67
|
+
return path.join(this.outputDir, source, `${promptId}.verification.json`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load verification report
|
|
71
|
+
*/
|
|
72
|
+
async loadReport(promptId) {
|
|
73
|
+
// Try both sources
|
|
74
|
+
for (const source of ['deep', 'fast']) {
|
|
75
|
+
const reportPath = this.getReportPath(promptId, source);
|
|
76
|
+
if (await fs.pathExists(reportPath)) {
|
|
77
|
+
try {
|
|
78
|
+
return await fs.readJson(reportPath);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Corrupt file, ignore
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Save verification report
|
|
89
|
+
*/
|
|
90
|
+
async saveReport(report) {
|
|
91
|
+
const reportPath = this.getReportPath(report.promptId, report.source);
|
|
92
|
+
await fs.ensureDir(path.dirname(reportPath));
|
|
93
|
+
await fs.writeJson(reportPath, report, { spaces: 2 });
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Mark a single item as verified
|
|
97
|
+
*/
|
|
98
|
+
async markItemVerified(promptId, itemId, status, options = {}) {
|
|
99
|
+
let report = await this.loadReport(promptId);
|
|
100
|
+
if (!report) {
|
|
101
|
+
// Initialize if doesn't exist
|
|
102
|
+
report = await this.initializeVerification(promptId);
|
|
103
|
+
}
|
|
104
|
+
// Find and update result
|
|
105
|
+
const resultIndex = report.results.findIndex((r) => r.itemId === itemId);
|
|
106
|
+
if (resultIndex === -1) {
|
|
107
|
+
throw new Error(`Item not found: ${itemId}`);
|
|
108
|
+
}
|
|
109
|
+
const item = report.items.find((i) => i.id === itemId);
|
|
110
|
+
report.results[resultIndex] = {
|
|
111
|
+
itemId,
|
|
112
|
+
status,
|
|
113
|
+
method: options.method || (item?.verificationType === 'automated' ? 'automated' : 'manual'),
|
|
114
|
+
confidence: options.confidence || 'medium',
|
|
115
|
+
evidence: options.evidence,
|
|
116
|
+
reason: options.reason,
|
|
117
|
+
verifiedAt: new Date().toISOString(),
|
|
118
|
+
};
|
|
119
|
+
// Recalculate summary and status
|
|
120
|
+
report.summary = this.calculateSummary(report.results);
|
|
121
|
+
report.status = this.calculateReportStatus(report.results);
|
|
122
|
+
if (report.status === 'completed') {
|
|
123
|
+
report.completedAt = new Date().toISOString();
|
|
124
|
+
}
|
|
125
|
+
await this.saveReport(report);
|
|
126
|
+
return report;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Run automated verification for a prompt
|
|
130
|
+
*/
|
|
131
|
+
async runAutomatedVerification(promptId) {
|
|
132
|
+
let report = await this.loadReport(promptId);
|
|
133
|
+
if (!report) {
|
|
134
|
+
report = await this.initializeVerification(promptId);
|
|
135
|
+
}
|
|
136
|
+
// Find automated items that are pending
|
|
137
|
+
const automatedItems = report.items.filter((item) => item.verificationType === 'automated' &&
|
|
138
|
+
report.results.find((r) => r.itemId === item.id)?.status === 'pending');
|
|
139
|
+
if (automatedItems.length === 0) {
|
|
140
|
+
return report;
|
|
141
|
+
}
|
|
142
|
+
// Detect hooks
|
|
143
|
+
const detectedHooks = await this.verificationHooks.detectHooks();
|
|
144
|
+
// Run relevant hooks
|
|
145
|
+
const hookResults = await this.verificationHooks.runAllHooks();
|
|
146
|
+
// Map hook results to checklist items
|
|
147
|
+
for (const item of automatedItems) {
|
|
148
|
+
const lowerContent = item.content.toLowerCase();
|
|
149
|
+
// Match item to hook result
|
|
150
|
+
let matched = false;
|
|
151
|
+
for (const hookResult of hookResults) {
|
|
152
|
+
if (this.matchItemToHook(lowerContent, hookResult.hook.name)) {
|
|
153
|
+
const resultIndex = report.results.findIndex((r) => r.itemId === item.id);
|
|
154
|
+
if (resultIndex !== -1) {
|
|
155
|
+
report.results[resultIndex] = {
|
|
156
|
+
itemId: item.id,
|
|
157
|
+
status: hookResult.success ? 'passed' : 'failed',
|
|
158
|
+
method: 'automated',
|
|
159
|
+
confidence: hookResult.confidence,
|
|
160
|
+
evidence: this.truncateOutput(hookResult.output),
|
|
161
|
+
reason: hookResult.success ? undefined : 'Hook failed',
|
|
162
|
+
verifiedAt: new Date().toISOString(),
|
|
163
|
+
};
|
|
164
|
+
matched = true;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// If no hook matched, mark as requiring manual verification
|
|
170
|
+
if (!matched) {
|
|
171
|
+
const resultIndex = report.results.findIndex((r) => r.itemId === item.id);
|
|
172
|
+
if (resultIndex !== -1 && report.results[resultIndex].status === 'pending') {
|
|
173
|
+
report.results[resultIndex].method = 'manual';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Update summary and status
|
|
178
|
+
report.summary = this.calculateSummary(report.results);
|
|
179
|
+
report.status = this.calculateReportStatus(report.results);
|
|
180
|
+
report.detectedHooks = detectedHooks;
|
|
181
|
+
await this.saveReport(report);
|
|
182
|
+
return report;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Match checklist item content to hook type
|
|
186
|
+
*/
|
|
187
|
+
matchItemToHook(content, hookName) {
|
|
188
|
+
const hookKeywords = {
|
|
189
|
+
test: ['tests pass', 'test pass', 'all tests', 'unit test', 'test coverage'],
|
|
190
|
+
build: ['compiles', 'builds', 'build succeeds', 'no errors', 'runs without errors'],
|
|
191
|
+
lint: ['lint', 'no warnings', 'style guide', 'conventions'],
|
|
192
|
+
typecheck: ['typecheck', 'type check', 'type errors', 'typescript'],
|
|
193
|
+
};
|
|
194
|
+
const keywords = hookKeywords[hookName] || [];
|
|
195
|
+
return keywords.some((kw) => content.includes(kw));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Truncate output for storage
|
|
199
|
+
*/
|
|
200
|
+
truncateOutput(output, maxLength = 500) {
|
|
201
|
+
if (output.length <= maxLength) {
|
|
202
|
+
return output;
|
|
203
|
+
}
|
|
204
|
+
return output.substring(0, maxLength) + '... (truncated)';
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Calculate summary from results
|
|
208
|
+
*/
|
|
209
|
+
calculateSummary(results) {
|
|
210
|
+
const total = results.length;
|
|
211
|
+
const passed = results.filter((r) => r.status === 'passed').length;
|
|
212
|
+
const failed = results.filter((r) => r.status === 'failed').length;
|
|
213
|
+
const skipped = results.filter((r) => r.status === 'skipped').length;
|
|
214
|
+
const notApplicable = results.filter((r) => r.status === 'not-applicable').length;
|
|
215
|
+
const automatedChecks = results.filter((r) => r.method === 'automated').length;
|
|
216
|
+
const manualChecks = results.filter((r) => r.method === 'manual' || r.method === 'semi-automated').length;
|
|
217
|
+
const denominator = total - skipped - notApplicable;
|
|
218
|
+
const coveragePercent = denominator > 0 ? Math.round((passed / denominator) * 100) : 0;
|
|
219
|
+
return {
|
|
220
|
+
total,
|
|
221
|
+
passed,
|
|
222
|
+
failed,
|
|
223
|
+
skipped,
|
|
224
|
+
notApplicable,
|
|
225
|
+
coveragePercent,
|
|
226
|
+
automatedChecks,
|
|
227
|
+
manualChecks,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Calculate overall report status
|
|
232
|
+
*/
|
|
233
|
+
calculateReportStatus(results) {
|
|
234
|
+
const pending = results.filter((r) => r.status === 'pending').length;
|
|
235
|
+
const failed = results.filter((r) => r.status === 'failed').length;
|
|
236
|
+
if (pending === results.length) {
|
|
237
|
+
return 'pending';
|
|
238
|
+
}
|
|
239
|
+
if (pending > 0) {
|
|
240
|
+
return 'in-progress';
|
|
241
|
+
}
|
|
242
|
+
if (failed > 0) {
|
|
243
|
+
return 'requires-attention';
|
|
244
|
+
}
|
|
245
|
+
return 'completed';
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Get pending items from report
|
|
249
|
+
*/
|
|
250
|
+
getPendingItems(report) {
|
|
251
|
+
const pendingIds = new Set(report.results.filter((r) => r.status === 'pending').map((r) => r.itemId));
|
|
252
|
+
return report.items.filter((item) => pendingIds.has(item.id));
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get failed items from report
|
|
256
|
+
*/
|
|
257
|
+
getFailedItems(report) {
|
|
258
|
+
return report.results
|
|
259
|
+
.filter((r) => r.status === 'failed')
|
|
260
|
+
.map((result) => ({
|
|
261
|
+
item: report.items.find((i) => i.id === result.itemId),
|
|
262
|
+
result,
|
|
263
|
+
}))
|
|
264
|
+
.filter((r) => r.item);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Check if verification is complete
|
|
268
|
+
*/
|
|
269
|
+
isComplete(report) {
|
|
270
|
+
return report.status === 'completed';
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Check if verification requires attention (has failures)
|
|
274
|
+
*/
|
|
275
|
+
requiresAttention(report) {
|
|
276
|
+
return report.status === 'requires-attention';
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Delete verification report
|
|
280
|
+
*/
|
|
281
|
+
async deleteReport(promptId) {
|
|
282
|
+
for (const source of ['deep', 'fast']) {
|
|
283
|
+
const reportPath = this.getReportPath(promptId, source);
|
|
284
|
+
if (await fs.pathExists(reportPath)) {
|
|
285
|
+
await fs.remove(reportPath);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get all verification reports
|
|
293
|
+
*/
|
|
294
|
+
async listReports() {
|
|
295
|
+
const reports = [];
|
|
296
|
+
for (const source of ['deep', 'fast']) {
|
|
297
|
+
const sourceDir = path.join(this.outputDir, source);
|
|
298
|
+
if (await fs.pathExists(sourceDir)) {
|
|
299
|
+
const files = await fs.readdir(sourceDir);
|
|
300
|
+
for (const file of files) {
|
|
301
|
+
if (file.endsWith('.verification.json')) {
|
|
302
|
+
try {
|
|
303
|
+
const report = await fs.readJson(path.join(sourceDir, file));
|
|
304
|
+
reports.push(report);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// Ignore corrupt files
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return reports;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get verification status for a prompt
|
|
317
|
+
*/
|
|
318
|
+
async getVerificationStatus(promptId) {
|
|
319
|
+
const report = await this.loadReport(promptId);
|
|
320
|
+
if (!report) {
|
|
321
|
+
return {
|
|
322
|
+
hasReport: false,
|
|
323
|
+
status: null,
|
|
324
|
+
summary: null,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
hasReport: true,
|
|
329
|
+
status: report.status,
|
|
330
|
+
summary: report.summary,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Format verification report for display
|
|
335
|
+
*/
|
|
336
|
+
formatReportForDisplay(report) {
|
|
337
|
+
const lines = [];
|
|
338
|
+
const sep = '═'.repeat(70);
|
|
339
|
+
lines.push(sep);
|
|
340
|
+
lines.push(' VERIFICATION REPORT');
|
|
341
|
+
lines.push(` ${report.promptId}`);
|
|
342
|
+
lines.push(sep);
|
|
343
|
+
lines.push('');
|
|
344
|
+
// Group results by category
|
|
345
|
+
const byCategory = new Map();
|
|
346
|
+
for (const item of report.items) {
|
|
347
|
+
const result = report.results.find((r) => r.itemId === item.id);
|
|
348
|
+
if (!result)
|
|
349
|
+
continue;
|
|
350
|
+
const category = item.category;
|
|
351
|
+
if (!byCategory.has(category)) {
|
|
352
|
+
byCategory.set(category, []);
|
|
353
|
+
}
|
|
354
|
+
byCategory.get(category).push({ item, result });
|
|
355
|
+
}
|
|
356
|
+
// Display each category
|
|
357
|
+
for (const [category, items] of byCategory.entries()) {
|
|
358
|
+
const categoryName = category === 'validation'
|
|
359
|
+
? 'VALIDATION CHECKLIST'
|
|
360
|
+
: category === 'edge-case'
|
|
361
|
+
? 'EDGE CASES'
|
|
362
|
+
: 'RISKS';
|
|
363
|
+
lines.push(`📋 ${categoryName} (${items.length} items)`);
|
|
364
|
+
lines.push('');
|
|
365
|
+
for (const { item, result } of items) {
|
|
366
|
+
const statusIcon = this.getStatusIcon(result.status);
|
|
367
|
+
const method = result.method === 'automated'
|
|
368
|
+
? '[automated]'
|
|
369
|
+
: result.method === 'semi-automated'
|
|
370
|
+
? '[semi-auto]'
|
|
371
|
+
: '[manual]';
|
|
372
|
+
lines.push(`${statusIcon} ${method} ${item.content}`);
|
|
373
|
+
if (result.evidence) {
|
|
374
|
+
lines.push(` Evidence: ${result.evidence.substring(0, 80)}`);
|
|
375
|
+
}
|
|
376
|
+
if (result.status === 'failed' && result.reason) {
|
|
377
|
+
lines.push(` Reason: ${result.reason}`);
|
|
378
|
+
}
|
|
379
|
+
if (result.confidence) {
|
|
380
|
+
lines.push(` Confidence: ${result.confidence.toUpperCase()}`);
|
|
381
|
+
}
|
|
382
|
+
lines.push('');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Summary
|
|
386
|
+
lines.push(sep);
|
|
387
|
+
lines.push(' SUMMARY');
|
|
388
|
+
lines.push(sep);
|
|
389
|
+
lines.push(`Total: ${report.summary.total} items`);
|
|
390
|
+
lines.push(`Passed: ${report.summary.passed} (${report.summary.coveragePercent}%)`);
|
|
391
|
+
lines.push(`Failed: ${report.summary.failed}${report.summary.failed > 0 ? ' (requires attention)' : ''}`);
|
|
392
|
+
lines.push(`Skipped: ${report.summary.skipped}`);
|
|
393
|
+
lines.push('');
|
|
394
|
+
lines.push(`Automated: ${report.summary.automatedChecks} checks`);
|
|
395
|
+
lines.push(`Manual: ${report.summary.manualChecks} checks`);
|
|
396
|
+
if (report.summary.failed > 0) {
|
|
397
|
+
lines.push('');
|
|
398
|
+
lines.push(`⚠️ ${report.summary.failed} item(s) require attention before marking complete`);
|
|
399
|
+
}
|
|
400
|
+
lines.push(sep);
|
|
401
|
+
return lines.join('\n');
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get status icon for display
|
|
405
|
+
*/
|
|
406
|
+
getStatusIcon(status) {
|
|
407
|
+
switch (status) {
|
|
408
|
+
case 'passed':
|
|
409
|
+
return '✅';
|
|
410
|
+
case 'failed':
|
|
411
|
+
return '❌';
|
|
412
|
+
case 'skipped':
|
|
413
|
+
return '⏭️';
|
|
414
|
+
case 'not-applicable':
|
|
415
|
+
return '➖';
|
|
416
|
+
case 'pending':
|
|
417
|
+
default:
|
|
418
|
+
return '⏳';
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=verification-manager.js.map
|
|
@@ -74,7 +74,78 @@ clavix execute --id <prompt-id>
|
|
|
74
74
|
1. Run `clavix execute --latest`
|
|
75
75
|
2. Read displayed prompt content
|
|
76
76
|
3. Implement requirements
|
|
77
|
-
4.
|
|
77
|
+
4. **REQUIRED: Run verification**: `clavix verify --latest`
|
|
78
|
+
5. After verification passes, cleanup: `clavix prompts clear --executed`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## ⚠️ REQUIRED: Post-Implementation Verification
|
|
83
|
+
|
|
84
|
+
**Verification is a REQUIRED step after implementation.**
|
|
85
|
+
|
|
86
|
+
After implementing the prompt requirements, you MUST verify your implementation against the checklist:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
clavix verify --latest
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### What Verification Does
|
|
93
|
+
|
|
94
|
+
1. **Loads the checklist** from your executed prompt (validation items, edge cases, risks)
|
|
95
|
+
2. **Runs automated hooks** (test, build, lint) for items that can be verified programmatically
|
|
96
|
+
3. **Guides manual verification** for items requiring human judgment
|
|
97
|
+
4. **Generates a verification report** with pass/fail status for each item
|
|
98
|
+
|
|
99
|
+
### Verification Report
|
|
100
|
+
|
|
101
|
+
The verification report shows:
|
|
102
|
+
- ✅ **Passed items** - Implementation covers the requirement
|
|
103
|
+
- ❌ **Failed items** - Implementation does NOT cover (with reason why)
|
|
104
|
+
- ⏭️ **Skipped items** - To be verified later
|
|
105
|
+
- ➖ **N/A items** - Does not apply to this implementation
|
|
106
|
+
|
|
107
|
+
### Fast Mode Prompts
|
|
108
|
+
|
|
109
|
+
Fast mode prompts don't have comprehensive checklists. When verifying a fast mode prompt:
|
|
110
|
+
- A **basic checklist is generated** based on detected intent
|
|
111
|
+
- Covers essential items (compiles, requirements met, no errors)
|
|
112
|
+
- For comprehensive checklists, use `/clavix:deep` instead
|
|
113
|
+
|
|
114
|
+
### Verification Commands
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Verify latest executed prompt
|
|
118
|
+
clavix verify --latest
|
|
119
|
+
|
|
120
|
+
# Verify specific prompt
|
|
121
|
+
clavix verify --id <prompt-id>
|
|
122
|
+
|
|
123
|
+
# Show verification status
|
|
124
|
+
clavix verify --status
|
|
125
|
+
|
|
126
|
+
# Re-run failed items only
|
|
127
|
+
clavix verify --retry-failed
|
|
128
|
+
|
|
129
|
+
# Export verification report
|
|
130
|
+
clavix verify --export markdown
|
|
131
|
+
clavix verify --export json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### After Verification
|
|
135
|
+
|
|
136
|
+
**If all items pass:**
|
|
137
|
+
```bash
|
|
138
|
+
# Cleanup executed prompts
|
|
139
|
+
clavix prompts clear --executed
|
|
140
|
+
|
|
141
|
+
# Or archive the project
|
|
142
|
+
/clavix:archive
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**If items fail:**
|
|
146
|
+
1. Review failed items and reasons
|
|
147
|
+
2. Fix implementation issues
|
|
148
|
+
3. Re-run verification: `clavix verify --retry-failed --id <prompt-id>`
|
|
78
149
|
|
|
79
150
|
---
|
|
80
151
|
|