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
|
@@ -1,22 +1,70 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { estimateTokensFromBytes, isRecord } from "@audit-tools/shared";
|
|
3
|
+
import { LENS_ORDER, priorityRank, sortLenses } from "./auditTaskUtils.js";
|
|
4
|
+
import { UnionFind } from "./unionFind.js";
|
|
3
5
|
const DEFAULT_MAX_TASKS_PER_PACKET = 0;
|
|
4
6
|
const DEFAULT_TARGET_PACKET_LINES = 8000;
|
|
5
7
|
export const ESTIMATED_TOKENS_PER_LINE = 4;
|
|
6
8
|
export const ESTIMATED_PACKET_PROMPT_TOKENS = 900;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Default per-packet content-token budget. Kept equal to the legacy
|
|
10
|
+
// line-target × per-line estimate so byte-derived sizing lands on the same
|
|
11
|
+
// thresholds as the old line-based sizing when the line fallback is in effect.
|
|
12
|
+
const DEFAULT_TARGET_PACKET_TOKENS = DEFAULT_TARGET_PACKET_LINES * ESTIMATED_TOKENS_PER_LINE;
|
|
13
|
+
/**
|
|
14
|
+
* Build a path → size_bytes index from a repo manifest. Byte counts are
|
|
15
|
+
* recorded during intake, so this never reads files. Review packet token
|
|
16
|
+
* estimates are derived from these bytes (Phase 2) instead of counted lines.
|
|
17
|
+
*/
|
|
18
|
+
export function sizeIndexFromManifest(repoManifest) {
|
|
19
|
+
if (!repoManifest)
|
|
20
|
+
return {};
|
|
21
|
+
return Object.fromEntries(repoManifest.files.map((file) => [file.path, file.size_bytes]));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Estimated content tokens for a single file. Prefers a byte-based estimate
|
|
25
|
+
* from `sizeIndex` (sourced from the repo manifest); falls back to the legacy
|
|
26
|
+
* line-based estimate when no positive byte count is available (e.g. manually
|
|
27
|
+
* built tasks in tests, or paths absent from the manifest).
|
|
28
|
+
*/
|
|
29
|
+
function pathContentTokens(owner, path, sizeIndex, lineIndex) {
|
|
30
|
+
const bytes = sizeIndex?.[path];
|
|
31
|
+
if (typeof bytes === "number" && bytes > 0) {
|
|
32
|
+
return estimateTokensFromBytes(bytes);
|
|
33
|
+
}
|
|
34
|
+
const lines = owner?.file_line_counts?.[path] ?? lineIndex?.[path] ?? 0;
|
|
35
|
+
return lines * ESTIMATED_TOKENS_PER_LINE;
|
|
36
|
+
}
|
|
37
|
+
/** Estimated content tokens for one task across all of its files. */
|
|
38
|
+
function taskContentTokens(task, sizeIndex, lineIndex) {
|
|
39
|
+
return task.file_paths.reduce((sum, path) => sum + pathContentTokens(task, path, sizeIndex, lineIndex), 0);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Estimated content tokens across a set of file paths, resolving an owning task
|
|
43
|
+
* per path so the line fallback can read its `file_line_counts`. Shared files
|
|
44
|
+
* are counted once.
|
|
45
|
+
*/
|
|
46
|
+
function fileGroupContentTokens(filePaths, tasks, sizeIndex, lineIndex) {
|
|
47
|
+
let total = 0;
|
|
48
|
+
for (const path of filePaths) {
|
|
49
|
+
const owner = tasks.find((task) => task.file_paths.includes(path));
|
|
50
|
+
total += pathContentTokens(owner, path, sizeIndex, lineIndex);
|
|
51
|
+
}
|
|
52
|
+
return total;
|
|
53
|
+
}
|
|
54
|
+
export function estimateTaskGroupTokens(tasks, sizeIndex, lineIndex) {
|
|
55
|
+
let contentTokens = 0;
|
|
9
56
|
for (const task of tasks) {
|
|
10
|
-
|
|
11
|
-
for (const count of Object.values(task.file_line_counts)) {
|
|
12
|
-
totalLines += count;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
57
|
+
contentTokens += taskContentTokens(task, sizeIndex, lineIndex);
|
|
15
58
|
}
|
|
16
|
-
return ESTIMATED_PACKET_PROMPT_TOKENS +
|
|
59
|
+
return ESTIMATED_PACKET_PROMPT_TOKENS + contentTokens;
|
|
17
60
|
}
|
|
18
61
|
const PACKET_EXPANSION_MIN_CONFIDENCE = 0.65;
|
|
19
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Fan-in / fan-out degree above which a node is treated as a hub. Exported so
|
|
64
|
+
* the Phase 3 delta-scope expansion skips the same hubs that packet planning
|
|
65
|
+
* skips, preventing scope blow-up through highly-connected modules.
|
|
66
|
+
*/
|
|
67
|
+
export const HIGH_FAN_DEGREE_THRESHOLD = 12;
|
|
20
68
|
const HIGH_FAN_EXPANSION_CONFIDENCE = 0.99;
|
|
21
69
|
const MAX_PACKET_KEY_EDGES = 8;
|
|
22
70
|
const MAX_PACKET_BOUNDARY_FILES = 12;
|
|
@@ -57,24 +105,9 @@ const BROAD_ANALYZER_OWNERSHIP_ROOTS = new Set([
|
|
|
57
105
|
"spec",
|
|
58
106
|
"specs",
|
|
59
107
|
]);
|
|
60
|
-
function priorityRank(priority) {
|
|
61
|
-
switch (priority) {
|
|
62
|
-
case "high":
|
|
63
|
-
return 3;
|
|
64
|
-
case "medium":
|
|
65
|
-
return 2;
|
|
66
|
-
case "low":
|
|
67
|
-
default:
|
|
68
|
-
return 1;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
108
|
function normalizePriority(priority) {
|
|
72
109
|
return priority ?? "low";
|
|
73
110
|
}
|
|
74
|
-
function sortLenses(lenses) {
|
|
75
|
-
const set = new Set(lenses);
|
|
76
|
-
return LENS_ORDER.filter((lens) => set.has(lens));
|
|
77
|
-
}
|
|
78
111
|
function lineCountForPath(task, path, lineIndex) {
|
|
79
112
|
return task.file_line_counts?.[path] ?? lineIndex?.[path] ?? 0;
|
|
80
113
|
}
|
|
@@ -99,13 +132,10 @@ function buildTaskGroups(tasks) {
|
|
|
99
132
|
}
|
|
100
133
|
return groups;
|
|
101
134
|
}
|
|
102
|
-
function normalizeGraphPath(path) {
|
|
135
|
+
export function normalizeGraphPath(path) {
|
|
103
136
|
return path.replace(/\\/g, "/").replace(/^\.\//, "").toLowerCase();
|
|
104
137
|
}
|
|
105
|
-
function
|
|
106
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
107
|
-
}
|
|
108
|
-
function collectGraphEdges(graphBundle) {
|
|
138
|
+
export function collectGraphEdges(graphBundle) {
|
|
109
139
|
if (!graphBundle?.graphs) {
|
|
110
140
|
return [];
|
|
111
141
|
}
|
|
@@ -141,7 +171,7 @@ function collectGraphEdges(graphBundle) {
|
|
|
141
171
|
}
|
|
142
172
|
return edges;
|
|
143
173
|
}
|
|
144
|
-
function graphEdgeConfidence(edge) {
|
|
174
|
+
export function graphEdgeConfidence(edge) {
|
|
145
175
|
if (typeof edge.confidence === "number" && Number.isFinite(edge.confidence)) {
|
|
146
176
|
return Math.min(1, Math.max(0, edge.confidence));
|
|
147
177
|
}
|
|
@@ -156,7 +186,7 @@ function graphEdgeConfidence(edge) {
|
|
|
156
186
|
function isConcreteGraphEdge(edge) {
|
|
157
187
|
return edge.kind !== "heuristic-container-edge";
|
|
158
188
|
}
|
|
159
|
-
function buildGraphDegreeIndex(edges) {
|
|
189
|
+
export function buildGraphDegreeIndex(edges) {
|
|
160
190
|
const fanIn = new Map();
|
|
161
191
|
const fanOut = new Map();
|
|
162
192
|
for (const edge of edges) {
|
|
@@ -255,33 +285,16 @@ function groupsOverlap(a, b) {
|
|
|
255
285
|
}
|
|
256
286
|
return false;
|
|
257
287
|
}
|
|
258
|
-
function
|
|
259
|
-
const
|
|
260
|
-
const parent = new Map(groupKeys.map((key) => [key, key]));
|
|
288
|
+
function unionFindFromGroups(groups, graphEdges) {
|
|
289
|
+
const uf = new UnionFind(groups.keys());
|
|
261
290
|
const fileToGroupKeys = buildFileToGroupKeys(groups);
|
|
262
291
|
const degreeIndex = buildGraphDegreeIndex(graphEdges);
|
|
263
|
-
function find(key) {
|
|
264
|
-
const current = parent.get(key) ?? key;
|
|
265
|
-
if (current === key)
|
|
266
|
-
return key;
|
|
267
|
-
const root = find(current);
|
|
268
|
-
parent.set(key, root);
|
|
269
|
-
return root;
|
|
270
|
-
}
|
|
271
|
-
function union(a, b) {
|
|
272
|
-
const rootA = find(a);
|
|
273
|
-
const rootB = find(b);
|
|
274
|
-
if (rootA === rootB)
|
|
275
|
-
return;
|
|
276
|
-
const [keep, move] = rootA.localeCompare(rootB) <= 0 ? [rootA, rootB] : [rootB, rootA];
|
|
277
|
-
parent.set(move, keep);
|
|
278
|
-
}
|
|
279
292
|
for (const keys of fileToGroupKeys.values()) {
|
|
280
293
|
const [first, ...rest] = [...keys].sort((a, b) => a.localeCompare(b));
|
|
281
294
|
if (!first)
|
|
282
295
|
continue;
|
|
283
296
|
for (const key of rest) {
|
|
284
|
-
union(first, key);
|
|
297
|
+
uf.union(first, key);
|
|
285
298
|
}
|
|
286
299
|
}
|
|
287
300
|
for (const edge of graphEdges) {
|
|
@@ -295,11 +308,15 @@ function buildGraphConnectedComponentIndex(groups, graphEdges) {
|
|
|
295
308
|
}
|
|
296
309
|
for (const fromKey of fromGroups) {
|
|
297
310
|
for (const toKey of toGroups) {
|
|
298
|
-
union(fromKey, toKey);
|
|
311
|
+
uf.union(fromKey, toKey);
|
|
299
312
|
}
|
|
300
313
|
}
|
|
301
314
|
}
|
|
302
|
-
return
|
|
315
|
+
return uf;
|
|
316
|
+
}
|
|
317
|
+
function buildGraphConnectedComponentIndex(groups, graphEdges) {
|
|
318
|
+
const uf = unionFindFromGroups(groups, graphEdges);
|
|
319
|
+
return new Map([...groups.keys()].map((key) => [key, uf.find(key)]));
|
|
303
320
|
}
|
|
304
321
|
function subsystemRootForPath(path) {
|
|
305
322
|
const segments = normalizeGraphPath(path).split("/").filter(Boolean);
|
|
@@ -375,13 +392,11 @@ function buildBoundedClusterEdges(params) {
|
|
|
375
392
|
const allFiles = new Set(componentEntries.flatMap((entry) => [...entry.filePaths]));
|
|
376
393
|
const totalTasks = componentEntries.reduce((sum, entry) => sum + entry.taskCount, 0);
|
|
377
394
|
const clusterTasks = entries.flatMap((entry) => entry.tasks);
|
|
378
|
-
const
|
|
379
|
-
const owner = clusterTasks.find((task) => task.file_paths.includes(path));
|
|
380
|
-
return sum + (owner ? lineCountForPath(owner, path, params.lineIndex) : 0);
|
|
381
|
-
}, 0);
|
|
395
|
+
const totalContentTokens = fileGroupContentTokens(allFiles, clusterTasks, params.sizeIndex, params.lineIndex);
|
|
382
396
|
if (allFiles.size > MAX_SUBSYSTEM_CLUSTER_FILES ||
|
|
383
397
|
totalTasks > MAX_SUBSYSTEM_CLUSTER_TASKS ||
|
|
384
|
-
|
|
398
|
+
totalContentTokens >
|
|
399
|
+
(params.targetPacketTokens ?? DEFAULT_TARGET_PACKET_TOKENS)) {
|
|
385
400
|
continue;
|
|
386
401
|
}
|
|
387
402
|
for (let index = 1; index < componentEntries.length; index++) {
|
|
@@ -399,7 +414,7 @@ function buildBoundedClusterEdges(params) {
|
|
|
399
414
|
}
|
|
400
415
|
return clusterEdges.sort(compareGraphEdges);
|
|
401
416
|
}
|
|
402
|
-
function buildSubsystemClusterEdges(groups, graphEdges, lineIndex,
|
|
417
|
+
function buildSubsystemClusterEdges(groups, graphEdges, lineIndex, sizeIndex, targetPacketTokens = DEFAULT_TARGET_PACKET_TOKENS) {
|
|
403
418
|
return buildBoundedClusterEdges({
|
|
404
419
|
groups,
|
|
405
420
|
graphEdges,
|
|
@@ -408,7 +423,8 @@ function buildSubsystemClusterEdges(groups, graphEdges, lineIndex, targetPacketL
|
|
|
408
423
|
edgeConfidence: SUBSYSTEM_CLUSTER_CONFIDENCE,
|
|
409
424
|
reasonForCluster: (root, fileCount) => `Bounded subsystem cluster '${root}' groups ${fileCount} file(s) without stronger graph evidence.`,
|
|
410
425
|
lineIndex,
|
|
411
|
-
|
|
426
|
+
sizeIndex,
|
|
427
|
+
targetPacketTokens,
|
|
412
428
|
});
|
|
413
429
|
}
|
|
414
430
|
function packageManifestRoot(path) {
|
|
@@ -435,39 +451,18 @@ function isCargoManifestPath(path) {
|
|
|
435
451
|
function isMavenPomPath(path) {
|
|
436
452
|
return normalizeGraphPath(path).split("/").at(-1) === "pom.xml";
|
|
437
453
|
}
|
|
438
|
-
function
|
|
439
|
-
const segments = normalizeGraphPath(path).split("/").filter(Boolean);
|
|
440
|
-
if (!isTypescriptProjectConfigPath(path) || segments.length < 2) {
|
|
441
|
-
return undefined;
|
|
442
|
-
}
|
|
443
|
-
return segments.slice(0, -1).join("/");
|
|
444
|
-
}
|
|
445
|
-
function goModuleRoot(path) {
|
|
446
|
-
const segments = normalizeGraphPath(path).split("/").filter(Boolean);
|
|
447
|
-
if (!isGoModuleManifestPath(path) || segments.length < 2) {
|
|
448
|
-
return undefined;
|
|
449
|
-
}
|
|
450
|
-
return segments.slice(0, -1).join("/");
|
|
451
|
-
}
|
|
452
|
-
function cargoModuleRoot(path) {
|
|
453
|
-
const segments = normalizeGraphPath(path).split("/").filter(Boolean);
|
|
454
|
-
if (!isCargoManifestPath(path) || segments.length < 2) {
|
|
455
|
-
return undefined;
|
|
456
|
-
}
|
|
457
|
-
return segments.slice(0, -1).join("/");
|
|
458
|
-
}
|
|
459
|
-
function mavenModuleRoot(path) {
|
|
454
|
+
function configFileRoot(path, predicate) {
|
|
460
455
|
const segments = normalizeGraphPath(path).split("/").filter(Boolean);
|
|
461
|
-
if (!
|
|
456
|
+
if (!predicate(path) || segments.length < 2) {
|
|
462
457
|
return undefined;
|
|
463
458
|
}
|
|
464
459
|
return segments.slice(0, -1).join("/");
|
|
465
460
|
}
|
|
466
461
|
function moduleConfigRoot(path) {
|
|
467
|
-
return (
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
462
|
+
return (configFileRoot(path, isTypescriptProjectConfigPath) ??
|
|
463
|
+
configFileRoot(path, isGoModuleManifestPath) ??
|
|
464
|
+
configFileRoot(path, isCargoManifestPath) ??
|
|
465
|
+
configFileRoot(path, isMavenPomPath));
|
|
471
466
|
}
|
|
472
467
|
function analyzerOwnershipRoot(path) {
|
|
473
468
|
const root = normalizeGraphPath(path).replace(/\/+$/, "");
|
|
@@ -529,7 +524,7 @@ function packageOwnershipRootForTasks(tasks, packageRoots) {
|
|
|
529
524
|
const roots = new Set(rootsForFiles);
|
|
530
525
|
return roots.size === 1 ? [...roots][0] : undefined;
|
|
531
526
|
}
|
|
532
|
-
function buildPackageOwnershipClusterEdges(groups, graphEdges, lineIndex,
|
|
527
|
+
function buildPackageOwnershipClusterEdges(groups, graphEdges, lineIndex, sizeIndex, targetPacketTokens = DEFAULT_TARGET_PACKET_TOKENS) {
|
|
533
528
|
const packageRoots = collectPackageOwnershipRoots(groups, graphEdges);
|
|
534
529
|
if (packageRoots.size === 0) {
|
|
535
530
|
return [];
|
|
@@ -542,7 +537,8 @@ function buildPackageOwnershipClusterEdges(groups, graphEdges, lineIndex, target
|
|
|
542
537
|
edgeConfidence: PACKAGE_OWNERSHIP_CLUSTER_CONFIDENCE,
|
|
543
538
|
reasonForCluster: (root, fileCount) => `Package ownership root '${root}' groups ${fileCount} file(s) across bounded package subdirectories.`,
|
|
544
539
|
lineIndex,
|
|
545
|
-
|
|
540
|
+
sizeIndex,
|
|
541
|
+
targetPacketTokens,
|
|
546
542
|
});
|
|
547
543
|
}
|
|
548
544
|
function collectModuleOwnershipRoots(groups, graphEdges) {
|
|
@@ -588,7 +584,7 @@ function moduleOwnershipRootForTasks(tasks, moduleRoots) {
|
|
|
588
584
|
const roots = new Set(rootsForFiles);
|
|
589
585
|
return roots.size === 1 ? [...roots][0] : undefined;
|
|
590
586
|
}
|
|
591
|
-
function buildModuleOwnershipClusterEdges(groups, graphEdges, lineIndex,
|
|
587
|
+
function buildModuleOwnershipClusterEdges(groups, graphEdges, lineIndex, sizeIndex, targetPacketTokens = DEFAULT_TARGET_PACKET_TOKENS) {
|
|
592
588
|
const moduleRoots = collectModuleOwnershipRoots(groups, graphEdges);
|
|
593
589
|
if (moduleRoots.size === 0) {
|
|
594
590
|
return [];
|
|
@@ -607,7 +603,8 @@ function buildModuleOwnershipClusterEdges(groups, graphEdges, lineIndex, targetP
|
|
|
607
603
|
: `Module ownership root '${root}' from project configuration groups ${fileCount} file(s) across bounded subdirectories.`;
|
|
608
604
|
},
|
|
609
605
|
lineIndex,
|
|
610
|
-
|
|
606
|
+
sizeIndex,
|
|
607
|
+
targetPacketTokens,
|
|
611
608
|
});
|
|
612
609
|
}
|
|
613
610
|
function buildEntrypointFlowBridgeEdges(groups, graphEdges, graphBundle) {
|
|
@@ -694,18 +691,18 @@ function buildEntrypointFlowBridgeEdges(groups, graphEdges, graphBundle) {
|
|
|
694
691
|
}
|
|
695
692
|
return [...bridgeEdges.values()].sort(compareGraphEdges);
|
|
696
693
|
}
|
|
697
|
-
function buildPlanningGraphEdges(groups, graphEdges, graphBundle, lineIndex,
|
|
694
|
+
function buildPlanningGraphEdges(groups, graphEdges, graphBundle, lineIndex, sizeIndex, targetPacketTokens = DEFAULT_TARGET_PACKET_TOKENS) {
|
|
698
695
|
const bridgeEdges = buildEntrypointFlowBridgeEdges(groups, graphEdges, graphBundle);
|
|
699
696
|
const graphWithBridges = bridgeEdges.length > 0 ? [...graphEdges, ...bridgeEdges] : graphEdges;
|
|
700
|
-
const subsystemEdges = buildSubsystemClusterEdges(groups, graphWithBridges, lineIndex,
|
|
697
|
+
const subsystemEdges = buildSubsystemClusterEdges(groups, graphWithBridges, lineIndex, sizeIndex, targetPacketTokens);
|
|
701
698
|
const graphWithSubsystems = subsystemEdges.length > 0
|
|
702
699
|
? [...graphWithBridges, ...subsystemEdges]
|
|
703
700
|
: graphWithBridges;
|
|
704
|
-
const packageOwnershipEdges = buildPackageOwnershipClusterEdges(groups, graphWithSubsystems, lineIndex,
|
|
701
|
+
const packageOwnershipEdges = buildPackageOwnershipClusterEdges(groups, graphWithSubsystems, lineIndex, sizeIndex, targetPacketTokens);
|
|
705
702
|
const graphWithPackageOwnership = packageOwnershipEdges.length > 0
|
|
706
703
|
? [...graphWithSubsystems, ...packageOwnershipEdges]
|
|
707
704
|
: graphWithSubsystems;
|
|
708
|
-
const moduleOwnershipEdges = buildModuleOwnershipClusterEdges(groups, graphWithPackageOwnership, lineIndex,
|
|
705
|
+
const moduleOwnershipEdges = buildModuleOwnershipClusterEdges(groups, graphWithPackageOwnership, lineIndex, sizeIndex, targetPacketTokens);
|
|
709
706
|
return moduleOwnershipEdges.length > 0
|
|
710
707
|
? [...graphWithPackageOwnership, ...moduleOwnershipEdges]
|
|
711
708
|
: graphWithPackageOwnership;
|
|
@@ -831,7 +828,8 @@ function chunkPacketTasks(tasks, options) {
|
|
|
831
828
|
let current = [];
|
|
832
829
|
for (const task of tasks.sort(compareTasksForPacket)) {
|
|
833
830
|
const isolatedLargeFileTask = task.file_paths.length === 1 &&
|
|
834
|
-
|
|
831
|
+
taskContentTokens(task, options.sizeIndex, options.lineIndex) >
|
|
832
|
+
options.targetPacketTokens;
|
|
835
833
|
if (isolatedLargeFileTask) {
|
|
836
834
|
if (current.length > 0) {
|
|
837
835
|
chunks.push(current);
|
|
@@ -842,13 +840,10 @@ function chunkPacketTasks(tasks, options) {
|
|
|
842
840
|
}
|
|
843
841
|
const candidate = [...current, task];
|
|
844
842
|
const uniquePaths = new Set(candidate.flatMap((item) => item.file_paths));
|
|
845
|
-
const
|
|
846
|
-
const owner = candidate.find((item) => item.file_paths.includes(path));
|
|
847
|
-
return sum + (owner ? lineCountForPath(owner, path, options.lineIndex) : 0);
|
|
848
|
-
}, 0);
|
|
843
|
+
const candidateContentTokens = fileGroupContentTokens(uniquePaths, candidate, options.sizeIndex, options.lineIndex);
|
|
849
844
|
const wouldExceedTaskCount = options.maxTasksPerPacket > 0 && current.length > 0 && candidate.length > options.maxTasksPerPacket;
|
|
850
|
-
const
|
|
851
|
-
if (wouldExceedTaskCount ||
|
|
845
|
+
const wouldExceedTokens = current.length > 0 && candidateContentTokens > options.targetPacketTokens;
|
|
846
|
+
if (wouldExceedTaskCount || wouldExceedTokens) {
|
|
852
847
|
chunks.push(current);
|
|
853
848
|
current = [];
|
|
854
849
|
}
|
|
@@ -860,59 +855,17 @@ function chunkPacketTasks(tasks, options) {
|
|
|
860
855
|
return chunks;
|
|
861
856
|
}
|
|
862
857
|
function mergeGraphConnectedGroups(groups, graphEdges) {
|
|
863
|
-
const
|
|
864
|
-
const parent = new Map(groupKeys.map((key) => [key, key]));
|
|
865
|
-
const fileToGroupKeys = buildFileToGroupKeys(groups);
|
|
866
|
-
const degreeIndex = buildGraphDegreeIndex(graphEdges);
|
|
867
|
-
function find(key) {
|
|
868
|
-
const current = parent.get(key) ?? key;
|
|
869
|
-
if (current === key)
|
|
870
|
-
return key;
|
|
871
|
-
const root = find(current);
|
|
872
|
-
parent.set(key, root);
|
|
873
|
-
return root;
|
|
874
|
-
}
|
|
875
|
-
function union(a, b) {
|
|
876
|
-
const rootA = find(a);
|
|
877
|
-
const rootB = find(b);
|
|
878
|
-
if (rootA === rootB)
|
|
879
|
-
return;
|
|
880
|
-
const [keep, move] = rootA.localeCompare(rootB) <= 0 ? [rootA, rootB] : [rootB, rootA];
|
|
881
|
-
parent.set(move, keep);
|
|
882
|
-
}
|
|
883
|
-
for (const keys of fileToGroupKeys.values()) {
|
|
884
|
-
const [first, ...rest] = [...keys].sort((a, b) => a.localeCompare(b));
|
|
885
|
-
if (!first)
|
|
886
|
-
continue;
|
|
887
|
-
for (const key of rest) {
|
|
888
|
-
union(first, key);
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
for (const edge of graphEdges) {
|
|
892
|
-
if (!isPacketExpansionEdge(edge, degreeIndex)) {
|
|
893
|
-
continue;
|
|
894
|
-
}
|
|
895
|
-
const fromGroups = fileToGroupKeys.get(normalizeGraphPath(edge.from));
|
|
896
|
-
const toGroups = fileToGroupKeys.get(normalizeGraphPath(edge.to));
|
|
897
|
-
if (!fromGroups || !toGroups) {
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
for (const fromKey of fromGroups) {
|
|
901
|
-
for (const toKey of toGroups) {
|
|
902
|
-
union(fromKey, toKey);
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
858
|
+
const uf = unionFindFromGroups(groups, graphEdges);
|
|
906
859
|
const merged = new Map();
|
|
907
|
-
for (const key of
|
|
908
|
-
const root = find(key);
|
|
860
|
+
for (const key of groups.keys()) {
|
|
861
|
+
const root = uf.find(key);
|
|
909
862
|
const current = merged.get(root) ?? [];
|
|
910
863
|
current.push(...(groups.get(key) ?? []));
|
|
911
864
|
merged.set(root, current);
|
|
912
865
|
}
|
|
913
866
|
return [...merged.values()];
|
|
914
867
|
}
|
|
915
|
-
function buildPacket(tasks, packetIndex, lineIndex, graphEdges = [], graphBundle) {
|
|
868
|
+
function buildPacket(tasks, packetIndex, lineIndex, sizeIndex, graphEdges = [], graphBundle) {
|
|
916
869
|
const filePaths = [...new Set(tasks.flatMap((task) => task.file_paths))].sort((a, b) => a.localeCompare(b));
|
|
917
870
|
const graphContext = buildPacketGraphContext(filePaths, graphEdges, graphBundle);
|
|
918
871
|
const fileLineCounts = Object.fromEntries(filePaths.map((path) => {
|
|
@@ -920,6 +873,8 @@ function buildPacket(tasks, packetIndex, lineIndex, graphEdges = [], graphBundle
|
|
|
920
873
|
return [path, owner ? lineCountForPath(owner, path, lineIndex) : 0];
|
|
921
874
|
}));
|
|
922
875
|
const totalLines = Object.values(fileLineCounts).reduce((sum, value) => sum + value, 0);
|
|
876
|
+
const estimatedTokens = ESTIMATED_PACKET_PROMPT_TOKENS +
|
|
877
|
+
fileGroupContentTokens(filePaths, tasks, sizeIndex, lineIndex);
|
|
923
878
|
const priority = tasks.reduce((highest, task) => priorityRank(task.priority) > priorityRank(highest)
|
|
924
879
|
? normalizePriority(task.priority)
|
|
925
880
|
: highest, "low");
|
|
@@ -955,19 +910,18 @@ function buildPacket(tasks, packetIndex, lineIndex, graphEdges = [], graphBundle
|
|
|
955
910
|
: undefined,
|
|
956
911
|
quality: graphContext.quality,
|
|
957
912
|
rationale: `${baseRationale}${graphRationale}`,
|
|
958
|
-
estimated_tokens:
|
|
913
|
+
estimated_tokens: estimatedTokens,
|
|
959
914
|
};
|
|
960
915
|
}
|
|
961
916
|
function buildReviewPacketPlanningData(tasks, options = {}) {
|
|
962
917
|
const maxTasksPerPacket = options.maxTasksPerPacket ?? DEFAULT_MAX_TASKS_PER_PACKET;
|
|
963
|
-
const
|
|
964
|
-
const
|
|
965
|
-
? Math.min(
|
|
966
|
-
|
|
967
|
-
: configuredTargetLines;
|
|
918
|
+
const configuredTargetTokens = options.targetPacketTokens ?? DEFAULT_TARGET_PACKET_TOKENS;
|
|
919
|
+
const targetPacketTokens = options.maxContextTokens != null
|
|
920
|
+
? Math.min(configuredTargetTokens, Math.max(1, options.maxContextTokens - ESTIMATED_PACKET_PROMPT_TOKENS))
|
|
921
|
+
: configuredTargetTokens;
|
|
968
922
|
const graphEdges = collectGraphEdges(options.graphBundle);
|
|
969
923
|
const groups = buildTaskGroups(tasks);
|
|
970
|
-
const planningGraphEdges = buildPlanningGraphEdges(groups, graphEdges, options.graphBundle, options.lineIndex,
|
|
924
|
+
const planningGraphEdges = buildPlanningGraphEdges(groups, graphEdges, options.graphBundle, options.lineIndex, options.sizeIndex, targetPacketTokens);
|
|
971
925
|
const packets = [];
|
|
972
926
|
let packetIndex = 0;
|
|
973
927
|
const groupedTasks = mergeGraphConnectedGroups(groups, planningGraphEdges).sort((a, b) => {
|
|
@@ -980,10 +934,11 @@ function buildReviewPacketPlanningData(tasks, options = {}) {
|
|
|
980
934
|
for (const group of groupedTasks) {
|
|
981
935
|
for (const chunk of chunkPacketTasks(group, {
|
|
982
936
|
lineIndex: options.lineIndex,
|
|
937
|
+
sizeIndex: options.sizeIndex,
|
|
983
938
|
maxTasksPerPacket,
|
|
984
|
-
|
|
939
|
+
targetPacketTokens,
|
|
985
940
|
})) {
|
|
986
|
-
packets.push(buildPacket(chunk, packetIndex, options.lineIndex, planningGraphEdges, options.graphBundle));
|
|
941
|
+
packets.push(buildPacket(chunk, packetIndex, options.lineIndex, options.sizeIndex, planningGraphEdges, options.graphBundle));
|
|
987
942
|
packetIndex += 1;
|
|
988
943
|
}
|
|
989
944
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { UnitManifest } from "../types.js";
|
|
2
2
|
import type { FlowCoverageManifest } from "../types/flowCoverage.js";
|
|
3
|
-
import type { CriticalFlowManifest } from "
|
|
3
|
+
import type { CriticalFlowManifest } from "@audit-tools/shared";
|
|
4
4
|
import type { RuntimeValidationReport, RuntimeValidationTaskManifest } from "../types/runtimeValidation.js";
|
|
5
5
|
export declare function discoverRuntimeValidationCommand(root: string): Promise<string[] | undefined>;
|
|
6
6
|
export declare function buildRuntimeValidationTasks(params: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { discoverProjectCommands } from "@audit-tools/shared";
|
|
2
2
|
function checksForFlow(requiredLenses) {
|
|
3
3
|
const checks = [];
|
|
4
4
|
if (requiredLenses.includes("security")) {
|
|
@@ -15,37 +15,10 @@ function checksForFlow(requiredLenses) {
|
|
|
15
15
|
}
|
|
16
16
|
return checks;
|
|
17
17
|
}
|
|
18
|
-
async function exists(path) {
|
|
19
|
-
try {
|
|
20
|
-
await access(path);
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
18
|
export async function discoverRuntimeValidationCommand(root) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
32
|
-
const testScript = packageJson.scripts?.test?.trim();
|
|
33
|
-
if (testScript &&
|
|
34
|
-
!/no test specified/i.test(testScript)) {
|
|
35
|
-
return ["npm", "test"];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// ignore unreadable package.json for runtime discovery
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (await exists(`${root}/go.mod`)) {
|
|
43
|
-
return ["go", "test", "./..."];
|
|
44
|
-
}
|
|
45
|
-
if (await exists(`${root}/pyproject.toml`) || await exists(`${root}/pytest.ini`)) {
|
|
46
|
-
return ["python", "-m", "pytest"];
|
|
47
|
-
}
|
|
48
|
-
return undefined;
|
|
19
|
+
// Shared discovery (Node test script → Go → Python) is the single source of
|
|
20
|
+
// truth; the runtime-validation command is the discovered test command.
|
|
21
|
+
return discoverProjectCommands(root).test;
|
|
49
22
|
}
|
|
50
23
|
export function buildRuntimeValidationTasks(params) {
|
|
51
24
|
if (!params.command) {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { GraphBundle } from "@audit-tools/shared";
|
|
2
|
+
import type { ArtifactBundle } from "../io/artifacts.js";
|
|
3
|
+
import type { CoverageMatrix } from "../types.js";
|
|
4
|
+
import type { AuditScopeBudget, AuditScopeManifest } from "../types/auditScope.js";
|
|
5
|
+
/** Default cap on in-scope files (seeds + expanded) before expansion stops. */
|
|
6
|
+
export declare const DEFAULT_SCOPE_MAX_FILES = 200;
|
|
7
|
+
/** Graph edges below this confidence are never traversed during expansion. */
|
|
8
|
+
export declare const SCOPE_EDGE_CONFIDENCE_FLOOR = 0.5;
|
|
9
|
+
/**
|
|
10
|
+
* Expansion stops along a path once the accumulated path-confidence (the product
|
|
11
|
+
* of the traversed edge confidences) drops below this floor. With no fixed hop
|
|
12
|
+
* count, this — together with hub-skipping and the file budget — bounds the
|
|
13
|
+
* frontier deterministically.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SCOPE_MIN_FRONTIER_CONFIDENCE = 0.5;
|
|
16
|
+
export interface ComputeAuditScopeInput {
|
|
17
|
+
/** The git ref the delta is measured against. */
|
|
18
|
+
since: string;
|
|
19
|
+
/** Raw changed paths (git output, posix-relative). */
|
|
20
|
+
changed: string[];
|
|
21
|
+
/** Canonical auditable file paths (repo-manifest paths, non-excluded). */
|
|
22
|
+
includedFiles: string[];
|
|
23
|
+
/** Dependency graph used to expand from seeds to neighbours. */
|
|
24
|
+
graphBundle?: GraphBundle;
|
|
25
|
+
budget?: AuditScopeBudget;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Deterministic priority-frontier expansion (Phase 3). Starting from the changed
|
|
29
|
+
* files (seeds), walk the dependency graph outward, always visiting the neighbour
|
|
30
|
+
* with the highest accumulated path-confidence first (tie-broken by path). High
|
|
31
|
+
* fan-in/out hubs are skipped so a single change near a hub does not drag the
|
|
32
|
+
* whole repo into scope, low-confidence edges are dropped, and expansion halts at
|
|
33
|
+
* the file budget or when the best remaining frontier confidence falls below the
|
|
34
|
+
* floor. Same inputs → identical scope.
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeAuditScope(input: ComputeAuditScopeInput): AuditScopeManifest;
|
|
37
|
+
/** A full-audit scope (the default, and every fallback). */
|
|
38
|
+
export declare function fullAuditScope(budget?: AuditScopeBudget, droppedNote?: string): AuditScopeManifest;
|
|
39
|
+
export interface ResolveAuditScopeInput {
|
|
40
|
+
root?: string;
|
|
41
|
+
/** The `--since` ref, if any. Absent/empty → full audit. */
|
|
42
|
+
since?: string;
|
|
43
|
+
bundle: ArtifactBundle;
|
|
44
|
+
budget?: AuditScopeBudget;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the scope for a planning run. Returns a full-audit scope unless a
|
|
48
|
+
* `--since` ref was supplied against a real git repository; an unusable ref or
|
|
49
|
+
* missing root degrades to a full audit with an honest note. Reads the auditable
|
|
50
|
+
* file set from the repo manifest + disposition (the same lookup the graph
|
|
51
|
+
* extractor uses) and the dependency graph from the bundle.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveAuditScope(input: ResolveAuditScopeInput): AuditScopeManifest;
|
|
54
|
+
/**
|
|
55
|
+
* Apply a delta scope to a freshly-built coverage matrix. In-scope files (seeds
|
|
56
|
+
* + expanded neighbours) keep their fresh `pending` status to be re-audited.
|
|
57
|
+
* Out-of-scope files inherit a prior `complete` record verbatim when present (so
|
|
58
|
+
* previously-finished work is preserved, not re-run), and are otherwise excluded
|
|
59
|
+
* from this run with `classification_status: "out_of_scope_delta"`. Deterministic
|
|
60
|
+
* exclusions (non-auditable/trivial) are left untouched. A full scope is a no-op.
|
|
61
|
+
*/
|
|
62
|
+
export declare function applyScopeToCoverage(coverage: CoverageMatrix, scope: AuditScopeManifest, priorCoverage?: CoverageMatrix): CoverageMatrix;
|