@jaimevalasek/aioson 1.30.2 → 1.33.1
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/CHANGELOG.md +27 -0
- package/README.md +19 -6
- package/docs/en/5-reference/cli-reference.md +1 -1
- package/docs/pt/5-referencia/comandos-cli.md +1 -1
- package/docs/pt/5-referencia/harness-retro.md +2 -1
- package/package.json +1 -1
- package/src/cli.js +38 -21
- package/src/commands/classify.js +389 -327
- package/src/commands/harness-retro-promote.js +387 -0
- package/src/commands/prototype-check.js +163 -0
- package/src/commands/verify-implementation.js +428 -0
- package/src/commands/workflow-next.js +222 -9
- package/src/constants.js +2 -0
- package/src/lib/retro/retro-render.js +10 -1
- package/src/lib/retro/retro-sources.js +45 -27
- package/src/lib/retro/verification-reports.js +230 -0
- package/src/runtime-store.js +13 -9
- package/src/verification/evidence-bundle.js +251 -0
- package/src/verification/ledger-store.js +221 -0
- package/src/verification/path-policy.js +74 -0
- package/src/verification/policy-engine.js +95 -0
- package/src/verification/prompt-package.js +314 -0
- package/src/verification/redaction.js +77 -0
- package/src/verification/report-parser.js +132 -0
- package/src/verification/report-store.js +97 -0
- package/src/verification/result.js +16 -0
- package/src/verification/runners/index.js +319 -0
- package/src/verification/runtime-telemetry.js +144 -0
- package/src/verification/schema.js +276 -0
- package/src/verification/source-discovery.js +153 -0
- package/template/.aioson/agents/analyst.md +9 -6
- package/template/.aioson/agents/briefing-refiner.md +22 -0
- package/template/.aioson/agents/briefing.md +69 -12
- package/template/.aioson/agents/design-hybrid-forge.md +18 -14
- package/template/.aioson/agents/dev.md +23 -10
- package/template/.aioson/agents/deyvin.md +3 -2
- package/template/.aioson/agents/product.md +15 -11
- package/template/.aioson/agents/qa.md +13 -4
- package/template/.aioson/agents/scope-check.md +19 -5
- package/template/.aioson/agents/sheldon.md +4 -3
- package/template/.aioson/agents/ux-ui.md +3 -2
- package/template/.aioson/docs/feature-expansion-taxonomy.md +31 -3
- package/template/.aioson/docs/prototype-contract.md +81 -0
- package/template/.aioson/skills/process/briefing-expansion-scout/SKILL.md +25 -3
- package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +5 -3
- package/template/.aioson/skills/process/design-hybrid-forge/references/external-source-ingestion.md +89 -0
- package/template/.aioson/skills/process/product-scope-expansion/SKILL.md +29 -2
- package/template/.aioson/skills/process/prototype-forge/SKILL.md +92 -0
- package/template/.aioson/skills/process/sheldon-expansion-audit/SKILL.md +23 -2
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* aioson verify:implementation — deterministic local implementation verification pilot.
|
|
5
|
+
*
|
|
6
|
+
* Pilot modes:
|
|
7
|
+
* aioson verify:implementation . --feature=<slug> --prepare-ledger --json
|
|
8
|
+
* aioson verify:implementation . --feature=<slug> --check-ledger --json
|
|
9
|
+
* aioson verify:implementation . --feature=<slug> --build-prompt --json
|
|
10
|
+
* aioson verify:implementation . --feature=<slug> --check-report=<path> --policy=strict --json
|
|
11
|
+
* aioson verify:implementation . --feature=<slug> --tool=<codex|claude|opencode> --json
|
|
12
|
+
*
|
|
13
|
+
* This command prepares, validates, and can optionally run a constrained clean
|
|
14
|
+
* auditor. It does not claim final correctness and does not replace QA.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('node:fs/promises');
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
validateFeatureSlug,
|
|
21
|
+
resolveProjectRoot,
|
|
22
|
+
resolveInsideRoot
|
|
23
|
+
} = require('../verification/path-policy');
|
|
24
|
+
const { normalizePolicy, makeError } = require('../verification/result');
|
|
25
|
+
const { discoverSourceArtifacts } = require('../verification/source-discovery');
|
|
26
|
+
const {
|
|
27
|
+
prepareLedger,
|
|
28
|
+
checkLedger
|
|
29
|
+
} = require('../verification/ledger-store');
|
|
30
|
+
const { buildEvidenceBundle } = require('../verification/evidence-bundle');
|
|
31
|
+
const { buildAndWritePromptPackage } = require('../verification/prompt-package');
|
|
32
|
+
const { parseVerificationReport } = require('../verification/report-parser');
|
|
33
|
+
const { applyPolicy } = require('../verification/policy-engine');
|
|
34
|
+
const {
|
|
35
|
+
normalizeRunnerTool,
|
|
36
|
+
normalizeRunnerModel,
|
|
37
|
+
runnerLimits,
|
|
38
|
+
runAuditorTool
|
|
39
|
+
} = require('../verification/runners');
|
|
40
|
+
const {
|
|
41
|
+
runnerRunStem,
|
|
42
|
+
writeVerificationRunFile,
|
|
43
|
+
promoteLatestReport,
|
|
44
|
+
systemInconclusiveReport
|
|
45
|
+
} = require('../verification/report-store');
|
|
46
|
+
const { recordVerificationTelemetry } = require('../verification/runtime-telemetry');
|
|
47
|
+
|
|
48
|
+
const BAR = '━'.repeat(42);
|
|
49
|
+
|
|
50
|
+
function hasMode(options, mode) {
|
|
51
|
+
return Boolean(options && options[mode]);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function detectMode(options) {
|
|
55
|
+
const modes = [
|
|
56
|
+
'prepare-ledger',
|
|
57
|
+
'check-ledger',
|
|
58
|
+
'build-prompt',
|
|
59
|
+
'check-report'
|
|
60
|
+
].filter((mode) => hasMode(options, mode));
|
|
61
|
+
if (options && options.tool) modes.push('run-tool');
|
|
62
|
+
if (modes.length === 0) return { ok: false, reason: 'missing_mode' };
|
|
63
|
+
if (modes.length > 1) return { ok: false, reason: 'multiple_modes', modes };
|
|
64
|
+
return { ok: true, mode: modes[0] };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function emit(result, options, logger) {
|
|
68
|
+
if (options.json) return result;
|
|
69
|
+
logger.log('');
|
|
70
|
+
logger.log(`Implementation verification — ${result.feature_slug || 'unknown'}`);
|
|
71
|
+
logger.log(BAR);
|
|
72
|
+
logger.log(`Status: ${result.ok ? 'ok' : 'blocked'}`);
|
|
73
|
+
if (result.reason) logger.log(`Reason: ${result.reason}`);
|
|
74
|
+
if (result.mode) logger.log(`Mode: ${result.mode}`);
|
|
75
|
+
if (result.ledger_path) logger.log(`Ledger: ${result.ledger_path}`);
|
|
76
|
+
if (result.prompt_path) logger.log(`Prompt: ${result.prompt_path}`);
|
|
77
|
+
if (result.raw_report_path) logger.log(`Raw report: ${result.raw_report_path}`);
|
|
78
|
+
if (result.report_path) logger.log(`Report: ${result.report_path}`);
|
|
79
|
+
if (result.tool) logger.log(`Tool: ${result.tool}`);
|
|
80
|
+
if (result.model) logger.log(`Model: ${result.model}`);
|
|
81
|
+
if (result.verdict) logger.log(`Verdict: ${result.verdict}`);
|
|
82
|
+
if (result.recommended_route) logger.log(`Route: ${result.recommended_route}`);
|
|
83
|
+
if (Array.isArray(result.missing_sections) && result.missing_sections.length) {
|
|
84
|
+
logger.log(`Missing sections: ${result.missing_sections.join(', ')}`);
|
|
85
|
+
}
|
|
86
|
+
if (Array.isArray(result.errors) && result.errors.length) {
|
|
87
|
+
logger.log(`Errors: ${result.errors.map((e) => `${e.field}:${e.reason}`).join(', ')}`);
|
|
88
|
+
}
|
|
89
|
+
logger.log('');
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function runPrepareLedger({ rootDir, slug, options }) {
|
|
94
|
+
const sourceArtifacts = await discoverSourceArtifacts(rootDir, slug);
|
|
95
|
+
const result = await prepareLedger(rootDir, slug, sourceArtifacts);
|
|
96
|
+
return {
|
|
97
|
+
mode: 'prepare-ledger',
|
|
98
|
+
...result
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function runCheckLedger({ rootDir, slug }) {
|
|
103
|
+
const result = await checkLedger(rootDir, slug);
|
|
104
|
+
return {
|
|
105
|
+
mode: 'check-ledger',
|
|
106
|
+
...result
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function runBuildPrompt({ rootDir, slug, policy, options }) {
|
|
111
|
+
const ledgerResult = await checkLedger(rootDir, slug);
|
|
112
|
+
if (!ledgerResult.ok) {
|
|
113
|
+
return {
|
|
114
|
+
mode: 'build-prompt',
|
|
115
|
+
...ledgerResult,
|
|
116
|
+
ready_for_prompt: false
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (!ledgerResult.ready_for_prompt) {
|
|
120
|
+
return {
|
|
121
|
+
mode: 'build-prompt',
|
|
122
|
+
ok: false,
|
|
123
|
+
reason: 'ledger_not_ready_for_prompt',
|
|
124
|
+
feature_slug: slug,
|
|
125
|
+
ledger_path: ledgerResult.ledger_path,
|
|
126
|
+
missing_evidence: ledgerResult.missing_evidence || [],
|
|
127
|
+
ready_for_prompt: false
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const sourceArtifacts = await discoverSourceArtifacts(rootDir, slug, ledgerResult.ledger);
|
|
132
|
+
const evidenceBundle = await buildEvidenceBundle(rootDir, slug, ledgerResult.ledger, sourceArtifacts, policy);
|
|
133
|
+
return {
|
|
134
|
+
mode: 'build-prompt',
|
|
135
|
+
...(await buildAndWritePromptPackage({
|
|
136
|
+
rootDir,
|
|
137
|
+
slug,
|
|
138
|
+
policy,
|
|
139
|
+
ledger: ledgerResult.ledger,
|
|
140
|
+
evidenceBundle,
|
|
141
|
+
outPath: options.out || null
|
|
142
|
+
}))
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function runnerFailureReason(status) {
|
|
147
|
+
if (status === 'timeout') return 'runner_timeout';
|
|
148
|
+
if (status === 'output_limit') return 'runner_output_limit';
|
|
149
|
+
if (status === 'spawn_error') return 'runner_spawn_error';
|
|
150
|
+
if (status === 'failed') return 'runner_failed';
|
|
151
|
+
return 'runner_inconclusive';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function buildPromptForRunner({ rootDir, slug, policy, options }) {
|
|
155
|
+
const promptResult = await runBuildPrompt({ rootDir, slug, policy, options: { ...options, out: null } });
|
|
156
|
+
if (!promptResult.ok) return promptResult;
|
|
157
|
+
const safePrompt = resolveInsideRoot(rootDir, promptResult.prompt_path);
|
|
158
|
+
if (!safePrompt.ok) return safePrompt;
|
|
159
|
+
const promptText = await fs.readFile(safePrompt.path, 'utf8');
|
|
160
|
+
return {
|
|
161
|
+
...promptResult,
|
|
162
|
+
prompt_absolute_path: safePrompt.path,
|
|
163
|
+
prompt_text: promptText
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function writeSystemRunnerReport({ rootDir, slug, policy, stem, runner, reason, summary, stderrPath = null }) {
|
|
168
|
+
const command = runner && runner.command ? runner.command : 'auditor runner';
|
|
169
|
+
const evidence = stderrPath
|
|
170
|
+
? `Runner stderr was stored separately at ${stderrPath}; raw stderr is intentionally omitted from the latest verification report.`
|
|
171
|
+
: summary;
|
|
172
|
+
const markdown = systemInconclusiveReport({
|
|
173
|
+
slug,
|
|
174
|
+
policy,
|
|
175
|
+
summary,
|
|
176
|
+
command,
|
|
177
|
+
status: reason,
|
|
178
|
+
evidence
|
|
179
|
+
});
|
|
180
|
+
const runReport = await writeVerificationRunFile(rootDir, slug, stem, 'system-report.md', markdown);
|
|
181
|
+
const latest = await promoteLatestReport(rootDir, slug, markdown);
|
|
182
|
+
const parsed = await parseVerificationReport(rootDir, slug, latest.relative_path, policy);
|
|
183
|
+
const policyResult = parsed.ok
|
|
184
|
+
? applyPolicy(parsed.report, policy)
|
|
185
|
+
: { verdict: 'INCONCLUSIVE', recommended_route: 'qa', blocking_findings_count: 0, policy, reason };
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
reason,
|
|
189
|
+
verdict: policyResult.verdict,
|
|
190
|
+
recommended_route: policyResult.recommended_route,
|
|
191
|
+
blocking_findings_count: policyResult.blocking_findings_count,
|
|
192
|
+
report: parsed.ok ? parsed.report : null,
|
|
193
|
+
report_path: latest.relative_path,
|
|
194
|
+
run_report_path: runReport.relative_path
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function runToolAudit({ rootDir, slug, policy, options, spawnImpl }) {
|
|
199
|
+
const toolResult = normalizeRunnerTool(options.tool);
|
|
200
|
+
if (!toolResult.ok) {
|
|
201
|
+
return {
|
|
202
|
+
mode: 'run-tool',
|
|
203
|
+
ok: false,
|
|
204
|
+
verdict: 'INCONCLUSIVE',
|
|
205
|
+
recommended_route: 'qa',
|
|
206
|
+
...toolResult
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
const modelResult = normalizeRunnerModel(options.model);
|
|
210
|
+
if (!modelResult.ok) {
|
|
211
|
+
return {
|
|
212
|
+
mode: 'run-tool',
|
|
213
|
+
ok: false,
|
|
214
|
+
verdict: 'INCONCLUSIVE',
|
|
215
|
+
recommended_route: 'qa',
|
|
216
|
+
tool: toolResult.tool,
|
|
217
|
+
...modelResult
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const prompt = await buildPromptForRunner({ rootDir, slug, policy, options });
|
|
222
|
+
if (!prompt.ok) {
|
|
223
|
+
return {
|
|
224
|
+
mode: 'run-tool',
|
|
225
|
+
...prompt
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const limits = runnerLimits(options);
|
|
230
|
+
const runner = await runAuditorTool({
|
|
231
|
+
rootDir,
|
|
232
|
+
tool: options.tool,
|
|
233
|
+
model: options.model,
|
|
234
|
+
promptPath: prompt.prompt_absolute_path,
|
|
235
|
+
promptText: prompt.prompt_text,
|
|
236
|
+
limits,
|
|
237
|
+
spawnImpl
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
if (!runner.ok && ['unsupported_tool', 'missing_tool', 'invalid_model', 'tool_not_found'].includes(runner.reason)) {
|
|
241
|
+
return {
|
|
242
|
+
mode: 'run-tool',
|
|
243
|
+
ok: false,
|
|
244
|
+
verdict: 'INCONCLUSIVE',
|
|
245
|
+
recommended_route: 'qa',
|
|
246
|
+
...runner
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const stem = runnerRunStem({ tool: runner.tool || options.tool, model: runner.model || options.model });
|
|
251
|
+
const raw = await writeVerificationRunFile(rootDir, slug, stem, 'raw.md', runner.stdout || '');
|
|
252
|
+
let stderrFile = null;
|
|
253
|
+
if (runner.stderr) {
|
|
254
|
+
stderrFile = await writeVerificationRunFile(rootDir, slug, stem, 'stderr.txt', runner.stderr);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const base = {
|
|
258
|
+
mode: 'run-tool',
|
|
259
|
+
feature_slug: slug,
|
|
260
|
+
policy,
|
|
261
|
+
tool: runner.tool,
|
|
262
|
+
model: runner.model,
|
|
263
|
+
prompt_path: prompt.prompt_path,
|
|
264
|
+
raw_report_path: raw.relative_path,
|
|
265
|
+
stderr_path: stderrFile ? stderrFile.relative_path : null,
|
|
266
|
+
runner: {
|
|
267
|
+
status: runner.status,
|
|
268
|
+
command: runner.command,
|
|
269
|
+
permission_mode: runner.permission_mode,
|
|
270
|
+
destructive_commands_allowed: runner.destructive_commands_allowed,
|
|
271
|
+
timeout_ms: runner.timeout_ms,
|
|
272
|
+
max_output_bytes: runner.max_output_bytes,
|
|
273
|
+
duration_ms: runner.duration_ms,
|
|
274
|
+
exit_code: runner.exit_code,
|
|
275
|
+
signal: runner.signal,
|
|
276
|
+
output_bytes: runner.output_bytes,
|
|
277
|
+
output_truncated: runner.output_truncated,
|
|
278
|
+
detected: runner.detected
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
if (!runner.ok) {
|
|
283
|
+
const reason = runnerFailureReason(runner.status);
|
|
284
|
+
return {
|
|
285
|
+
...base,
|
|
286
|
+
...(await writeSystemRunnerReport({
|
|
287
|
+
rootDir,
|
|
288
|
+
slug,
|
|
289
|
+
policy,
|
|
290
|
+
stem,
|
|
291
|
+
runner,
|
|
292
|
+
reason,
|
|
293
|
+
summary: `Auditor runner did not complete successfully: ${runner.status}.`,
|
|
294
|
+
stderrPath: stderrFile ? stderrFile.relative_path : null
|
|
295
|
+
}))
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const parsed = await parseVerificationReport(rootDir, slug, raw.relative_path, policy);
|
|
300
|
+
if (!parsed.ok) {
|
|
301
|
+
return {
|
|
302
|
+
...base,
|
|
303
|
+
parse_error: parsed,
|
|
304
|
+
...(await writeSystemRunnerReport({
|
|
305
|
+
rootDir,
|
|
306
|
+
slug,
|
|
307
|
+
policy,
|
|
308
|
+
stem,
|
|
309
|
+
runner,
|
|
310
|
+
reason: 'invalid_runner_report',
|
|
311
|
+
summary: `Auditor output did not match the verification report contract: ${parsed.reason}.`,
|
|
312
|
+
stderrPath: stderrFile ? stderrFile.relative_path : null
|
|
313
|
+
}))
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const latest = await promoteLatestReport(rootDir, slug, runner.stdout);
|
|
318
|
+
const machineJson = await writeVerificationRunFile(
|
|
319
|
+
rootDir,
|
|
320
|
+
slug,
|
|
321
|
+
stem,
|
|
322
|
+
'report.json',
|
|
323
|
+
`${JSON.stringify(parsed.report, null, 2)}\n`
|
|
324
|
+
);
|
|
325
|
+
const policyResult = applyPolicy(parsed.report, policy);
|
|
326
|
+
return {
|
|
327
|
+
...base,
|
|
328
|
+
ok: policyResult.verdict === 'PASS',
|
|
329
|
+
report_path: latest.relative_path,
|
|
330
|
+
report_json_path: machineJson.relative_path,
|
|
331
|
+
run_report_path: raw.relative_path,
|
|
332
|
+
report: parsed.report,
|
|
333
|
+
verdict: policyResult.verdict,
|
|
334
|
+
recommended_route: policyResult.recommended_route,
|
|
335
|
+
blocking_findings_count: policyResult.blocking_findings_count,
|
|
336
|
+
reason: policyResult.reason
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function runCheckReport({ rootDir, slug, policy, options }) {
|
|
341
|
+
const reportPath = options['check-report'];
|
|
342
|
+
if (reportPath === true || !reportPath) {
|
|
343
|
+
return makeError('missing_report_path', {
|
|
344
|
+
mode: 'check-report',
|
|
345
|
+
feature_slug: slug
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const parsed = await parseVerificationReport(rootDir, slug, reportPath, policy);
|
|
350
|
+
if (!parsed.ok) {
|
|
351
|
+
return {
|
|
352
|
+
mode: 'check-report',
|
|
353
|
+
verdict: 'INCONCLUSIVE',
|
|
354
|
+
recommended_route: 'qa',
|
|
355
|
+
...parsed
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const policyResult = applyPolicy(parsed.report, policy);
|
|
360
|
+
return {
|
|
361
|
+
mode: 'check-report',
|
|
362
|
+
ok: policyResult.verdict === 'PASS',
|
|
363
|
+
feature_slug: slug,
|
|
364
|
+
report_path: parsed.report_path,
|
|
365
|
+
report: parsed.report,
|
|
366
|
+
verdict: policyResult.verdict,
|
|
367
|
+
recommended_route: policyResult.recommended_route,
|
|
368
|
+
blocking_findings_count: policyResult.blocking_findings_count,
|
|
369
|
+
policy: policyResult.policy,
|
|
370
|
+
reason: policyResult.reason
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async function runVerifyImplementation({ args, options = {}, logger, spawnImpl }) {
|
|
375
|
+
const startedAt = Date.now();
|
|
376
|
+
const rootDir = resolveProjectRoot(process.cwd(), args && args[0] ? args[0] : '.');
|
|
377
|
+
const slugResult = validateFeatureSlug(options.feature || options.slug);
|
|
378
|
+
if (!slugResult.ok) {
|
|
379
|
+
return emit(makeError(slugResult.reason, {
|
|
380
|
+
mode: 'verify-implementation',
|
|
381
|
+
feature_slug: slugResult.feature_slug || null
|
|
382
|
+
}), options, logger);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const modeResult = detectMode(options);
|
|
386
|
+
if (!modeResult.ok) {
|
|
387
|
+
return emit(makeError(modeResult.reason, {
|
|
388
|
+
feature_slug: slugResult.feature_slug,
|
|
389
|
+
modes: modeResult.modes || []
|
|
390
|
+
}), options, logger);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const policy = normalizePolicy(options.policy || 'standard');
|
|
394
|
+
if (!policy) {
|
|
395
|
+
return emit(makeError('invalid_policy', {
|
|
396
|
+
feature_slug: slugResult.feature_slug,
|
|
397
|
+
policy: options.policy
|
|
398
|
+
}), options, logger);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const slug = slugResult.feature_slug;
|
|
402
|
+
let result;
|
|
403
|
+
if (modeResult.mode === 'prepare-ledger') {
|
|
404
|
+
result = await runPrepareLedger({ rootDir, slug, options });
|
|
405
|
+
} else if (modeResult.mode === 'check-ledger') {
|
|
406
|
+
result = await runCheckLedger({ rootDir, slug });
|
|
407
|
+
} else if (modeResult.mode === 'build-prompt') {
|
|
408
|
+
result = await runBuildPrompt({ rootDir, slug, policy, options });
|
|
409
|
+
} else if (modeResult.mode === 'check-report') {
|
|
410
|
+
result = await runCheckReport({ rootDir, slug, policy, options });
|
|
411
|
+
} else if (modeResult.mode === 'run-tool') {
|
|
412
|
+
result = await runToolAudit({ rootDir, slug, policy, options, spawnImpl });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const finalResult = {
|
|
416
|
+
feature_slug: slug,
|
|
417
|
+
policy,
|
|
418
|
+
...result
|
|
419
|
+
};
|
|
420
|
+
finalResult.telemetry = await recordVerificationTelemetry(rootDir, finalResult, { startedAt });
|
|
421
|
+
|
|
422
|
+
return emit(finalResult, options, logger);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
module.exports = {
|
|
426
|
+
runVerifyImplementation,
|
|
427
|
+
detectMode
|
|
428
|
+
};
|