auditor-lambda 0.6.9 → 0.6.10
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/dist/cli/auditStep.d.ts +63 -0
- package/dist/cli/auditStep.js +133 -0
- package/dist/cli/envelope.d.ts +47 -0
- package/dist/cli/envelope.js +64 -0
- package/dist/cli/reviewRun.d.ts +29 -0
- package/dist/cli/reviewRun.js +143 -0
- package/dist/cli.js +6 -319
- package/dist/extractors/graph.js +5 -825
- package/dist/extractors/graphPathUtils.d.ts +12 -0
- package/dist/extractors/graphPathUtils.js +58 -0
- package/dist/extractors/graphRoutes.d.ts +12 -0
- package/dist/extractors/graphRoutes.js +435 -0
- package/dist/extractors/graphSuites.d.ts +4 -0
- package/dist/extractors/graphSuites.js +246 -0
- package/dist/extractors/graphTestSources.d.ts +2 -0
- package/dist/extractors/graphTestSources.js +102 -0
- package/dist/providers/claudeCodeProvider.js +3 -2
- package/dist/providers/localSubprocessProvider.js +2 -2
- package/dist/providers/opencodeProvider.js +6 -22
- package/dist/providers/subprocessTemplateProvider.js +22 -9
- package/package.json +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AuditResult } from "../types.js";
|
|
2
|
+
import type { AnalyzerSetting } from "@audit-tools/shared";
|
|
3
|
+
import type { RuntimeValidationReport } from "../types/runtimeValidation.js";
|
|
4
|
+
import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
|
|
5
|
+
export declare function runAuditStep(options: {
|
|
6
|
+
root: string;
|
|
7
|
+
artifactsDir: string;
|
|
8
|
+
preferredExecutor?: string;
|
|
9
|
+
auditResultsPath?: string;
|
|
10
|
+
runtimeUpdatesPath?: string;
|
|
11
|
+
externalAnalyzerPath?: string;
|
|
12
|
+
narrativeResultsPath?: string;
|
|
13
|
+
edgeReasoningResultsPath?: string;
|
|
14
|
+
analyzers?: Record<string, AnalyzerSetting>;
|
|
15
|
+
graphLlmEdgeReasoning?: boolean;
|
|
16
|
+
since?: string;
|
|
17
|
+
opentoken?: boolean;
|
|
18
|
+
runLog?: boolean;
|
|
19
|
+
}): Promise<import("../orchestrator/advance.js").AdvanceAuditResult>;
|
|
20
|
+
export declare function ingestBatchAuditResults(options: {
|
|
21
|
+
root: string;
|
|
22
|
+
artifactsDir: string;
|
|
23
|
+
batchDir: string;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
batchFiles: string[];
|
|
26
|
+
bundle: Partial<{
|
|
27
|
+
repo_manifest: import("../types.js").RepoManifest;
|
|
28
|
+
file_disposition: import("@audit-tools/shared").FileDisposition;
|
|
29
|
+
auto_fixes_applied: unknown;
|
|
30
|
+
unit_manifest: import("../types.js").UnitManifest;
|
|
31
|
+
graph_bundle: import("@audit-tools/shared").GraphBundle;
|
|
32
|
+
surface_manifest: import("@audit-tools/shared").SurfaceManifest;
|
|
33
|
+
critical_flows: import("@audit-tools/shared").CriticalFlowManifest;
|
|
34
|
+
flow_coverage: import("../types/flowCoverage.js").FlowCoverageManifest;
|
|
35
|
+
risk_register: import("@audit-tools/shared").RiskRegister;
|
|
36
|
+
design_assessment: import("../types/designAssessment.js").DesignAssessment;
|
|
37
|
+
analyzer_capability: import("../types/analyzerCapability.js").AnalyzerCapabilityRecord;
|
|
38
|
+
scope: import("../types/auditScope.js").AuditScopeManifest;
|
|
39
|
+
coverage_matrix: import("../types.js").CoverageMatrix;
|
|
40
|
+
runtime_validation_tasks: import("../types/runtimeValidation.js").RuntimeValidationTaskManifest;
|
|
41
|
+
runtime_validation_report: RuntimeValidationReport;
|
|
42
|
+
external_analyzer_results: ExternalAnalyzerResults;
|
|
43
|
+
syntax_resolution_status: unknown;
|
|
44
|
+
audit_results: AuditResult[];
|
|
45
|
+
audit_tasks: import("../types.js").AuditTask[];
|
|
46
|
+
audit_plan_metrics: import("../types/reviewPlanning.js").AuditPlanMetrics;
|
|
47
|
+
review_packets: import("../types/reviewPlanning.js").ReviewPacket[];
|
|
48
|
+
requeue_tasks: import("../types.js").AuditTask[];
|
|
49
|
+
audit_report: string;
|
|
50
|
+
audit_findings: import("@audit-tools/shared").AuditFindingsReport;
|
|
51
|
+
synthesis_narrative: import("../types/synthesisNarrative.js").SynthesisNarrativeRecord;
|
|
52
|
+
audit_state: import("../types/auditState.js").AuditState;
|
|
53
|
+
artifact_metadata: import("../types/artifactMetadata.js").ArtifactMetadataManifest;
|
|
54
|
+
tooling_manifest: import("../types/toolingManifest.js").ToolingManifest;
|
|
55
|
+
}>;
|
|
56
|
+
audit_state: import("../types/auditState.js").AuditState;
|
|
57
|
+
selected_obligation: string | null;
|
|
58
|
+
selected_executor: string;
|
|
59
|
+
progress_made: boolean;
|
|
60
|
+
artifacts_written: string[];
|
|
61
|
+
progress_summary: string;
|
|
62
|
+
next_likely_step: string | null;
|
|
63
|
+
}>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { rename } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, join } from "node:path";
|
|
3
|
+
import { readJsonFile, RunLogger } from "@audit-tools/shared";
|
|
4
|
+
import { loadArtifactBundle, writeCoreArtifacts, } from "../io/artifacts.js";
|
|
5
|
+
import { advanceAudit } from "../orchestrator/advance.js";
|
|
6
|
+
import { deriveAuditState } from "../orchestrator/state.js";
|
|
7
|
+
import { decideNextStep } from "../orchestrator/nextStep.js";
|
|
8
|
+
import { sizeIndexFromManifest } from "../orchestrator/reviewPackets.js";
|
|
9
|
+
import { validateAuditResults, formatAuditResultIssues, } from "../validation/auditResults.js";
|
|
10
|
+
import { formatAuditResultValidationError } from "./workerResult.js";
|
|
11
|
+
import { looksLikeCliFlag, listBatchResultFiles } from "./args.js";
|
|
12
|
+
import { buildLineIndex } from "./lineIndex.js";
|
|
13
|
+
async function maybeArchiveLegacyPendingResults(auditResultsPath) {
|
|
14
|
+
if (!auditResultsPath || basename(auditResultsPath) !== "worker_results_pending.json") {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const archivedPath = join(dirname(auditResultsPath), `worker_results_submitted_${new Date().toISOString().replace(/[:.]/g, "-")}.json`);
|
|
18
|
+
try {
|
|
19
|
+
await rename(auditResultsPath, archivedPath);
|
|
20
|
+
return archivedPath;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
process.stderr.write(`[audit-results cleanup] failed to archive ${auditResultsPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function runAuditStep(options) {
|
|
28
|
+
const bundle = await loadArtifactBundle(options.artifactsDir);
|
|
29
|
+
const runLogger = new RunLogger(join(options.artifactsDir, "run.log.jsonl"), {
|
|
30
|
+
enabled: options.runLog ?? true,
|
|
31
|
+
});
|
|
32
|
+
const lineIndex = bundle.repo_manifest
|
|
33
|
+
? await buildLineIndex(options.root, bundle.repo_manifest)
|
|
34
|
+
: undefined;
|
|
35
|
+
const sizeIndex = bundle.repo_manifest
|
|
36
|
+
? sizeIndexFromManifest(bundle.repo_manifest)
|
|
37
|
+
: undefined;
|
|
38
|
+
if (looksLikeCliFlag(options.auditResultsPath)) {
|
|
39
|
+
throw new Error(`Invalid audit results path '${options.auditResultsPath}'. This looks like a CLI flag rather than a file path.`);
|
|
40
|
+
}
|
|
41
|
+
const auditResults = options.auditResultsPath
|
|
42
|
+
? await readJsonFile(options.auditResultsPath)
|
|
43
|
+
: undefined;
|
|
44
|
+
if (auditResults !== undefined) {
|
|
45
|
+
const issues = validateAuditResults(auditResults, bundle.audit_tasks ?? [], {
|
|
46
|
+
lineIndex,
|
|
47
|
+
});
|
|
48
|
+
const errors = issues.filter((issue) => issue.severity === "error");
|
|
49
|
+
const warnings = issues.filter((issue) => issue.severity === "warning");
|
|
50
|
+
if (warnings.length > 0) {
|
|
51
|
+
process.stderr.write(`audit-results validation: ${warnings.length} warning(s):\n` +
|
|
52
|
+
formatAuditResultIssues(warnings) +
|
|
53
|
+
"\n");
|
|
54
|
+
}
|
|
55
|
+
if (errors.length > 0) {
|
|
56
|
+
throw new Error(formatAuditResultValidationError(errors));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const runtimeValidationUpdates = options.runtimeUpdatesPath
|
|
60
|
+
? await readJsonFile(options.runtimeUpdatesPath)
|
|
61
|
+
: undefined;
|
|
62
|
+
const externalAnalyzerResults = options.externalAnalyzerPath
|
|
63
|
+
? await readJsonFile(options.externalAnalyzerPath)
|
|
64
|
+
: undefined;
|
|
65
|
+
const narrativeResults = options.narrativeResultsPath
|
|
66
|
+
? await readJsonFile(options.narrativeResultsPath)
|
|
67
|
+
: undefined;
|
|
68
|
+
const edgeReasoningResults = options.edgeReasoningResultsPath
|
|
69
|
+
? await readJsonFile(options.edgeReasoningResultsPath)
|
|
70
|
+
: undefined;
|
|
71
|
+
const result = await advanceAudit(bundle, {
|
|
72
|
+
root: options.root,
|
|
73
|
+
lineIndex,
|
|
74
|
+
sizeIndex,
|
|
75
|
+
auditResults: auditResults,
|
|
76
|
+
runtimeValidationUpdates,
|
|
77
|
+
externalAnalyzerResults,
|
|
78
|
+
narrativeResults,
|
|
79
|
+
edgeReasoningResults,
|
|
80
|
+
analyzers: options.analyzers,
|
|
81
|
+
graphLlmEdgeReasoning: options.graphLlmEdgeReasoning,
|
|
82
|
+
since: options.since,
|
|
83
|
+
preferredExecutor: options.preferredExecutor,
|
|
84
|
+
opentoken: options.opentoken,
|
|
85
|
+
runLogger,
|
|
86
|
+
});
|
|
87
|
+
await writeCoreArtifacts(options.artifactsDir, result.updated_bundle);
|
|
88
|
+
const archivedPendingResults = await maybeArchiveLegacyPendingResults(options.auditResultsPath);
|
|
89
|
+
if (archivedPendingResults) {
|
|
90
|
+
result.progress_summary +=
|
|
91
|
+
` Archived legacy staging file to ${archivedPendingResults}.`;
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
export async function ingestBatchAuditResults(options) {
|
|
96
|
+
const batchFiles = await listBatchResultFiles(options.batchDir);
|
|
97
|
+
const artifactsWritten = new Set();
|
|
98
|
+
const progressSummaries = [];
|
|
99
|
+
let lastStep = null;
|
|
100
|
+
let anyProgress = false;
|
|
101
|
+
for (const batchFile of batchFiles) {
|
|
102
|
+
const step = await runAuditStep({
|
|
103
|
+
root: options.root,
|
|
104
|
+
artifactsDir: options.artifactsDir,
|
|
105
|
+
preferredExecutor: "result_ingestion_executor",
|
|
106
|
+
auditResultsPath: batchFile,
|
|
107
|
+
});
|
|
108
|
+
lastStep = step;
|
|
109
|
+
anyProgress ||= step.progress_made;
|
|
110
|
+
for (const artifact of step.artifacts_written) {
|
|
111
|
+
artifactsWritten.add(artifact);
|
|
112
|
+
}
|
|
113
|
+
progressSummaries.push(`${basename(batchFile)}: ${step.progress_summary}`);
|
|
114
|
+
}
|
|
115
|
+
const bundle = lastStep?.updated_bundle ??
|
|
116
|
+
(await loadArtifactBundle(options.artifactsDir));
|
|
117
|
+
const state = deriveAuditState(bundle);
|
|
118
|
+
const decision = decideNextStep(bundle);
|
|
119
|
+
return {
|
|
120
|
+
batchFiles,
|
|
121
|
+
bundle,
|
|
122
|
+
audit_state: state,
|
|
123
|
+
selected_obligation: lastStep?.selected_obligation ?? decision.selected_obligation,
|
|
124
|
+
selected_executor: lastStep?.selected_executor ?? "result_ingestion_executor",
|
|
125
|
+
progress_made: anyProgress,
|
|
126
|
+
artifacts_written: Array.from(artifactsWritten),
|
|
127
|
+
progress_summary: `Imported ${batchFiles.length} batch result file${batchFiles.length === 1 ? "" : "s"} from ${options.batchDir}.` +
|
|
128
|
+
(progressSummaries.length > 0
|
|
129
|
+
? `\n${progressSummaries.join("\n")}`
|
|
130
|
+
: ""),
|
|
131
|
+
next_likely_step: state.status === "complete" ? null : decision.selected_obligation,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ArtifactBundle } from "../io/artifacts.js";
|
|
2
|
+
import type { AuditState } from "../types/auditState.js";
|
|
3
|
+
import { type AuditCodeHandoff, type ActiveReviewRun } from "../supervisor/operatorHandoff.js";
|
|
4
|
+
export declare const ADVANCE_AUDIT_CONTRACT_VERSION = "audit-code/v1alpha1";
|
|
5
|
+
export declare function buildEnvelope(params: {
|
|
6
|
+
audit_state: unknown;
|
|
7
|
+
selected_obligation: string | null;
|
|
8
|
+
selected_executor: string | null;
|
|
9
|
+
progress_made: boolean;
|
|
10
|
+
artifacts_written: string[];
|
|
11
|
+
progress_summary: string;
|
|
12
|
+
next_likely_step: string | null;
|
|
13
|
+
handoff: AuditCodeHandoff;
|
|
14
|
+
}): {
|
|
15
|
+
contract_version: string;
|
|
16
|
+
audit_state: unknown;
|
|
17
|
+
selected_obligation: string | null;
|
|
18
|
+
selected_executor: string | null;
|
|
19
|
+
progress_made: boolean;
|
|
20
|
+
artifacts_written: string[];
|
|
21
|
+
progress_summary: string;
|
|
22
|
+
next_likely_step: string | null;
|
|
23
|
+
handoff: AuditCodeHandoff;
|
|
24
|
+
};
|
|
25
|
+
export declare function emitEnvelope(params: {
|
|
26
|
+
root: string;
|
|
27
|
+
artifactsDir: string;
|
|
28
|
+
bundle: ArtifactBundle;
|
|
29
|
+
audit_state: AuditState;
|
|
30
|
+
selected_obligation: string | null;
|
|
31
|
+
selected_executor: string | null;
|
|
32
|
+
progress_made: boolean;
|
|
33
|
+
artifacts_written: string[];
|
|
34
|
+
progress_summary: string;
|
|
35
|
+
next_likely_step: string | null;
|
|
36
|
+
providerName?: string | null;
|
|
37
|
+
isConfigError?: boolean;
|
|
38
|
+
activeReviewRun?: ActiveReviewRun;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
export declare function buildManualReviewBlocker(providerName: string): string;
|
|
41
|
+
export declare function shouldRunInlineExecutor(selectedExecutor: string | null): boolean;
|
|
42
|
+
export declare function buildBlockedAuditState(params: {
|
|
43
|
+
state: AuditState;
|
|
44
|
+
obligationId: string | null;
|
|
45
|
+
executor: string | null;
|
|
46
|
+
blocker: string;
|
|
47
|
+
}): AuditState;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { LOCAL_SUBPROCESS_PROVIDER_NAME } from "../providers/constants.js";
|
|
2
|
+
import { buildAuditCodeHandoff, writeAuditCodeHandoffArtifacts, } from "../supervisor/operatorHandoff.js";
|
|
3
|
+
export const ADVANCE_AUDIT_CONTRACT_VERSION = "audit-code/v1alpha1";
|
|
4
|
+
export function buildEnvelope(params) {
|
|
5
|
+
return {
|
|
6
|
+
contract_version: ADVANCE_AUDIT_CONTRACT_VERSION,
|
|
7
|
+
audit_state: params.audit_state,
|
|
8
|
+
selected_obligation: params.selected_obligation,
|
|
9
|
+
selected_executor: params.selected_executor,
|
|
10
|
+
progress_made: params.progress_made,
|
|
11
|
+
artifacts_written: params.artifacts_written,
|
|
12
|
+
progress_summary: params.progress_summary,
|
|
13
|
+
next_likely_step: params.next_likely_step,
|
|
14
|
+
handoff: params.handoff,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export async function emitEnvelope(params) {
|
|
18
|
+
const handoff = buildAuditCodeHandoff({
|
|
19
|
+
root: params.root,
|
|
20
|
+
artifactsDir: params.artifactsDir,
|
|
21
|
+
state: params.audit_state,
|
|
22
|
+
bundle: params.bundle,
|
|
23
|
+
providerName: params.providerName,
|
|
24
|
+
progressSummary: params.progress_summary,
|
|
25
|
+
isConfigError: params.isConfigError,
|
|
26
|
+
activeReviewRun: params.activeReviewRun,
|
|
27
|
+
});
|
|
28
|
+
await writeAuditCodeHandoffArtifacts(handoff);
|
|
29
|
+
console.log(JSON.stringify(buildEnvelope({
|
|
30
|
+
audit_state: params.audit_state,
|
|
31
|
+
selected_obligation: params.selected_obligation,
|
|
32
|
+
selected_executor: params.selected_executor,
|
|
33
|
+
progress_made: params.progress_made,
|
|
34
|
+
artifacts_written: params.artifacts_written,
|
|
35
|
+
progress_summary: params.progress_summary,
|
|
36
|
+
next_likely_step: params.next_likely_step,
|
|
37
|
+
handoff,
|
|
38
|
+
}), null, 2));
|
|
39
|
+
}
|
|
40
|
+
export function buildManualReviewBlocker(providerName) {
|
|
41
|
+
return providerName === LOCAL_SUBPROCESS_PROVIDER_NAME
|
|
42
|
+
? "Ready for LLM semantic review. If the host exposes a callable subagent tool, prepare dispatch and fan out packets. " +
|
|
43
|
+
"If not, use single-task fallback: review only the first pending task, write one AuditResult to the run audit-results path, execute worker_command, then stop."
|
|
44
|
+
: "Audit blocked: waiting for manual audit results or interactive provider configuration.";
|
|
45
|
+
}
|
|
46
|
+
export function shouldRunInlineExecutor(selectedExecutor) {
|
|
47
|
+
return selectedExecutor !== null && selectedExecutor !== "agent";
|
|
48
|
+
}
|
|
49
|
+
export function buildBlockedAuditState(params) {
|
|
50
|
+
return {
|
|
51
|
+
...params.state,
|
|
52
|
+
status: "blocked",
|
|
53
|
+
last_executor: params.executor ?? params.state.last_executor,
|
|
54
|
+
last_obligation: params.obligationId ?? params.state.last_obligation,
|
|
55
|
+
blockers: [...new Set([...(params.state.blockers ?? []), params.blocker])],
|
|
56
|
+
obligations: params.state.obligations.map((item) => item.id === params.obligationId
|
|
57
|
+
? {
|
|
58
|
+
...item,
|
|
59
|
+
state: "blocked",
|
|
60
|
+
reason: params.blocker,
|
|
61
|
+
}
|
|
62
|
+
: item),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ArtifactBundle } from "../io/artifacts.js";
|
|
2
|
+
import type { AuditState } from "../types/auditState.js";
|
|
3
|
+
import type { WorkerTask } from "../types/workerSession.js";
|
|
4
|
+
import { type ActiveReviewRun } from "../supervisor/operatorHandoff.js";
|
|
5
|
+
export declare function activeReviewRunFromTask(artifactsDir: string, task: WorkerTask): ActiveReviewRun | null;
|
|
6
|
+
export declare function loadCurrentActiveReviewRun(artifactsDir: string): Promise<ActiveReviewRun | null>;
|
|
7
|
+
export declare function writeHandoffOnly(params: {
|
|
8
|
+
root: string;
|
|
9
|
+
artifactsDir: string;
|
|
10
|
+
bundle: ArtifactBundle;
|
|
11
|
+
audit_state: AuditState;
|
|
12
|
+
progress_summary: string;
|
|
13
|
+
providerName?: string | null;
|
|
14
|
+
isConfigError?: boolean;
|
|
15
|
+
activeReviewRun?: ActiveReviewRun;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
export declare function ensureSemanticReviewRun(params: {
|
|
18
|
+
root: string;
|
|
19
|
+
artifactsDir: string;
|
|
20
|
+
bundle: ArtifactBundle;
|
|
21
|
+
state: AuditState;
|
|
22
|
+
obligationId: string | null;
|
|
23
|
+
selfCliPath: string;
|
|
24
|
+
timeoutMs: number;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
state: AuditState;
|
|
27
|
+
bundle: ArtifactBundle;
|
|
28
|
+
activeReviewRun: ActiveReviewRun;
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { isFileMissingError, readJsonFile, writeJsonFile } from "@audit-tools/shared";
|
|
3
|
+
import { writeCoreArtifacts } from "../io/artifacts.js";
|
|
4
|
+
import { buildRunId, getRunPaths, writeWorkerTaskFiles, } from "../io/runArtifacts.js";
|
|
5
|
+
import { renderWorkerPrompt } from "../prompts/renderWorkerPrompt.js";
|
|
6
|
+
import { buildAuditCodeHandoff, writeAuditCodeHandoffArtifacts, } from "../supervisor/operatorHandoff.js";
|
|
7
|
+
import { LOCAL_SUBPROCESS_PROVIDER_NAME } from "../providers/constants.js";
|
|
8
|
+
import { addFileLineCountHints } from "./lineIndex.js";
|
|
9
|
+
import { buildPendingAuditTasks } from "./dispatch.js";
|
|
10
|
+
import { buildBlockedAuditState, buildManualReviewBlocker } from "./envelope.js";
|
|
11
|
+
export function activeReviewRunFromTask(artifactsDir, task) {
|
|
12
|
+
if (task.preferred_executor !== "agent" || !task.audit_results_path) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const paths = getRunPaths(artifactsDir, task.run_id);
|
|
16
|
+
return {
|
|
17
|
+
run_id: task.run_id,
|
|
18
|
+
task_path: paths.taskPath,
|
|
19
|
+
prompt_path: paths.promptPath,
|
|
20
|
+
pending_audit_tasks_path: task.pending_audit_tasks_path,
|
|
21
|
+
audit_results_path: task.audit_results_path,
|
|
22
|
+
worker_command: task.worker_command,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export async function loadCurrentActiveReviewRun(artifactsDir) {
|
|
26
|
+
try {
|
|
27
|
+
const task = await readJsonFile(join(artifactsDir, "dispatch", "current-task.json"));
|
|
28
|
+
return activeReviewRunFromTask(artifactsDir, task);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (isFileMissingError(error)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function writeHandoffOnly(params) {
|
|
38
|
+
const handoff = buildAuditCodeHandoff({
|
|
39
|
+
root: params.root,
|
|
40
|
+
artifactsDir: params.artifactsDir,
|
|
41
|
+
state: params.audit_state,
|
|
42
|
+
bundle: params.bundle,
|
|
43
|
+
providerName: params.providerName,
|
|
44
|
+
progressSummary: params.progress_summary,
|
|
45
|
+
isConfigError: params.isConfigError,
|
|
46
|
+
activeReviewRun: params.activeReviewRun,
|
|
47
|
+
});
|
|
48
|
+
await writeAuditCodeHandoffArtifacts(handoff);
|
|
49
|
+
}
|
|
50
|
+
export async function ensureSemanticReviewRun(params) {
|
|
51
|
+
const existingRun = await loadCurrentActiveReviewRun(params.artifactsDir);
|
|
52
|
+
if (existingRun) {
|
|
53
|
+
const blockedState = params.bundle.audit_state?.status === "blocked"
|
|
54
|
+
? params.bundle.audit_state
|
|
55
|
+
: buildBlockedAuditState({
|
|
56
|
+
state: params.state,
|
|
57
|
+
obligationId: params.obligationId,
|
|
58
|
+
executor: "agent",
|
|
59
|
+
blocker: buildManualReviewBlocker(LOCAL_SUBPROCESS_PROVIDER_NAME),
|
|
60
|
+
});
|
|
61
|
+
const blockedBundle = { ...params.bundle, audit_state: blockedState };
|
|
62
|
+
await writeCoreArtifacts(params.artifactsDir, blockedBundle);
|
|
63
|
+
await writeHandoffOnly({
|
|
64
|
+
root: params.root,
|
|
65
|
+
artifactsDir: params.artifactsDir,
|
|
66
|
+
bundle: blockedBundle,
|
|
67
|
+
audit_state: blockedState,
|
|
68
|
+
progress_summary: buildManualReviewBlocker(LOCAL_SUBPROCESS_PROVIDER_NAME),
|
|
69
|
+
providerName: LOCAL_SUBPROCESS_PROVIDER_NAME,
|
|
70
|
+
activeReviewRun: existingRun,
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
state: blockedState,
|
|
74
|
+
bundle: blockedBundle,
|
|
75
|
+
activeReviewRun: existingRun,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const blockedState = buildBlockedAuditState({
|
|
79
|
+
state: params.state,
|
|
80
|
+
obligationId: params.obligationId,
|
|
81
|
+
executor: "agent",
|
|
82
|
+
blocker: buildManualReviewBlocker(LOCAL_SUBPROCESS_PROVIDER_NAME),
|
|
83
|
+
});
|
|
84
|
+
await writeCoreArtifacts(params.artifactsDir, {
|
|
85
|
+
...params.bundle,
|
|
86
|
+
audit_state: blockedState,
|
|
87
|
+
});
|
|
88
|
+
const runId = buildRunId(params.obligationId, 1);
|
|
89
|
+
const paths = getRunPaths(params.artifactsDir, runId);
|
|
90
|
+
const pendingTasks = await addFileLineCountHints(params.root, buildPendingAuditTasks(params.bundle));
|
|
91
|
+
const pendingTasksPath = join(paths.runDir, "pending-audit-tasks.json");
|
|
92
|
+
const auditResultsPath = join(paths.runDir, "audit-results.json");
|
|
93
|
+
const taskReadPaths = new Set();
|
|
94
|
+
for (const pt of pendingTasks) {
|
|
95
|
+
for (const fp of pt.file_paths)
|
|
96
|
+
taskReadPaths.add(fp);
|
|
97
|
+
}
|
|
98
|
+
const task = {
|
|
99
|
+
contract_version: "audit-code-worker/v1alpha1",
|
|
100
|
+
run_id: runId,
|
|
101
|
+
repo_root: params.root,
|
|
102
|
+
artifacts_dir: params.artifactsDir,
|
|
103
|
+
obligation_id: params.obligationId,
|
|
104
|
+
preferred_executor: "agent",
|
|
105
|
+
result_path: paths.resultPath,
|
|
106
|
+
worker_command: [
|
|
107
|
+
process.execPath,
|
|
108
|
+
params.selfCliPath,
|
|
109
|
+
"worker-run",
|
|
110
|
+
"--task",
|
|
111
|
+
paths.taskPath,
|
|
112
|
+
],
|
|
113
|
+
audit_results_path: auditResultsPath,
|
|
114
|
+
pending_audit_tasks_path: pendingTasksPath,
|
|
115
|
+
timeout_ms: params.timeoutMs,
|
|
116
|
+
max_retries: 0,
|
|
117
|
+
access: {
|
|
118
|
+
read_paths: [...taskReadPaths],
|
|
119
|
+
write_paths: [auditResultsPath, paths.resultPath],
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
const prompt = renderWorkerPrompt(task);
|
|
123
|
+
await writeWorkerTaskFiles(task, prompt, paths, params.artifactsDir, pendingTasks);
|
|
124
|
+
await writeJsonFile(pendingTasksPath, pendingTasks);
|
|
125
|
+
const activeReviewRun = activeReviewRunFromTask(params.artifactsDir, task);
|
|
126
|
+
if (!activeReviewRun) {
|
|
127
|
+
throw new Error("Internal error: failed to materialize active review run.");
|
|
128
|
+
}
|
|
129
|
+
const blockedBundle = {
|
|
130
|
+
...params.bundle,
|
|
131
|
+
audit_state: blockedState,
|
|
132
|
+
};
|
|
133
|
+
await writeHandoffOnly({
|
|
134
|
+
root: params.root,
|
|
135
|
+
artifactsDir: params.artifactsDir,
|
|
136
|
+
bundle: blockedBundle,
|
|
137
|
+
audit_state: blockedState,
|
|
138
|
+
progress_summary: buildManualReviewBlocker(LOCAL_SUBPROCESS_PROVIDER_NAME),
|
|
139
|
+
providerName: LOCAL_SUBPROCESS_PROVIDER_NAME,
|
|
140
|
+
activeReviewRun,
|
|
141
|
+
});
|
|
142
|
+
return { state: blockedState, bundle: blockedBundle, activeReviewRun };
|
|
143
|
+
}
|