auditor-lambda 0.3.2 → 0.3.4

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 (47) hide show
  1. package/README.md +6 -1
  2. package/audit-code-wrapper-lib.mjs +78 -5
  3. package/dist/cli.js +205 -67
  4. package/dist/extractors/graph.d.ts +5 -1
  5. package/dist/extractors/graph.js +223 -3
  6. package/dist/extractors/pathPatterns.d.ts +3 -2
  7. package/dist/extractors/pathPatterns.js +97 -24
  8. package/dist/io/artifacts.d.ts +5 -0
  9. package/dist/io/artifacts.js +2 -0
  10. package/dist/io/json.js +3 -3
  11. package/dist/io/runArtifacts.js +4 -0
  12. package/dist/mcp/server.js +24 -11
  13. package/dist/orchestrator/advance.js +1 -1
  14. package/dist/orchestrator/dependencyMap.js +18 -0
  15. package/dist/orchestrator/internalExecutors.d.ts +1 -1
  16. package/dist/orchestrator/internalExecutors.js +120 -33
  17. package/dist/orchestrator/reviewPackets.d.ts +14 -0
  18. package/dist/orchestrator/reviewPackets.js +300 -0
  19. package/dist/orchestrator/selectiveDeepening.d.ts +14 -0
  20. package/dist/orchestrator/selectiveDeepening.js +392 -0
  21. package/dist/orchestrator/state.js +6 -1
  22. package/dist/orchestrator/taskBuilder.d.ts +16 -0
  23. package/dist/orchestrator/taskBuilder.js +68 -11
  24. package/dist/orchestrator.js +53 -2
  25. package/dist/prompts/renderWorkerPrompt.js +11 -4
  26. package/dist/providers/index.js +1 -1
  27. package/dist/supervisor/sessionConfig.js +1 -1
  28. package/dist/types/graph.d.ts +1 -0
  29. package/dist/types/reviewPlanning.d.ts +41 -0
  30. package/dist/types/reviewPlanning.js +1 -0
  31. package/dist/validation/artifacts.js +13 -0
  32. package/dist/validation/sessionConfig.js +1 -1
  33. package/docs/agent-integrations.md +17 -8
  34. package/docs/bootstrap-install.md +3 -0
  35. package/docs/dispatch-implementation-plan.md +179 -481
  36. package/docs/next-steps.md +13 -8
  37. package/docs/product-direction.md +5 -3
  38. package/docs/run-flow.md +23 -30
  39. package/docs/session-config.md +10 -3
  40. package/docs/supervisor.md +12 -4
  41. package/docs/workflow-refactor-brief.md +85 -147
  42. package/package.json +1 -1
  43. package/schemas/audit_results.schema.json +10 -0
  44. package/schemas/finding.schema.json +1 -15
  45. package/schemas/graph_bundle.schema.json +16 -0
  46. package/skills/audit-code/SKILL.md +12 -3
  47. package/skills/audit-code/audit-code.prompt.md +87 -57
@@ -7,11 +7,18 @@ export function renderWorkerPrompt(task) {
7
7
  if (task.preferred_executor === "agent" && task.audit_results_path) {
8
8
  const tasksPath = task.pending_audit_tasks_path ??
9
9
  `${task.artifacts_dir}/audit_tasks.json`;
10
+ const resultsSchemaPath = `${task.artifacts_dir}/dispatch/audit-results.schema.json`;
11
+ const singleResultSchemaPath = `${task.artifacts_dir}/dispatch/audit-result.schema.json`;
10
12
  const lines = [
11
13
  `Audit run: ${task.run_id}`,
12
14
  `Read: ${tasksPath}`,
13
- "For each task: read all file_paths in full, review under the specified lens,",
14
- "and emit one AuditResult with:",
15
+ `Array schema: ${resultsSchemaPath}`,
16
+ `Single-result schema: ${singleResultSchemaPath}`,
17
+ "Scope: review only the tasks listed in the Read file. Do not add tasks,",
18
+ "edit source files, remediate findings, run unrelated audits, or write result_path.",
19
+ "For each listed task: read the assigned file_paths under the specified lens,",
20
+ "using targeted reads/searches where they give complete enough evidence without loading unrelated context,",
21
+ "and emit exactly one AuditResult object with:",
15
22
  " task_id, unit_id, pass_id, lens (copy from task),",
16
23
  " file_coverage: [{path, total_lines}] — use file_line_counts[path] from the task for each file,",
17
24
  " findings: [] or array of finding objects.",
@@ -19,13 +26,13 @@ export function renderWorkerPrompt(task) {
19
26
  " affected_files [{path, line_start, line_end, symbol}] (objects, not strings; min 1 entry),",
20
27
  " evidence [strings] (min 1 entry).",
21
28
  "Constraint: line_end must not exceed total_lines for that file.",
22
- `Write all results as a JSON array to: ${task.audit_results_path}`,
29
+ `Write only the JSON array of AuditResult objects to: ${task.audit_results_path}`,
23
30
  ];
24
31
  if (usesDeferredWorkerCommand(task)) {
25
32
  lines.push("Deferred mode: write results, do not execute worker_command.");
26
33
  }
27
34
  else {
28
- lines.push("Then execute worker_command from task.json exactly.", `Command: ${commandArgv}`);
35
+ lines.push("After writing audit_results_path, execute worker_command from task.json exactly.", "The worker command ingests audit_results_path and writes result_path.", `Command: ${commandArgv}`);
29
36
  }
30
37
  return lines.join("\n");
31
38
  }
@@ -21,7 +21,7 @@ function commandExists(command) {
21
21
  return result.status === 0;
22
22
  }
23
23
  export function resolveFreshSessionProviderName(name, sessionConfig = {}, options = {}) {
24
- const requestedProvider = name ?? sessionConfig.provider ?? "auto";
24
+ const requestedProvider = name ?? sessionConfig.provider ?? "local-subprocess";
25
25
  if (requestedProvider !== "auto") {
26
26
  return requestedProvider;
27
27
  }
@@ -4,7 +4,7 @@ import { formatValidationIssues, } from "../validation/basic.js";
4
4
  import { validateSessionConfig } from "../validation/sessionConfig.js";
5
5
  import { writeJsonFile } from "../io/json.js";
6
6
  const SESSION_CONFIG_FILENAME = "session-config.json";
7
- const DEFAULT_SESSION_CONFIG = { provider: "auto" };
7
+ const DEFAULT_SESSION_CONFIG = { provider: "local-subprocess" };
8
8
  export function getSessionConfigPath(artifactsDir) {
9
9
  return join(artifactsDir, SESSION_CONFIG_FILENAME);
10
10
  }
@@ -12,6 +12,7 @@ export interface GraphBundle {
12
12
  graphs: {
13
13
  imports?: GraphEdge[];
14
14
  calls?: GraphEdge[];
15
+ references?: GraphEdge[];
15
16
  routes?: RouteEdge[];
16
17
  [key: string]: unknown;
17
18
  };
@@ -0,0 +1,41 @@
1
+ import type { AuditTask, Lens } from "../types.js";
2
+ export interface ReviewPacket {
3
+ packet_id: string;
4
+ task_ids: string[];
5
+ unit_ids: string[];
6
+ pass_ids: string[];
7
+ lenses: Lens[];
8
+ file_paths: string[];
9
+ file_line_counts: Record<string, number>;
10
+ total_lines: number;
11
+ priority: NonNullable<AuditTask["priority"]>;
12
+ tags?: string[];
13
+ rationale: string;
14
+ estimated_tokens: number;
15
+ }
16
+ export interface AuditPlanMetrics {
17
+ generated_at: string;
18
+ task_count: number;
19
+ packet_count: number;
20
+ estimated_agent_reduction: number;
21
+ estimated_agent_reduction_ratio: number;
22
+ unique_file_count: number;
23
+ task_file_reference_count: number;
24
+ repeated_file_reference_count: number;
25
+ total_task_lines: number;
26
+ total_packet_lines: number;
27
+ repeated_line_reference_count: number;
28
+ min_task_lines: number;
29
+ max_task_lines: number;
30
+ average_task_lines: number;
31
+ largest_task_id?: string;
32
+ largest_packet_id?: string;
33
+ lens_task_counts: Partial<Record<Lens, number>>;
34
+ priority_task_counts: Record<NonNullable<AuditTask["priority"]>, number>;
35
+ packet_size: {
36
+ single_task_packets: number;
37
+ multi_task_packets: number;
38
+ max_tasks_per_packet: number;
39
+ max_files_per_packet: number;
40
+ };
41
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -40,6 +40,19 @@ export function validateArtifactBundle(bundle) {
40
40
  if (bundle.external_analyzer_results) {
41
41
  issues.push(...requireKeys(bundle.external_analyzer_results, "external_analyzer_results", ["tool", "results"]));
42
42
  }
43
+ if (bundle.audit_plan_metrics) {
44
+ issues.push(...requireKeys(bundle.audit_plan_metrics, "audit_plan_metrics", ["generated_at", "task_count", "packet_count"]));
45
+ }
46
+ if (bundle.review_packets) {
47
+ for (const [index, packet] of bundle.review_packets.entries()) {
48
+ issues.push(...requireKeys(packet, `review_packets:${index}`, [
49
+ "packet_id",
50
+ "task_ids",
51
+ "lenses",
52
+ "file_paths",
53
+ ]));
54
+ }
55
+ }
43
56
  if (bundle.tooling_manifest) {
44
57
  issues.push(...requireKeys(bundle.tooling_manifest, "tooling_manifest", ["generated_at", "package_root", "implementation_hash", "inputs"]));
45
58
  }
@@ -156,7 +156,7 @@ export function validateConfiguredProviderEnvironment(sessionConfig, options = {
156
156
  const issues = [];
157
157
  const lookupCommand = options.commandExists ?? commandExists;
158
158
  const lookupPath = options.pathExists ?? configuredPathExists;
159
- const provider = sessionConfig.provider ?? "auto";
159
+ const provider = sessionConfig.provider ?? "local-subprocess";
160
160
  if (provider === "claude-code") {
161
161
  const command = sessionConfig.claude_code?.command ?? "claude";
162
162
  if (isBareExecutableName(command) && !lookupCommand(command)) {
@@ -120,13 +120,13 @@ Use the backend wrapper only when you intentionally need the repo-local fallback
120
120
 
121
121
  ## What the wrapper actually does
122
122
 
123
- `audit-code` is the stable backend entrypoint.
123
+ `audit-code` is the stable backend entrypoint behind the slash command.
124
124
 
125
125
  It:
126
126
 
127
127
  - defaults artifacts to `<repo-root>/.audit-artifacts`
128
128
  - persists audit continuity there
129
- - calls `run-to-completion` by default
129
+ - calls `run-to-completion` by default for deterministic work
130
130
  - creates fresh worker runs behind the scenes
131
131
  - returns a stable top-level JSON contract with `contract_version: "audit-code/v1alpha1"`
132
132
 
@@ -145,13 +145,15 @@ Inspect the returned JSON and continue invoking the same entrypoint until either
145
145
  Terminal interpretation:
146
146
 
147
147
  - `audit_state.status === "complete"` means the audit finished end to end.
148
- - `audit_state.status === "blocked"` means the wrapper exhausted automatic work and the remaining review still needs imported results or a provider-capable continuation path.
148
+ - `audit_state.status === "blocked"` means the wrapper exhausted deterministic
149
+ work and exposed scoped semantic-review task artifacts for the slash-command
150
+ orchestrator.
149
151
 
150
152
  Current implementation note:
151
153
 
152
154
  - the backend fallback still supports explicit provider bridges such as `claude-code`, `opencode`, `subprocess-template`, and `vscode-task`
153
155
  - those bridges are compatibility modes, not the intended default review owner
154
- - the intended long-term workflow is documented in [docs/workflow-refactor-brief.md](/C:/Code/auditor-lambda/docs/workflow-refactor-brief.md)
156
+ - the intended workflow is documented in [docs/workflow-refactor-brief.md](/C:/Code/auditor-lambda/docs/workflow-refactor-brief.md)
155
157
 
156
158
  When additional evidence exists, pass it into the same wrapper:
157
159
 
@@ -172,9 +174,15 @@ Use it when the current host cannot keep review inside the active conversation,
172
174
 
173
175
  Use when you want the supervisor to stay entirely local.
174
176
 
175
- This requires no external agent CLI. Deterministic executors run in-process during normal wrapper runs, and the supervisor only stops once the remaining work is genuinely semantic review.
177
+ This requires no external agent CLI. Deterministic executors run in-process
178
+ during normal wrapper runs, and the supervisor only stops once the remaining
179
+ work is genuinely semantic review.
176
180
 
177
- When that review boundary is reached, `local-subprocess` stops in a terminal blocked handoff instead of pretending more automatic progress is available. Use `--results <file>` for a single batch or `--batch-results <dir>` when the active conversation agent reviewed multiple task batches before ingestion.
181
+ When that review boundary is reached, `local-subprocess` stops in a terminal
182
+ blocked handoff instead of pretending more automatic progress is available.
183
+ The slash-command orchestrator should dispatch subagents from the handoff when
184
+ available; otherwise it should review exactly one task, write results, run the
185
+ provided worker command, and stop.
178
186
 
179
187
  This is the safest default backend when the repository is already available locally.
180
188
 
@@ -255,7 +263,8 @@ Highest-value follow-through:
255
263
 
256
264
  The product direction remains skill-first:
257
265
 
258
- - in conversation, use the active conversation model by default
266
+ - in conversation, keep orchestration in the active model and delegate semantic
267
+ review to bounded subagents when the host supports them
259
268
  - for backend CLI delegation, let the chosen provider own its own model-selection behavior unless explicitly configured otherwise
260
269
 
261
270
  ## Practical recommendation
@@ -265,7 +274,7 @@ For a polished operator experience today:
265
274
  1. treat `/audit-code` as the canonical user-facing contract
266
275
  2. use `audit-code install` first, and fall back to `audit-code prompt-path` only for hosts that still require manual prompt import
267
276
  3. use `audit-code` as the repo-local backend fallback
268
- 4. prefer `local-subprocess` unless you want interactive review to continue automatically through agent tasks
277
+ 4. prefer `local-subprocess` unless you explicitly want a backend provider bridge
269
278
  5. use `subprocess-template` only when integrating a non-native editor or launcher surface
270
279
 
271
280
  If you intentionally want the backend fallback to bridge semantic review into another process, re-run with an explicit `--provider` flag after configuring the matching section in `.audit-artifacts/session-config.json`.
@@ -7,6 +7,9 @@ audit-code install
7
7
  ```
8
8
 
9
9
  That command installs the repo-local `/audit-code` surfaces we can automate today.
10
+ It is also the single refresh path: rerun `audit-code install` after prompt or
11
+ skill updates to rewrite the shared install assets and every generated
12
+ host-specific surface from the same source files.
10
13
 
11
14
  After bootstrap, run:
12
15