auditor-lambda 0.2.6 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +29 -7
  2. package/audit-code-wrapper-lib.mjs +1605 -330
  3. package/dist/adapters/eslint.js +9 -5
  4. package/dist/cli.d.ts +42 -1
  5. package/dist/cli.js +192 -80
  6. package/dist/coverage.d.ts +2 -2
  7. package/dist/coverage.js +5 -5
  8. package/dist/extractors/bucketing.d.ts +4 -0
  9. package/dist/extractors/bucketing.js +6 -2
  10. package/dist/extractors/disposition.d.ts +4 -0
  11. package/dist/extractors/disposition.js +15 -2
  12. package/dist/extractors/fileInventory.js +24 -28
  13. package/dist/extractors/flows.d.ts +5 -0
  14. package/dist/extractors/flows.js +25 -39
  15. package/dist/extractors/pathPatterns.d.ts +13 -3
  16. package/dist/extractors/pathPatterns.js +116 -53
  17. package/dist/extractors/risk.js +7 -1
  18. package/dist/extractors/surfaces.d.ts +4 -0
  19. package/dist/extractors/surfaces.js +11 -11
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +2 -1
  22. package/dist/io/artifacts.d.ts +59 -44
  23. package/dist/io/artifacts.js +80 -120
  24. package/dist/io/json.d.ts +2 -0
  25. package/dist/io/json.js +65 -19
  26. package/dist/io/runArtifacts.d.ts +2 -1
  27. package/dist/io/runArtifacts.js +44 -7
  28. package/dist/mcp/server.d.ts +1 -0
  29. package/dist/mcp/server.js +579 -0
  30. package/dist/orchestrator/advance.js +84 -56
  31. package/dist/orchestrator/dependencyMap.js +9 -13
  32. package/dist/orchestrator/executors.js +7 -2
  33. package/dist/orchestrator/flowCoverage.js +11 -5
  34. package/dist/orchestrator/flowPlanning.d.ts +7 -2
  35. package/dist/orchestrator/flowPlanning.js +46 -21
  36. package/dist/orchestrator/flowRequeue.js +29 -9
  37. package/dist/orchestrator/internalExecutors.d.ts +2 -1
  38. package/dist/orchestrator/internalExecutors.js +130 -69
  39. package/dist/orchestrator/planning.js +25 -3
  40. package/dist/orchestrator/requeue.js +20 -5
  41. package/dist/orchestrator/resultIngestion.js +5 -6
  42. package/dist/orchestrator/runtimeValidation.d.ts +7 -2
  43. package/dist/orchestrator/runtimeValidation.js +61 -49
  44. package/dist/orchestrator/runtimeValidationUpdate.js +2 -4
  45. package/dist/orchestrator/state.js +18 -13
  46. package/dist/orchestrator/taskBuilder.d.ts +4 -2
  47. package/dist/orchestrator/taskBuilder.js +153 -52
  48. package/dist/orchestrator/trivialAudit.js +8 -5
  49. package/dist/orchestrator/unitBuilder.d.ts +3 -1
  50. package/dist/orchestrator/unitBuilder.js +24 -16
  51. package/dist/prompts/renderWorkerPrompt.d.ts +1 -1
  52. package/dist/prompts/renderWorkerPrompt.js +19 -10
  53. package/dist/providers/claudeCodeProvider.d.ts +4 -1
  54. package/dist/providers/claudeCodeProvider.js +8 -5
  55. package/dist/providers/localSubprocessProvider.d.ts +4 -0
  56. package/dist/providers/localSubprocessProvider.js +7 -2
  57. package/dist/providers/spawnLoggedCommand.d.ts +9 -1
  58. package/dist/providers/spawnLoggedCommand.js +77 -29
  59. package/dist/reporting/mergeFindings.js +0 -11
  60. package/dist/reporting/synthesis.d.ts +26 -21
  61. package/dist/reporting/synthesis.js +97 -61
  62. package/dist/reporting/workBlocks.d.ts +12 -3
  63. package/dist/reporting/workBlocks.js +124 -70
  64. package/dist/supervisor/operatorHandoff.js +48 -18
  65. package/dist/supervisor/runLedger.d.ts +1 -1
  66. package/dist/supervisor/runLedger.js +112 -5
  67. package/dist/supervisor/sessionConfig.js +10 -10
  68. package/dist/types/externalAnalyzer.d.ts +3 -0
  69. package/dist/types/flowCoverage.d.ts +5 -1
  70. package/dist/types/flowCoverage.js +5 -1
  71. package/dist/types/flows.d.ts +6 -0
  72. package/dist/types/flows.js +1 -1
  73. package/dist/types/runLedger.d.ts +5 -1
  74. package/dist/types/runLedger.js +6 -1
  75. package/dist/types/runtimeValidation.d.ts +13 -3
  76. package/dist/types/runtimeValidation.js +16 -1
  77. package/dist/types/sessionConfig.d.ts +15 -2
  78. package/dist/types/sessionConfig.js +15 -1
  79. package/dist/types/surfaces.d.ts +4 -1
  80. package/dist/types/surfaces.js +1 -1
  81. package/dist/types/workerSession.d.ts +9 -0
  82. package/dist/types/workerSession.js +5 -1
  83. package/dist/types.d.ts +4 -7
  84. package/dist/validation/artifacts.d.ts +1 -1
  85. package/dist/validation/artifacts.js +33 -20
  86. package/dist/validation/auditResults.d.ts +2 -2
  87. package/dist/validation/auditResults.js +71 -114
  88. package/dist/validation/basic.d.ts +9 -1
  89. package/dist/validation/basic.js +40 -3
  90. package/dist/validation/sessionConfig.d.ts +4 -2
  91. package/dist/validation/sessionConfig.js +62 -15
  92. package/docs/agent-integrations.md +67 -38
  93. package/docs/artifacts.md +16 -56
  94. package/docs/bootstrap-install.md +60 -30
  95. package/docs/contract.md +22 -205
  96. package/docs/next-steps.md +76 -44
  97. package/docs/packaging.md +27 -3
  98. package/docs/product-direction.md +22 -0
  99. package/docs/production-launch-bar.md +4 -2
  100. package/docs/production-readiness.md +9 -5
  101. package/docs/releasing.md +98 -0
  102. package/docs/remediation-baseline.md +75 -0
  103. package/docs/run-flow.md +23 -11
  104. package/docs/session-config.md +50 -5
  105. package/docs/supervisor.md +7 -0
  106. package/docs/workflow-refactor-brief.md +177 -0
  107. package/package.json +4 -1
  108. package/schemas/audit_result.schema.json +8 -7
  109. package/schemas/audit_task.schema.json +3 -1
  110. package/schemas/coverage_matrix.schema.json +3 -3
  111. package/schemas/critical_flows.schema.json +6 -2
  112. package/schemas/file_disposition.schema.json +2 -2
  113. package/schemas/finding.schema.json +9 -4
  114. package/schemas/flow_coverage.schema.json +2 -2
  115. package/schemas/repo_manifest.schema.json +4 -4
  116. package/schemas/risk_register.schema.json +2 -2
  117. package/schemas/runtime_validation_report.schema.json +3 -3
  118. package/schemas/runtime_validation_tasks.schema.json +8 -2
  119. package/schemas/surface_manifest.schema.json +6 -3
  120. package/schemas/unit_manifest.schema.json +3 -2
  121. package/skills/audit-code/SKILL.md +16 -2
  122. package/skills/audit-code/audit-code.prompt.md +5 -8
  123. package/schemas/merged_findings.schema.json +0 -19
  124. package/schemas/root_cause_clusters.schema.json +0 -28
  125. package/schemas/synthesis_report.schema.json +0 -61
@@ -9,53 +9,68 @@ import type { GraphBundle } from "../types/graph.js";
9
9
  import type { RiskRegister } from "../types/risk.js";
10
10
  import type { RuntimeValidationReport, RuntimeValidationTaskManifest } from "../types/runtimeValidation.js";
11
11
  import type { SurfaceManifest } from "../types/surfaces.js";
12
- export interface ArtifactBundle {
13
- repo_manifest?: RepoManifest;
14
- file_disposition?: FileDisposition;
15
- auto_fixes_applied?: unknown;
16
- unit_manifest?: UnitManifest;
17
- graph_bundle?: GraphBundle;
18
- surface_manifest?: SurfaceManifest;
19
- critical_flows?: CriticalFlowManifest;
20
- flow_coverage?: FlowCoverageManifest;
21
- risk_register?: RiskRegister;
22
- coverage_matrix?: CoverageMatrix;
23
- runtime_validation_tasks?: RuntimeValidationTaskManifest;
24
- runtime_validation_report?: RuntimeValidationReport;
25
- external_analyzer_results?: ExternalAnalyzerResults;
26
- audit_results?: AuditResult[];
27
- audit_tasks?: AuditTask[];
28
- requeue_tasks?: AuditTask[];
29
- merged_findings?: unknown;
30
- root_cause_clusters?: unknown;
31
- synthesis_report?: unknown;
32
- audit_state?: AuditState;
33
- artifact_metadata?: ArtifactMetadataManifest;
12
+ type ArtifactPayloadMap = {
13
+ repo_manifest: RepoManifest;
14
+ file_disposition: FileDisposition;
15
+ auto_fixes_applied: unknown;
16
+ unit_manifest: UnitManifest;
17
+ graph_bundle: GraphBundle;
18
+ surface_manifest: SurfaceManifest;
19
+ critical_flows: CriticalFlowManifest;
20
+ flow_coverage: FlowCoverageManifest;
21
+ risk_register: RiskRegister;
22
+ coverage_matrix: CoverageMatrix;
23
+ runtime_validation_tasks: RuntimeValidationTaskManifest;
24
+ runtime_validation_report: RuntimeValidationReport;
25
+ external_analyzer_results: ExternalAnalyzerResults;
26
+ audit_results: AuditResult[];
27
+ audit_tasks: AuditTask[];
28
+ requeue_tasks: AuditTask[];
29
+ audit_report: string;
30
+ audit_state: AuditState;
31
+ artifact_metadata: ArtifactMetadataManifest;
32
+ };
33
+ /**
34
+ * Audit artifacts accumulate phase-by-phase as the orchestrator advances.
35
+ * Missing keys mean the corresponding artifact has not been produced yet.
36
+ */
37
+ export type ArtifactBundle = Partial<ArtifactPayloadMap>;
38
+ export type ArtifactBundleKey = keyof ArtifactPayloadMap;
39
+ type ArtifactPhase = "intake" | "analysis" | "execution" | "reporting" | "supervisor";
40
+ interface ArtifactDefinition<K extends ArtifactBundleKey = ArtifactBundleKey> {
41
+ fileName: string;
42
+ phase: ArtifactPhase;
43
+ read: (path: string) => Promise<ArtifactPayloadMap[K] | undefined>;
44
+ write: (path: string, value: ArtifactPayloadMap[K]) => Promise<void>;
34
45
  }
35
- export declare const ARTIFACT_FILE_TO_BUNDLE_KEY: {
36
- readonly "repo_manifest.json": "repo_manifest";
37
- readonly "file_disposition.json": "file_disposition";
38
- readonly "auto_fixes_applied.json": "auto_fixes_applied";
39
- readonly "unit_manifest.json": "unit_manifest";
40
- readonly "graph_bundle.json": "graph_bundle";
41
- readonly "surface_manifest.json": "surface_manifest";
42
- readonly "critical_flows.json": "critical_flows";
43
- readonly "flow_coverage.json": "flow_coverage";
44
- readonly "risk_register.json": "risk_register";
45
- readonly "coverage_matrix.json": "coverage_matrix";
46
- readonly "runtime_validation_tasks.json": "runtime_validation_tasks";
47
- readonly "runtime_validation_report.json": "runtime_validation_report";
48
- readonly "external_analyzer_results.json": "external_analyzer_results";
49
- readonly "audit_results.jsonl": "audit_results";
50
- readonly "audit_tasks.json": "audit_tasks";
51
- readonly "requeue_tasks.json": "requeue_tasks";
52
- readonly "merged_findings.json": "merged_findings";
53
- readonly "root_cause_clusters.json": "root_cause_clusters";
54
- readonly "synthesis_report.json": "synthesis_report";
55
- readonly "audit_state.json": "audit_state";
56
- readonly "artifact_metadata.json": "artifact_metadata";
46
+ export declare const ARTIFACT_DEFINITIONS: {
47
+ readonly repo_manifest: ArtifactDefinition<"repo_manifest">;
48
+ readonly file_disposition: ArtifactDefinition<"file_disposition">;
49
+ readonly auto_fixes_applied: ArtifactDefinition<"auto_fixes_applied">;
50
+ readonly unit_manifest: ArtifactDefinition<"unit_manifest">;
51
+ readonly graph_bundle: ArtifactDefinition<"graph_bundle">;
52
+ readonly surface_manifest: ArtifactDefinition<"surface_manifest">;
53
+ readonly critical_flows: ArtifactDefinition<"critical_flows">;
54
+ readonly flow_coverage: ArtifactDefinition<"flow_coverage">;
55
+ readonly risk_register: ArtifactDefinition<"risk_register">;
56
+ readonly coverage_matrix: ArtifactDefinition<"coverage_matrix">;
57
+ readonly runtime_validation_tasks: ArtifactDefinition<"runtime_validation_tasks">;
58
+ readonly runtime_validation_report: ArtifactDefinition<"runtime_validation_report">;
59
+ readonly external_analyzer_results: ArtifactDefinition<"external_analyzer_results">;
60
+ readonly audit_results: ArtifactDefinition<"audit_results">;
61
+ readonly audit_tasks: ArtifactDefinition<"audit_tasks">;
62
+ readonly requeue_tasks: ArtifactDefinition<"requeue_tasks">;
63
+ readonly audit_report: ArtifactDefinition<"audit_report">;
64
+ readonly audit_state: ArtifactDefinition<"audit_state">;
65
+ readonly artifact_metadata: ArtifactDefinition<"artifact_metadata">;
57
66
  };
67
+ export declare const ARTIFACT_FILE_TO_BUNDLE_KEY: Record<string, ArtifactBundleKey>;
58
68
  export declare function getArtifactValue(bundle: ArtifactBundle, artifactName: string): unknown;
59
69
  export declare function loadArtifactBundle(root: string): Promise<ArtifactBundle>;
60
70
  export declare function writeCoreArtifacts(root: string, bundle: ArtifactBundle): Promise<void>;
61
71
  export declare function cleanupIntermediateArtifacts(root: string): Promise<string[]>;
72
+ export declare function promoteFinalAuditReport(params: {
73
+ artifactsDir: string;
74
+ repoRoot: string;
75
+ }): Promise<void>;
76
+ export {};
@@ -1,139 +1,99 @@
1
- import { unlink } from "node:fs/promises";
1
+ import { cp, rm, unlink } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { writeJsonFile, readOptionalJsonFile, readOptionalNdjsonFile, writeNdjsonFile, } from "./json.js";
4
- export const ARTIFACT_FILE_TO_BUNDLE_KEY = {
5
- "repo_manifest.json": "repo_manifest",
6
- "file_disposition.json": "file_disposition",
7
- "auto_fixes_applied.json": "auto_fixes_applied",
8
- "unit_manifest.json": "unit_manifest",
9
- "graph_bundle.json": "graph_bundle",
10
- "surface_manifest.json": "surface_manifest",
11
- "critical_flows.json": "critical_flows",
12
- "flow_coverage.json": "flow_coverage",
13
- "risk_register.json": "risk_register",
14
- "coverage_matrix.json": "coverage_matrix",
15
- "runtime_validation_tasks.json": "runtime_validation_tasks",
16
- "runtime_validation_report.json": "runtime_validation_report",
17
- "external_analyzer_results.json": "external_analyzer_results",
18
- "audit_results.jsonl": "audit_results",
19
- "audit_tasks.json": "audit_tasks",
20
- "requeue_tasks.json": "requeue_tasks",
21
- "merged_findings.json": "merged_findings",
22
- "root_cause_clusters.json": "root_cause_clusters",
23
- "synthesis_report.json": "synthesis_report",
24
- "audit_state.json": "audit_state",
25
- "artifact_metadata.json": "artifact_metadata",
3
+ import { isFileMissingError, readOptionalJsonFile, readOptionalNdjsonFile, readOptionalTextFile, writeJsonFile, writeNdjsonFile, writeTextFile, } from "./json.js";
4
+ function jsonArtifact(fileName, phase) {
5
+ return {
6
+ fileName,
7
+ phase,
8
+ read: (path) => readOptionalJsonFile(path),
9
+ write: (path, value) => writeJsonFile(path, value),
10
+ };
11
+ }
12
+ function ndjsonArtifact(fileName, phase) {
13
+ return {
14
+ fileName,
15
+ phase,
16
+ read: (path) => readOptionalNdjsonFile(path),
17
+ write: (path, value) => writeNdjsonFile(path, value),
18
+ };
19
+ }
20
+ function textArtifact(fileName, phase) {
21
+ return {
22
+ fileName,
23
+ phase,
24
+ read: (path) => readOptionalTextFile(path),
25
+ write: (path, value) => writeTextFile(path, value),
26
+ };
27
+ }
28
+ export const ARTIFACT_DEFINITIONS = {
29
+ repo_manifest: jsonArtifact("repo_manifest.json", "intake"),
30
+ file_disposition: jsonArtifact("file_disposition.json", "intake"),
31
+ auto_fixes_applied: jsonArtifact("auto_fixes_applied.json", "intake"),
32
+ unit_manifest: jsonArtifact("unit_manifest.json", "analysis"),
33
+ graph_bundle: jsonArtifact("graph_bundle.json", "analysis"),
34
+ surface_manifest: jsonArtifact("surface_manifest.json", "analysis"),
35
+ critical_flows: jsonArtifact("critical_flows.json", "analysis"),
36
+ flow_coverage: jsonArtifact("flow_coverage.json", "analysis"),
37
+ risk_register: jsonArtifact("risk_register.json", "analysis"),
38
+ coverage_matrix: jsonArtifact("coverage_matrix.json", "execution"),
39
+ runtime_validation_tasks: jsonArtifact("runtime_validation_tasks.json", "execution"),
40
+ runtime_validation_report: jsonArtifact("runtime_validation_report.json", "execution"),
41
+ external_analyzer_results: jsonArtifact("external_analyzer_results.json", "execution"),
42
+ audit_results: ndjsonArtifact("audit_results.jsonl", "execution"),
43
+ audit_tasks: jsonArtifact("audit_tasks.json", "execution"),
44
+ requeue_tasks: jsonArtifact("requeue_tasks.json", "execution"),
45
+ audit_report: textArtifact("audit-report.md", "reporting"),
46
+ audit_state: jsonArtifact("audit_state.json", "supervisor"),
47
+ artifact_metadata: jsonArtifact("artifact_metadata.json", "supervisor"),
26
48
  };
27
- const _bundleKeyCoverage = true;
49
+ const ARTIFACT_ENTRIES = Object.entries(ARTIFACT_DEFINITIONS);
50
+ export const ARTIFACT_FILE_TO_BUNDLE_KEY = Object.fromEntries(ARTIFACT_ENTRIES.map(([key, definition]) => [definition.fileName, key]));
28
51
  export function getArtifactValue(bundle, artifactName) {
29
- const map = ARTIFACT_FILE_TO_BUNDLE_KEY;
30
- const key = map[artifactName];
52
+ const key = ARTIFACT_FILE_TO_BUNDLE_KEY[artifactName];
31
53
  return key ? bundle[key] : undefined;
32
54
  }
33
55
  export async function loadArtifactBundle(root) {
34
56
  const bundle = {};
35
- bundle.repo_manifest = await readOptionalJsonFile(`${root}/repo_manifest.json`);
36
- bundle.file_disposition = await readOptionalJsonFile(`${root}/file_disposition.json`);
37
- bundle.auto_fixes_applied = await readOptionalJsonFile(`${root}/auto_fixes_applied.json`);
38
- bundle.unit_manifest = await readOptionalJsonFile(`${root}/unit_manifest.json`);
39
- bundle.graph_bundle = await readOptionalJsonFile(`${root}/graph_bundle.json`);
40
- bundle.surface_manifest = await readOptionalJsonFile(`${root}/surface_manifest.json`);
41
- bundle.critical_flows = await readOptionalJsonFile(`${root}/critical_flows.json`);
42
- bundle.flow_coverage = await readOptionalJsonFile(`${root}/flow_coverage.json`);
43
- bundle.risk_register = await readOptionalJsonFile(`${root}/risk_register.json`);
44
- bundle.coverage_matrix = await readOptionalJsonFile(`${root}/coverage_matrix.json`);
45
- bundle.runtime_validation_tasks =
46
- await readOptionalJsonFile(`${root}/runtime_validation_tasks.json`);
47
- bundle.runtime_validation_report =
48
- await readOptionalJsonFile(`${root}/runtime_validation_report.json`);
49
- bundle.external_analyzer_results =
50
- await readOptionalJsonFile(`${root}/external_analyzer_results.json`);
51
- bundle.audit_results = await readOptionalNdjsonFile(`${root}/audit_results.jsonl`);
52
- bundle.audit_tasks = await readOptionalJsonFile(`${root}/audit_tasks.json`);
53
- bundle.requeue_tasks = await readOptionalJsonFile(`${root}/requeue_tasks.json`);
54
- bundle.merged_findings = await readOptionalJsonFile(`${root}/merged_findings.json`);
55
- bundle.root_cause_clusters = await readOptionalJsonFile(`${root}/root_cause_clusters.json`);
56
- bundle.synthesis_report = await readOptionalJsonFile(`${root}/synthesis_report.json`);
57
- bundle.audit_state = await readOptionalJsonFile(`${root}/audit_state.json`);
58
- bundle.artifact_metadata = await readOptionalJsonFile(`${root}/artifact_metadata.json`);
57
+ const bundleRecord = bundle;
58
+ for (const entry of ARTIFACT_ENTRIES) {
59
+ const [key, definition] = entry;
60
+ const value = await definition.read(join(root, definition.fileName));
61
+ if (value !== undefined) {
62
+ bundleRecord[key] = value;
63
+ }
64
+ }
59
65
  return bundle;
60
66
  }
61
67
  export async function writeCoreArtifacts(root, bundle) {
62
- if (bundle.repo_manifest)
63
- await writeJsonFile(`${root}/repo_manifest.json`, bundle.repo_manifest);
64
- if (bundle.file_disposition)
65
- await writeJsonFile(`${root}/file_disposition.json`, bundle.file_disposition);
66
- if (bundle.auto_fixes_applied)
67
- await writeJsonFile(`${root}/auto_fixes_applied.json`, bundle.auto_fixes_applied);
68
- if (bundle.unit_manifest)
69
- await writeJsonFile(`${root}/unit_manifest.json`, bundle.unit_manifest);
70
- if (bundle.graph_bundle)
71
- await writeJsonFile(`${root}/graph_bundle.json`, bundle.graph_bundle);
72
- if (bundle.surface_manifest)
73
- await writeJsonFile(`${root}/surface_manifest.json`, bundle.surface_manifest);
74
- if (bundle.critical_flows)
75
- await writeJsonFile(`${root}/critical_flows.json`, bundle.critical_flows);
76
- if (bundle.flow_coverage)
77
- await writeJsonFile(`${root}/flow_coverage.json`, bundle.flow_coverage);
78
- if (bundle.risk_register)
79
- await writeJsonFile(`${root}/risk_register.json`, bundle.risk_register);
80
- if (bundle.coverage_matrix)
81
- await writeJsonFile(`${root}/coverage_matrix.json`, bundle.coverage_matrix);
82
- if (bundle.runtime_validation_tasks)
83
- await writeJsonFile(`${root}/runtime_validation_tasks.json`, bundle.runtime_validation_tasks);
84
- if (bundle.runtime_validation_report)
85
- await writeJsonFile(`${root}/runtime_validation_report.json`, bundle.runtime_validation_report);
86
- if (bundle.external_analyzer_results)
87
- await writeJsonFile(`${root}/external_analyzer_results.json`, bundle.external_analyzer_results);
88
- if (bundle.audit_results)
89
- await writeNdjsonFile(`${root}/audit_results.jsonl`, bundle.audit_results);
90
- if (bundle.audit_tasks)
91
- await writeJsonFile(`${root}/audit_tasks.json`, bundle.audit_tasks);
92
- if (bundle.requeue_tasks)
93
- await writeJsonFile(`${root}/requeue_tasks.json`, bundle.requeue_tasks);
94
- if (bundle.merged_findings)
95
- await writeJsonFile(`${root}/merged_findings.json`, bundle.merged_findings);
96
- if (bundle.root_cause_clusters)
97
- await writeJsonFile(`${root}/root_cause_clusters.json`, bundle.root_cause_clusters);
98
- if (bundle.synthesis_report)
99
- await writeJsonFile(`${root}/synthesis_report.json`, bundle.synthesis_report);
100
- if (bundle.audit_state)
101
- await writeJsonFile(`${root}/audit_state.json`, bundle.audit_state);
102
- if (bundle.artifact_metadata)
103
- await writeJsonFile(`${root}/artifact_metadata.json`, bundle.artifact_metadata);
68
+ const bundleRecord = bundle;
69
+ for (const entry of ARTIFACT_ENTRIES) {
70
+ const [key, definition] = entry;
71
+ const value = bundleRecord[key];
72
+ if (value !== undefined) {
73
+ await definition.write(join(root, definition.fileName), value);
74
+ }
75
+ }
104
76
  }
105
- // Intermediate files deleted after synthesis completes. The final outputs
106
- // (synthesis_report.json, merged_findings.json, root_cause_clusters.json,
107
- // audit_state.json) are retained.
108
- const INTERMEDIATE_ARTIFACTS = [
109
- "repo_manifest.json",
110
- "file_disposition.json",
111
- "auto_fixes_applied.json",
112
- "unit_manifest.json",
113
- "graph_bundle.json",
114
- "surface_manifest.json",
115
- "critical_flows.json",
116
- "flow_coverage.json",
117
- "risk_register.json",
118
- "coverage_matrix.json",
119
- "runtime_validation_tasks.json",
120
- "runtime_validation_report.json",
121
- "external_analyzer_results.json",
122
- "audit_results.jsonl",
123
- "audit_tasks.json",
124
- "requeue_tasks.json",
125
- "artifact_metadata.json",
126
- ];
127
77
  export async function cleanupIntermediateArtifacts(root) {
128
78
  const deleted = [];
129
- for (const name of INTERMEDIATE_ARTIFACTS) {
79
+ for (const [, definition] of ARTIFACT_ENTRIES) {
80
+ const path = join(root, definition.fileName);
130
81
  try {
131
- await unlink(join(root, name));
132
- deleted.push(name);
82
+ await unlink(path);
83
+ deleted.push(definition.fileName);
133
84
  }
134
- catch {
135
- // file absent — nothing to delete
85
+ catch (error) {
86
+ if (isFileMissingError(error)) {
87
+ continue;
88
+ }
89
+ throw error;
136
90
  }
137
91
  }
138
92
  return deleted;
139
93
  }
94
+ export async function promoteFinalAuditReport(params) {
95
+ const source = join(params.artifactsDir, "audit-report.md");
96
+ const destination = join(params.repoRoot, "audit-report.md");
97
+ await cp(source, destination, { force: true });
98
+ await rm(params.artifactsDir, { recursive: true, force: true });
99
+ }
package/dist/io/json.d.ts CHANGED
@@ -6,3 +6,5 @@ export declare function readNdjsonFile<T>(path: string): Promise<T[]>;
6
6
  export declare function readOptionalJsonFile<T>(path: string): Promise<T | undefined>;
7
7
  export declare function readOptionalNdjsonFile<T>(path: string): Promise<T[] | undefined>;
8
8
  export declare function writeNdjsonFile(path: string, values: unknown[]): Promise<void>;
9
+ export declare function readOptionalTextFile(path: string): Promise<string | undefined>;
10
+ export declare function writeTextFile(path: string, value: string): Promise<void>;
package/dist/io/json.js CHANGED
@@ -3,6 +3,17 @@ import { dirname } from "node:path";
3
3
  function errorMessage(error) {
4
4
  return error instanceof Error ? error.message : String(error);
5
5
  }
6
+ function ioError(action, path, error) {
7
+ return new Error(`Failed to ${action} ${path}: ${errorMessage(error)}`);
8
+ }
9
+ async function ensureParentDirectory(path) {
10
+ try {
11
+ await mkdir(dirname(path), { recursive: true });
12
+ }
13
+ catch (error) {
14
+ throw ioError("prepare parent directory", path, error);
15
+ }
16
+ }
6
17
  export function isFileMissingError(error) {
7
18
  return (typeof error === "object" &&
8
19
  error !== null &&
@@ -28,31 +39,41 @@ export async function readJsonFile(path) {
28
39
  }
29
40
  }
30
41
  export async function writeJsonFile(path, value) {
31
- await mkdir(dirname(path), { recursive: true });
32
- await writeFile(path, JSON.stringify(value, null, 2) + "\n", "utf8");
42
+ await ensureParentDirectory(path);
43
+ try {
44
+ await writeFile(path, JSON.stringify(value, null, 2) + "\n", "utf8");
45
+ }
46
+ catch (error) {
47
+ throw ioError("write", path, error);
48
+ }
33
49
  }
34
50
  export async function appendNdjsonFile(path, value) {
35
- await mkdir(dirname(path), { recursive: true });
36
- await appendFile(path, JSON.stringify(value) + "\n", "utf8");
51
+ await ensureParentDirectory(path);
52
+ try {
53
+ await appendFile(path, JSON.stringify(value) + "\n", "utf8");
54
+ }
55
+ catch (error) {
56
+ throw ioError("append", path, error);
57
+ }
37
58
  }
38
59
  export async function readNdjsonFile(path) {
39
60
  try {
40
61
  const content = await readFile(path, "utf8");
41
- if (content.trim().length === 0) {
42
- return [];
43
- }
44
- return content
45
- .trim()
46
- .split(/\r?\n/)
47
- .filter(Boolean)
48
- .map((line, index) => {
62
+ const values = [];
63
+ let sawContent = false;
64
+ for (const [index, line] of content.split(/\r?\n/).entries()) {
65
+ if (line.trim().length === 0) {
66
+ continue;
67
+ }
68
+ sawContent = true;
49
69
  try {
50
- return JSON.parse(line);
70
+ values.push(JSON.parse(line));
51
71
  }
52
72
  catch (error) {
53
73
  throw new Error(`Invalid NDJSON in ${path} at line ${index + 1}: ${errorMessage(error)}`);
54
74
  }
55
- });
75
+ }
76
+ return sawContent ? values : [];
56
77
  }
57
78
  catch (error) {
58
79
  if (isFileMissingError(error)) {
@@ -87,10 +108,35 @@ export async function readOptionalNdjsonFile(path) {
87
108
  }
88
109
  }
89
110
  export async function writeNdjsonFile(path, values) {
90
- await mkdir(dirname(path), { recursive: true });
91
- if (values.length === 0) {
92
- await writeFile(path, "", "utf8");
93
- return;
111
+ await ensureParentDirectory(path);
112
+ try {
113
+ if (values.length === 0) {
114
+ await writeFile(path, "", "utf8");
115
+ return;
116
+ }
117
+ await writeFile(path, values.map((v) => JSON.stringify(v)).join("\n") + "\n", "utf8");
118
+ }
119
+ catch (error) {
120
+ throw ioError("write", path, error);
121
+ }
122
+ }
123
+ export async function readOptionalTextFile(path) {
124
+ try {
125
+ return await readFile(path, "utf8");
126
+ }
127
+ catch (error) {
128
+ if (isFileMissingError(error)) {
129
+ return undefined;
130
+ }
131
+ throw new Error(`Failed to read ${path}: ${errorMessage(error)}`);
132
+ }
133
+ }
134
+ export async function writeTextFile(path, value) {
135
+ await ensureParentDirectory(path);
136
+ try {
137
+ await writeFile(path, value, "utf8");
138
+ }
139
+ catch (error) {
140
+ throw ioError("write", path, error);
94
141
  }
95
- await writeFile(path, values.map((v) => JSON.stringify(v)).join("\n") + "\n", "utf8");
96
142
  }
@@ -9,7 +9,8 @@ export interface RunPaths {
9
9
  stderrPath: string;
10
10
  statusPath: string;
11
11
  }
12
- export declare function buildRunId(obligationId: string | null, index: number): string;
12
+ export declare function buildRunId(obligationId: string | null, index: number, now?: Date): string;
13
13
  export declare function getRunPaths(artifactsDir: string, runId: string): RunPaths;
14
14
  export declare function ensureSupervisorDirs(artifactsDir: string): Promise<void>;
15
15
  export declare function writeWorkerTaskFiles(task: WorkerTask, prompt: string, paths: RunPaths, artifactsDir: string, currentTasks?: AuditTask[]): Promise<void>;
16
+ export declare function clearDispatchFiles(artifactsDir: string): Promise<void>;
@@ -1,9 +1,36 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
1
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
3
4
  import { writeJsonFile } from "./json.js";
4
- export function buildRunId(obligationId, index) {
5
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
6
- const obligation = (obligationId ?? "terminal").replace(/[^a-zA-Z0-9_-]/g, "-");
5
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
6
+ const packageRoot = resolve(moduleDir, "..", "..");
7
+ const auditResultSchemaPath = join(packageRoot, "schemas", "audit_result.schema.json");
8
+ function pad(value, size = 2) {
9
+ return String(value).padStart(size, "0");
10
+ }
11
+ function formatRunTimestamp(value) {
12
+ return [
13
+ pad(value.getUTCFullYear(), 4),
14
+ pad(value.getUTCMonth() + 1),
15
+ pad(value.getUTCDate()),
16
+ "T",
17
+ pad(value.getUTCHours()),
18
+ pad(value.getUTCMinutes()),
19
+ pad(value.getUTCSeconds()),
20
+ pad(value.getUTCMilliseconds(), 3),
21
+ "Z",
22
+ ].join("");
23
+ }
24
+ function normalizeRunIdSegment(value) {
25
+ const normalized = (value ?? "terminal")
26
+ .trim()
27
+ .replace(/[^a-zA-Z0-9_-]+/g, "-")
28
+ .replace(/^-+|-+$/g, "");
29
+ return normalized.length > 0 ? normalized : "terminal";
30
+ }
31
+ export function buildRunId(obligationId, index, now = new Date()) {
32
+ const timestamp = formatRunTimestamp(now);
33
+ const obligation = normalizeRunIdSegment(obligationId);
7
34
  return `${timestamp}_${obligation}_${String(index).padStart(3, "0")}`;
8
35
  }
9
36
  export function getRunPaths(artifactsDir, runId) {
@@ -20,8 +47,6 @@ export function getRunPaths(artifactsDir, runId) {
20
47
  }
21
48
  export async function ensureSupervisorDirs(artifactsDir) {
22
49
  await mkdir(join(artifactsDir, "dispatch"), { recursive: true });
23
- await mkdir(join(artifactsDir, "worker-results"), { recursive: true });
24
- await mkdir(join(artifactsDir, "worker-logs"), { recursive: true });
25
50
  await mkdir(join(artifactsDir, "runs"), { recursive: true });
26
51
  }
27
52
  export async function writeWorkerTaskFiles(task, prompt, paths, artifactsDir, currentTasks) {
@@ -35,4 +60,16 @@ export async function writeWorkerTaskFiles(task, prompt, paths, artifactsDir, cu
35
60
  await writeJsonFile(join(artifactsDir, "dispatch", "current-task.json"), task);
36
61
  await writeFile(join(artifactsDir, "dispatch", "current-prompt.md"), prompt, "utf8");
37
62
  await writeJsonFile(join(artifactsDir, "dispatch", "current-tasks.json"), currentTasks ?? []);
63
+ await writeFile(join(artifactsDir, "dispatch", "audit-result.schema.json"), await readFile(auditResultSchemaPath, "utf8"), "utf8");
64
+ }
65
+ export async function clearDispatchFiles(artifactsDir) {
66
+ const targets = [
67
+ "current-task.json",
68
+ "current-prompt.md",
69
+ "current-tasks.json",
70
+ "audit-result.schema.json",
71
+ ];
72
+ for (const name of targets) {
73
+ await rm(join(artifactsDir, "dispatch", name), { force: true });
74
+ }
38
75
  }
@@ -0,0 +1 @@
1
+ export declare function runAuditCodeMcpServer(argv: string[]): Promise<void>;