auditor-lambda 0.6.12 → 0.8.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 (56) hide show
  1. package/README.md +0 -21
  2. package/audit-code-wrapper-lib.mjs +44 -1
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.js +8 -0
  5. package/dist/cli/auditStep.js +7 -1
  6. package/dist/cli/dispatch.js +14 -3
  7. package/dist/cli/nextStepCommand.js +37 -0
  8. package/dist/cli/prompts.js +2 -0
  9. package/dist/cli.d.ts +0 -1
  10. package/dist/cli.js +22 -15
  11. package/dist/extractors/fileInventory.js +15 -2
  12. package/dist/extractors/graph.js +12 -2
  13. package/dist/io/artifacts.d.ts +3 -1
  14. package/dist/io/artifacts.js +18 -2
  15. package/dist/orchestrator/advance.js +2 -1
  16. package/dist/orchestrator/artifactFreshness.js +12 -2
  17. package/dist/orchestrator/artifactMetadata.d.ts +1 -0
  18. package/dist/orchestrator/artifactMetadata.js +15 -0
  19. package/dist/orchestrator/autoFixExecutor.d.ts +1 -1
  20. package/dist/orchestrator/autoFixExecutor.js +10 -0
  21. package/dist/orchestrator/executorResult.d.ts +12 -0
  22. package/dist/orchestrator/executorResult.js +1 -0
  23. package/dist/orchestrator/fileIntegrity.d.ts +1 -0
  24. package/dist/orchestrator/fileIntegrity.js +12 -3
  25. package/dist/orchestrator/flowRequeue.js +1 -14
  26. package/dist/orchestrator/graphEnrichmentExecutor.d.ts +1 -1
  27. package/dist/orchestrator/graphEnrichmentExecutor.js +3 -1
  28. package/dist/orchestrator/internalExecutors.d.ts +1 -18
  29. package/dist/orchestrator/internalExecutors.js +1 -158
  30. package/dist/orchestrator/reviewPacketGraph.d.ts +31 -0
  31. package/dist/orchestrator/reviewPacketGraph.js +691 -0
  32. package/dist/orchestrator/reviewPacketSizing.d.ts +25 -0
  33. package/dist/orchestrator/reviewPacketSizing.js +60 -0
  34. package/dist/orchestrator/reviewPackets.d.ts +3 -28
  35. package/dist/orchestrator/reviewPackets.js +6 -740
  36. package/dist/orchestrator/runtimeCommand.d.ts +11 -0
  37. package/dist/orchestrator/runtimeCommand.js +79 -0
  38. package/dist/orchestrator/scope.js +1 -1
  39. package/dist/orchestrator/syntaxResolutionExecutor.d.ts +1 -1
  40. package/dist/orchestrator/synthesisExecutors.d.ts +12 -0
  41. package/dist/orchestrator/synthesisExecutors.js +90 -0
  42. package/dist/orchestrator.js +1 -4
  43. package/dist/quota/index.d.ts +1 -1
  44. package/dist/quota/index.js +1 -1
  45. package/dist/types/workerSession.d.ts +1 -3
  46. package/dist/types.d.ts +6 -0
  47. package/dist/types.js +20 -1
  48. package/docs/development.md +35 -139
  49. package/docs/history.md +26 -0
  50. package/docs/product.md +41 -108
  51. package/package.json +1 -1
  52. package/schemas/audit_findings.schema.json +3 -2
  53. package/schemas/dispatch_quota.schema.json +2 -0
  54. package/schemas/external_analyzer_results.schema.json +2 -2
  55. package/schemas/repo_manifest.schema.json +1 -1
  56. package/docs/handoff.md +0 -204
@@ -133,7 +133,9 @@ export async function runGraphEnrichmentExecutor(bundle, options = {}) {
133
133
  setting,
134
134
  edges_added: 0,
135
135
  routes_added: 0,
136
- note: `Analyzer failed: ${error instanceof Error ? error.message : String(error)}.`,
136
+ note: error instanceof Error
137
+ ? `Analyzer failed [${error.name}]: ${error.message}${error.stack ? ` — stack: ${error.stack.split("\n").slice(0, 4).join(" | ")}` : ""}`
138
+ : `Analyzer failed: ${String(error)}.`,
137
139
  });
138
140
  continue;
139
141
  }
@@ -3,16 +3,7 @@ import type { AuditResult } from "../types.js";
3
3
  import type { RuntimeValidationReport } from "../types/runtimeValidation.js";
4
4
  import type { ExternalAnalyzerResults } from "../types/externalAnalyzer.js";
5
5
  import type { AuditScopeManifest } from "../types/auditScope.js";
6
- import type { SynthesisNarrative } from "@audit-tools/shared";
7
- export interface ExecutorRunResult {
8
- updated: ArtifactBundle;
9
- artifacts_written: string[];
10
- progress_summary: string;
11
- }
12
- export declare function resolveRuntimeValidationSpawnCommand(command: string[], platform?: NodeJS.Platform, shellCommand?: string): {
13
- command: string;
14
- args: string[];
15
- };
6
+ import type { ExecutorRunResult } from "./executorResult.js";
16
7
  export declare function runIntakeExecutor(bundle: ArtifactBundle, root: string): Promise<ExecutorRunResult>;
17
8
  export declare function runStructureExecutor(bundle: ArtifactBundle, root?: string): Promise<ExecutorRunResult>;
18
9
  export declare function runDesignAssessmentExecutor(bundle: ArtifactBundle): ExecutorRunResult;
@@ -23,12 +14,4 @@ export declare function runRuntimeValidationExecutor(bundle: ArtifactBundle, roo
23
14
  opentoken?: boolean;
24
15
  }): Promise<ExecutorRunResult>;
25
16
  export declare function runRuntimeValidationUpdateExecutor(bundle: ArtifactBundle, updates: RuntimeValidationReport): ExecutorRunResult;
26
- export declare function runSynthesisExecutor(bundle: ArtifactBundle, results?: AuditResult[]): ExecutorRunResult;
27
- /**
28
- * Resolve the optional synthesis-narrative obligation. When a host/provider
29
- * narrative is supplied it is merged into the canonical findings report and the
30
- * human report is re-rendered with themes/executive-summary/top-risks; without
31
- * one the narrative is recorded as omitted and the deterministic report stands.
32
- */
33
- export declare function runSynthesisNarrativeExecutor(bundle: ArtifactBundle, narrative?: SynthesisNarrative): ExecutorRunResult;
34
17
  export declare function runExternalAnalyzerImportExecutor(bundle: ArtifactBundle, externalResults: ExternalAnalyzerResults): ExecutorRunResult;
@@ -1,4 +1,4 @@
1
- import { spawn } from "node:child_process";
1
+ import { runCommand } from "./runtimeCommand.js";
2
2
  import { buildFileDisposition, isAuditExcludedStatus, } from "../extractors/disposition.js";
3
3
  import { buildGraphBundle, buildGraphBundleFromFs, } from "../extractors/graph.js";
4
4
  import { buildCriticalFlowManifest } from "../extractors/flows.js";
@@ -9,7 +9,6 @@ import { applyScopeToCoverage, fullAuditScope } from "./scope.js";
9
9
  import { buildFlowCoverage } from "./flowCoverage.js";
10
10
  import { buildRequeuePayload } from "./requeueCommand.js";
11
11
  import { buildRuntimeValidationTasks, discoverRuntimeValidationCommand, mergeRuntimeValidationReport, } from "./runtimeValidation.js";
12
- import { applyNarrative, buildAuditFindingsReport, buildAuditReportModel, renderAuditReportMarkdown, } from "../reporting/synthesis.js";
13
12
  import { buildChunkedAuditTasks, } from "./taskBuilder.js";
14
13
  import { buildAuditPlanMetrics, buildReviewPackets, sizeIndexFromManifest, } from "./reviewPackets.js";
15
14
  import { buildUnitManifest } from "./unitBuilder.js";
@@ -60,79 +59,6 @@ function appendSelectiveDeepeningTasks(params) {
60
59
  artifacts: ["audit_tasks.json", "audit_plan_metrics.json", "review_packets.json"],
61
60
  };
62
61
  }
63
- function resolveOpentokenWrap(resolved, platform = process.platform) {
64
- if (platform === "win32") {
65
- const shell = process.env.ComSpec ?? "cmd.exe";
66
- const inner = [resolved.command, ...resolved.args]
67
- .map((v) => (/^[A-Za-z0-9_./:=@+-]+$/.test(v) ? v : `"${v.replace(/(["^&|<>%])/g, "^$1")}"`))
68
- .join(" ");
69
- return { command: shell, args: ["/d", "/s", "/c", `opentoken wrap ${inner}`] };
70
- }
71
- return { command: "opentoken", args: ["wrap", resolved.command, ...resolved.args] };
72
- }
73
- async function runCommand(command, cwd, options = {}) {
74
- let spawnCommand = resolveRuntimeValidationSpawnCommand(command);
75
- if (options.opentoken) {
76
- spawnCommand = resolveOpentokenWrap(spawnCommand);
77
- }
78
- const displayCommand = command.join(" ");
79
- return await new Promise((resolve) => {
80
- const child = spawn(spawnCommand.command, spawnCommand.args, {
81
- cwd,
82
- env: process.env,
83
- stdio: ["ignore", "pipe", "pipe"],
84
- });
85
- let stdout = "";
86
- let stderr = "";
87
- child.stdout.on("data", (chunk) => {
88
- stdout += String(chunk);
89
- });
90
- child.stderr.on("data", (chunk) => {
91
- stderr += String(chunk);
92
- });
93
- child.on("error", (error) => {
94
- resolve({
95
- status: "inconclusive",
96
- summary: `Failed to execute ${displayCommand}: ${error.message}`,
97
- evidence: [],
98
- });
99
- });
100
- child.on("exit", (code) => {
101
- const output = `${stdout}\n${stderr}`.trim();
102
- const evidence = output.length > 0 ? output.split(/\r?\n/).slice(-10) : [];
103
- resolve({
104
- status: code === 0 ? "confirmed" : "not_confirmed",
105
- summary: code === 0
106
- ? `Deterministic runtime command succeeded: ${displayCommand}`
107
- : `Deterministic runtime command failed with exit code ${code}: ${displayCommand}`,
108
- evidence,
109
- });
110
- });
111
- });
112
- }
113
- export function resolveRuntimeValidationSpawnCommand(command, platform = process.platform, shellCommand = process.env.ComSpec ?? "cmd.exe") {
114
- const [executable, ...args] = command;
115
- if (!executable) {
116
- return { command: "", args: [] };
117
- }
118
- if (platform !== "win32") {
119
- return { command: executable, args };
120
- }
121
- const packageManager = executable.replace(/\.(cmd|bat)$/i, "").toLowerCase();
122
- if (["npm", "npx", "pnpm", "yarn"].includes(packageManager)) {
123
- return {
124
- command: shellCommand,
125
- args: ["/d", "/s", "/c", command.map(quoteCmdArg).join(" ")],
126
- };
127
- }
128
- return { command: executable, args };
129
- }
130
- function quoteCmdArg(value) {
131
- if (/^[A-Za-z0-9_./:=+-]+$/.test(value)) {
132
- return value;
133
- }
134
- return `"${value.replace(/(["^&|<>%])/g, "^$1")}"`;
135
- }
136
62
  export async function runIntakeExecutor(bundle, root) {
137
63
  const ignore = await loadIgnoreFile(root);
138
64
  const repoManifest = await buildRepoManifestFromFs({
@@ -476,89 +402,6 @@ export function runRuntimeValidationUpdateExecutor(bundle, updates) {
476
402
  : ""),
477
403
  };
478
404
  }
479
- function buildBaseFindingsReport(bundle, results) {
480
- return buildAuditFindingsReport(buildAuditReportModel({
481
- results,
482
- unitManifest: bundle.unit_manifest,
483
- graphBundle: bundle.graph_bundle,
484
- criticalFlows: bundle.critical_flows,
485
- coverageMatrix: bundle.coverage_matrix,
486
- runtimeValidationReport: bundle.runtime_validation_report,
487
- externalAnalyzerResults: bundle.external_analyzer_results,
488
- designAssessment: bundle.design_assessment,
489
- }));
490
- }
491
- export function runSynthesisExecutor(bundle, results) {
492
- const finalResults = results ?? bundle.audit_results ?? [];
493
- // Emit the canonical machine contract and render the human report from it.
494
- // No narrative yet — that is layered by the synthesis-narrative obligation.
495
- const findings = buildBaseFindingsReport(bundle, finalResults);
496
- return {
497
- updated: {
498
- ...bundle,
499
- audit_results: finalResults,
500
- audit_findings: findings,
501
- audit_report: renderAuditReportMarkdown(findings, { scope: bundle.scope }),
502
- },
503
- artifacts_written: ["audit-findings.json", "audit-report.md"],
504
- progress_summary: `Rendered deterministic audit report and canonical findings for ${finalResults.length} audit result entries.`,
505
- };
506
- }
507
- /**
508
- * Resolve the optional synthesis-narrative obligation. When a host/provider
509
- * narrative is supplied it is merged into the canonical findings report and the
510
- * human report is re-rendered with themes/executive-summary/top-risks; without
511
- * one the narrative is recorded as omitted and the deterministic report stands.
512
- */
513
- export function runSynthesisNarrativeExecutor(bundle, narrative) {
514
- const baseReport = bundle.audit_findings ??
515
- buildBaseFindingsReport(bundle, bundle.audit_results ?? []);
516
- const needsBaseWrite = !bundle.audit_findings;
517
- const hasNarrative = Boolean(narrative &&
518
- ((narrative.themes?.length ?? 0) > 0 ||
519
- (narrative.executive_summary?.trim().length ?? 0) > 0 ||
520
- (narrative.top_risks?.length ?? 0) > 0));
521
- if (!hasNarrative) {
522
- const record = {
523
- status: "omitted",
524
- theme_count: 0,
525
- executive_summary_present: false,
526
- top_risk_count: 0,
527
- };
528
- return {
529
- updated: {
530
- ...bundle,
531
- audit_findings: baseReport,
532
- synthesis_narrative: record,
533
- },
534
- artifacts_written: needsBaseWrite
535
- ? ["audit-findings.json", "synthesis-narrative.json"]
536
- : ["synthesis-narrative.json"],
537
- progress_summary: "Synthesis narrative omitted; deterministic findings report retained.",
538
- };
539
- }
540
- const enriched = applyNarrative(baseReport, narrative);
541
- const record = {
542
- status: "applied",
543
- theme_count: enriched.themes?.length ?? 0,
544
- executive_summary_present: (enriched.executive_summary?.trim().length ?? 0) > 0,
545
- top_risk_count: enriched.top_risks?.length ?? 0,
546
- };
547
- return {
548
- updated: {
549
- ...bundle,
550
- audit_findings: enriched,
551
- audit_report: renderAuditReportMarkdown(enriched, { scope: bundle.scope }),
552
- synthesis_narrative: record,
553
- },
554
- artifacts_written: [
555
- "audit-findings.json",
556
- "audit-report.md",
557
- "synthesis-narrative.json",
558
- ],
559
- progress_summary: `Synthesis narrative applied: ${record.theme_count} theme(s), ${record.top_risk_count} top risk(s).`,
560
- };
561
- }
562
405
  export function runExternalAnalyzerImportExecutor(bundle, externalResults) {
563
406
  const summary = `Imported ${externalResults.results.length} normalized findings from ${externalResults.tool}.`;
564
407
  return {
@@ -0,0 +1,31 @@
1
+ import type { AuditTask } from "../types.js";
2
+ import type { ReviewPacketGraphEdge, ReviewPacketQuality } from "../types/reviewPlanning.js";
3
+ import type { GraphBundle, GraphEdge } from "@audit-tools/shared";
4
+ import { UnionFind } from "./unionFind.js";
5
+ import { normalizeGraphPath } from "../extractors/graphPathUtils.js";
6
+ export { normalizeGraphPath };
7
+ /**
8
+ * Fan-in / fan-out degree above which a node is treated as a hub. Exported so
9
+ * the Phase 3 delta-scope expansion skips the same hubs that packet planning
10
+ * skips, preventing scope blow-up through highly-connected modules.
11
+ */
12
+ export declare const HIGH_FAN_DEGREE_THRESHOLD = 12;
13
+ export declare function collectGraphEdges(graphBundle?: GraphBundle): GraphEdge[];
14
+ export declare function graphEdgeConfidence(edge: GraphEdge): number;
15
+ export declare function isConcreteGraphEdge(edge: GraphEdge): boolean;
16
+ export interface GraphDegreeIndex {
17
+ fanIn: Map<string, number>;
18
+ fanOut: Map<string, number>;
19
+ }
20
+ export declare function buildGraphDegreeIndex(edges: GraphEdge[]): GraphDegreeIndex;
21
+ export declare function isPacketExpansionEdge(edge: GraphEdge, degreeIndex: GraphDegreeIndex): boolean;
22
+ export declare function buildFileToGroupKeys(groups: Map<string, AuditTask[]>): Map<string, Set<string>>;
23
+ export declare function unionFindFromGroups(groups: Map<string, AuditTask[]>, graphEdges: GraphEdge[]): UnionFind;
24
+ export declare function buildPlanningGraphEdges(groups: Map<string, AuditTask[]>, graphEdges: GraphEdge[], graphBundle?: GraphBundle, lineIndex?: Record<string, number>, sizeIndex?: Record<string, number>, targetPacketTokens?: number): GraphEdge[];
25
+ export declare function roundQuality(value: number): number;
26
+ export declare function buildPacketGraphContext(filePaths: string[], graphEdges: GraphEdge[], graphBundle?: GraphBundle): {
27
+ keyEdges: ReviewPacketGraphEdge[];
28
+ boundaryFiles: string[];
29
+ entrypoints: string[];
30
+ quality: ReviewPacketQuality;
31
+ };