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.
Files changed (47) hide show
  1. package/README.md +6 -1
  2. package/audit-code-wrapper-lib.mjs +87 -7
  3. package/dist/cli.js +517 -91
  4. package/dist/extractors/graph.d.ts +5 -1
  5. package/dist/extractors/graph.js +223 -3
  6. package/dist/extractors/pathPatterns.d.ts +3 -2
  7. package/dist/extractors/pathPatterns.js +97 -24
  8. package/dist/io/artifacts.d.ts +5 -0
  9. package/dist/io/artifacts.js +2 -0
  10. package/dist/orchestrator/advance.js +1 -1
  11. package/dist/orchestrator/dependencyMap.js +18 -0
  12. package/dist/orchestrator/fileAnchors.d.ts +32 -0
  13. package/dist/orchestrator/fileAnchors.js +217 -0
  14. package/dist/orchestrator/internalExecutors.d.ts +1 -1
  15. package/dist/orchestrator/internalExecutors.js +120 -33
  16. package/dist/orchestrator/reviewPackets.d.ts +14 -0
  17. package/dist/orchestrator/reviewPackets.js +310 -0
  18. package/dist/orchestrator/selectiveDeepening.d.ts +14 -0
  19. package/dist/orchestrator/selectiveDeepening.js +392 -0
  20. package/dist/orchestrator/state.js +6 -1
  21. package/dist/orchestrator/taskBuilder.d.ts +16 -0
  22. package/dist/orchestrator/taskBuilder.js +68 -11
  23. package/dist/prompts/renderWorkerPrompt.js +2 -1
  24. package/dist/providers/claudeCodeProvider.js +3 -1
  25. package/dist/providers/index.js +2 -1
  26. package/dist/supervisor/operatorHandoff.js +22 -11
  27. package/dist/types/graph.d.ts +1 -0
  28. package/dist/types/reviewPlanning.d.ts +41 -0
  29. package/dist/types/reviewPlanning.js +1 -0
  30. package/dist/types/sessionConfig.d.ts +1 -0
  31. package/dist/validation/artifacts.js +13 -0
  32. package/dist/validation/auditResults.js +50 -2
  33. package/dist/validation/sessionConfig.js +5 -0
  34. package/docs/agent-integrations.md +4 -1
  35. package/docs/bootstrap-install.md +3 -0
  36. package/docs/contract.md +3 -0
  37. package/docs/dispatch-implementation-plan.md +220 -489
  38. package/docs/next-steps.md +13 -8
  39. package/docs/product-direction.md +5 -3
  40. package/docs/run-flow.md +25 -30
  41. package/docs/session-config.md +15 -4
  42. package/docs/supervisor.md +5 -3
  43. package/docs/workflow-refactor-brief.md +114 -176
  44. package/package.json +1 -1
  45. package/schemas/finding.schema.json +1 -15
  46. package/schemas/graph_bundle.schema.json +16 -0
  47. package/skills/audit-code/audit-code.prompt.md +11 -6
@@ -1,4 +1,8 @@
1
1
  import type { RepoManifest } from "../types.js";
2
2
  import type { FileDisposition } from "../types/disposition.js";
3
3
  import type { GraphBundle } from "../types/graph.js";
4
- export declare function buildGraphBundle(repoManifest: RepoManifest, disposition?: FileDisposition): GraphBundle;
4
+ export interface BuildGraphBundleOptions {
5
+ fileContents?: Record<string, string>;
6
+ }
7
+ export declare function buildGraphBundleFromFs(repoManifest: RepoManifest, root: string, disposition?: FileDisposition): Promise<GraphBundle>;
8
+ export declare function buildGraphBundle(repoManifest: RepoManifest, disposition?: FileDisposition, options?: BuildGraphBundleOptions): GraphBundle;
@@ -1,11 +1,220 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { isAbsolute, relative, resolve } from "node:path";
3
+ import { posix } from "node:path";
1
4
  import { isAuditExcludedStatus } from "./disposition.js";
2
- export function buildGraphBundle(repoManifest, disposition) {
5
+ const MAX_GRAPH_SOURCE_BYTES = 512 * 1024;
6
+ const RESOLVABLE_EXTENSIONS = [
7
+ "",
8
+ ".ts",
9
+ ".tsx",
10
+ ".mts",
11
+ ".cts",
12
+ ".js",
13
+ ".jsx",
14
+ ".mjs",
15
+ ".cjs",
16
+ ".json",
17
+ ];
18
+ const INDEX_EXTENSIONS = [
19
+ "index.ts",
20
+ "index.tsx",
21
+ "index.mts",
22
+ "index.cts",
23
+ "index.js",
24
+ "index.jsx",
25
+ "index.mjs",
26
+ "index.cjs",
27
+ "index.json",
28
+ ];
29
+ const SOURCE_LANGUAGES = new Set([
30
+ "typescript",
31
+ "javascript",
32
+ "json",
33
+ "yaml",
34
+ "python",
35
+ "go",
36
+ "rust",
37
+ "java",
38
+ "csharp",
39
+ ]);
40
+ const SOURCE_EXTENSIONS = [
41
+ ".ts",
42
+ ".tsx",
43
+ ".mts",
44
+ ".cts",
45
+ ".js",
46
+ ".jsx",
47
+ ".mjs",
48
+ ".cjs",
49
+ ".json",
50
+ ".yml",
51
+ ".yaml",
52
+ ".py",
53
+ ".go",
54
+ ".rs",
55
+ ".java",
56
+ ".cs",
57
+ ];
58
+ const IMPORT_PATTERNS = [
59
+ {
60
+ pattern: /\bimport\s+(?:type\s+)?(?:[^"'()]*?\s+from\s+)?["']([^"']+)["']/g,
61
+ kind: "esm",
62
+ },
63
+ {
64
+ pattern: /\bexport\s+(?:type\s+)?[^"']*?\s+from\s+["']([^"']+)["']/g,
65
+ kind: "re-export",
66
+ },
67
+ {
68
+ pattern: /\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,
69
+ kind: "dynamic-import",
70
+ },
71
+ {
72
+ pattern: /\brequire\s*\(\s*["']([^"']+)["']\s*\)/g,
73
+ kind: "commonjs",
74
+ },
75
+ ];
76
+ const STRING_LITERAL_PATTERN = /["'`]([^"'`\r\n]{1,260})["'`]/g;
77
+ function normalizeGraphPath(path) {
78
+ return posix
79
+ .normalize(path.replace(/\\/g, "/"))
80
+ .replace(/^\.\//, "");
81
+ }
82
+ function graphLookupKey(path) {
83
+ return normalizeGraphPath(path).toLowerCase();
84
+ }
85
+ function shouldReadForGraph(file) {
86
+ const normalized = normalizeGraphPath(file.path);
87
+ return (file.size_bytes <= MAX_GRAPH_SOURCE_BYTES &&
88
+ (SOURCE_LANGUAGES.has(file.language) ||
89
+ SOURCE_EXTENSIONS.some((extension) => normalized.endsWith(extension))));
90
+ }
91
+ function buildPathLookup(repoManifest, dispositionMap) {
92
+ return new Map(repoManifest.files
93
+ .filter((file) => {
94
+ const status = dispositionMap.get(file.path);
95
+ return !(file.excluded || (status && isAuditExcludedStatus(status)));
96
+ })
97
+ .map((file) => [graphLookupKey(file.path), file.path]));
98
+ }
99
+ function resolveCandidate(candidate, pathLookup) {
100
+ const normalized = normalizeGraphPath(candidate);
101
+ const direct = pathLookup.get(normalized.toLowerCase());
102
+ if (direct)
103
+ return direct;
104
+ for (const extension of RESOLVABLE_EXTENSIONS) {
105
+ const withExtension = `${normalized}${extension}`;
106
+ const match = pathLookup.get(withExtension.toLowerCase());
107
+ if (match)
108
+ return match;
109
+ }
110
+ for (const indexFile of INDEX_EXTENSIONS) {
111
+ const match = pathLookup.get(posix.join(normalized, indexFile).toLowerCase());
112
+ if (match)
113
+ return match;
114
+ }
115
+ return undefined;
116
+ }
117
+ function resolveSpecifier(fromPath, specifier, pathLookup) {
118
+ if (!specifier.startsWith(".")) {
119
+ return undefined;
120
+ }
121
+ const baseDir = posix.dirname(normalizeGraphPath(fromPath));
122
+ return resolveCandidate(posix.join(baseDir, specifier), pathLookup);
123
+ }
124
+ function resolveReferenceLiteral(fromPath, literal, pathLookup) {
125
+ const normalizedLiteral = normalizeGraphPath(literal);
126
+ if (literal.startsWith(".")) {
127
+ return resolveSpecifier(fromPath, literal, pathLookup);
128
+ }
129
+ if (!normalizedLiteral.includes("/")) {
130
+ return undefined;
131
+ }
132
+ return resolveCandidate(normalizedLiteral, pathLookup);
133
+ }
134
+ function edgeSignature(edge) {
135
+ return `${edge.from}\0${edge.to}\0${edge.kind ?? ""}`;
136
+ }
137
+ function uniqueSortedEdges(edges) {
138
+ const deduped = new Map();
139
+ for (const edge of edges) {
140
+ if (edge.from === edge.to)
141
+ continue;
142
+ deduped.set(edgeSignature(edge), edge);
143
+ }
144
+ return [...deduped.values()].sort((a, b) => a.from.localeCompare(b.from) ||
145
+ a.to.localeCompare(b.to) ||
146
+ (a.kind ?? "").localeCompare(b.kind ?? ""));
147
+ }
148
+ function extractImportEdges(fromPath, content, pathLookup) {
149
+ const edges = [];
150
+ for (const { pattern, kind } of IMPORT_PATTERNS) {
151
+ pattern.lastIndex = 0;
152
+ for (const match of content.matchAll(pattern)) {
153
+ const specifier = match[1];
154
+ if (!specifier)
155
+ continue;
156
+ const target = resolveSpecifier(fromPath, specifier, pathLookup);
157
+ if (target) {
158
+ edges.push({ from: fromPath, to: target, kind });
159
+ }
160
+ }
161
+ }
162
+ return edges;
163
+ }
164
+ function extractReferenceEdges(fromPath, content, pathLookup) {
165
+ const edges = [];
166
+ STRING_LITERAL_PATTERN.lastIndex = 0;
167
+ for (const match of content.matchAll(STRING_LITERAL_PATTERN)) {
168
+ const literal = match[1];
169
+ if (!literal)
170
+ continue;
171
+ const target = resolveReferenceLiteral(fromPath, literal, pathLookup);
172
+ if (target) {
173
+ edges.push({
174
+ from: fromPath,
175
+ to: target,
176
+ kind: literal.startsWith(".")
177
+ ? "relative-string-reference"
178
+ : "repo-path-reference",
179
+ });
180
+ }
181
+ }
182
+ return edges;
183
+ }
184
+ export async function buildGraphBundleFromFs(repoManifest, root, disposition) {
185
+ const rootPath = resolve(root);
186
+ const dispositionMap = new Map(disposition?.files.map((item) => [item.path, item.status]) ?? []);
187
+ const fileContents = {};
188
+ await Promise.all(repoManifest.files.map(async (file) => {
189
+ const status = dispositionMap.get(file.path);
190
+ if ((status && isAuditExcludedStatus(status)) ||
191
+ file.excluded ||
192
+ !shouldReadForGraph(file)) {
193
+ return;
194
+ }
195
+ const absolutePath = resolve(rootPath, file.path);
196
+ const relativeToRoot = relative(rootPath, absolutePath);
197
+ if (relativeToRoot.startsWith("..") || isAbsolute(relativeToRoot)) {
198
+ return;
199
+ }
200
+ try {
201
+ fileContents[file.path] = await readFile(absolutePath, "utf8");
202
+ }
203
+ catch {
204
+ // Best-effort graph extraction should not block structure planning.
205
+ }
206
+ }));
207
+ return buildGraphBundle(repoManifest, disposition, { fileContents });
208
+ }
209
+ export function buildGraphBundle(repoManifest, disposition, options = {}) {
3
210
  const imports = [];
211
+ const references = [];
4
212
  const routes = [];
5
213
  const dispositionMap = new Map(disposition?.files.map((item) => [item.path, item.status]) ?? []);
214
+ const pathLookup = buildPathLookup(repoManifest, dispositionMap);
6
215
  for (const file of repoManifest.files) {
7
216
  const status = dispositionMap.get(file.path);
8
- if (status && isAuditExcludedStatus(status)) {
217
+ if (file.excluded || (status && isAuditExcludedStatus(status))) {
9
218
  continue;
10
219
  }
11
220
  const normalized = file.path.toLowerCase();
@@ -41,6 +250,17 @@ export function buildGraphBundle(repoManifest, disposition) {
41
250
  }
42
251
  }
43
252
  }
253
+ const content = options.fileContents?.[file.path];
254
+ if (content) {
255
+ imports.push(...extractImportEdges(file.path, content, pathLookup));
256
+ references.push(...extractReferenceEdges(file.path, content, pathLookup));
257
+ }
44
258
  }
45
- return { graphs: { imports, routes } };
259
+ return {
260
+ graphs: {
261
+ imports: uniqueSortedEdges(imports),
262
+ references: uniqueSortedEdges(references),
263
+ routes,
264
+ },
265
+ };
46
266
  }
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Shared bootstrap heuristics for the extractor layer. These rules run before
3
3
  * richer graph/unit analysis exists, so they intentionally favor recall over
4
- * precision and always normalize case plus path separators first.
4
+ * precision and always normalize case, path separators, and simple camelCase
5
+ * boundaries first.
5
6
  */
6
- export declare const EXTRACTOR_HEURISTIC_NOTE = "Heuristic path classification normalizes case and path separators, then matches conservative keyword groups; confirm unusual repo layouts manually.";
7
+ export declare const EXTRACTOR_HEURISTIC_NOTE = "Heuristic path classification normalizes case, path separators, and simple camelCase boundaries, then matches conservative keyword groups; confirm unusual repo layouts manually.";
7
8
  export declare function normalizeExtractorPath(path: string): string;
8
9
  export declare function pathTokens(normalized: string): string[];
9
10
  export declare function isNodeModulesOrGit(normalized: string): boolean;
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Shared bootstrap heuristics for the extractor layer. These rules run before
3
3
  * richer graph/unit analysis exists, so they intentionally favor recall over
4
- * precision and always normalize case plus path separators first.
4
+ * precision and always normalize case, path separators, and simple camelCase
5
+ * boundaries first.
5
6
  */
6
- export const EXTRACTOR_HEURISTIC_NOTE = "Heuristic path classification normalizes case and path separators, then matches conservative keyword groups; confirm unusual repo layouts manually.";
7
+ export const EXTRACTOR_HEURISTIC_NOTE = "Heuristic path classification normalizes case, path separators, and simple camelCase boundaries, then matches conservative keyword groups; confirm unusual repo layouts manually.";
7
8
  const BINARY_EXTENSIONS = [
8
9
  ".png",
9
10
  ".jpg",
@@ -20,15 +21,46 @@ const LOCKFILE_NAMES = [
20
21
  "composer.lock",
21
22
  "go.sum",
22
23
  ];
23
- const TEST_KEYWORDS = ["test", "spec", "__tests__"];
24
- const INTERFACE_KEYWORDS = ["route", "controller", "handler"];
25
- const DATA_LAYER_KEYWORDS = ["model", "schema", "migration", "seed"];
24
+ const TEST_SEGMENTS = ["test", "tests", "spec", "specs", "__tests__"];
25
+ const TEST_FILE_TOKENS = ["test", "spec"];
26
+ const INTERFACE_KEYWORDS = [
27
+ "route",
28
+ "routes",
29
+ "controller",
30
+ "controllers",
31
+ "handler",
32
+ "handlers",
33
+ "endpoint",
34
+ "endpoints",
35
+ ];
36
+ const DATA_LAYER_KEYWORDS = [
37
+ "model",
38
+ "models",
39
+ "schema",
40
+ "schemas",
41
+ "migration",
42
+ "migrations",
43
+ "seed",
44
+ "seeds",
45
+ ];
26
46
  const SECURITY_KEYWORDS = [
27
47
  "auth",
48
+ "authentication",
49
+ "authorization",
50
+ "credential",
51
+ "credentials",
52
+ "jwt",
53
+ "oauth",
54
+ "password",
55
+ "passwords",
28
56
  "secret",
57
+ "secrets",
29
58
  "token",
59
+ "tokens",
30
60
  "permission",
61
+ "permissions",
31
62
  "session",
63
+ "sessions",
32
64
  ];
33
65
  const CONCURRENCY_KEYWORDS = [
34
66
  "queue",
@@ -44,26 +76,49 @@ const CONCURRENCY_KEYWORDS = [
44
76
  "lock",
45
77
  "locks",
46
78
  ];
47
- const SCRIPT_KEYWORDS = ["script"];
79
+ const SCRIPT_KEYWORDS = ["script", "scripts"];
48
80
  const DEPLOYMENT_KEYWORDS = [
49
81
  "docker",
50
82
  "terraform",
51
83
  "deploy",
84
+ "deployment",
85
+ "deployments",
52
86
  "workflow",
87
+ "workflows",
53
88
  "k8s",
54
89
  ];
55
- const SURFACE_KEYWORDS = ["route", "controller", "worker", "job", "command"];
90
+ const SURFACE_KEYWORDS = [
91
+ "route",
92
+ "routes",
93
+ "controller",
94
+ "controllers",
95
+ "handler",
96
+ "handlers",
97
+ "worker",
98
+ "workers",
99
+ "job",
100
+ "jobs",
101
+ "command",
102
+ "commands",
103
+ ];
56
104
  const BILLING_KEYWORDS = [
57
105
  "billing",
58
106
  "invoice",
107
+ "invoices",
59
108
  "payment",
109
+ "payments",
60
110
  "ledger",
111
+ "ledgers",
61
112
  "subscription",
113
+ "subscriptions",
62
114
  ];
63
- const IDENTITY_KEYWORDS = ["user"];
64
- const ASYNC_TASK_KEYWORDS = ["task"];
115
+ const IDENTITY_KEYWORDS = ["user", "users"];
116
+ const ASYNC_TASK_KEYWORDS = ["task", "tasks"];
65
117
  export function normalizeExtractorPath(path) {
66
- return path.replace(/\\/g, "/").toLowerCase();
118
+ return path
119
+ .replace(/\\/g, "/")
120
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
121
+ .toLowerCase();
67
122
  }
68
123
  function splitSegments(normalized) {
69
124
  return normalized.split("/").filter(Boolean);
@@ -95,7 +150,9 @@ export function isBuildOutput(normalized) {
95
150
  return hasSegment(normalized, "dist") || hasSegment(normalized, "build");
96
151
  }
97
152
  export function isVendorPath(normalized) {
98
- return normalized.includes("vendor") || normalized.includes("third_party");
153
+ return (hasSegment(normalized, "vendor") ||
154
+ hasSegment(normalized, "vendors") ||
155
+ hasSegment(normalized, "third_party"));
99
156
  }
100
157
  export function isBinaryArtifact(normalized) {
101
158
  return endsWithAny(normalized, BINARY_EXTENSIONS);
@@ -120,10 +177,15 @@ export function isAuditArtifactPath(normalized) {
120
177
  return splitSegments(normalized).some((segment) => segment.startsWith(".audit-artifacts"));
121
178
  }
122
179
  export function isTestPath(normalized) {
123
- return includesAny(normalized, TEST_KEYWORDS);
180
+ const segments = splitSegments(normalized);
181
+ if (segments.some((segment) => TEST_SEGMENTS.some((testSegment) => testSegment === segment))) {
182
+ return true;
183
+ }
184
+ const fileTokens = pathTokens(baseName(normalized));
185
+ return TEST_FILE_TOKENS.some((token) => fileTokens.includes(token));
124
186
  }
125
187
  export function isInterfacePath(normalized) {
126
- return includesAny(normalized, INTERFACE_KEYWORDS) || hasSegment(normalized, "api");
188
+ return hasToken(normalized, INTERFACE_KEYWORDS) || hasSegment(normalized, "api");
127
189
  }
128
190
  export function isDataLayerPath(normalized) {
129
191
  return (hasToken(normalized, DATA_LAYER_KEYWORDS) ||
@@ -134,7 +196,7 @@ export function isDataLayerPath(normalized) {
134
196
  hasSegment(normalized, "db"));
135
197
  }
136
198
  export function isSecuritySensitivePath(normalized) {
137
- return includesAny(normalized, SECURITY_KEYWORDS);
199
+ return hasToken(normalized, SECURITY_KEYWORDS);
138
200
  }
139
201
  export function isConcurrencyPath(normalized) {
140
202
  return hasToken(normalized, CONCURRENCY_KEYWORDS);
@@ -143,33 +205,44 @@ export function isExamplesOrFixturesPath(normalized) {
143
205
  return hasSegment(normalized, "examples") || hasSegment(normalized, "fixtures");
144
206
  }
145
207
  export function isScriptPath(normalized) {
146
- return (includesAny(normalized, SCRIPT_KEYWORDS) ||
208
+ return (hasToken(normalized, SCRIPT_KEYWORDS) ||
147
209
  hasSegment(normalized, "scripts") ||
148
210
  hasSegment(normalized, "bin"));
149
211
  }
150
212
  export function isDeploymentConfigPath(normalized) {
151
- return includesAny(normalized, DEPLOYMENT_KEYWORDS) || endsWithAny(normalized, [".yml", ".yaml"]);
213
+ return hasToken(normalized, DEPLOYMENT_KEYWORDS) || endsWithAny(normalized, [".yml", ".yaml"]);
152
214
  }
153
215
  export function isGeneratedPath(normalized) {
154
- return normalized.includes("vendor") || normalized.includes("generated");
216
+ return isVendorPath(normalized) || hasToken(normalized, ["generated", "autogenerated"]);
155
217
  }
156
218
  export function isSurfacePath(normalized) {
157
219
  return (hasSegment(normalized, "api") ||
158
- includesAny(normalized, SURFACE_KEYWORDS) ||
159
- hasSegment(normalized, "cli"));
220
+ hasToken(normalized, SURFACE_KEYWORDS) ||
221
+ hasSegment(normalized, "cli") ||
222
+ hasToken(normalized, ["cli"]));
160
223
  }
161
224
  export function isBackgroundSurfacePath(normalized) {
162
- return includesAny(normalized, ["worker", "job"]);
225
+ return hasToken(normalized, ["worker", "workers", "job", "jobs"]);
163
226
  }
164
227
  export function isNetworkSurfacePath(normalized) {
165
- return hasSegment(normalized, "api") || includesAny(normalized, ["route", "controller"]);
228
+ return (hasSegment(normalized, "api") ||
229
+ hasToken(normalized, [
230
+ "route",
231
+ "routes",
232
+ "controller",
233
+ "controllers",
234
+ "handler",
235
+ "handlers",
236
+ "endpoint",
237
+ "endpoints",
238
+ ]));
166
239
  }
167
240
  export function isBillingPath(normalized) {
168
- return includesAny(normalized, BILLING_KEYWORDS);
241
+ return hasToken(normalized, BILLING_KEYWORDS);
169
242
  }
170
243
  export function isIdentityPath(normalized) {
171
- return isSecuritySensitivePath(normalized) || includesAny(normalized, IDENTITY_KEYWORDS);
244
+ return isSecuritySensitivePath(normalized) || hasToken(normalized, IDENTITY_KEYWORDS);
172
245
  }
173
246
  export function isAsyncTaskPath(normalized) {
174
- return isConcurrencyPath(normalized) || includesAny(normalized, ASYNC_TASK_KEYWORDS);
247
+ return isConcurrencyPath(normalized) || hasToken(normalized, ASYNC_TASK_KEYWORDS);
175
248
  }
@@ -7,6 +7,7 @@ import type { FlowCoverageManifest } from "../types/flowCoverage.js";
7
7
  import type { CriticalFlowManifest } from "../types/flows.js";
8
8
  import type { GraphBundle } from "../types/graph.js";
9
9
  import type { RiskRegister } from "../types/risk.js";
10
+ import type { AuditPlanMetrics, ReviewPacket } from "../types/reviewPlanning.js";
10
11
  import type { RuntimeValidationReport, RuntimeValidationTaskManifest } from "../types/runtimeValidation.js";
11
12
  import type { SurfaceManifest } from "../types/surfaces.js";
12
13
  import type { ToolingManifest } from "../types/toolingManifest.js";
@@ -26,6 +27,8 @@ type ArtifactPayloadMap = {
26
27
  external_analyzer_results: ExternalAnalyzerResults;
27
28
  audit_results: AuditResult[];
28
29
  audit_tasks: AuditTask[];
30
+ audit_plan_metrics: AuditPlanMetrics;
31
+ review_packets: ReviewPacket[];
29
32
  requeue_tasks: AuditTask[];
30
33
  audit_report: string;
31
34
  audit_state: AuditState;
@@ -61,6 +64,8 @@ export declare const ARTIFACT_DEFINITIONS: {
61
64
  readonly external_analyzer_results: ArtifactDefinition<"external_analyzer_results">;
62
65
  readonly audit_results: ArtifactDefinition<"audit_results">;
63
66
  readonly audit_tasks: ArtifactDefinition<"audit_tasks">;
67
+ readonly audit_plan_metrics: ArtifactDefinition<"audit_plan_metrics">;
68
+ readonly review_packets: ArtifactDefinition<"review_packets">;
64
69
  readonly requeue_tasks: ArtifactDefinition<"requeue_tasks">;
65
70
  readonly audit_report: ArtifactDefinition<"audit_report">;
66
71
  readonly audit_state: ArtifactDefinition<"audit_state">;
@@ -42,6 +42,8 @@ export const ARTIFACT_DEFINITIONS = {
42
42
  external_analyzer_results: jsonArtifact("external_analyzer_results.json", "execution"),
43
43
  audit_results: ndjsonArtifact("audit_results.jsonl", "execution"),
44
44
  audit_tasks: jsonArtifact("audit_tasks.json", "execution"),
45
+ audit_plan_metrics: jsonArtifact("audit_plan_metrics.json", "execution"),
46
+ review_packets: jsonArtifact("review_packets.json", "execution"),
45
47
  requeue_tasks: jsonArtifact("requeue_tasks.json", "execution"),
46
48
  audit_report: textArtifact("audit-report.md", "reporting"),
47
49
  audit_state: jsonArtifact("audit_state.json", "supervisor"),
@@ -51,7 +51,7 @@ export async function advanceAudit(bundle, options = {}) {
51
51
  run = await runIntakeExecutor(bundle, options.root);
52
52
  break;
53
53
  case "structure_executor":
54
- run = runStructureExecutor(bundle);
54
+ run = await runStructureExecutor(bundle, options.root);
55
55
  break;
56
56
  case "planning_executor":
57
57
  if (!options.root)
@@ -12,6 +12,8 @@ export const ARTIFACT_DEPENDENCY_MAP = {
12
12
  "coverage_matrix.json",
13
13
  "flow_coverage.json",
14
14
  "audit_tasks.json",
15
+ "audit_plan_metrics.json",
16
+ "review_packets.json",
15
17
  "requeue_tasks.json",
16
18
  "runtime_validation_tasks.json",
17
19
  "runtime_validation_report.json",
@@ -26,6 +28,8 @@ export const ARTIFACT_DEPENDENCY_MAP = {
26
28
  "coverage_matrix.json",
27
29
  "flow_coverage.json",
28
30
  "audit_tasks.json",
31
+ "audit_plan_metrics.json",
32
+ "review_packets.json",
29
33
  "requeue_tasks.json",
30
34
  "runtime_validation_tasks.json",
31
35
  "runtime_validation_report.json",
@@ -35,6 +39,8 @@ export const ARTIFACT_DEPENDENCY_MAP = {
35
39
  "risk_register.json",
36
40
  "coverage_matrix.json",
37
41
  "audit_tasks.json",
42
+ "audit_plan_metrics.json",
43
+ "review_packets.json",
38
44
  "runtime_validation_tasks.json",
39
45
  "requeue_tasks.json",
40
46
  "audit-report.md",
@@ -49,6 +55,8 @@ export const ARTIFACT_DEPENDENCY_MAP = {
49
55
  "flow_coverage.json",
50
56
  "risk_register.json",
51
57
  "audit_tasks.json",
58
+ "audit_plan_metrics.json",
59
+ "review_packets.json",
52
60
  "requeue_tasks.json",
53
61
  "runtime_validation_tasks.json",
54
62
  "runtime_validation_report.json",
@@ -58,12 +66,16 @@ export const ARTIFACT_DEPENDENCY_MAP = {
58
66
  "coverage_matrix.json",
59
67
  "flow_coverage.json",
60
68
  "requeue_tasks.json",
69
+ "audit_plan_metrics.json",
70
+ "review_packets.json",
61
71
  "runtime_validation_tasks.json",
62
72
  "runtime_validation_report.json",
63
73
  "audit-report.md",
64
74
  ],
65
75
  "coverage_matrix.json": [
66
76
  "flow_coverage.json",
77
+ "audit_plan_metrics.json",
78
+ "review_packets.json",
67
79
  "requeue_tasks.json",
68
80
  "runtime_validation_tasks.json",
69
81
  "runtime_validation_report.json",
@@ -75,6 +87,12 @@ export const ARTIFACT_DEPENDENCY_MAP = {
75
87
  "runtime_validation_report.json",
76
88
  "audit-report.md",
77
89
  ],
90
+ "audit_tasks.json": [
91
+ "audit_plan_metrics.json",
92
+ "review_packets.json",
93
+ ],
94
+ "audit_plan_metrics.json": [],
95
+ "review_packets.json": [],
78
96
  "runtime_validation_report.json": [
79
97
  "audit-report.md",
80
98
  ],
@@ -0,0 +1,32 @@
1
+ import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
2
+ import type { GraphBundle } from "../types/graph.js";
3
+ export type FileAnchorKind = "boundary" | "import" | "export" | "symbol" | "route" | "keyword" | "graph" | "analyzer_signal";
4
+ export interface FileAnchor {
5
+ kind: FileAnchorKind;
6
+ name: string;
7
+ line?: number;
8
+ detail?: string;
9
+ }
10
+ export interface FileAnchorSummary {
11
+ contract_version: "audit-code-file-anchors/v1alpha1";
12
+ path: string;
13
+ total_lines: number;
14
+ review_mode: "isolated_large_file";
15
+ scope_basis: string[];
16
+ anchors: FileAnchor[];
17
+ omitted_anchor_count: number;
18
+ counts: {
19
+ symbols: number;
20
+ routes: number;
21
+ keywords: number;
22
+ graph_edges: number;
23
+ analyzer_signals: number;
24
+ };
25
+ }
26
+ export declare function buildFileAnchorSummary(params: {
27
+ path: string;
28
+ content: string;
29
+ totalLines: number;
30
+ graphBundle?: GraphBundle;
31
+ externalAnalyzerResults?: ExternalAnalyzerResults;
32
+ }): FileAnchorSummary;