auditor-lambda 0.3.40 → 0.5.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/audit-code-wrapper-lib.mjs +20 -2
- package/dist/cli/args.d.ts +59 -0
- package/dist/cli/args.js +244 -0
- package/dist/cli/dispatch.d.ts +80 -0
- package/dist/cli/dispatch.js +532 -0
- package/dist/cli/prompts.d.ts +37 -0
- package/dist/cli/prompts.js +225 -0
- package/dist/cli/steps.d.ts +29 -0
- package/dist/cli/steps.js +30 -0
- package/dist/cli/waveManifest.d.ts +40 -0
- package/dist/cli/waveManifest.js +41 -0
- package/dist/cli/workerResult.d.ts +18 -0
- package/dist/cli/workerResult.js +42 -0
- package/dist/cli.d.ts +2 -22
- package/dist/cli.js +442 -975
- package/dist/extractors/analyzers/css.d.ts +2 -0
- package/dist/extractors/analyzers/css.js +101 -0
- package/dist/extractors/analyzers/html.d.ts +2 -0
- package/dist/extractors/analyzers/html.js +92 -0
- package/dist/extractors/analyzers/merge.d.ts +14 -0
- package/dist/extractors/analyzers/merge.js +85 -0
- package/dist/extractors/analyzers/python.d.ts +2 -0
- package/dist/extractors/analyzers/python.js +104 -0
- package/dist/extractors/analyzers/registry.d.ts +33 -0
- package/dist/extractors/analyzers/registry.js +100 -0
- package/dist/extractors/analyzers/resourceUrl.d.ts +7 -0
- package/dist/extractors/analyzers/resourceUrl.js +25 -0
- package/dist/extractors/analyzers/sql.d.ts +2 -0
- package/dist/extractors/analyzers/sql.js +19 -0
- package/dist/extractors/analyzers/treeSitter.d.ts +34 -0
- package/dist/extractors/analyzers/treeSitter.js +111 -0
- package/dist/extractors/analyzers/types.d.ts +53 -0
- package/dist/extractors/analyzers/typescript.d.ts +2 -0
- package/dist/extractors/analyzers/typescript.js +257 -0
- package/dist/extractors/browserExtension.d.ts +1 -3
- package/dist/extractors/browserExtension.js +2 -2
- package/dist/extractors/designAssessment.d.ts +1 -3
- package/dist/extractors/disposition.d.ts +2 -1
- package/dist/extractors/disposition.js +11 -1
- package/dist/extractors/flows.d.ts +1 -3
- package/dist/extractors/flows.js +2 -2
- package/dist/extractors/graph.d.ts +2 -2
- package/dist/extractors/graph.js +171 -327
- package/dist/extractors/graphManifestEdges.d.ts +1 -1
- package/dist/extractors/graphPathUtils.d.ts +1 -1
- package/dist/extractors/graphPythonImports.d.ts +18 -0
- package/dist/extractors/graphPythonImports.js +362 -0
- package/dist/extractors/pathPatterns.d.ts +6 -0
- package/dist/extractors/pathPatterns.js +8 -0
- package/dist/extractors/risk.d.ts +1 -2
- package/dist/extractors/surfaces.d.ts +1 -3
- package/dist/extractors/surfaces.js +2 -2
- package/dist/io/artifacts.d.ts +12 -5
- package/dist/io/artifacts.js +13 -1
- package/dist/io/runArtifacts.js +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/orchestrator/advance.d.ts +21 -0
- package/dist/orchestrator/advance.js +69 -7
- package/dist/orchestrator/auditTaskUtils.d.ts +4 -0
- package/dist/orchestrator/auditTaskUtils.js +27 -0
- package/dist/orchestrator/dependencyMap.js +27 -0
- package/dist/orchestrator/edgeReasoning.d.ts +39 -0
- package/dist/orchestrator/edgeReasoning.js +125 -0
- package/dist/orchestrator/executors.js +11 -1
- package/dist/orchestrator/fileAnchors.d.ts +1 -1
- package/dist/orchestrator/fileIntegrity.d.ts +7 -0
- package/dist/orchestrator/fileIntegrity.js +41 -0
- package/dist/orchestrator/flowCoverage.d.ts +1 -1
- package/dist/orchestrator/flowPlanning.d.ts +1 -1
- package/dist/orchestrator/flowRequeue.d.ts +1 -1
- package/dist/orchestrator/graphEnrichmentExecutor.d.ts +29 -0
- package/dist/orchestrator/graphEnrichmentExecutor.js +196 -0
- package/dist/orchestrator/internalExecutors.d.ts +13 -2
- package/dist/orchestrator/internalExecutors.js +112 -16
- package/dist/orchestrator/localCommands.js +6 -25
- package/dist/orchestrator/nextStep.d.ts +2 -1
- package/dist/orchestrator/nextStep.js +3 -1
- package/dist/orchestrator/planning.d.ts +1 -1
- package/dist/orchestrator/requeueCommand.d.ts +1 -1
- package/dist/orchestrator/reviewPackets.d.ts +37 -4
- package/dist/orchestrator/reviewPackets.js +113 -158
- package/dist/orchestrator/runtimeValidation.d.ts +1 -1
- package/dist/orchestrator/runtimeValidation.js +4 -31
- package/dist/orchestrator/scope.d.ts +62 -0
- package/dist/orchestrator/scope.js +227 -0
- package/dist/orchestrator/state.js +2 -0
- package/dist/orchestrator/taskBuilder.d.ts +1 -1
- package/dist/orchestrator/taskBuilder.js +1 -12
- package/dist/orchestrator/unionFind.d.ts +7 -0
- package/dist/orchestrator/unionFind.js +32 -0
- package/dist/orchestrator/unitBuilder.d.ts +2 -2
- package/dist/orchestrator/unitBuilder.js +4 -18
- package/dist/prompts/renderWorkerPrompt.js +18 -1
- package/dist/providers/claudeCodeProvider.d.ts +4 -4
- package/dist/providers/claudeCodeProvider.js +9 -3
- package/dist/providers/constants.d.ts +1 -1
- package/dist/providers/constants.js +1 -1
- package/dist/providers/index.d.ts +1 -2
- package/dist/providers/index.js +5 -4
- package/dist/providers/localSubprocessProvider.d.ts +2 -2
- package/dist/providers/localSubprocessProvider.js +1 -1
- package/dist/providers/opencodeProvider.d.ts +4 -4
- package/dist/providers/opencodeProvider.js +7 -2
- package/dist/providers/spawnLoggedCommand.d.ts +3 -1
- package/dist/providers/spawnLoggedCommand.js +21 -0
- package/dist/providers/subprocessTemplateProvider.d.ts +4 -4
- package/dist/providers/subprocessTemplateProvider.js +8 -3
- package/dist/providers/vscodeTaskProvider.d.ts +3 -4
- package/dist/providers/vscodeTaskProvider.js +2 -2
- package/dist/quota/discoveredLimits.js +1 -1
- package/dist/quota/hostLimits.d.ts +1 -2
- package/dist/quota/hostLimits.js +4 -46
- package/dist/quota/index.d.ts +18 -15
- package/dist/quota/index.js +4 -9
- package/dist/quota/scheduler.d.ts +1 -3
- package/dist/quota/scheduler.js +1 -2
- package/dist/reporting/synthesis.d.ts +37 -3
- package/dist/reporting/synthesis.js +97 -16
- package/dist/reporting/synthesisNarrativePrompt.d.ts +7 -0
- package/dist/reporting/synthesisNarrativePrompt.js +60 -0
- package/dist/reporting/workBlocks.d.ts +2 -11
- package/dist/supervisor/operatorHandoff.js +1 -1
- package/dist/supervisor/runLedger.d.ts +1 -1
- package/dist/supervisor/runLedger.js +2 -2
- package/dist/supervisor/sessionConfig.d.ts +8 -1
- package/dist/supervisor/sessionConfig.js +22 -3
- package/dist/types/analyzerCapability.d.ts +16 -0
- package/dist/types/auditScope.d.ts +43 -0
- package/dist/types/auditScope.js +14 -0
- package/dist/types/reviewPlanning.d.ts +1 -1
- package/dist/types/synthesisNarrative.d.ts +7 -0
- package/dist/types/synthesisNarrative.js +5 -0
- package/dist/types/workerSession.d.ts +6 -0
- package/dist/types.d.ts +2 -19
- package/dist/validation/artifacts.d.ts +1 -1
- package/dist/validation/artifacts.js +10 -1
- package/dist/validation/auditResults.d.ts +1 -1
- package/dist/validation/auditResults.js +1 -1
- package/dist/validation/sessionConfig.d.ts +2 -3
- package/dist/validation/sessionConfig.js +25 -3
- package/package.json +7 -3
- package/schemas/analyzer_capability.schema.json +47 -0
- package/schemas/audit_findings.schema.json +141 -0
- package/schemas/finding.schema.json +2 -1
- package/schemas/graph_bundle.schema.json +5 -0
- package/schemas/scope.schema.json +46 -0
- package/scripts/postinstall.mjs +0 -1
- package/dist/io/json.d.ts +0 -10
- package/dist/io/json.js +0 -142
- package/dist/providers/types.d.ts +0 -33
- package/dist/quota/compositeQuotaSource.d.ts +0 -7
- package/dist/quota/compositeQuotaSource.js +0 -20
- package/dist/quota/errorParsers/claudeCodeErrorParser.d.ts +0 -6
- package/dist/quota/errorParsers/claudeCodeErrorParser.js +0 -39
- package/dist/quota/errorParsers/genericErrorParser.d.ts +0 -9
- package/dist/quota/errorParsers/genericErrorParser.js +0 -7
- package/dist/quota/errorParsers/index.d.ts +0 -5
- package/dist/quota/errorParsers/index.js +0 -12
- package/dist/quota/errorParsing.d.ts +0 -7
- package/dist/quota/errorParsing.js +0 -69
- package/dist/quota/fileLock.d.ts +0 -6
- package/dist/quota/fileLock.js +0 -64
- package/dist/quota/learnedQuotaSource.d.ts +0 -7
- package/dist/quota/learnedQuotaSource.js +0 -25
- package/dist/quota/limits.d.ts +0 -16
- package/dist/quota/limits.js +0 -77
- package/dist/quota/quotaSource.d.ts +0 -12
- package/dist/quota/slidingWindow.d.ts +0 -4
- package/dist/quota/slidingWindow.js +0 -28
- package/dist/quota/state.d.ts +0 -15
- package/dist/quota/state.js +0 -148
- package/dist/quota/types.d.ts +0 -67
- package/dist/quota/types.js +0 -1
- package/dist/reporting/rootCause.d.ts +0 -10
- package/dist/reporting/rootCause.js +0 -146
- package/dist/types/disposition.d.ts +0 -9
- package/dist/types/disposition.js +0 -1
- package/dist/types/flows.d.ts +0 -17
- package/dist/types/flows.js +0 -1
- package/dist/types/graph.d.ts +0 -22
- package/dist/types/graph.js +0 -1
- package/dist/types/risk.d.ts +0 -9
- package/dist/types/risk.js +0 -1
- package/dist/types/runLedger.d.ts +0 -17
- package/dist/types/runLedger.js +0 -6
- package/dist/types/sessionConfig.d.ts +0 -79
- package/dist/types/sessionConfig.js +0 -15
- package/dist/types/surfaces.d.ts +0 -15
- package/dist/types/surfaces.js +0 -1
- package/dist/validation/basic.d.ts +0 -13
- package/dist/validation/basic.js +0 -46
- /package/dist/{providers → extractors/analyzers}/types.js +0 -0
- /package/dist/{quota/quotaSource.js → types/analyzerCapability.js} +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { installToCache, resolveAnalyzerDep } from "@audit-tools/shared";
|
|
2
|
+
import { buildDispositionMap } from "../extractors/disposition.js";
|
|
3
|
+
import { buildPathLookup } from "../extractors/graph.js";
|
|
4
|
+
import { mergeAnalyzerEdges } from "../extractors/analyzers/merge.js";
|
|
5
|
+
import { ANALYZER_REGISTRY } from "../extractors/analyzers/registry.js";
|
|
6
|
+
import { applyEdgeReasoning, } from "./edgeReasoning.js";
|
|
7
|
+
const BUCKET_BY_KIND = {
|
|
8
|
+
"ts-import": "imports",
|
|
9
|
+
"ts-reexport": "imports",
|
|
10
|
+
"ts-call": "calls",
|
|
11
|
+
"ts-extends": "references",
|
|
12
|
+
"ts-implements": "references",
|
|
13
|
+
// Python (tree-sitter) imports merge into the imports bucket alongside the
|
|
14
|
+
// regex floor's python-* edges.
|
|
15
|
+
"py-import": "imports",
|
|
16
|
+
"py-from-import": "imports",
|
|
17
|
+
// HTML/CSS (tree-sitter) resource references live with the floor's
|
|
18
|
+
// html-resource-link / reference edges.
|
|
19
|
+
"html-resource": "references",
|
|
20
|
+
"css-import": "references",
|
|
21
|
+
"css-url": "references",
|
|
22
|
+
};
|
|
23
|
+
function bucketForKind(kind) {
|
|
24
|
+
const bucket = kind ? BUCKET_BY_KIND[kind] : undefined;
|
|
25
|
+
return bucket ?? "references";
|
|
26
|
+
}
|
|
27
|
+
function settingFor(analyzers, id) {
|
|
28
|
+
return analyzers?.[id] ?? "auto";
|
|
29
|
+
}
|
|
30
|
+
function routeSignature(route) {
|
|
31
|
+
return `${route.method ?? ""}\0${route.path}\0${route.handler}`;
|
|
32
|
+
}
|
|
33
|
+
function mergeRoutes(floor, analyzer) {
|
|
34
|
+
const deduped = new Map();
|
|
35
|
+
for (const route of [...floor, ...analyzer]) {
|
|
36
|
+
deduped.set(routeSignature(route), route);
|
|
37
|
+
}
|
|
38
|
+
return [...deduped.values()].sort((a, b) => a.path.localeCompare(b.path) ||
|
|
39
|
+
a.handler.localeCompare(b.handler) ||
|
|
40
|
+
(a.method ?? "").localeCompare(b.method ?? ""));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a dependency for actual execution (may install for ephemeral/permanent).
|
|
44
|
+
* `auto`/`repo` with an absent dependency falls back to the regex floor.
|
|
45
|
+
*/
|
|
46
|
+
function resolveForRun(analyzer, root, setting, cacheRoot) {
|
|
47
|
+
if (!analyzer.dependency) {
|
|
48
|
+
return { resolution: "repo" };
|
|
49
|
+
}
|
|
50
|
+
const options = cacheRoot ? { cacheRoot } : {};
|
|
51
|
+
const resolved = resolveAnalyzerDep(analyzer.dependency, root, options);
|
|
52
|
+
if (resolved.via === "repo" || resolved.via === "cache") {
|
|
53
|
+
return { resolution: resolved.via, path: resolved.path };
|
|
54
|
+
}
|
|
55
|
+
if (setting === "ephemeral" || setting === "permanent") {
|
|
56
|
+
const install = installToCache(analyzer.dependency, options);
|
|
57
|
+
if (install.ok && install.path) {
|
|
58
|
+
return { resolution: "installed", path: install.path };
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
resolution: "absent",
|
|
62
|
+
note: `Install of '${analyzer.dependency}' failed: ${install.error ?? "unknown error"}.`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
resolution: "absent",
|
|
67
|
+
note: `Dependency '${analyzer.dependency}' not resolvable; kept regex floor.`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the optional graph-enrichment obligation. Layers language-analyzer
|
|
72
|
+
* edges onto the deterministic regex floor in `graph_bundle.json`
|
|
73
|
+
* (higher-confidence-kind-wins) and records provenance in
|
|
74
|
+
* `analyzer_capability.json`. With no root, or when every analyzer skips / is
|
|
75
|
+
* absent / not-applicable, the graph bundle is left byte-identical to the floor
|
|
76
|
+
* and only the marker is written.
|
|
77
|
+
*/
|
|
78
|
+
export async function runGraphEnrichmentExecutor(bundle, options = {}) {
|
|
79
|
+
const floor = bundle.graph_bundle;
|
|
80
|
+
if (!floor) {
|
|
81
|
+
throw new Error("Cannot run graph enrichment without graph_bundle");
|
|
82
|
+
}
|
|
83
|
+
const registry = options.registry ?? ANALYZER_REGISTRY;
|
|
84
|
+
const root = options.root;
|
|
85
|
+
const disposition = bundle.file_disposition;
|
|
86
|
+
const dispositionMap = buildDispositionMap(disposition);
|
|
87
|
+
const pathLookup = bundle.repo_manifest
|
|
88
|
+
? buildPathLookup(bundle.repo_manifest, dispositionMap)
|
|
89
|
+
: new Map();
|
|
90
|
+
const includedFiles = [...new Set(pathLookup.values())].sort((a, b) => a.localeCompare(b));
|
|
91
|
+
const entries = [];
|
|
92
|
+
const bucketEdges = { imports: [], calls: [], references: [] };
|
|
93
|
+
const routeEdges = [];
|
|
94
|
+
const analyzersUsed = [];
|
|
95
|
+
for (const analyzer of registry) {
|
|
96
|
+
const setting = settingFor(options.analyzers, analyzer.id);
|
|
97
|
+
const supportedFiles = includedFiles.filter((file) => analyzer.supports(file));
|
|
98
|
+
if (supportedFiles.length === 0) {
|
|
99
|
+
entries.push({ id: analyzer.id, resolution: "not_applicable", setting, edges_added: 0, routes_added: 0 });
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (setting === "skip") {
|
|
103
|
+
entries.push({ id: analyzer.id, resolution: "skip", setting, edges_added: 0, routes_added: 0, note: "Analyzer disabled via session config." });
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (!root || !bundle.repo_manifest) {
|
|
107
|
+
entries.push({ id: analyzer.id, resolution: "absent", setting, edges_added: 0, routes_added: 0, note: "No repository root available for analysis." });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const run = resolveForRun(analyzer, root, setting, options.cacheRoot);
|
|
111
|
+
if (run.resolution === "absent") {
|
|
112
|
+
entries.push({ id: analyzer.id, resolution: "absent", setting, edges_added: 0, routes_added: 0, note: run.note });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
let edges = [];
|
|
116
|
+
let routes = [];
|
|
117
|
+
try {
|
|
118
|
+
const output = await analyzer.analyze(supportedFiles, {
|
|
119
|
+
root,
|
|
120
|
+
repoManifest: bundle.repo_manifest,
|
|
121
|
+
disposition,
|
|
122
|
+
includedFiles,
|
|
123
|
+
pathLookup,
|
|
124
|
+
dependencyPath: run.path,
|
|
125
|
+
});
|
|
126
|
+
edges = output.edges ?? [];
|
|
127
|
+
routes = output.routes ?? [];
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
entries.push({
|
|
131
|
+
id: analyzer.id,
|
|
132
|
+
resolution: run.resolution,
|
|
133
|
+
setting,
|
|
134
|
+
edges_added: 0,
|
|
135
|
+
routes_added: 0,
|
|
136
|
+
note: `Analyzer failed: ${error instanceof Error ? error.message : String(error)}.`,
|
|
137
|
+
});
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
for (const edge of edges) {
|
|
141
|
+
bucketEdges[bucketForKind(edge.kind)].push(edge);
|
|
142
|
+
}
|
|
143
|
+
routeEdges.push(...routes);
|
|
144
|
+
if (edges.length + routes.length > 0) {
|
|
145
|
+
analyzersUsed.push(analyzer.id);
|
|
146
|
+
}
|
|
147
|
+
entries.push({ id: analyzer.id, resolution: run.resolution, setting, edges_added: edges.length, routes_added: routes.length });
|
|
148
|
+
}
|
|
149
|
+
const applied = analyzersUsed.length > 0;
|
|
150
|
+
const record = {
|
|
151
|
+
status: applied ? "applied" : "omitted",
|
|
152
|
+
analyzers: entries,
|
|
153
|
+
};
|
|
154
|
+
// The graph this obligation produces: the enriched bundle when analyzers
|
|
155
|
+
// contributed, otherwise the regex floor. Phase 4B may then rewrite the
|
|
156
|
+
// reasons of low-confidence edges on whichever graph stands — the floor's
|
|
157
|
+
// heuristic edges exist regardless of analyzers.
|
|
158
|
+
const graphBundle = applied
|
|
159
|
+
? {
|
|
160
|
+
...floor,
|
|
161
|
+
graphs: {
|
|
162
|
+
...floor.graphs,
|
|
163
|
+
imports: mergeAnalyzerEdges(floor.graphs.imports ?? [], bucketEdges.imports),
|
|
164
|
+
calls: mergeAnalyzerEdges(floor.graphs.calls ?? [], bucketEdges.calls),
|
|
165
|
+
references: mergeAnalyzerEdges(floor.graphs.references ?? [], bucketEdges.references),
|
|
166
|
+
...(routeEdges.length > 0
|
|
167
|
+
? { routes: mergeRoutes(floor.graphs.routes ?? [], routeEdges) }
|
|
168
|
+
: {}),
|
|
169
|
+
},
|
|
170
|
+
analyzers_used: [...new Set(analyzersUsed)].sort(),
|
|
171
|
+
}
|
|
172
|
+
: floor;
|
|
173
|
+
let reasoned = { rewritten: 0, candidates: 0 };
|
|
174
|
+
if (options.llmEdgeReasoning === true && options.edgeReasoning) {
|
|
175
|
+
reasoned = applyEdgeReasoning(graphBundle, options.edgeReasoning);
|
|
176
|
+
}
|
|
177
|
+
const graphChanged = applied || reasoned.rewritten > 0;
|
|
178
|
+
const reasonSuffix = reasoned.rewritten > 0
|
|
179
|
+
? ` Edge reasoning rewrote ${reasoned.rewritten} reason(s).`
|
|
180
|
+
: "";
|
|
181
|
+
if (!graphChanged) {
|
|
182
|
+
return {
|
|
183
|
+
updated: { ...bundle, analyzer_capability: record },
|
|
184
|
+
artifacts_written: ["analyzer_capability.json"],
|
|
185
|
+
progress_summary: "Graph enrichment omitted; deterministic regex graph retained.",
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const totalEdges = entries.reduce((sum, entry) => sum + entry.edges_added, 0);
|
|
189
|
+
return {
|
|
190
|
+
updated: { ...bundle, graph_bundle: graphBundle, analyzer_capability: record },
|
|
191
|
+
artifacts_written: ["graph_bundle.json", "analyzer_capability.json"],
|
|
192
|
+
progress_summary: applied
|
|
193
|
+
? `Graph enrichment applied ${totalEdges} analyzer edge(s) from ${analyzersUsed.join(", ")}.${reasonSuffix}`
|
|
194
|
+
: `Graph enrichment omitted analyzers; edge reasoning rewrote ${reasoned.rewritten} reason(s).`,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -2,6 +2,8 @@ import type { ArtifactBundle } from "../io/artifacts.js";
|
|
|
2
2
|
import type { AuditResult } from "../types.js";
|
|
3
3
|
import type { RuntimeValidationReport } from "../types/runtimeValidation.js";
|
|
4
4
|
import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
|
|
5
|
+
import type { AuditScopeManifest } from "../types/auditScope.js";
|
|
6
|
+
import type { SynthesisNarrative } from "@audit-tools/shared";
|
|
5
7
|
export interface ExecutorRunResult {
|
|
6
8
|
updated: ArtifactBundle;
|
|
7
9
|
artifacts_written: string[];
|
|
@@ -15,9 +17,18 @@ export declare function runIntakeExecutor(bundle: ArtifactBundle, root: string):
|
|
|
15
17
|
export declare function runStructureExecutor(bundle: ArtifactBundle, root?: string): Promise<ExecutorRunResult>;
|
|
16
18
|
export declare function runDesignAssessmentExecutor(bundle: ArtifactBundle): ExecutorRunResult;
|
|
17
19
|
export declare function runDesignReviewAutoComplete(bundle: ArtifactBundle): ExecutorRunResult;
|
|
18
|
-
export declare function runPlanningExecutor(bundle: ArtifactBundle, root: string, lineIndex?: Record<string, number
|
|
20
|
+
export declare function runPlanningExecutor(bundle: ArtifactBundle, root: string, lineIndex?: Record<string, number>, sizeIndex?: Record<string, number>, scope?: AuditScopeManifest): Promise<ExecutorRunResult>;
|
|
19
21
|
export declare function runResultIngestionExecutor(bundle: ArtifactBundle, results: AuditResult[]): ExecutorRunResult;
|
|
20
|
-
export declare function runRuntimeValidationExecutor(bundle: ArtifactBundle, root: string
|
|
22
|
+
export declare function runRuntimeValidationExecutor(bundle: ArtifactBundle, root: string, options?: {
|
|
23
|
+
opentoken?: boolean;
|
|
24
|
+
}): Promise<ExecutorRunResult>;
|
|
21
25
|
export declare function runRuntimeValidationUpdateExecutor(bundle: ArtifactBundle, updates: RuntimeValidationReport): ExecutorRunResult;
|
|
22
26
|
export declare function runSynthesisExecutor(bundle: ArtifactBundle, results?: AuditResult[]): ExecutorRunResult;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the optional synthesis-narrative obligation. When a host/provider
|
|
29
|
+
* narrative is supplied it is merged into the canonical findings report and the
|
|
30
|
+
* human report is re-rendered with themes/executive-summary/top-risks; without
|
|
31
|
+
* one the narrative is recorded as omitted and the deterministic report stands.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runSynthesisNarrativeExecutor(bundle: ArtifactBundle, narrative?: SynthesisNarrative): ExecutorRunResult;
|
|
23
34
|
export declare function runExternalAnalyzerImportExecutor(bundle: ArtifactBundle, externalResults: ExternalAnalyzerResults): ExecutorRunResult;
|
|
@@ -5,12 +5,13 @@ import { buildCriticalFlowManifest } from "../extractors/flows.js";
|
|
|
5
5
|
import { buildRiskRegister } from "../extractors/risk.js";
|
|
6
6
|
import { buildSurfaceManifest } from "../extractors/surfaces.js";
|
|
7
7
|
import { initializeCoverageFromPlan } from "./planning.js";
|
|
8
|
+
import { applyScopeToCoverage, fullAuditScope } from "./scope.js";
|
|
8
9
|
import { buildFlowCoverage } from "./flowCoverage.js";
|
|
9
10
|
import { buildRequeuePayload } from "./requeueCommand.js";
|
|
10
11
|
import { buildRuntimeValidationTasks, discoverRuntimeValidationCommand, mergeRuntimeValidationReport, } from "./runtimeValidation.js";
|
|
11
|
-
import { buildAuditReportModel, renderAuditReportMarkdown, } from "../reporting/synthesis.js";
|
|
12
|
+
import { applyNarrative, buildAuditFindingsReport, buildAuditReportModel, renderAuditReportMarkdown, } from "../reporting/synthesis.js";
|
|
12
13
|
import { buildChunkedAuditTasks, } from "./taskBuilder.js";
|
|
13
|
-
import { buildAuditPlanMetrics, buildReviewPackets, } from "./reviewPackets.js";
|
|
14
|
+
import { buildAuditPlanMetrics, buildReviewPackets, sizeIndexFromManifest, } from "./reviewPackets.js";
|
|
14
15
|
import { buildUnitManifest } from "./unitBuilder.js";
|
|
15
16
|
import { buildRepoManifestFromFs } from "../extractors/fsIntake.js";
|
|
16
17
|
import { loadIgnoreFile } from "../extractors/ignore.js";
|
|
@@ -27,6 +28,7 @@ function appendSelectiveDeepeningTasks(params) {
|
|
|
27
28
|
return { bundle: params.bundle, taskCount: 0, artifacts: [] };
|
|
28
29
|
}
|
|
29
30
|
const lineIndex = lineIndexFromTasks(params.bundle.audit_tasks);
|
|
31
|
+
const sizeIndex = sizeIndexFromManifest(params.bundle.repo_manifest);
|
|
30
32
|
const selectiveDeepeningTasks = buildSelectiveDeepeningTasks({
|
|
31
33
|
existingTasks: params.bundle.audit_tasks,
|
|
32
34
|
results: params.results,
|
|
@@ -46,18 +48,33 @@ function appendSelectiveDeepeningTasks(params) {
|
|
|
46
48
|
audit_plan_metrics: buildAuditPlanMetrics(auditTasks, {
|
|
47
49
|
graphBundle: params.bundle.graph_bundle,
|
|
48
50
|
lineIndex,
|
|
51
|
+
sizeIndex,
|
|
49
52
|
}),
|
|
50
53
|
review_packets: buildReviewPackets(auditTasks, {
|
|
51
54
|
graphBundle: params.bundle.graph_bundle,
|
|
52
55
|
lineIndex,
|
|
56
|
+
sizeIndex,
|
|
53
57
|
}),
|
|
54
58
|
},
|
|
55
59
|
taskCount: selectiveDeepeningTasks.length,
|
|
56
60
|
artifacts: ["audit_tasks.json", "audit_plan_metrics.json", "review_packets.json"],
|
|
57
61
|
};
|
|
58
62
|
}
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
function resolveOpentokenWrap(resolved, platform = process.platform) {
|
|
64
|
+
if (platform === "win32") {
|
|
65
|
+
const shell = process.env.ComSpec ?? "cmd.exe";
|
|
66
|
+
const inner = [resolved.command, ...resolved.args]
|
|
67
|
+
.map((v) => (/^[A-Za-z0-9_./:=@+-]+$/.test(v) ? v : `"${v.replace(/(["^&|<>%])/g, "^$1")}"`))
|
|
68
|
+
.join(" ");
|
|
69
|
+
return { command: shell, args: ["/d", "/s", "/c", `opentoken wrap ${inner}`] };
|
|
70
|
+
}
|
|
71
|
+
return { command: "opentoken", args: ["wrap", resolved.command, ...resolved.args] };
|
|
72
|
+
}
|
|
73
|
+
async function runCommand(command, cwd, options = {}) {
|
|
74
|
+
let spawnCommand = resolveRuntimeValidationSpawnCommand(command);
|
|
75
|
+
if (options.opentoken) {
|
|
76
|
+
spawnCommand = resolveOpentokenWrap(spawnCommand);
|
|
77
|
+
}
|
|
61
78
|
const displayCommand = command.join(" ");
|
|
62
79
|
return await new Promise((resolve) => {
|
|
63
80
|
const child = spawn(spawnCommand.command, spawnCommand.args, {
|
|
@@ -121,7 +138,7 @@ export async function runIntakeExecutor(bundle, root) {
|
|
|
121
138
|
const repoManifest = await buildRepoManifestFromFs({
|
|
122
139
|
root,
|
|
123
140
|
ignore,
|
|
124
|
-
hash_files:
|
|
141
|
+
hash_files: true,
|
|
125
142
|
});
|
|
126
143
|
const disposition = buildFileDisposition(repoManifest);
|
|
127
144
|
const auditableCount = disposition.files.filter((file) => !isAuditExcludedStatus(file.status)).length;
|
|
@@ -192,6 +209,11 @@ export function runDesignAssessmentExecutor(bundle) {
|
|
|
192
209
|
criticalFlows: bundle.critical_flows,
|
|
193
210
|
riskRegister: bundle.risk_register,
|
|
194
211
|
});
|
|
212
|
+
const previous = bundle.design_assessment;
|
|
213
|
+
if (previous?.reviewed) {
|
|
214
|
+
designAssessment.reviewed = true;
|
|
215
|
+
designAssessment.review_findings = previous.review_findings ?? [];
|
|
216
|
+
}
|
|
195
217
|
return {
|
|
196
218
|
updated: {
|
|
197
219
|
...bundle,
|
|
@@ -220,10 +242,11 @@ export function runDesignReviewAutoComplete(bundle) {
|
|
|
220
242
|
progress_summary: "Design review auto-completed (host-agent review available via next-step).",
|
|
221
243
|
};
|
|
222
244
|
}
|
|
223
|
-
export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
245
|
+
export async function runPlanningExecutor(bundle, root, lineIndex = {}, sizeIndex, scope) {
|
|
224
246
|
if (!bundle.repo_manifest) {
|
|
225
247
|
throw new Error("Cannot run planning executor without repo_manifest");
|
|
226
248
|
}
|
|
249
|
+
const resolvedSizeIndex = sizeIndex ?? sizeIndexFromManifest(bundle.repo_manifest);
|
|
227
250
|
if (!bundle.file_disposition ||
|
|
228
251
|
!bundle.unit_manifest ||
|
|
229
252
|
!bundle.surface_manifest ||
|
|
@@ -231,9 +254,13 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
231
254
|
!bundle.risk_register) {
|
|
232
255
|
throw new Error("Cannot run planning executor without current structure artifacts");
|
|
233
256
|
}
|
|
257
|
+
const resolvedScope = scope ?? fullAuditScope();
|
|
234
258
|
const externalAnalyzerResults = bundle.external_analyzer_results;
|
|
235
259
|
const coverage = initializeCoverageFromPlan(bundle.repo_manifest, bundle.unit_manifest, bundle.file_disposition, externalAnalyzerResults);
|
|
236
260
|
const skippedTrivialPaths = autoCompleteTrivialCoverage(coverage, lineIndex, externalAnalyzerResults);
|
|
261
|
+
// Delta scope: only seed + expanded files stay pending; the rest inherit prior
|
|
262
|
+
// completion or are excluded from this run. Full scope is a no-op.
|
|
263
|
+
applyScopeToCoverage(coverage, resolvedScope, bundle.coverage_matrix);
|
|
237
264
|
const flowCoverage = buildFlowCoverage(bundle.critical_flows, coverage);
|
|
238
265
|
const runtimeCommand = await discoverRuntimeValidationCommand(root);
|
|
239
266
|
const runtimeValidationTasks = buildRuntimeValidationTasks({
|
|
@@ -256,15 +283,21 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
256
283
|
const reviewPackets = buildReviewPackets(taggedAuditTasks, {
|
|
257
284
|
graphBundle: bundle.graph_bundle,
|
|
258
285
|
lineIndex,
|
|
286
|
+
sizeIndex: resolvedSizeIndex,
|
|
259
287
|
});
|
|
260
288
|
const auditPlanMetrics = buildAuditPlanMetrics(taggedAuditTasks, {
|
|
261
289
|
graphBundle: bundle.graph_bundle,
|
|
262
290
|
lineIndex,
|
|
291
|
+
sizeIndex: resolvedSizeIndex,
|
|
263
292
|
});
|
|
264
293
|
const requeuePayload = buildRequeuePayload(coverage, bundle.critical_flows, flowCoverage, externalAnalyzerResults);
|
|
294
|
+
const scopeSummary = resolvedScope.mode === "delta"
|
|
295
|
+
? ` Delta scope since ${resolvedScope.since}: ${resolvedScope.seed_files.length} changed file(s) + ${resolvedScope.expanded_files.length} graph neighbour(s) queued; a full audit is advised before release.`
|
|
296
|
+
: "";
|
|
265
297
|
return {
|
|
266
298
|
updated: {
|
|
267
299
|
...bundle,
|
|
300
|
+
scope: resolvedScope,
|
|
268
301
|
coverage_matrix: coverage,
|
|
269
302
|
flow_coverage: flowCoverage,
|
|
270
303
|
runtime_validation_tasks: runtimeValidationTasks,
|
|
@@ -276,6 +309,7 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
276
309
|
audit_report: undefined,
|
|
277
310
|
},
|
|
278
311
|
artifacts_written: [
|
|
312
|
+
"scope.json",
|
|
279
313
|
"coverage_matrix.json",
|
|
280
314
|
"flow_coverage.json",
|
|
281
315
|
"runtime_validation_tasks.json",
|
|
@@ -286,6 +320,7 @@ export async function runPlanningExecutor(bundle, root, lineIndex = {}) {
|
|
|
286
320
|
"requeue_tasks.json",
|
|
287
321
|
],
|
|
288
322
|
progress_summary: `Built planning artifacts; generated ${taggedAuditTasks.length} review tasks in ${reviewPackets.length} packet(s) and ${requeuePayload.task_count} requeue tasks.` +
|
|
323
|
+
scopeSummary +
|
|
289
324
|
(skippedTrivialPaths.length > 0
|
|
290
325
|
? ` Skipped ${skippedTrivialPaths.length} trivial path${skippedTrivialPaths.length === 1 ? "" : "s"} from semantic review.`
|
|
291
326
|
: "") +
|
|
@@ -354,7 +389,7 @@ export function runResultIngestionExecutor(bundle, results) {
|
|
|
354
389
|
: ""),
|
|
355
390
|
};
|
|
356
391
|
}
|
|
357
|
-
export async function runRuntimeValidationExecutor(bundle, root) {
|
|
392
|
+
export async function runRuntimeValidationExecutor(bundle, root, options = {}) {
|
|
358
393
|
if (!bundle.runtime_validation_tasks) {
|
|
359
394
|
throw new Error("Cannot execute runtime validation without runtime_validation_tasks");
|
|
360
395
|
}
|
|
@@ -378,7 +413,7 @@ export async function runRuntimeValidationExecutor(bundle, root) {
|
|
|
378
413
|
continue;
|
|
379
414
|
}
|
|
380
415
|
const signature = task.command.join("\0");
|
|
381
|
-
const outcome = byCommand.get(signature) ?? (await runCommand(task.command, root));
|
|
416
|
+
const outcome = byCommand.get(signature) ?? (await runCommand(task.command, root, { opentoken: options.opentoken }));
|
|
382
417
|
byCommand.set(signature, outcome);
|
|
383
418
|
byTaskId.set(task.id, {
|
|
384
419
|
task_id: task.id,
|
|
@@ -441,10 +476,9 @@ export function runRuntimeValidationUpdateExecutor(bundle, updates) {
|
|
|
441
476
|
: ""),
|
|
442
477
|
};
|
|
443
478
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
results: finalResults,
|
|
479
|
+
function buildBaseFindingsReport(bundle, results) {
|
|
480
|
+
return buildAuditFindingsReport(buildAuditReportModel({
|
|
481
|
+
results,
|
|
448
482
|
unitManifest: bundle.unit_manifest,
|
|
449
483
|
graphBundle: bundle.graph_bundle,
|
|
450
484
|
criticalFlows: bundle.critical_flows,
|
|
@@ -452,15 +486,77 @@ export function runSynthesisExecutor(bundle, results) {
|
|
|
452
486
|
runtimeValidationReport: bundle.runtime_validation_report,
|
|
453
487
|
externalAnalyzerResults: bundle.external_analyzer_results,
|
|
454
488
|
designAssessment: bundle.design_assessment,
|
|
455
|
-
});
|
|
489
|
+
}));
|
|
490
|
+
}
|
|
491
|
+
export function runSynthesisExecutor(bundle, results) {
|
|
492
|
+
const finalResults = results ?? bundle.audit_results ?? [];
|
|
493
|
+
// Emit the canonical machine contract and render the human report from it.
|
|
494
|
+
// No narrative yet — that is layered by the synthesis-narrative obligation.
|
|
495
|
+
const findings = buildBaseFindingsReport(bundle, finalResults);
|
|
456
496
|
return {
|
|
457
497
|
updated: {
|
|
458
498
|
...bundle,
|
|
459
499
|
audit_results: finalResults,
|
|
460
|
-
|
|
500
|
+
audit_findings: findings,
|
|
501
|
+
audit_report: renderAuditReportMarkdown(findings, { scope: bundle.scope }),
|
|
502
|
+
},
|
|
503
|
+
artifacts_written: ["audit-findings.json", "audit-report.md"],
|
|
504
|
+
progress_summary: `Rendered deterministic audit report and canonical findings for ${finalResults.length} audit result entries.`,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Resolve the optional synthesis-narrative obligation. When a host/provider
|
|
509
|
+
* narrative is supplied it is merged into the canonical findings report and the
|
|
510
|
+
* human report is re-rendered with themes/executive-summary/top-risks; without
|
|
511
|
+
* one the narrative is recorded as omitted and the deterministic report stands.
|
|
512
|
+
*/
|
|
513
|
+
export function runSynthesisNarrativeExecutor(bundle, narrative) {
|
|
514
|
+
const baseReport = bundle.audit_findings ??
|
|
515
|
+
buildBaseFindingsReport(bundle, bundle.audit_results ?? []);
|
|
516
|
+
const needsBaseWrite = !bundle.audit_findings;
|
|
517
|
+
const hasNarrative = Boolean(narrative &&
|
|
518
|
+
((narrative.themes?.length ?? 0) > 0 ||
|
|
519
|
+
(narrative.executive_summary?.trim().length ?? 0) > 0 ||
|
|
520
|
+
(narrative.top_risks?.length ?? 0) > 0));
|
|
521
|
+
if (!hasNarrative) {
|
|
522
|
+
const record = {
|
|
523
|
+
status: "omitted",
|
|
524
|
+
theme_count: 0,
|
|
525
|
+
executive_summary_present: false,
|
|
526
|
+
top_risk_count: 0,
|
|
527
|
+
};
|
|
528
|
+
return {
|
|
529
|
+
updated: {
|
|
530
|
+
...bundle,
|
|
531
|
+
audit_findings: baseReport,
|
|
532
|
+
synthesis_narrative: record,
|
|
533
|
+
},
|
|
534
|
+
artifacts_written: needsBaseWrite
|
|
535
|
+
? ["audit-findings.json", "synthesis-narrative.json"]
|
|
536
|
+
: ["synthesis-narrative.json"],
|
|
537
|
+
progress_summary: "Synthesis narrative omitted; deterministic findings report retained.",
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
const enriched = applyNarrative(baseReport, narrative);
|
|
541
|
+
const record = {
|
|
542
|
+
status: "applied",
|
|
543
|
+
theme_count: enriched.themes?.length ?? 0,
|
|
544
|
+
executive_summary_present: (enriched.executive_summary?.trim().length ?? 0) > 0,
|
|
545
|
+
top_risk_count: enriched.top_risks?.length ?? 0,
|
|
546
|
+
};
|
|
547
|
+
return {
|
|
548
|
+
updated: {
|
|
549
|
+
...bundle,
|
|
550
|
+
audit_findings: enriched,
|
|
551
|
+
audit_report: renderAuditReportMarkdown(enriched, { scope: bundle.scope }),
|
|
552
|
+
synthesis_narrative: record,
|
|
461
553
|
},
|
|
462
|
-
artifacts_written: [
|
|
463
|
-
|
|
554
|
+
artifacts_written: [
|
|
555
|
+
"audit-findings.json",
|
|
556
|
+
"audit-report.md",
|
|
557
|
+
"synthesis-narrative.json",
|
|
558
|
+
],
|
|
559
|
+
progress_summary: `Synthesis narrative applied: ${record.theme_count} theme(s), ${record.top_risk_count} top risk(s).`,
|
|
464
560
|
};
|
|
465
561
|
}
|
|
466
562
|
export function runExternalAnalyzerImportExecutor(bundle, externalResults) {
|
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import { delimiter, extname, isAbsolute, join } from "node:path";
|
|
4
|
-
|
|
5
|
-
return process.platform === "win32" && /\.(cmd|bat)$/i.test(path);
|
|
6
|
-
}
|
|
7
|
-
function quoteForCmd(arg) {
|
|
8
|
-
if (arg.length === 0)
|
|
9
|
-
return '""';
|
|
10
|
-
if (!/[\s"]/u.test(arg))
|
|
11
|
-
return arg;
|
|
12
|
-
return `"${arg.replace(/"/g, '""')}"`;
|
|
13
|
-
}
|
|
4
|
+
import { resolveExecArgv } from "@audit-tools/shared";
|
|
14
5
|
function toSpawnTuple(candidate) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
command: process.env.ComSpec ?? "cmd.exe",
|
|
23
|
-
args: [
|
|
24
|
-
"/d",
|
|
25
|
-
"/s",
|
|
26
|
-
"/c",
|
|
27
|
-
[candidate.command, ...candidate.args].map(quoteForCmd).join(" "),
|
|
28
|
-
],
|
|
29
|
-
};
|
|
6
|
+
// Shared resolver applies the single Windows `.cmd`/`.bat` wrapping impl.
|
|
7
|
+
// The candidate command is already PATH-resolved (absolute path or
|
|
8
|
+
// process.execPath), so package-manager shim mapping is a no-op here.
|
|
9
|
+
const resolved = resolveExecArgv([candidate.command, ...candidate.args]);
|
|
10
|
+
return { command: resolved[0], args: resolved.slice(1) };
|
|
30
11
|
}
|
|
31
12
|
function resolveFromPath(command) {
|
|
32
13
|
if (command.trim().length === 0) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ArtifactBundle } from "../io/artifacts.js";
|
|
2
|
-
import type { AuditState } from "../types/auditState.js";
|
|
2
|
+
import type { AuditObligation, AuditState } from "../types/auditState.js";
|
|
3
3
|
export interface NextStepDecision {
|
|
4
4
|
state: AuditState;
|
|
5
5
|
selected_obligation: string | null;
|
|
6
6
|
selected_executor: string | null;
|
|
7
7
|
reason: string;
|
|
8
8
|
}
|
|
9
|
+
export declare function findObligation(obligations: AuditObligation[]): AuditObligation | undefined;
|
|
9
10
|
export declare function decideNextStep(bundle: ArtifactBundle): NextStepDecision;
|
|
@@ -6,6 +6,7 @@ const PRIORITY = [
|
|
|
6
6
|
"auto_fixes_applied",
|
|
7
7
|
"syntax_resolved",
|
|
8
8
|
"structure_artifacts",
|
|
9
|
+
"graph_enrichment_current",
|
|
9
10
|
"design_assessment_current",
|
|
10
11
|
"design_review_completed",
|
|
11
12
|
"planning_artifacts",
|
|
@@ -13,8 +14,9 @@ const PRIORITY = [
|
|
|
13
14
|
"audit_results_ingested",
|
|
14
15
|
"runtime_validation_current",
|
|
15
16
|
"synthesis_current",
|
|
17
|
+
"synthesis_narrative_current",
|
|
16
18
|
];
|
|
17
|
-
function findObligation(obligations) {
|
|
19
|
+
export function findObligation(obligations) {
|
|
18
20
|
for (const id of PRIORITY) {
|
|
19
21
|
const item = obligations.find((o) => o.id === id);
|
|
20
22
|
if (item && (item.state === "missing" || item.state === "stale")) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { CoverageMatrix, RepoManifest, UnitManifest } from "../types.js";
|
|
2
|
-
import type { FileDisposition } from "
|
|
2
|
+
import type { FileDisposition } from "@audit-tools/shared";
|
|
3
3
|
import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
|
|
4
4
|
export declare function initializeCoverageFromPlan(repoManifest: RepoManifest, unitManifest: UnitManifest, disposition: FileDisposition, externalAnalyzerResults?: ExternalAnalyzerResults): CoverageMatrix;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
|
|
2
2
|
import type { CoverageMatrix } from "../types.js";
|
|
3
3
|
import type { FlowCoverageManifest } from "../types/flowCoverage.js";
|
|
4
|
-
import type { CriticalFlowManifest } from "
|
|
4
|
+
import type { CriticalFlowManifest } from "@audit-tools/shared";
|
|
5
5
|
export declare function buildRequeuePayload(matrix: CoverageMatrix, criticalFlows?: CriticalFlowManifest, flowCoverage?: FlowCoverageManifest, externalAnalyzerResults?: ExternalAnalyzerResults): {
|
|
6
6
|
task_count: number;
|
|
7
7
|
file_task_count: number;
|
|
@@ -1,20 +1,53 @@
|
|
|
1
1
|
import type { AuditTask } from "../types.js";
|
|
2
2
|
import type { AuditPlanMetrics, ReviewPacket } from "../types/reviewPlanning.js";
|
|
3
|
-
import type { GraphBundle } from "
|
|
3
|
+
import type { GraphBundle, GraphEdge } from "@audit-tools/shared";
|
|
4
4
|
export declare const ESTIMATED_TOKENS_PER_LINE = 4;
|
|
5
5
|
export declare const ESTIMATED_PACKET_PROMPT_TOKENS = 900;
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Build a path → size_bytes index from a repo manifest. Byte counts are
|
|
8
|
+
* recorded during intake, so this never reads files. Review packet token
|
|
9
|
+
* estimates are derived from these bytes (Phase 2) instead of counted lines.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sizeIndexFromManifest(repoManifest?: {
|
|
12
|
+
files: ReadonlyArray<{
|
|
13
|
+
path: string;
|
|
14
|
+
size_bytes: number;
|
|
15
|
+
}>;
|
|
16
|
+
}): Record<string, number>;
|
|
17
|
+
export declare function estimateTaskGroupTokens(tasks: AuditTask[], sizeIndex?: Record<string, number>, lineIndex?: Record<string, number>): number;
|
|
18
|
+
/**
|
|
19
|
+
* Fan-in / fan-out degree above which a node is treated as a hub. Exported so
|
|
20
|
+
* the Phase 3 delta-scope expansion skips the same hubs that packet planning
|
|
21
|
+
* skips, preventing scope blow-up through highly-connected modules.
|
|
22
|
+
*/
|
|
23
|
+
export declare const HIGH_FAN_DEGREE_THRESHOLD = 12;
|
|
7
24
|
export interface BuildReviewPacketOptions {
|
|
8
25
|
graphBundle?: GraphBundle;
|
|
9
26
|
lineIndex?: Record<string, number>;
|
|
27
|
+
/** Path → size_bytes (from the repo manifest); drives byte-based token sizing. */
|
|
28
|
+
sizeIndex?: Record<string, number>;
|
|
10
29
|
maxTasksPerPacket?: number;
|
|
11
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Soft per-packet content-token budget. Defaults to
|
|
32
|
+
* DEFAULT_TARGET_PACKET_TOKENS. A packet is split when its estimated content
|
|
33
|
+
* tokens would exceed this budget.
|
|
34
|
+
*/
|
|
35
|
+
targetPacketTokens?: number;
|
|
12
36
|
/**
|
|
13
37
|
* Available context budget in tokens (context_tokens − reserved_output_tokens).
|
|
14
|
-
* When provided,
|
|
38
|
+
* When provided, targetPacketTokens is capped to fit within this budget so a
|
|
39
|
+
* packet's estimated tokens never exceed it.
|
|
15
40
|
*/
|
|
16
41
|
maxContextTokens?: number;
|
|
17
42
|
}
|
|
43
|
+
export declare function normalizeGraphPath(path: string): string;
|
|
44
|
+
export declare function collectGraphEdges(graphBundle?: GraphBundle): GraphEdge[];
|
|
45
|
+
export declare function graphEdgeConfidence(edge: GraphEdge): number;
|
|
46
|
+
export interface GraphDegreeIndex {
|
|
47
|
+
fanIn: Map<string, number>;
|
|
48
|
+
fanOut: Map<string, number>;
|
|
49
|
+
}
|
|
50
|
+
export declare function buildGraphDegreeIndex(edges: GraphEdge[]): GraphDegreeIndex;
|
|
18
51
|
export declare function buildReviewPackets(tasks: AuditTask[], options?: BuildReviewPacketOptions): ReviewPacket[];
|
|
19
52
|
export declare function orderTasksForPacketReview(tasks: AuditTask[], options?: BuildReviewPacketOptions): AuditTask[];
|
|
20
53
|
export declare function buildAuditPlanMetrics(tasks: AuditTask[], options?: BuildReviewPacketOptions & {
|