auditor-lambda 0.1.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.
Files changed (199) hide show
  1. package/README.md +173 -0
  2. package/audit-code-wrapper-lib.mjs +905 -0
  3. package/audit-code.mjs +13 -0
  4. package/dist/adapters/coverageSummary.d.ts +8 -0
  5. package/dist/adapters/coverageSummary.js +13 -0
  6. package/dist/adapters/eslint.d.ts +13 -0
  7. package/dist/adapters/eslint.js +21 -0
  8. package/dist/adapters/normalizeExternal.d.ts +12 -0
  9. package/dist/adapters/normalizeExternal.js +19 -0
  10. package/dist/adapters/npmAudit.d.ts +15 -0
  11. package/dist/adapters/npmAudit.js +12 -0
  12. package/dist/adapters/semgrep.d.ts +22 -0
  13. package/dist/adapters/semgrep.js +14 -0
  14. package/dist/cli.d.ts +1 -0
  15. package/dist/cli.js +724 -0
  16. package/dist/coverage.d.ts +11 -0
  17. package/dist/coverage.js +102 -0
  18. package/dist/extractors/bucketing.d.ts +7 -0
  19. package/dist/extractors/bucketing.js +72 -0
  20. package/dist/extractors/disposition.d.ts +4 -0
  21. package/dist/extractors/disposition.js +41 -0
  22. package/dist/extractors/fileInventory.d.ts +7 -0
  23. package/dist/extractors/fileInventory.js +44 -0
  24. package/dist/extractors/flows.d.ts +5 -0
  25. package/dist/extractors/flows.js +125 -0
  26. package/dist/extractors/fsIntake.d.ts +8 -0
  27. package/dist/extractors/fsIntake.js +66 -0
  28. package/dist/extractors/graph.d.ts +4 -0
  29. package/dist/extractors/graph.js +46 -0
  30. package/dist/extractors/ignore.d.ts +1 -0
  31. package/dist/extractors/ignore.js +17 -0
  32. package/dist/extractors/risk.d.ts +5 -0
  33. package/dist/extractors/risk.js +45 -0
  34. package/dist/extractors/surfaces.d.ts +4 -0
  35. package/dist/extractors/surfaces.js +40 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +1 -0
  38. package/dist/io/artifacts.d.ts +38 -0
  39. package/dist/io/artifacts.js +100 -0
  40. package/dist/io/json.d.ts +8 -0
  41. package/dist/io/json.js +96 -0
  42. package/dist/io/runArtifacts.d.ts +14 -0
  43. package/dist/io/runArtifacts.js +37 -0
  44. package/dist/orchestrator/advance.d.ts +24 -0
  45. package/dist/orchestrator/advance.js +104 -0
  46. package/dist/orchestrator/artifactMetadata.d.ts +4 -0
  47. package/dist/orchestrator/artifactMetadata.js +111 -0
  48. package/dist/orchestrator/autoFixExecutor.d.ts +3 -0
  49. package/dist/orchestrator/autoFixExecutor.js +63 -0
  50. package/dist/orchestrator/chunking.d.ts +5 -0
  51. package/dist/orchestrator/chunking.js +13 -0
  52. package/dist/orchestrator/dependencyMap.d.ts +1 -0
  53. package/dist/orchestrator/dependencyMap.js +82 -0
  54. package/dist/orchestrator/executors.d.ts +6 -0
  55. package/dist/orchestrator/executors.js +52 -0
  56. package/dist/orchestrator/flowCoverage.d.ts +4 -0
  57. package/dist/orchestrator/flowCoverage.js +44 -0
  58. package/dist/orchestrator/flowPlanning.d.ts +3 -0
  59. package/dist/orchestrator/flowPlanning.js +42 -0
  60. package/dist/orchestrator/flowRequeue.d.ts +5 -0
  61. package/dist/orchestrator/flowRequeue.js +58 -0
  62. package/dist/orchestrator/internalExecutors.d.ts +16 -0
  63. package/dist/orchestrator/internalExecutors.js +212 -0
  64. package/dist/orchestrator/nextStep.d.ts +9 -0
  65. package/dist/orchestrator/nextStep.js +44 -0
  66. package/dist/orchestrator/planning.d.ts +4 -0
  67. package/dist/orchestrator/planning.js +62 -0
  68. package/dist/orchestrator/requeue.d.ts +3 -0
  69. package/dist/orchestrator/requeue.js +25 -0
  70. package/dist/orchestrator/requeueCommand.d.ts +10 -0
  71. package/dist/orchestrator/requeueCommand.js +27 -0
  72. package/dist/orchestrator/resultIngestion.d.ts +2 -0
  73. package/dist/orchestrator/resultIngestion.js +13 -0
  74. package/dist/orchestrator/runtimeValidation.d.ts +7 -0
  75. package/dist/orchestrator/runtimeValidation.js +103 -0
  76. package/dist/orchestrator/runtimeValidationUpdate.d.ts +2 -0
  77. package/dist/orchestrator/runtimeValidationUpdate.js +52 -0
  78. package/dist/orchestrator/staleness.d.ts +2 -0
  79. package/dist/orchestrator/staleness.js +83 -0
  80. package/dist/orchestrator/state.d.ts +3 -0
  81. package/dist/orchestrator/state.js +85 -0
  82. package/dist/orchestrator/syntaxResolutionExecutor.d.ts +3 -0
  83. package/dist/orchestrator/syntaxResolutionExecutor.js +99 -0
  84. package/dist/orchestrator/taskBuilder.d.ts +12 -0
  85. package/dist/orchestrator/taskBuilder.js +154 -0
  86. package/dist/orchestrator/unitBuilder.d.ts +3 -0
  87. package/dist/orchestrator/unitBuilder.js +145 -0
  88. package/dist/orchestrator.d.ts +6 -0
  89. package/dist/orchestrator.js +33 -0
  90. package/dist/prompts/renderWorkerPrompt.d.ts +2 -0
  91. package/dist/prompts/renderWorkerPrompt.js +19 -0
  92. package/dist/providers/claudeCodeProvider.d.ts +8 -0
  93. package/dist/providers/claudeCodeProvider.js +20 -0
  94. package/dist/providers/index.d.ts +7 -0
  95. package/dist/providers/index.js +77 -0
  96. package/dist/providers/localSubprocessProvider.d.ts +5 -0
  97. package/dist/providers/localSubprocessProvider.js +13 -0
  98. package/dist/providers/opencodeProvider.d.ts +8 -0
  99. package/dist/providers/opencodeProvider.js +15 -0
  100. package/dist/providers/spawnLoggedCommand.d.ts +2 -0
  101. package/dist/providers/spawnLoggedCommand.js +48 -0
  102. package/dist/providers/subprocessTemplateProvider.d.ts +8 -0
  103. package/dist/providers/subprocessTemplateProvider.js +41 -0
  104. package/dist/providers/types.d.ts +22 -0
  105. package/dist/providers/types.js +1 -0
  106. package/dist/providers/vscodeTaskProvider.d.ts +8 -0
  107. package/dist/providers/vscodeTaskProvider.js +14 -0
  108. package/dist/reporting/mergeFindings.d.ts +4 -0
  109. package/dist/reporting/mergeFindings.js +136 -0
  110. package/dist/reporting/rootCause.d.ts +11 -0
  111. package/dist/reporting/rootCause.js +69 -0
  112. package/dist/reporting/synthesis.d.ts +21 -0
  113. package/dist/reporting/synthesis.js +55 -0
  114. package/dist/supervisor/operatorHandoff.d.ts +37 -0
  115. package/dist/supervisor/operatorHandoff.js +144 -0
  116. package/dist/supervisor/runLedger.d.ts +3 -0
  117. package/dist/supervisor/runLedger.js +17 -0
  118. package/dist/supervisor/sessionConfig.d.ts +4 -0
  119. package/dist/supervisor/sessionConfig.js +26 -0
  120. package/dist/types/artifactMetadata.d.ts +8 -0
  121. package/dist/types/artifactMetadata.js +1 -0
  122. package/dist/types/auditState.d.ts +14 -0
  123. package/dist/types/auditState.js +1 -0
  124. package/dist/types/disposition.d.ts +9 -0
  125. package/dist/types/disposition.js +1 -0
  126. package/dist/types/externalAnalyzer.d.ts +16 -0
  127. package/dist/types/externalAnalyzer.js +1 -0
  128. package/dist/types/flowCoverage.d.ts +11 -0
  129. package/dist/types/flowCoverage.js +1 -0
  130. package/dist/types/flows.d.ts +11 -0
  131. package/dist/types/flows.js +1 -0
  132. package/dist/types/graph.d.ts +18 -0
  133. package/dist/types/graph.js +1 -0
  134. package/dist/types/risk.d.ts +9 -0
  135. package/dist/types/risk.js +1 -0
  136. package/dist/types/runLedger.d.ts +13 -0
  137. package/dist/types/runLedger.js +1 -0
  138. package/dist/types/runtimeValidation.d.ts +22 -0
  139. package/dist/types/runtimeValidation.js +1 -0
  140. package/dist/types/sessionConfig.d.ts +27 -0
  141. package/dist/types/sessionConfig.js +1 -0
  142. package/dist/types/surfaces.d.ts +11 -0
  143. package/dist/types/surfaces.js +1 -0
  144. package/dist/types/workerResult.d.ts +13 -0
  145. package/dist/types/workerResult.js +1 -0
  146. package/dist/types/workerSession.d.ts +13 -0
  147. package/dist/types/workerSession.js +1 -0
  148. package/dist/types.d.ts +104 -0
  149. package/dist/types.js +1 -0
  150. package/dist/validation/artifacts.d.ts +3 -0
  151. package/dist/validation/artifacts.js +191 -0
  152. package/dist/validation/basic.d.ts +5 -0
  153. package/dist/validation/basic.js +9 -0
  154. package/dist/validation/sessionConfig.d.ts +6 -0
  155. package/dist/validation/sessionConfig.js +139 -0
  156. package/docs/agent-integrations.md +237 -0
  157. package/docs/agent-roles.md +69 -0
  158. package/docs/architecture.md +90 -0
  159. package/docs/artifacts.md +69 -0
  160. package/docs/bootstrap-install.md +79 -0
  161. package/docs/contract.md +140 -0
  162. package/docs/github-copilot.md +50 -0
  163. package/docs/model-selection.md +86 -0
  164. package/docs/next-steps.md +161 -0
  165. package/docs/packaging.md +88 -0
  166. package/docs/pipeline.md +152 -0
  167. package/docs/product-direction.md +111 -0
  168. package/docs/production-launch-bar.md +83 -0
  169. package/docs/production-readiness.md +52 -0
  170. package/docs/repo-layout.md +30 -0
  171. package/docs/run-flow.md +49 -0
  172. package/docs/session-config.md +232 -0
  173. package/docs/supervisor.md +83 -0
  174. package/docs/usage.md +172 -0
  175. package/docs/windows-setup.md +146 -0
  176. package/package.json +56 -0
  177. package/schemas/audit-code-v1alpha1.schema.json +191 -0
  178. package/schemas/audit_result.schema.json +48 -0
  179. package/schemas/audit_state.schema.json +36 -0
  180. package/schemas/audit_task.schema.json +49 -0
  181. package/schemas/blind_spot_register.schema.json +40 -0
  182. package/schemas/coverage_matrix.schema.json +50 -0
  183. package/schemas/critical_flows.schema.json +38 -0
  184. package/schemas/external_analyzer_results.schema.json +31 -0
  185. package/schemas/file_disposition.schema.json +33 -0
  186. package/schemas/finding.schema.json +62 -0
  187. package/schemas/flow_coverage.schema.json +44 -0
  188. package/schemas/graph_bundle.schema.json +55 -0
  189. package/schemas/merged_findings.schema.json +14 -0
  190. package/schemas/repo_manifest.schema.json +37 -0
  191. package/schemas/risk_register.schema.json +30 -0
  192. package/schemas/root_cause_clusters.schema.json +31 -0
  193. package/schemas/runtime_validation_report.schema.json +34 -0
  194. package/schemas/runtime_validation_tasks.schema.json +36 -0
  195. package/schemas/surface_manifest.schema.json +32 -0
  196. package/schemas/synthesis_report.schema.json +61 -0
  197. package/schemas/unit_manifest.schema.json +36 -0
  198. package/skills/audit-code/SKILL.md +54 -0
  199. package/skills/audit-code/audit-code.prompt.md +66 -0
@@ -0,0 +1,62 @@
1
+ import { applyUnitCoverage, createCoverageMatrix, markExcludedPath, } from "../coverage.js";
2
+ import { isAuditExcludedStatus } from "../extractors/disposition.js";
3
+ function analyzerCategoryToLenses(category) {
4
+ const normalized = category.toLowerCase();
5
+ if (normalized.includes("security") || normalized.includes("secret")) {
6
+ return ["security", "correctness"];
7
+ }
8
+ if (normalized.includes("dependency") || normalized.includes("vuln")) {
9
+ return ["security", "config_deployment"];
10
+ }
11
+ if (normalized.includes("tests") || normalized.includes("coverage")) {
12
+ return ["tests"];
13
+ }
14
+ if (normalized.includes("data")) {
15
+ return ["data_integrity", "correctness"];
16
+ }
17
+ if (normalized.includes("reliability") ||
18
+ normalized.includes("concurrency")) {
19
+ return ["reliability", "correctness"];
20
+ }
21
+ if (normalized.includes("maintainability") ||
22
+ normalized.includes("lint") ||
23
+ normalized.includes("style")) {
24
+ return ["maintainability"];
25
+ }
26
+ return ["correctness"];
27
+ }
28
+ function applyAnalyzerCoverage(coverage, externalAnalyzerResults) {
29
+ if (!externalAnalyzerResults) {
30
+ return;
31
+ }
32
+ for (const result of externalAnalyzerResults.results) {
33
+ const record = coverage.files.find((file) => file.path === result.path);
34
+ if (!record || record.audit_status === "excluded") {
35
+ continue;
36
+ }
37
+ const extraLenses = analyzerCategoryToLenses(result.category);
38
+ record.required_lenses = [
39
+ ...new Set([...record.required_lenses, ...extraLenses]),
40
+ ];
41
+ if (record.classification_status === "unclassified") {
42
+ record.classification_status = "classified";
43
+ }
44
+ }
45
+ }
46
+ export function initializeCoverageFromPlan(repoManifest, unitManifest, disposition, externalAnalyzerResults) {
47
+ const coverage = createCoverageMatrix(repoManifest.files.map((file) => file.path));
48
+ const dispositionMap = new Map(disposition.files.map((item) => [item.path, item.status]));
49
+ for (const file of repoManifest.files) {
50
+ const status = dispositionMap.get(file.path);
51
+ if (status && isAuditExcludedStatus(status)) {
52
+ markExcludedPath(coverage, file.path, status);
53
+ }
54
+ }
55
+ for (const unit of unitManifest.units) {
56
+ for (const path of unit.files) {
57
+ applyUnitCoverage(coverage, path, unit.unit_id, unit.required_lenses);
58
+ }
59
+ }
60
+ applyAnalyzerCoverage(coverage, externalAnalyzerResults);
61
+ return coverage;
62
+ }
@@ -0,0 +1,3 @@
1
+ import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
2
+ import type { AuditTask, CoverageMatrix } from "../types.js";
3
+ export declare function buildRequeueTasks(matrix: CoverageMatrix, externalAnalyzerResults?: ExternalAnalyzerResults): AuditTask[];
@@ -0,0 +1,25 @@
1
+ import { buildRequeueTargets } from "../coverage.js";
2
+ function taskPriority(hasExternalSignal) {
3
+ return hasExternalSignal ? "high" : "medium";
4
+ }
5
+ export function buildRequeueTasks(matrix, externalAnalyzerResults) {
6
+ const targets = buildRequeueTargets(matrix);
7
+ const tasks = [];
8
+ const externalPaths = new Set((externalAnalyzerResults?.results ?? []).map((item) => item.path));
9
+ for (const target of targets) {
10
+ for (const lens of target.missing_lenses) {
11
+ const hasExternalSignal = externalPaths.has(target.path);
12
+ tasks.push({
13
+ task_id: `requeue:${lens}:${target.path}`,
14
+ unit_id: `requeue:${target.path}`,
15
+ pass_id: `requeue:${lens}`,
16
+ lens,
17
+ file_paths: [target.path],
18
+ rationale: `Requeue ${target.path} because the ${lens} lens is still missing.${hasExternalSignal ? " External analyzer signals make this follow-up higher priority." : ""}`,
19
+ priority: taskPriority(hasExternalSignal),
20
+ tags: hasExternalSignal ? ["external_analyzer_signal"] : [],
21
+ });
22
+ }
23
+ }
24
+ return tasks;
25
+ }
@@ -0,0 +1,10 @@
1
+ import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
2
+ import type { CoverageMatrix } from "../types.js";
3
+ import type { FlowCoverageManifest } from "../types/flowCoverage.js";
4
+ import type { CriticalFlowManifest } from "../types/flows.js";
5
+ export declare function buildRequeuePayload(matrix: CoverageMatrix, criticalFlows?: CriticalFlowManifest, flowCoverage?: FlowCoverageManifest, externalAnalyzerResults?: ExternalAnalyzerResults): {
6
+ task_count: number;
7
+ file_task_count: number;
8
+ flow_task_count: number;
9
+ tasks: import("../types.js").AuditTask[];
10
+ };
@@ -0,0 +1,27 @@
1
+ import { buildRequeueTasks } from "./requeue.js";
2
+ import { buildFlowRequeueTasks } from "./flowRequeue.js";
3
+ function dedupeTasks(tasks) {
4
+ const seen = new Set();
5
+ const deduped = [];
6
+ for (const task of tasks) {
7
+ if (seen.has(task.task_id)) {
8
+ continue;
9
+ }
10
+ seen.add(task.task_id);
11
+ deduped.push(task);
12
+ }
13
+ return deduped;
14
+ }
15
+ export function buildRequeuePayload(matrix, criticalFlows, flowCoverage, externalAnalyzerResults) {
16
+ const fileTasks = dedupeTasks(buildRequeueTasks(matrix, externalAnalyzerResults));
17
+ const flowTasks = criticalFlows && flowCoverage
18
+ ? dedupeTasks(buildFlowRequeueTasks(criticalFlows, flowCoverage, externalAnalyzerResults))
19
+ : [];
20
+ const tasks = dedupeTasks([...fileTasks, ...flowTasks]);
21
+ return {
22
+ task_count: tasks.length,
23
+ file_task_count: fileTasks.length,
24
+ flow_task_count: flowTasks.length,
25
+ tasks,
26
+ };
27
+ }
@@ -0,0 +1,2 @@
1
+ import type { AuditResult, CoverageMatrix } from "../types.js";
2
+ export declare function ingestAuditResults(coverageMatrix: CoverageMatrix, results: AuditResult[]): CoverageMatrix;
@@ -0,0 +1,13 @@
1
+ import { applyReviewedRanges } from "../coverage.js";
2
+ export function ingestAuditResults(coverageMatrix, results) {
3
+ const reviewedRanges = results.flatMap((result) => result.reviewed_ranges.map((range) => ({
4
+ path: range.path,
5
+ start: range.start,
6
+ end: range.end,
7
+ pass_id: result.pass_id,
8
+ lens: result.lens,
9
+ agent_role: result.agent_role,
10
+ })));
11
+ applyReviewedRanges(coverageMatrix, reviewedRanges);
12
+ return coverageMatrix;
13
+ }
@@ -0,0 +1,7 @@
1
+ import type { UnitManifest } from "../types.js";
2
+ import type { FlowCoverageManifest } from "../types/flowCoverage.js";
3
+ import type { CriticalFlowManifest } from "../types/flows.js";
4
+ import type { RuntimeValidationReport, RuntimeValidationTaskManifest } from "../types/runtimeValidation.js";
5
+ export declare function buildRuntimeValidationTasks(unitManifest: UnitManifest, criticalFlows?: CriticalFlowManifest, flowCoverage?: FlowCoverageManifest): RuntimeValidationTaskManifest;
6
+ export declare function buildPlaceholderRuntimeValidationReport(tasks: RuntimeValidationTaskManifest): RuntimeValidationReport;
7
+ export declare function mergeRuntimeValidationReport(tasks: RuntimeValidationTaskManifest, existing?: RuntimeValidationReport): RuntimeValidationReport;
@@ -0,0 +1,103 @@
1
+ function checksForFlow(requiredLenses) {
2
+ const checks = [];
3
+ if (requiredLenses.includes("security")) {
4
+ checks.push("Exercise malformed or unauthorized inputs against the flow.");
5
+ }
6
+ if (requiredLenses.includes("reliability")) {
7
+ checks.push("Exercise retries, repeated submissions, or partial failure behavior.");
8
+ }
9
+ if (requiredLenses.includes("correctness")) {
10
+ checks.push("Exercise representative success and edge-case paths end to end.");
11
+ }
12
+ if (requiredLenses.includes("data_integrity")) {
13
+ checks.push("Verify state transitions and persistence invariants after execution.");
14
+ }
15
+ return checks;
16
+ }
17
+ export function buildRuntimeValidationTasks(unitManifest, criticalFlows, flowCoverage) {
18
+ const tasks = [];
19
+ const seen = new Set();
20
+ const highRiskUnits = unitManifest.units.filter((unit) => (unit.risk_score ?? 0) >= 5 ||
21
+ unit.required_lenses.includes("security") ||
22
+ unit.required_lenses.includes("data_integrity"));
23
+ for (const unit of highRiskUnits) {
24
+ const id = `runtime:unit:${unit.unit_id}`;
25
+ if (seen.has(id))
26
+ continue;
27
+ seen.add(id);
28
+ tasks.push({
29
+ id,
30
+ kind: "unit-risk-check",
31
+ target_paths: unit.files,
32
+ reason: `Unit ${unit.unit_id} is high risk or touches sensitive concerns.`,
33
+ priority: (unit.risk_score ?? 0) >= 7 ? "high" : "medium",
34
+ suggested_checks: [
35
+ "Run representative happy-path execution.",
36
+ "Run malformed-input or failure-path execution where feasible.",
37
+ ],
38
+ source_artifacts: ["unit_manifest.json", "risk_register.json"],
39
+ });
40
+ }
41
+ if (criticalFlows && flowCoverage) {
42
+ const flowMap = new Map(criticalFlows.flows.map((flow) => [flow.id, flow]));
43
+ for (const record of flowCoverage.flows) {
44
+ if (record.status === "complete") {
45
+ continue;
46
+ }
47
+ const flow = flowMap.get(record.flow_id);
48
+ if (!flow) {
49
+ continue;
50
+ }
51
+ const id = `runtime:flow:${record.flow_id}`;
52
+ if (seen.has(id))
53
+ continue;
54
+ seen.add(id);
55
+ tasks.push({
56
+ id,
57
+ kind: "critical-flow-check",
58
+ target_paths: flow.paths,
59
+ reason: `Critical flow ${record.flow_id} is still ${record.status} and should receive runtime validation.`,
60
+ priority: record.status === "pending" ? "high" : "medium",
61
+ suggested_checks: checksForFlow(record.required_lenses),
62
+ source_artifacts: ["critical_flows.json", "flow_coverage.json"],
63
+ });
64
+ }
65
+ }
66
+ return { tasks };
67
+ }
68
+ export function buildPlaceholderRuntimeValidationReport(tasks) {
69
+ return {
70
+ results: tasks.tasks.map((task) => ({
71
+ task_id: task.id,
72
+ status: "pending",
73
+ summary: `No runtime evidence recorded yet for ${task.id}.`,
74
+ evidence: [],
75
+ notes: ["Placeholder entry generated from runtime validation task list."],
76
+ })),
77
+ };
78
+ }
79
+ export function mergeRuntimeValidationReport(tasks, existing) {
80
+ const existingMap = new Map((existing?.results ?? []).map((result) => [result.task_id, result]));
81
+ const mergedResults = tasks.tasks.map((task) => {
82
+ const prior = existingMap.get(task.id);
83
+ if (prior) {
84
+ return {
85
+ ...prior,
86
+ notes: [
87
+ ...new Set([
88
+ ...(prior.notes ?? []),
89
+ "Preserved across runtime validation refresh.",
90
+ ]),
91
+ ],
92
+ };
93
+ }
94
+ return {
95
+ task_id: task.id,
96
+ status: "pending",
97
+ summary: `No runtime evidence recorded yet for ${task.id}.`,
98
+ evidence: [],
99
+ notes: ["Placeholder entry generated from runtime validation task list."],
100
+ };
101
+ });
102
+ return { results: mergedResults };
103
+ }
@@ -0,0 +1,2 @@
1
+ import type { RuntimeValidationReport, RuntimeValidationTaskManifest } from "../types/runtimeValidation.js";
2
+ export declare function updateRuntimeValidationReport(tasks: RuntimeValidationTaskManifest, existing: RuntimeValidationReport, updates: RuntimeValidationReport): RuntimeValidationReport;
@@ -0,0 +1,52 @@
1
+ function normalizeResult(result) {
2
+ return {
3
+ ...result,
4
+ evidence: [...new Set(result.evidence ?? [])],
5
+ notes: [...new Set(result.notes ?? [])],
6
+ };
7
+ }
8
+ export function updateRuntimeValidationReport(tasks, existing, updates) {
9
+ const validTaskIds = new Set(tasks.tasks.map((task) => task.id));
10
+ const merged = new Map();
11
+ for (const result of existing.results) {
12
+ if (!validTaskIds.has(result.task_id)) {
13
+ continue;
14
+ }
15
+ merged.set(result.task_id, normalizeResult(result));
16
+ }
17
+ for (const update of updates.results) {
18
+ if (!validTaskIds.has(update.task_id)) {
19
+ continue;
20
+ }
21
+ const prior = merged.get(update.task_id);
22
+ if (!prior) {
23
+ merged.set(update.task_id, normalizeResult(update));
24
+ continue;
25
+ }
26
+ merged.set(update.task_id, {
27
+ task_id: update.task_id,
28
+ status: update.status,
29
+ summary: update.summary,
30
+ evidence: [
31
+ ...new Set([...(prior.evidence ?? []), ...(update.evidence ?? [])]),
32
+ ],
33
+ notes: [...new Set([...(prior.notes ?? []), ...(update.notes ?? [])])],
34
+ });
35
+ }
36
+ for (const task of tasks.tasks) {
37
+ if (!merged.has(task.id)) {
38
+ merged.set(task.id, {
39
+ task_id: task.id,
40
+ status: "pending",
41
+ summary: `No runtime evidence recorded yet for ${task.id}.`,
42
+ evidence: [],
43
+ notes: [
44
+ "Placeholder entry generated from runtime validation task list.",
45
+ ],
46
+ });
47
+ }
48
+ }
49
+ return {
50
+ results: [...merged.values()].sort((a, b) => a.task_id.localeCompare(b.task_id)),
51
+ };
52
+ }
@@ -0,0 +1,2 @@
1
+ import type { ArtifactBundle } from "../io/artifacts.js";
2
+ export declare function computeStaleArtifacts(bundle: ArtifactBundle): Set<string>;
@@ -0,0 +1,83 @@
1
+ import { createHash } from "node:crypto";
2
+ import { getArtifactValue } from "../io/artifacts.js";
3
+ import { ARTIFACT_DEPENDENCY_MAP } from "./dependencyMap.js";
4
+ import { present } from "./artifactMetadata.js";
5
+ function stableStringify(value) {
6
+ if (value === undefined)
7
+ return "null";
8
+ if (value === null || typeof value !== "object")
9
+ return JSON.stringify(value);
10
+ if (Array.isArray(value))
11
+ return `[${value.map((item) => stableStringify(item ?? null)).join(",")}]`;
12
+ const entries = Object.entries(value)
13
+ .filter(([, item]) => item !== undefined)
14
+ .sort(([a], [b]) => a.localeCompare(b));
15
+ return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
16
+ }
17
+ function normalizeForMetadataHash(artifactName, value) {
18
+ if (artifactName === "repo_manifest.json" &&
19
+ value &&
20
+ typeof value === "object" &&
21
+ !Array.isArray(value)) {
22
+ const record = value;
23
+ const { generated_at: _generatedAt, ...rest } = record;
24
+ return rest;
25
+ }
26
+ return value;
27
+ }
28
+ function computeContentHash(artifactName, bundle) {
29
+ const value = getArtifactValue(bundle, artifactName);
30
+ if (value === undefined || value === null)
31
+ return undefined;
32
+ return createHash("sha256")
33
+ .update(stableStringify(normalizeForMetadataHash(artifactName, value)))
34
+ .digest("hex");
35
+ }
36
+ export function computeStaleArtifacts(bundle) {
37
+ const stale = new Set();
38
+ const metadata = bundle.artifact_metadata;
39
+ if (metadata) {
40
+ for (const [artifactName, entry] of Object.entries(metadata.artifacts)) {
41
+ if (!present(bundle, artifactName))
42
+ continue;
43
+ let isStale = false;
44
+ for (const [dependencyName, recordedRevision] of Object.entries(entry.dependency_revisions)) {
45
+ if (!present(bundle, dependencyName)) {
46
+ if (recordedRevision > 0) {
47
+ isStale = true;
48
+ break;
49
+ }
50
+ continue;
51
+ }
52
+ const dependencyEntry = metadata.artifacts[dependencyName];
53
+ if (!dependencyEntry) {
54
+ if (recordedRevision > 0) {
55
+ isStale = true;
56
+ break;
57
+ }
58
+ continue;
59
+ }
60
+ const currentHash = computeContentHash(dependencyName, bundle);
61
+ if (!currentHash ||
62
+ dependencyEntry.content_hash !== currentHash ||
63
+ dependencyEntry.revision !== recordedRevision) {
64
+ isStale = true;
65
+ break;
66
+ }
67
+ }
68
+ if (isStale)
69
+ stale.add(artifactName);
70
+ }
71
+ }
72
+ for (const [upstream, downstreamList] of Object.entries(ARTIFACT_DEPENDENCY_MAP)) {
73
+ if (!present(bundle, upstream)) {
74
+ for (const downstream of downstreamList) {
75
+ const hasMetadataEntry = Boolean(metadata?.artifacts[downstream]);
76
+ if (present(bundle, downstream) && (!metadata || !hasMetadataEntry)) {
77
+ stale.add(downstream);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ return stale;
83
+ }
@@ -0,0 +1,3 @@
1
+ import type { ArtifactBundle } from "../io/artifacts.js";
2
+ import type { AuditState } from "../types/auditState.js";
3
+ export declare function deriveAuditState(bundle: ArtifactBundle): AuditState;
@@ -0,0 +1,85 @@
1
+ import { computeStaleArtifacts } from "./staleness.js";
2
+ function has(value) {
3
+ return value !== undefined && value !== null;
4
+ }
5
+ function obligation(id, state, reason) {
6
+ return { id, state, reason };
7
+ }
8
+ function staleOrSatisfied(staleArtifacts, deps, present) {
9
+ if (!present)
10
+ return "missing";
11
+ return deps.some((dep) => staleArtifacts.has(dep)) ? "stale" : "satisfied";
12
+ }
13
+ export function deriveAuditState(bundle) {
14
+ const obligations = [];
15
+ const staleArtifacts = computeStaleArtifacts(bundle);
16
+ obligations.push(obligation("repo_manifest", has(bundle.repo_manifest) ? "satisfied" : "missing"));
17
+ obligations.push(obligation("file_disposition", staleOrSatisfied(staleArtifacts, ["file_disposition.json"], has(bundle.file_disposition))));
18
+ obligations.push(obligation("auto_fixes_applied", staleOrSatisfied(staleArtifacts, ["file_disposition.json"], has(bundle.auto_fixes_applied))));
19
+ obligations.push(obligation("syntax_resolved", staleOrSatisfied(staleArtifacts, ["auto_fixes_applied.json"], has(bundle.external_analyzer_results))));
20
+ const structureReady = has(bundle.unit_manifest) &&
21
+ has(bundle.surface_manifest) &&
22
+ has(bundle.graph_bundle) &&
23
+ has(bundle.critical_flows) &&
24
+ has(bundle.risk_register);
25
+ obligations.push(obligation("structure_artifacts", staleOrSatisfied(staleArtifacts, [
26
+ "unit_manifest.json",
27
+ "surface_manifest.json",
28
+ "graph_bundle.json",
29
+ "critical_flows.json",
30
+ "risk_register.json",
31
+ ], structureReady)));
32
+ const planningReady = has(bundle.coverage_matrix) &&
33
+ has(bundle.flow_coverage) &&
34
+ has(bundle.runtime_validation_tasks) &&
35
+ has(bundle.audit_tasks) &&
36
+ has(bundle.requeue_tasks);
37
+ obligations.push(obligation("planning_artifacts", staleOrSatisfied(staleArtifacts, [
38
+ "external_analyzer_results.json",
39
+ "coverage_matrix.json",
40
+ "flow_coverage.json",
41
+ "runtime_validation_tasks.json",
42
+ "audit_tasks.json",
43
+ "requeue_tasks.json",
44
+ ], planningReady)));
45
+ const hasRequiredCoverage = bundle.coverage_matrix?.files.every((f) => f.required_lenses.every((req) => f.completed_lenses.includes(req))) ?? true;
46
+ if (!hasRequiredCoverage &&
47
+ has(bundle.audit_tasks) &&
48
+ (bundle.audit_tasks?.length ?? 0) > 0) {
49
+ obligations.push(obligation("audit_tasks_completed", "missing"));
50
+ }
51
+ else if (hasRequiredCoverage && has(bundle.audit_tasks)) {
52
+ obligations.push(obligation("audit_tasks_completed", "satisfied"));
53
+ }
54
+ obligations.push(obligation("audit_results_ingested", has(bundle.audit_results) ? "present" : "missing"));
55
+ obligations.push(obligation("runtime_validation_current", staleOrSatisfied(staleArtifacts, ["runtime_validation_report.json"], has(bundle.runtime_validation_report))));
56
+ obligations.push(obligation("synthesis_current", staleOrSatisfied(staleArtifacts, [
57
+ "merged_findings.json",
58
+ "root_cause_clusters.json",
59
+ "synthesis_report.json",
60
+ ], has(bundle.merged_findings) &&
61
+ has(bundle.root_cause_clusters) &&
62
+ has(bundle.synthesis_report))));
63
+ let status = "not_started";
64
+ if (!has(bundle.repo_manifest)) {
65
+ status = "not_started";
66
+ }
67
+ else if (obligations.some((o) => o.state === "blocked")) {
68
+ status = "blocked";
69
+ }
70
+ else {
71
+ status = "active";
72
+ }
73
+ const incomplete = obligations.some((o) => o.state === "missing" || o.state === "stale");
74
+ if (!incomplete &&
75
+ has(bundle.synthesis_report) &&
76
+ has(bundle.merged_findings) &&
77
+ has(bundle.root_cause_clusters)) {
78
+ status = "complete";
79
+ }
80
+ return {
81
+ status,
82
+ blockers: [],
83
+ obligations,
84
+ };
85
+ }
@@ -0,0 +1,3 @@
1
+ import type { ArtifactBundle } from "../io/artifacts.js";
2
+ import type { ExecutorRunResult } from "./internalExecutors.js";
3
+ export declare function runSyntaxResolutionExecutor(bundle: ArtifactBundle, root: string): ExecutorRunResult;
@@ -0,0 +1,99 @@
1
+ import { execSync } from "node:child_process";
2
+ function runTsc(root) {
3
+ const results = [];
4
+ try {
5
+ execSync("npx tsc --noEmit", {
6
+ cwd: root,
7
+ stdio: "pipe",
8
+ windowsHide: true,
9
+ });
10
+ }
11
+ catch (error) {
12
+ if (error.stdout) {
13
+ const output = error.stdout.toString();
14
+ const lines = output.split("\n");
15
+ for (const line of lines) {
16
+ const match = line.match(/^([^:]+)\((\d+),\d+\):\s+(error\s+TS\d+:.*)$/);
17
+ if (match) {
18
+ results.push({
19
+ id: `tsc-${results.length}`,
20
+ category: "correctness",
21
+ severity: "error",
22
+ path: match[1].replace(/\\/g, "/"),
23
+ summary: match[3],
24
+ rule: "tsc",
25
+ });
26
+ }
27
+ }
28
+ }
29
+ }
30
+ return results;
31
+ }
32
+ function runEslint(root) {
33
+ const results = [];
34
+ try {
35
+ execSync("npx eslint . --ext .ts,.js,.tsx,.jsx --format json", {
36
+ cwd: root,
37
+ stdio: "pipe",
38
+ windowsHide: true,
39
+ });
40
+ }
41
+ catch (error) {
42
+ if (error.stdout) {
43
+ try {
44
+ const output = JSON.parse(error.stdout.toString());
45
+ for (const fileResult of output) {
46
+ for (const msg of fileResult.messages) {
47
+ results.push({
48
+ id: `eslint-${results.length}`,
49
+ category: "maintainability",
50
+ severity: msg.severity === 2 ? "error" : "warning",
51
+ path: fileResult.filePath
52
+ .replace(/\\/g, "/")
53
+ .replace(root.replace(/\\/g, "/") + "/", ""),
54
+ summary: msg.message,
55
+ rule: msg.ruleId || "eslint-error",
56
+ });
57
+ }
58
+ }
59
+ }
60
+ catch (e) {
61
+ // failed to parse
62
+ }
63
+ }
64
+ }
65
+ return results;
66
+ }
67
+ export function runSyntaxResolutionExecutor(bundle, root) {
68
+ const items = [];
69
+ if (bundle.file_disposition?.files.some((f) => f.path.endsWith(".ts"))) {
70
+ items.push(...runTsc(root));
71
+ }
72
+ if (bundle.file_disposition?.files.some((f) => f.path.endsWith(".ts") || f.path.endsWith(".js"))) {
73
+ items.push(...runEslint(root));
74
+ }
75
+ const existing = bundle.external_analyzer_results?.results ?? [];
76
+ const merged = [...existing, ...items];
77
+ // Deduplicate by path + rule + summary
78
+ const seen = new Set();
79
+ const deduped = [];
80
+ for (const r of merged) {
81
+ const key = `${r.path}:${r.rule}:${r.summary}`;
82
+ if (!seen.has(key)) {
83
+ seen.add(key);
84
+ deduped.push(r);
85
+ }
86
+ }
87
+ const resultsArtifact = {
88
+ tool: "syntax_resolution_executor",
89
+ results: deduped,
90
+ };
91
+ return {
92
+ updated: {
93
+ ...bundle,
94
+ external_analyzer_results: resultsArtifact,
95
+ },
96
+ artifacts_written: ["external_analyzer_results.json"],
97
+ progress_summary: `Phase 2 Syntax Resolution complete. Extracted ${items.length} unfixable syntax/lint errors, triggering high-priority LLM resolution tasks.`,
98
+ };
99
+ }
@@ -0,0 +1,12 @@
1
+ import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
2
+ import type { AuditTask, CoverageMatrix, Lens, UnitManifest } from "../types.js";
3
+ export interface UnitLineIndex {
4
+ [path: string]: number;
5
+ }
6
+ export interface BuildChunkedTaskOptions {
7
+ chunk_size?: number;
8
+ limit_lenses?: Lens[];
9
+ external_analyzer_results?: ExternalAnalyzerResults;
10
+ }
11
+ export declare function buildChunkedAuditTasks(unitManifest: UnitManifest, unitLineIndex: UnitLineIndex, options?: BuildChunkedTaskOptions): AuditTask[];
12
+ export declare function buildExternalSignalTasks(coverageMatrix: CoverageMatrix, unitLineIndex: UnitLineIndex, externalAnalyzerResults?: ExternalAnalyzerResults): AuditTask[];