auditor-lambda 0.3.3 → 0.3.5
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/README.md +6 -1
- package/audit-code-wrapper-lib.mjs +87 -7
- package/dist/cli.js +517 -91
- package/dist/extractors/graph.d.ts +5 -1
- package/dist/extractors/graph.js +223 -3
- package/dist/extractors/pathPatterns.d.ts +3 -2
- package/dist/extractors/pathPatterns.js +97 -24
- package/dist/io/artifacts.d.ts +5 -0
- package/dist/io/artifacts.js +2 -0
- package/dist/orchestrator/advance.js +1 -1
- package/dist/orchestrator/dependencyMap.js +18 -0
- package/dist/orchestrator/fileAnchors.d.ts +32 -0
- package/dist/orchestrator/fileAnchors.js +217 -0
- package/dist/orchestrator/internalExecutors.d.ts +1 -1
- package/dist/orchestrator/internalExecutors.js +120 -33
- package/dist/orchestrator/reviewPackets.d.ts +14 -0
- package/dist/orchestrator/reviewPackets.js +310 -0
- package/dist/orchestrator/selectiveDeepening.d.ts +14 -0
- package/dist/orchestrator/selectiveDeepening.js +392 -0
- package/dist/orchestrator/state.js +6 -1
- package/dist/orchestrator/taskBuilder.d.ts +16 -0
- package/dist/orchestrator/taskBuilder.js +68 -11
- package/dist/prompts/renderWorkerPrompt.js +2 -1
- package/dist/providers/claudeCodeProvider.js +3 -1
- package/dist/providers/index.js +2 -1
- package/dist/supervisor/operatorHandoff.js +22 -11
- package/dist/types/graph.d.ts +1 -0
- package/dist/types/reviewPlanning.d.ts +41 -0
- package/dist/types/reviewPlanning.js +1 -0
- package/dist/types/sessionConfig.d.ts +1 -0
- package/dist/validation/artifacts.js +13 -0
- package/dist/validation/auditResults.js +50 -2
- package/dist/validation/sessionConfig.js +5 -0
- package/docs/agent-integrations.md +4 -1
- package/docs/bootstrap-install.md +3 -0
- package/docs/contract.md +3 -0
- package/docs/dispatch-implementation-plan.md +220 -489
- package/docs/next-steps.md +13 -8
- package/docs/product-direction.md +5 -3
- package/docs/run-flow.md +25 -30
- package/docs/session-config.md +15 -4
- package/docs/supervisor.md +5 -3
- package/docs/workflow-refactor-brief.md +114 -176
- package/package.json +1 -1
- package/schemas/finding.schema.json +1 -15
- package/schemas/graph_bundle.schema.json +16 -0
- package/skills/audit-code/audit-code.prompt.md +11 -6
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
const MAX_ANCHORS = 160;
|
|
2
|
+
const KEYWORD_PATTERN = /\b(auth|token|password|secret|permission|role|sql|query|exec|spawn|eval|deserialize|encrypt|decrypt|cache|retry|timeout|transaction|lock|race|TODO|FIXME)\b/i;
|
|
3
|
+
const SYMBOL_PATTERNS = [
|
|
4
|
+
{
|
|
5
|
+
kind: "import",
|
|
6
|
+
pattern: /^\s*import\s+(?:type\s+)?(?:[^"'()]*?\s+from\s+)?["']([^"']+)["']/,
|
|
7
|
+
label: "import",
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
kind: "symbol",
|
|
11
|
+
pattern: /^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\b/,
|
|
12
|
+
label: "function",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
kind: "symbol",
|
|
16
|
+
pattern: /^\s*(?:export\s+)?class\s+([A-Za-z_$][\w$]*)\b/,
|
|
17
|
+
label: "class",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
kind: "symbol",
|
|
21
|
+
pattern: /^\s*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)\b/,
|
|
22
|
+
label: "interface",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
kind: "symbol",
|
|
26
|
+
pattern: /^\s*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\b/,
|
|
27
|
+
label: "type",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
kind: "symbol",
|
|
31
|
+
pattern: /^\s*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\b/,
|
|
32
|
+
label: "binding",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
kind: "export",
|
|
36
|
+
pattern: /^\s*export\s+(?:type\s+)?(?:[^"'()]*?\s+from\s+["']([^"']+)["']|(?:default\s+)?(?:async\s+)?(?:function|class|const|let|var|interface|type)\s+([A-Za-z_$][\w$-]*))/,
|
|
37
|
+
label: "export",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
kind: "symbol",
|
|
41
|
+
pattern: /^\s*(?:export\s+)?def\s+([A-Za-z_][\w]*)\b/,
|
|
42
|
+
label: "function",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
kind: "symbol",
|
|
46
|
+
pattern: /^\s*(?:export\s+)?func\s+(?:\([^)]+\)\s*)?([A-Za-z_][\w]*)\b/,
|
|
47
|
+
label: "function",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
kind: "symbol",
|
|
51
|
+
pattern: /^\s*(?:pub\s+)?fn\s+([A-Za-z_][\w]*)\b/,
|
|
52
|
+
label: "function",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
kind: "route",
|
|
56
|
+
pattern: /\b(?:app|router|server)\s*\.\s*(get|post|put|patch|delete|use)\s*\(/i,
|
|
57
|
+
label: "route",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
kind: "route",
|
|
61
|
+
pattern: /^\s*@(?:Get|Post|Put|Patch|Delete|Route|Controller)\b/,
|
|
62
|
+
label: "route",
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
function normalizePath(path) {
|
|
66
|
+
return path.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
67
|
+
}
|
|
68
|
+
function truncate(value, maxLength) {
|
|
69
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
70
|
+
return normalized.length > maxLength
|
|
71
|
+
? `${normalized.slice(0, maxLength - 3)}...`
|
|
72
|
+
: normalized;
|
|
73
|
+
}
|
|
74
|
+
function addAnchor(anchors, seen, anchor) {
|
|
75
|
+
const key = `${anchor.kind}\0${anchor.line ?? ""}\0${anchor.name}\0${anchor.detail ?? ""}`;
|
|
76
|
+
if (seen.has(key)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
seen.add(key);
|
|
80
|
+
anchors.push(anchor);
|
|
81
|
+
}
|
|
82
|
+
function collectGraphEdges(graphBundle, path) {
|
|
83
|
+
if (!graphBundle?.graphs) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const normalizedPath = normalizePath(path).toLowerCase();
|
|
87
|
+
const edges = [];
|
|
88
|
+
for (const key of ["imports", "calls", "references"]) {
|
|
89
|
+
const raw = graphBundle.graphs[key];
|
|
90
|
+
if (!Array.isArray(raw)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
for (const item of raw) {
|
|
94
|
+
const record = item;
|
|
95
|
+
if (item &&
|
|
96
|
+
typeof item === "object" &&
|
|
97
|
+
!Array.isArray(item) &&
|
|
98
|
+
typeof record.from === "string" &&
|
|
99
|
+
typeof record.to === "string") {
|
|
100
|
+
const from = normalizePath(record.from).toLowerCase();
|
|
101
|
+
const to = normalizePath(record.to).toLowerCase();
|
|
102
|
+
if (from === normalizedPath || to === normalizedPath) {
|
|
103
|
+
edges.push({
|
|
104
|
+
from: record.from,
|
|
105
|
+
to: record.to,
|
|
106
|
+
kind: typeof record.kind === "string" ? record.kind : key,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return edges.sort((a, b) => (a.kind ?? "").localeCompare(b.kind ?? "") ||
|
|
113
|
+
a.from.localeCompare(b.from) ||
|
|
114
|
+
a.to.localeCompare(b.to));
|
|
115
|
+
}
|
|
116
|
+
export function buildFileAnchorSummary(params) {
|
|
117
|
+
const anchors = [];
|
|
118
|
+
const seen = new Set();
|
|
119
|
+
const path = normalizePath(params.path);
|
|
120
|
+
const lines = params.content.split(/\r?\n/);
|
|
121
|
+
let symbolCount = 0;
|
|
122
|
+
let routeCount = 0;
|
|
123
|
+
let keywordCount = 0;
|
|
124
|
+
addAnchor(anchors, seen, {
|
|
125
|
+
kind: "boundary",
|
|
126
|
+
name: "file_start",
|
|
127
|
+
line: 1,
|
|
128
|
+
detail: "Start of isolated large-file review boundary.",
|
|
129
|
+
});
|
|
130
|
+
if (params.totalLines > 1) {
|
|
131
|
+
addAnchor(anchors, seen, {
|
|
132
|
+
kind: "boundary",
|
|
133
|
+
name: "file_end",
|
|
134
|
+
line: params.totalLines,
|
|
135
|
+
detail: "End of isolated large-file review boundary.",
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
lines.forEach((line, index) => {
|
|
139
|
+
const lineNumber = index + 1;
|
|
140
|
+
for (const { kind, pattern, label } of SYMBOL_PATTERNS) {
|
|
141
|
+
const match = line.match(pattern);
|
|
142
|
+
if (!match) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const name = match.slice(1).find((value) => value && value.trim().length > 0) ?? label;
|
|
146
|
+
if (kind === "route") {
|
|
147
|
+
routeCount += 1;
|
|
148
|
+
}
|
|
149
|
+
else if (kind === "symbol") {
|
|
150
|
+
symbolCount += 1;
|
|
151
|
+
}
|
|
152
|
+
addAnchor(anchors, seen, {
|
|
153
|
+
kind,
|
|
154
|
+
name: truncate(name, 80),
|
|
155
|
+
line: lineNumber,
|
|
156
|
+
detail: truncate(`${label}: ${line}`, 180),
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
if (KEYWORD_PATTERN.test(line)) {
|
|
161
|
+
keywordCount += 1;
|
|
162
|
+
addAnchor(anchors, seen, {
|
|
163
|
+
kind: "keyword",
|
|
164
|
+
name: truncate(line.match(KEYWORD_PATTERN)?.[1] ?? "keyword", 80),
|
|
165
|
+
line: lineNumber,
|
|
166
|
+
detail: truncate(line, 180),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const graphEdges = collectGraphEdges(params.graphBundle, path);
|
|
171
|
+
for (const edge of graphEdges) {
|
|
172
|
+
addAnchor(anchors, seen, {
|
|
173
|
+
kind: "graph",
|
|
174
|
+
name: edge.kind ?? "edge",
|
|
175
|
+
detail: normalizePath(edge.from).toLowerCase() === path.toLowerCase()
|
|
176
|
+
? `outbound: ${edge.to}`
|
|
177
|
+
: `inbound: ${edge.from}`,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const analyzerSignals = (params.externalAnalyzerResults?.results ?? [])
|
|
181
|
+
.filter((result) => normalizePath(result.path).toLowerCase() === path.toLowerCase())
|
|
182
|
+
.sort((a, b) => (a.line_start ?? 0) - (b.line_start ?? 0) ||
|
|
183
|
+
a.id.localeCompare(b.id));
|
|
184
|
+
for (const signal of analyzerSignals) {
|
|
185
|
+
addAnchor(anchors, seen, {
|
|
186
|
+
kind: "analyzer_signal",
|
|
187
|
+
name: truncate(signal.rule ?? signal.category, 80),
|
|
188
|
+
line: signal.line_start,
|
|
189
|
+
detail: truncate(signal.summary, 180),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
const sorted = anchors.sort((a, b) => (a.line ?? Number.MAX_SAFE_INTEGER) - (b.line ?? Number.MAX_SAFE_INTEGER) ||
|
|
193
|
+
a.kind.localeCompare(b.kind) ||
|
|
194
|
+
a.name.localeCompare(b.name));
|
|
195
|
+
const boundedAnchors = sorted.slice(0, MAX_ANCHORS);
|
|
196
|
+
return {
|
|
197
|
+
contract_version: "audit-code-file-anchors/v1alpha1",
|
|
198
|
+
path,
|
|
199
|
+
total_lines: params.totalLines,
|
|
200
|
+
review_mode: "isolated_large_file",
|
|
201
|
+
scope_basis: [
|
|
202
|
+
"single assigned file",
|
|
203
|
+
"single review packet",
|
|
204
|
+
"mechanically extracted symbols, routes, graph edges, keywords, and analyzer signals",
|
|
205
|
+
"backend-owned submit-packet result write path",
|
|
206
|
+
],
|
|
207
|
+
anchors: boundedAnchors,
|
|
208
|
+
omitted_anchor_count: Math.max(0, sorted.length - boundedAnchors.length),
|
|
209
|
+
counts: {
|
|
210
|
+
symbols: symbolCount,
|
|
211
|
+
routes: routeCount,
|
|
212
|
+
keywords: keywordCount,
|
|
213
|
+
graph_edges: graphEdges.length,
|
|
214
|
+
analyzer_signals: analyzerSignals.length,
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -8,7 +8,7 @@ export interface ExecutorRunResult {
|
|
|
8
8
|
progress_summary: string;
|
|
9
9
|
}
|
|
10
10
|
export declare function runIntakeExecutor(bundle: ArtifactBundle, root: string): Promise<ExecutorRunResult>;
|
|
11
|
-
export declare function runStructureExecutor(bundle: ArtifactBundle): ExecutorRunResult
|
|
11
|
+
export declare function runStructureExecutor(bundle: ArtifactBundle, root?: string): Promise<ExecutorRunResult>;
|
|
12
12
|
export declare function runPlanningExecutor(bundle: ArtifactBundle, root: string, lineIndex?: Record<string, number>): Promise<ExecutorRunResult>;
|
|
13
13
|
export declare function runResultIngestionExecutor(bundle: ArtifactBundle, results: AuditResult[]): ExecutorRunResult;
|
|
14
14
|
export declare function runRuntimeValidationExecutor(bundle: ArtifactBundle, root: string): Promise<ExecutorRunResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { buildFileDisposition } from "../extractors/disposition.js";
|
|
3
|
-
import { buildGraphBundle } from "../extractors/graph.js";
|
|
3
|
+
import { buildGraphBundle, buildGraphBundleFromFs, } from "../extractors/graph.js";
|
|
4
4
|
import { buildCriticalFlowManifest } from "../extractors/flows.js";
|
|
5
5
|
import { buildRiskRegister } from "../extractors/risk.js";
|
|
6
6
|
import { buildSurfaceManifest } from "../extractors/surfaces.js";
|
|
@@ -10,12 +10,50 @@ import { buildRequeuePayload } from "./requeueCommand.js";
|
|
|
10
10
|
import { buildRuntimeValidationTasks, discoverRuntimeValidationCommand, mergeRuntimeValidationReport, } from "./runtimeValidation.js";
|
|
11
11
|
import { buildAuditReportModel, renderAuditReportMarkdown, } from "../reporting/synthesis.js";
|
|
12
12
|
import { buildChunkedAuditTasks, } from "./taskBuilder.js";
|
|
13
|
+
import { buildAuditPlanMetrics, buildReviewPackets, } from "./reviewPackets.js";
|
|
13
14
|
import { buildUnitManifest } from "./unitBuilder.js";
|
|
14
15
|
import { buildRepoManifestFromFs } from "../extractors/fsIntake.js";
|
|
15
16
|
import { loadIgnoreFile } from "../extractors/ignore.js";
|
|
16
17
|
import { ingestAuditResults, updateAuditTaskStatuses, } from "./resultIngestion.js";
|
|
18
|
+
import { buildSelectiveDeepeningTasks } from "./selectiveDeepening.js";
|
|
17
19
|
import { updateRuntimeValidationReport } from "./runtimeValidationUpdate.js";
|
|
18
20
|
import { autoCompleteTrivialCoverage } from "./trivialAudit.js";
|
|
21
|
+
function lineIndexFromTasks(tasks) {
|
|
22
|
+
return Object.fromEntries((tasks ?? []).flatMap((task) => Object.entries(task.file_line_counts ?? {})));
|
|
23
|
+
}
|
|
24
|
+
function appendSelectiveDeepeningTasks(params) {
|
|
25
|
+
if (!params.bundle.audit_tasks) {
|
|
26
|
+
return { bundle: params.bundle, taskCount: 0, artifacts: [] };
|
|
27
|
+
}
|
|
28
|
+
const lineIndex = lineIndexFromTasks(params.bundle.audit_tasks);
|
|
29
|
+
const selectiveDeepeningTasks = buildSelectiveDeepeningTasks({
|
|
30
|
+
existingTasks: params.bundle.audit_tasks,
|
|
31
|
+
results: params.results,
|
|
32
|
+
lineIndex,
|
|
33
|
+
runtimeValidationTasks: params.bundle.runtime_validation_tasks,
|
|
34
|
+
runtimeValidationReport: params.runtimeValidationReport ?? params.bundle.runtime_validation_report,
|
|
35
|
+
});
|
|
36
|
+
if (selectiveDeepeningTasks.length === 0) {
|
|
37
|
+
return { bundle: params.bundle, taskCount: 0, artifacts: [] };
|
|
38
|
+
}
|
|
39
|
+
const auditTasks = [...params.bundle.audit_tasks, ...selectiveDeepeningTasks];
|
|
40
|
+
return {
|
|
41
|
+
bundle: {
|
|
42
|
+
...params.bundle,
|
|
43
|
+
audit_tasks: auditTasks,
|
|
44
|
+
audit_plan_metrics: buildAuditPlanMetrics(auditTasks, {
|
|
45
|
+
graphBundle: params.bundle.graph_bundle,
|
|
46
|
+
lineIndex,
|
|
47
|
+
}),
|
|
48
|
+
review_packets: buildReviewPackets(auditTasks, {
|
|
49
|
+
graphBundle: params.bundle.graph_bundle,
|
|
50
|
+
lineIndex,
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
taskCount: selectiveDeepeningTasks.length,
|
|
54
|
+
artifacts: ["audit_tasks.json", "audit_plan_metrics.json", "review_packets.json"],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
19
57
|
async function runCommand(command, cwd) {
|
|
20
58
|
return await new Promise((resolve) => {
|
|
21
59
|
const child = spawn(command[0], command.slice(1), {
|
|
@@ -69,7 +107,7 @@ export async function runIntakeExecutor(bundle, root) {
|
|
|
69
107
|
progress_summary: `Created intake artifacts for ${repoManifest.files.length} files.`,
|
|
70
108
|
};
|
|
71
109
|
}
|
|
72
|
-
export function runStructureExecutor(bundle) {
|
|
110
|
+
export async function runStructureExecutor(bundle, root) {
|
|
73
111
|
if (!bundle.repo_manifest) {
|
|
74
112
|
throw new Error("Cannot run structure executor without repo_manifest");
|
|
75
113
|
}
|
|
@@ -77,7 +115,9 @@ export function runStructureExecutor(bundle) {
|
|
|
77
115
|
const disposition = bundle.file_disposition ?? buildFileDisposition(bundle.repo_manifest);
|
|
78
116
|
const unitManifest = buildUnitManifest(bundle.repo_manifest, disposition);
|
|
79
117
|
const surfaceManifest = buildSurfaceManifest(bundle.repo_manifest, disposition);
|
|
80
|
-
const graphBundle =
|
|
118
|
+
const graphBundle = root
|
|
119
|
+
? await buildGraphBundleFromFs(bundle.repo_manifest, root, disposition)
|
|
120
|
+
: buildGraphBundle(bundle.repo_manifest, disposition);
|
|
81
121
|
const criticalFlows = buildCriticalFlowManifest(bundle.repo_manifest, surfaceManifest, disposition);
|
|
82
122
|
const riskRegister = buildRiskRegister(unitManifest, criticalFlows, externalAnalyzerResults);
|
|
83
123
|
return {
|
|
@@ -137,6 +177,14 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
137
177
|
...task,
|
|
138
178
|
status: task.status ?? "pending",
|
|
139
179
|
}));
|
|
180
|
+
const reviewPackets = buildReviewPackets(taggedAuditTasks, {
|
|
181
|
+
graphBundle: bundle.graph_bundle,
|
|
182
|
+
lineIndex,
|
|
183
|
+
});
|
|
184
|
+
const auditPlanMetrics = buildAuditPlanMetrics(taggedAuditTasks, {
|
|
185
|
+
graphBundle: bundle.graph_bundle,
|
|
186
|
+
lineIndex,
|
|
187
|
+
});
|
|
140
188
|
const requeuePayload = buildRequeuePayload(coverage, bundle.critical_flows, flowCoverage, externalAnalyzerResults);
|
|
141
189
|
return {
|
|
142
190
|
updated: {
|
|
@@ -146,6 +194,8 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
146
194
|
runtime_validation_tasks: runtimeValidationTasks,
|
|
147
195
|
runtime_validation_report: runtimeValidationReport,
|
|
148
196
|
audit_tasks: taggedAuditTasks,
|
|
197
|
+
audit_plan_metrics: auditPlanMetrics,
|
|
198
|
+
review_packets: reviewPackets,
|
|
149
199
|
requeue_tasks: requeuePayload.tasks,
|
|
150
200
|
audit_report: undefined,
|
|
151
201
|
},
|
|
@@ -155,9 +205,11 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
155
205
|
"runtime_validation_tasks.json",
|
|
156
206
|
...(runtimeValidationReport ? ["runtime_validation_report.json"] : []),
|
|
157
207
|
"audit_tasks.json",
|
|
208
|
+
"audit_plan_metrics.json",
|
|
209
|
+
"review_packets.json",
|
|
158
210
|
"requeue_tasks.json",
|
|
159
211
|
],
|
|
160
|
-
progress_summary: `Built planning artifacts; generated ${taggedAuditTasks.length} review
|
|
212
|
+
progress_summary: `Built planning artifacts; generated ${taggedAuditTasks.length} review tasks in ${reviewPackets.length} packet(s) and ${requeuePayload.task_count} requeue tasks.` +
|
|
161
213
|
(skippedTrivialPaths.length > 0
|
|
162
214
|
? ` Skipped ${skippedTrivialPaths.length} trivial path${skippedTrivialPaths.length === 1 ? "" : "s"} from semantic review.`
|
|
163
215
|
: "") +
|
|
@@ -188,19 +240,25 @@ export function runResultIngestionExecutor(bundle, results) {
|
|
|
188
240
|
: bundle.runtime_validation_report;
|
|
189
241
|
const requeuePayload = buildRequeuePayload(updatedCoverageMatrix, bundle.critical_flows, flowCoverage, bundle.external_analyzer_results);
|
|
190
242
|
const mergedResults = [...(bundle.audit_results ?? []), ...results];
|
|
191
|
-
const
|
|
243
|
+
const completedAuditTasks = updateAuditTaskStatuses(bundle.audit_tasks, mergedResults);
|
|
244
|
+
const baseUpdatedBundle = {
|
|
245
|
+
...bundle,
|
|
246
|
+
coverage_matrix: updatedCoverageMatrix,
|
|
247
|
+
flow_coverage: flowCoverage,
|
|
248
|
+
runtime_validation_tasks: runtimeValidationTasks,
|
|
249
|
+
runtime_validation_report: runtimeValidationReport,
|
|
250
|
+
audit_results: mergedResults,
|
|
251
|
+
audit_tasks: completedAuditTasks,
|
|
252
|
+
requeue_tasks: requeuePayload.tasks,
|
|
253
|
+
audit_report: undefined,
|
|
254
|
+
};
|
|
255
|
+
const selectiveDeepening = appendSelectiveDeepeningTasks({
|
|
256
|
+
bundle: baseUpdatedBundle,
|
|
257
|
+
results: mergedResults,
|
|
258
|
+
runtimeValidationReport,
|
|
259
|
+
});
|
|
192
260
|
return {
|
|
193
|
-
updated:
|
|
194
|
-
...bundle,
|
|
195
|
-
coverage_matrix: updatedCoverageMatrix,
|
|
196
|
-
flow_coverage: flowCoverage,
|
|
197
|
-
runtime_validation_tasks: runtimeValidationTasks,
|
|
198
|
-
runtime_validation_report: runtimeValidationReport,
|
|
199
|
-
audit_results: mergedResults,
|
|
200
|
-
audit_tasks: updatedAuditTasks,
|
|
201
|
-
requeue_tasks: requeuePayload.tasks,
|
|
202
|
-
audit_report: undefined,
|
|
203
|
-
},
|
|
261
|
+
updated: selectiveDeepening.bundle,
|
|
204
262
|
artifacts_written: [
|
|
205
263
|
"coverage_matrix.json",
|
|
206
264
|
"flow_coverage.json",
|
|
@@ -208,9 +266,13 @@ export function runResultIngestionExecutor(bundle, results) {
|
|
|
208
266
|
...(runtimeValidationReport ? ["runtime_validation_report.json"] : []),
|
|
209
267
|
"audit_results.jsonl",
|
|
210
268
|
"audit_tasks.json",
|
|
269
|
+
...selectiveDeepening.artifacts.filter((artifact) => artifact !== "audit_tasks.json"),
|
|
211
270
|
"requeue_tasks.json",
|
|
212
271
|
],
|
|
213
|
-
progress_summary: `Ingested ${results.length} audit result entries and refreshed dependent artifacts
|
|
272
|
+
progress_summary: `Ingested ${results.length} audit result entries and refreshed dependent artifacts.` +
|
|
273
|
+
(selectiveDeepening.taskCount > 0
|
|
274
|
+
? ` Added ${selectiveDeepening.taskCount} selective deepening task(s).`
|
|
275
|
+
: ""),
|
|
214
276
|
};
|
|
215
277
|
}
|
|
216
278
|
export async function runRuntimeValidationExecutor(bundle, root) {
|
|
@@ -247,16 +309,29 @@ export async function runRuntimeValidationExecutor(bundle, root) {
|
|
|
247
309
|
notes: [`Target paths: ${task.target_paths.join(", ")}`],
|
|
248
310
|
});
|
|
249
311
|
}
|
|
312
|
+
const runtimeValidationReport = {
|
|
313
|
+
results: [...byTaskId.values()].sort((a, b) => a.task_id.localeCompare(b.task_id)),
|
|
314
|
+
};
|
|
315
|
+
const baseUpdatedBundle = {
|
|
316
|
+
...bundle,
|
|
317
|
+
runtime_validation_report: runtimeValidationReport,
|
|
318
|
+
audit_report: undefined,
|
|
319
|
+
};
|
|
320
|
+
const selectiveDeepening = appendSelectiveDeepeningTasks({
|
|
321
|
+
bundle: baseUpdatedBundle,
|
|
322
|
+
results: bundle.audit_results ?? [],
|
|
323
|
+
runtimeValidationReport,
|
|
324
|
+
});
|
|
250
325
|
return {
|
|
251
|
-
updated:
|
|
252
|
-
|
|
253
|
-
runtime_validation_report
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
326
|
+
updated: selectiveDeepening.bundle,
|
|
327
|
+
artifacts_written: [
|
|
328
|
+
"runtime_validation_report.json",
|
|
329
|
+
...selectiveDeepening.artifacts,
|
|
330
|
+
],
|
|
331
|
+
progress_summary: `Executed deterministic runtime validation for ${bundle.runtime_validation_tasks.tasks.length} task(s).` +
|
|
332
|
+
(selectiveDeepening.taskCount > 0
|
|
333
|
+
? ` Added ${selectiveDeepening.taskCount} selective deepening task(s).`
|
|
334
|
+
: ""),
|
|
260
335
|
};
|
|
261
336
|
}
|
|
262
337
|
export function runRuntimeValidationUpdateExecutor(bundle, updates) {
|
|
@@ -265,14 +340,26 @@ export function runRuntimeValidationUpdateExecutor(bundle, updates) {
|
|
|
265
340
|
}
|
|
266
341
|
const existingReport = bundle.runtime_validation_report ?? { results: [] };
|
|
267
342
|
const mergedReport = updateRuntimeValidationReport(bundle.runtime_validation_tasks, existingReport, updates);
|
|
343
|
+
const baseUpdatedBundle = {
|
|
344
|
+
...bundle,
|
|
345
|
+
runtime_validation_report: mergedReport,
|
|
346
|
+
audit_report: undefined,
|
|
347
|
+
};
|
|
348
|
+
const selectiveDeepening = appendSelectiveDeepeningTasks({
|
|
349
|
+
bundle: baseUpdatedBundle,
|
|
350
|
+
results: bundle.audit_results ?? [],
|
|
351
|
+
runtimeValidationReport: mergedReport,
|
|
352
|
+
});
|
|
268
353
|
return {
|
|
269
|
-
updated:
|
|
270
|
-
|
|
271
|
-
runtime_validation_report
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
354
|
+
updated: selectiveDeepening.bundle,
|
|
355
|
+
artifacts_written: [
|
|
356
|
+
"runtime_validation_report.json",
|
|
357
|
+
...selectiveDeepening.artifacts,
|
|
358
|
+
],
|
|
359
|
+
progress_summary: `Merged ${updates.results.length} runtime validation updates.` +
|
|
360
|
+
(selectiveDeepening.taskCount > 0
|
|
361
|
+
? ` Added ${selectiveDeepening.taskCount} selective deepening task(s).`
|
|
362
|
+
: ""),
|
|
276
363
|
};
|
|
277
364
|
}
|
|
278
365
|
export function runSynthesisExecutor(bundle, results) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AuditTask } from "../types.js";
|
|
2
|
+
import type { AuditPlanMetrics, ReviewPacket } from "../types/reviewPlanning.js";
|
|
3
|
+
import type { GraphBundle } from "../types/graph.js";
|
|
4
|
+
export interface BuildReviewPacketOptions {
|
|
5
|
+
graphBundle?: GraphBundle;
|
|
6
|
+
lineIndex?: Record<string, number>;
|
|
7
|
+
maxTasksPerPacket?: number;
|
|
8
|
+
targetPacketLines?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildReviewPackets(tasks: AuditTask[], options?: BuildReviewPacketOptions): ReviewPacket[];
|
|
11
|
+
export declare function orderTasksForPacketReview(tasks: AuditTask[], options?: BuildReviewPacketOptions): AuditTask[];
|
|
12
|
+
export declare function buildAuditPlanMetrics(tasks: AuditTask[], options?: BuildReviewPacketOptions & {
|
|
13
|
+
generatedAt?: Date;
|
|
14
|
+
}): AuditPlanMetrics;
|