auditor-lambda 0.2.6 → 0.2.8

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 (58) hide show
  1. package/README.md +23 -7
  2. package/audit-code-wrapper-lib.mjs +1605 -330
  3. package/dist/cli.js +78 -16
  4. package/dist/coverage.d.ts +2 -2
  5. package/dist/coverage.js +5 -5
  6. package/dist/extractors/disposition.js +10 -1
  7. package/dist/extractors/flows.js +7 -1
  8. package/dist/extractors/pathPatterns.d.ts +3 -0
  9. package/dist/extractors/pathPatterns.js +15 -0
  10. package/dist/extractors/risk.js +7 -1
  11. package/dist/io/artifacts.d.ts +6 -6
  12. package/dist/io/artifacts.js +14 -17
  13. package/dist/io/json.d.ts +2 -0
  14. package/dist/io/json.js +15 -0
  15. package/dist/io/runArtifacts.d.ts +1 -0
  16. package/dist/io/runArtifacts.js +18 -4
  17. package/dist/mcp/server.d.ts +1 -0
  18. package/dist/mcp/server.js +579 -0
  19. package/dist/orchestrator/advance.js +9 -2
  20. package/dist/orchestrator/dependencyMap.js +9 -13
  21. package/dist/orchestrator/executors.js +7 -2
  22. package/dist/orchestrator/flowRequeue.js +1 -1
  23. package/dist/orchestrator/internalExecutors.d.ts +2 -1
  24. package/dist/orchestrator/internalExecutors.js +120 -63
  25. package/dist/orchestrator/requeue.js +9 -4
  26. package/dist/orchestrator/resultIngestion.js +5 -6
  27. package/dist/orchestrator/runtimeValidation.d.ts +7 -2
  28. package/dist/orchestrator/runtimeValidation.js +61 -49
  29. package/dist/orchestrator/runtimeValidationUpdate.js +2 -4
  30. package/dist/orchestrator/state.js +18 -13
  31. package/dist/orchestrator/trivialAudit.js +8 -5
  32. package/dist/prompts/renderWorkerPrompt.js +3 -2
  33. package/dist/reporting/mergeFindings.js +0 -11
  34. package/dist/reporting/synthesis.d.ts +25 -22
  35. package/dist/reporting/synthesis.js +92 -59
  36. package/dist/reporting/workBlocks.d.ts +12 -3
  37. package/dist/reporting/workBlocks.js +124 -70
  38. package/dist/types/flows.d.ts +2 -0
  39. package/dist/types/runtimeValidation.d.ts +2 -1
  40. package/dist/types.d.ts +4 -7
  41. package/dist/validation/auditResults.js +64 -99
  42. package/docs/agent-integrations.md +38 -29
  43. package/docs/artifacts.md +16 -56
  44. package/docs/bootstrap-install.md +60 -30
  45. package/docs/contract.md +22 -205
  46. package/docs/next-steps.md +59 -44
  47. package/docs/packaging.md +13 -3
  48. package/docs/production-launch-bar.md +2 -2
  49. package/docs/production-readiness.md +9 -5
  50. package/docs/releasing.md +81 -0
  51. package/package.json +4 -1
  52. package/schemas/audit_result.schema.json +4 -6
  53. package/schemas/runtime_validation_report.schema.json +1 -1
  54. package/skills/audit-code/SKILL.md +11 -2
  55. package/skills/audit-code/audit-code.prompt.md +5 -8
  56. package/schemas/merged_findings.schema.json +0 -19
  57. package/schemas/root_cause_clusters.schema.json +0 -28
  58. package/schemas/synthesis_report.schema.json +0 -61
@@ -203,10 +203,11 @@ function validateFinding(finding, label, taskId, resultIndex) {
203
203
  }
204
204
  return issues;
205
205
  }
206
- function coversAffectedSpan(ranges, path, start, end) {
207
- return ranges.some((range) => range.path === path &&
208
- range.start <= start &&
209
- range.end >= end);
206
+ function coversAffectedSpan(coverage, path, start, end) {
207
+ return coverage.some((entry) => entry.path === path &&
208
+ start > 0 &&
209
+ end > 0 &&
210
+ end <= entry.total_lines);
210
211
  }
211
212
  export function validateAuditResults(results, tasks, options = {}) {
212
213
  const issues = [];
@@ -251,149 +252,113 @@ export function validateAuditResults(results, tasks, options = {}) {
251
252
  result_index: i,
252
253
  task_id: taskId,
253
254
  field: "task_id",
254
- message: `Unknown task_id '${taskId}'.`,
255
+ message: `Unknown task_id '${taskId}'. Use the active task manifest for valid ids: ` +
256
+ tasks.map((item) => item.task_id).join(", "),
255
257
  });
256
258
  }
257
- const reviewedRanges = result.reviewed_ranges;
258
- const normalizedReviewedRanges = [];
259
- if (!Array.isArray(reviewedRanges) || reviewedRanges.length === 0) {
259
+ const fileCoverage = result.file_coverage;
260
+ const normalizedFileCoverage = [];
261
+ if (!Array.isArray(fileCoverage) || fileCoverage.length === 0) {
260
262
  pushIssue(issues, {
261
263
  result_index: i,
262
264
  task_id: taskId,
263
- field: "reviewed_ranges",
264
- message: "reviewed_ranges is empty — no proof of file reading was recorded. Each result must include the line ranges actually read.",
265
+ field: "file_coverage",
266
+ message: "file_coverage is empty — each result must declare every assigned file it reviewed and the file's total line count.",
265
267
  });
266
268
  }
267
269
  else {
268
- for (let j = 0; j < reviewedRanges.length; j++) {
269
- const range = reviewedRanges[j];
270
- if (!isRecord(range)) {
270
+ const seenCoveragePaths = new Set();
271
+ for (let j = 0; j < fileCoverage.length; j++) {
272
+ const entry = fileCoverage[j];
273
+ if (!isRecord(entry)) {
271
274
  pushIssue(issues, {
272
275
  result_index: i,
273
276
  task_id: taskId,
274
- field: `reviewed_ranges[${j}]`,
275
- message: `reviewed_ranges[${j}] must be an object, got ${describeValue(range)}.`,
277
+ field: `file_coverage[${j}]`,
278
+ message: `file_coverage[${j}] must be an object, got ${describeValue(entry)}.`,
276
279
  });
277
280
  continue;
278
281
  }
279
- if (!isNonEmptyString(range.path)) {
282
+ if (!isNonEmptyString(entry.path)) {
280
283
  pushIssue(issues, {
281
284
  result_index: i,
282
285
  task_id: taskId,
283
- field: `reviewed_ranges[${j}].path`,
284
- message: "reviewed_ranges entry has an empty path.",
286
+ field: `file_coverage[${j}].path`,
287
+ message: "file_coverage entry has an empty path.",
285
288
  });
286
289
  }
287
- else if (task && !task.file_paths.includes(range.path)) {
290
+ else if (task && !task.file_paths.includes(entry.path)) {
288
291
  pushIssue(issues, {
289
292
  result_index: i,
290
293
  task_id: taskId,
291
294
  severity: "warning",
292
- field: `reviewed_ranges[${j}].path`,
293
- message: `reviewed_ranges path '${range.path}' is not listed in the task file_paths.`,
295
+ field: `file_coverage[${j}].path`,
296
+ message: `file_coverage path '${entry.path}' is not listed in the task file_paths.`,
294
297
  });
295
298
  }
296
- if (!Number.isInteger(range.start)) {
299
+ else if (seenCoveragePaths.has(entry.path)) {
297
300
  pushIssue(issues, {
298
301
  result_index: i,
299
302
  task_id: taskId,
300
- field: `reviewed_ranges[${j}].start`,
301
- message: `reviewed_ranges[${j}].start must be an integer, got ${describeValue(range.start)}.`,
303
+ field: `file_coverage[${j}].path`,
304
+ message: `file_coverage path '${entry.path}' is duplicated. Declare each file once.`,
302
305
  });
303
306
  }
304
- if (!Number.isInteger(range.end)) {
305
- pushIssue(issues, {
306
- result_index: i,
307
- task_id: taskId,
308
- field: `reviewed_ranges[${j}].end`,
309
- message: `reviewed_ranges[${j}].end must be an integer, got ${describeValue(range.end)}.`,
310
- });
311
- }
312
- if (!Number.isInteger(range.line_count)) {
313
- pushIssue(issues, {
314
- result_index: i,
315
- task_id: taskId,
316
- field: `reviewed_ranges[${j}].line_count`,
317
- message: `reviewed_ranges[${j}].line_count must be an integer, got ${describeValue(range.line_count)}.`,
318
- });
319
- }
320
- if (Number.isInteger(range.start) &&
321
- Number.isInteger(range.end) &&
322
- Number(range.start) > Number(range.end)) {
323
- pushIssue(issues, {
324
- result_index: i,
325
- task_id: taskId,
326
- field: `reviewed_ranges[${j}]`,
327
- message: "reviewed_ranges start must be less than or equal to end.",
328
- });
307
+ else {
308
+ seenCoveragePaths.add(entry.path);
329
309
  }
330
- if (Number.isInteger(range.line_count) &&
331
- Number(range.line_count) <= 0) {
310
+ if (!Number.isInteger(entry.total_lines)) {
332
311
  pushIssue(issues, {
333
312
  result_index: i,
334
313
  task_id: taskId,
335
- field: `reviewed_ranges[${j}].line_count`,
336
- message: "reviewed_ranges line_count must be greater than zero.",
314
+ field: `file_coverage[${j}].total_lines`,
315
+ message: `file_coverage[${j}].total_lines must be an integer, got ${describeValue(entry.total_lines)}.`,
337
316
  });
338
317
  }
339
- if (Number.isInteger(range.start) &&
340
- Number(range.start) <= 0) {
318
+ if (Number.isInteger(entry.total_lines) &&
319
+ Number(entry.total_lines) <= 0) {
341
320
  pushIssue(issues, {
342
321
  result_index: i,
343
322
  task_id: taskId,
344
- field: `reviewed_ranges[${j}].start`,
345
- message: "reviewed_ranges start must be greater than zero.",
323
+ field: `file_coverage[${j}].total_lines`,
324
+ message: "file_coverage total_lines must be greater than zero.",
346
325
  });
347
326
  }
348
- if (Number.isInteger(range.end) &&
349
- Number(range.end) <= 0) {
350
- pushIssue(issues, {
351
- result_index: i,
352
- task_id: taskId,
353
- field: `reviewed_ranges[${j}].end`,
354
- message: "reviewed_ranges end must be greater than zero.",
355
- });
356
- }
357
- if (Number.isInteger(range.end) &&
358
- Number.isInteger(range.line_count) &&
359
- Number(range.end) > Number(range.line_count)) {
360
- pushIssue(issues, {
361
- result_index: i,
362
- task_id: taskId,
363
- field: `reviewed_ranges[${j}]`,
364
- message: "reviewed_ranges end must not exceed the declared file line_count.",
365
- });
366
- }
367
- const expectedLineCount = typeof range.path === "string"
368
- ? options.lineIndex?.[range.path]
327
+ const expectedLineCount = typeof entry.path === "string"
328
+ ? options.lineIndex?.[entry.path]
369
329
  : undefined;
370
- if (Number.isInteger(range.line_count) &&
330
+ if (Number.isInteger(entry.total_lines) &&
371
331
  typeof expectedLineCount === "number" &&
372
- Number(range.line_count) !== expectedLineCount) {
332
+ Number(entry.total_lines) !== expectedLineCount) {
373
333
  pushIssue(issues, {
374
334
  result_index: i,
375
335
  task_id: taskId,
376
- field: `reviewed_ranges[${j}].line_count`,
377
- message: `reviewed_ranges[${j}].line_count must match the current file line count for '${range.path}' ` +
378
- `(expected ${expectedLineCount}, got ${range.line_count}).`,
336
+ field: `file_coverage[${j}].total_lines`,
337
+ message: `file_coverage[${j}].total_lines must match the current file line count for '${entry.path}' ` +
338
+ `(expected ${expectedLineCount}, got ${entry.total_lines}).`,
379
339
  });
380
340
  }
381
- if (isNonEmptyString(range.path) &&
382
- Number.isInteger(range.start) &&
383
- Number.isInteger(range.end) &&
384
- Number.isInteger(range.line_count) &&
385
- Number(range.start) > 0 &&
386
- Number(range.end) > 0 &&
387
- Number(range.start) <= Number(range.end) &&
388
- Number(range.end) <= Number(range.line_count)) {
389
- normalizedReviewedRanges.push({
390
- path: range.path,
391
- start: Number(range.start),
392
- end: Number(range.end),
393
- line_count: Number(range.line_count),
341
+ if (isNonEmptyString(entry.path) &&
342
+ Number.isInteger(entry.total_lines) &&
343
+ Number(entry.total_lines) > 0) {
344
+ normalizedFileCoverage.push({
345
+ path: entry.path,
346
+ total_lines: Number(entry.total_lines),
394
347
  });
395
348
  }
396
349
  }
350
+ if (task) {
351
+ for (const path of task.file_paths) {
352
+ if (!seenCoveragePaths.has(path)) {
353
+ pushIssue(issues, {
354
+ result_index: i,
355
+ task_id: taskId,
356
+ field: "file_coverage",
357
+ message: `file_coverage must include every assigned file. Missing '${path}'.`,
358
+ });
359
+ }
360
+ }
361
+ }
397
362
  }
398
363
  const findings = result.findings;
399
364
  if (!Array.isArray(findings)) {
@@ -424,13 +389,13 @@ export function validateAuditResults(results, tasks, options = {}) {
424
389
  const end = Number.isInteger(affected.line_end)
425
390
  ? Number(affected.line_end)
426
391
  : start;
427
- if (!coversAffectedSpan(normalizedReviewedRanges, affected.path, start, end)) {
392
+ if (!coversAffectedSpan(normalizedFileCoverage, affected.path, start, end)) {
428
393
  pushIssue(issues, {
429
394
  result_index: i,
430
395
  task_id: taskId,
431
396
  field: `${label}.affected_files[${k}]`,
432
- message: `affected_files line span ${affected.path}:${start}-${end} falls outside the declared reviewed_ranges. ` +
433
- "Expand reviewed_ranges to cover the cited lines or fix the affected_files location.",
397
+ message: `affected_files line span ${affected.path}:${start}-${end} falls outside the declared file_coverage. ` +
398
+ "Fix the affected_files location or correct file_coverage.total_lines.",
434
399
  });
435
400
  }
436
401
  }
@@ -26,8 +26,8 @@ The preferred bootstrap path is:
26
26
  audit-code install
27
27
  ```
28
28
 
29
- That installs repo-local `/audit-code` surfaces for VS Code / Copilot, OpenCode, Claude Code, and compatibility instruction files such as `AGENTS.md` and `CLAUDE.md`.
30
- It also writes `.audit-code/install/GETTING-STARTED.md` with dedicated quick-start sections for VS Code, OpenCode, Claude Code, Claude Desktop, and Antigravity.
29
+ That installs repo-local `/audit-code` surfaces and MCP-oriented support assets for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity.
30
+ It also writes `.audit-code/install/GETTING-STARTED.md` with dedicated quick-start sections for each host plus `.audit-code/install/manifest.json` and a shared repo-local MCP launcher.
31
31
 
32
32
  Use one of these supported ways to obtain the raw prompt asset directly when you need prompt import instead:
33
33
 
@@ -44,58 +44,56 @@ This is the intended product surface.
44
44
 
45
45
  Use `/audit-code` in conversation, treat the active conversation model as the default model, and treat project files plus attached repository context as the default context.
46
46
 
47
- ### GitHub Copilot
47
+ ### Codex
48
48
 
49
- Use `audit-code install` from the target repository root.
49
+ Use `audit-code install --host codex` or the default `audit-code install` from the target repository root.
50
50
 
51
- That writes `.github/prompts/audit-code.prompt.md` and `.github/copilot-instructions.md` so the repository carries the canonical `/audit-code` instructions instead of relying on manual copy-paste.
52
- The generated prompt file explicitly sets `agent: agent` so `/audit-code` lands in the tool-capable Copilot agent flow.
51
+ That writes a repo-local Codex skill bundle, updates `AGENTS.md` through a managed block when needed, and emits Codex-specific MCP setup guidance plus an automation recipe in `.audit-code/install/codex/`.
52
+ The intended operator flow is still conversational first, with the generated skill and AGENTS guidance steering the active Codex session toward `/audit-code` and the MCP-backed workflow.
53
53
 
54
- The narrower `audit-code install-host --host copilot` alias still exists, but it is no longer the preferred setup path.
54
+ The Codex automation recipe should still be treated as optional follow-through after the basic local flow is validated in the real app.
55
55
 
56
- ### OpenCode
56
+ ### Claude Desktop
57
57
 
58
- Use `audit-code install` from the target repository root.
58
+ Use `audit-code install --host claude-desktop` or the default `audit-code install` from the target repository root.
59
59
 
60
- That writes `.opencode/commands/audit-code.md` plus `AGENTS.md` and compatibility skills so `/audit-code` is available in the repository with no extra provider flags.
61
- The generated OpenCode command now sets `agent: build` and keeps the current model selection, which makes the slash command behave more like the intended autonomous editing flow.
62
- The generated `.audit-code/install/GETTING-STARTED.md` file also includes an OpenCode-specific quick start so the repo-local command path is obvious after bootstrap.
60
+ This repository now treats Claude Desktop as an MCP-first host. The installer writes:
63
61
 
64
- ### Claude Code
62
+ - `.audit-code/install/claude-desktop/PROJECT-TEMPLATE.md`
63
+ - `.audit-code/install/claude-desktop/remote-mcp-connector.json`
64
+ - generated local bundle artifacts including `auditor-lambda.dxt` and `auditor-lambda.mcpb`
65
+
66
+ The intended path is to install or reference the generated local MCP bundle, then use the shared prompt and project-template guidance to run `/audit-code` conversationally.
67
+ Manual prompt import remains a fallback, not the primary documented path.
68
+
69
+ ### OpenCode
65
70
 
66
71
  Use `audit-code install` from the target repository root.
67
72
 
68
- That writes `.claude/commands/audit-code.md`, `CLAUDE.md`, and compatibility skills so `/audit-code` is available in the repository with no extra provider flags.
69
- The generated `.audit-code/install/GETTING-STARTED.md` file also includes a Claude Code-specific quick start so the repo-local command path is obvious after bootstrap.
73
+ That writes `.opencode/commands/audit-code.md`, a repo-local OpenCode skill bundle, and `opencode.json` so `/audit-code` is available in the repository with no extra provider flags.
74
+ The generated OpenCode assets also point OpenCode toward the shared auditor MCP server instead of rebuilding backend state ad hoc.
70
75
 
71
76
  ### VS Code
72
77
 
73
78
  Run `audit-code install` from the target repository root, then open `.audit-code/install/GETTING-STARTED.md` if you want the exact repo-local path that bootstrap created for VS Code chat surfaces.
74
79
 
80
+ That writes `.github/prompts/audit-code.prompt.md`, `.github/copilot-instructions.md`, `.github/agents/auditor.agent.md`, and `.vscode/mcp.json`.
75
81
  The expected happy path is still to invoke `/audit-code` from chat, not to start from the backend CLI.
76
82
 
77
- ### Claude Desktop
78
-
79
- Run `audit-code install` from the target repository root, then open `.audit-code/install/GETTING-STARTED.md`.
80
-
81
- There is no verified project-local slash-command install surface for Claude Desktop in this repository today, so the intended path is:
82
-
83
- 1. import `.audit-code/install/audit-code.import.md` into Claude Desktop's prompt or instruction surface
84
- 2. invoke `/audit-code` conversationally inside Claude Desktop
85
-
86
83
  ### Antigravity
87
84
 
88
85
  Run `audit-code install` from the target repository root, then open `.audit-code/install/GETTING-STARTED.md`.
89
86
 
90
- There is no verified repo-local slash-command install surface for Antigravity in this repository today, so the intended path is:
87
+ There is still no documented native repo-local saved-workflow surface for Antigravity in this repository today, so the intended path is:
91
88
 
92
- 1. import `.audit-code/install/audit-code.import.md` into Antigravity's prompt or instruction surface when available
93
- 2. invoke `/audit-code` conversationally inside Antigravity
94
- 3. fall back to `audit-code` from an Antigravity-managed terminal only when you intentionally need the repo-local backend wrapper
89
+ 1. use the generated planning-mode and MCP setup guidance
90
+ 2. invoke `/audit-code` conversationally inside Antigravity when the host surface allows it
91
+ 3. use the shared MCP tools and resources when structured state exchange is needed
92
+ 4. fall back to `audit-code` from an Antigravity-managed terminal only when you intentionally need the repo-local backend wrapper
95
93
 
96
94
  ### Similar manual-import hosts
97
95
 
98
- Use the same installed prompt asset and repo-local guide pattern as Claude Desktop and Antigravity.
96
+ Use the same installed prompt asset and repo-local guide pattern as Antigravity, or the same MCP-first bundle pattern as Claude Desktop, depending on what the host actually supports.
99
97
 
100
98
  The backend CLI remains optional fallback infrastructure.
101
99
 
@@ -224,6 +222,17 @@ Current recommended usage is one of these:
224
222
 
225
223
  That keeps the product usable in Antigravity now without pretending that a native adapter already exists.
226
224
 
225
+ ## Remaining steps
226
+
227
+ The current implementation shipped the shared installer and MCP substrate. The remaining work is operational validation and fit-and-finish, not a fresh redesign.
228
+
229
+ Highest-value follow-through:
230
+
231
+ 1. validate the generated Codex, Claude Desktop, OpenCode, and VS Code assets inside the real products they target
232
+ 2. tighten generated quick-start guidance anywhere those host smoke tests expose ambiguity
233
+ 3. document exactly how Antigravity artifacts should map into `import_results` and `import_runtime_updates`
234
+ 4. keep host claims conservative until those end-to-end product checks are complete
235
+
227
236
  ## Model-selection rule
228
237
 
229
238
  The product direction remains skill-first:
package/docs/artifacts.md CHANGED
@@ -1,8 +1,10 @@
1
- # Core artifacts
1
+ # Core Artifacts
2
2
 
3
- These JSON artifacts are the stable contract between deterministic tooling and LLM audit passes.
3
+ This document follows [audit-goals.md](C:/Code/auditor-lambda/spec/audit-goals.md).
4
4
 
5
- ## Core files
5
+ ## Incomplete-run artifacts
6
+
7
+ During an incomplete or blocked audit, `.audit-artifacts/` may contain:
6
8
 
7
9
  - `repo_manifest.json`
8
10
  - `file_disposition.json`
@@ -13,64 +15,22 @@ These JSON artifacts are the stable contract between deterministic tooling and L
13
15
  - `flow_coverage.json`
14
16
  - `risk_register.json`
15
17
  - `coverage_matrix.json`
16
- - `runtime_validation_tasks.json`
17
- - `runtime_validation_report.json`
18
+ - `runtime_validation_tasks.json` when deterministic runtime validation is planned
19
+ - `runtime_validation_report.json` when runtime validation has executed or been updated
18
20
  - `external_analyzer_results.json`
19
21
  - `audit_tasks.json`
20
22
  - `audit_results.jsonl`
21
23
  - `requeue_tasks.json`
22
- - `merged_findings.json`
23
- - `root_cause_clusters.json`
24
- - `synthesis_report.json`
25
-
26
- ## Design rule
27
-
28
- Tool-specific collectors should write into these normalized formats so that the agent layer can remain portable across runtimes.
29
-
30
- ## Coverage rule
31
-
32
- Coverage is not based only on test instrumentation. It is based on explicit audit accounting:
33
-
34
- - file classification
35
- - file disposition
36
- - unit assignment
37
- - required lenses
38
- - reviewed source ranges
39
- - completed passes
40
- - requeue targets for missing review
41
- - critical-flow coverage state
42
-
43
- ## Excluded artifact behavior
44
-
45
- Files marked as generated, vendor, binary, doc-only, or explicitly excluded should remain visible in manifests and disposition tracking, but should not receive normal audit-unit assignment or requeue tasks.
46
-
47
- ## Critical flow role
48
-
49
- `critical_flows.json` is intended to bridge deterministic planning and higher-order semantic review. It gives LLM agents a bounded way to inspect important end-to-end paths without reading the entire repository at once.
50
-
51
- `flow_coverage.json` tracks whether those important paths have received the intended lenses, which allows the planner to treat critical-flow review as a first-class coverage requirement rather than a loose advisory layer.
52
-
53
- ## Runtime validation role
54
-
55
- `runtime_validation_tasks.json` turns unresolved high-risk units and incomplete critical flows into explicit dynamic follow-up work.
56
-
57
- `runtime_validation_report.json` is where evidence from those checks should land so that later synthesis can distinguish confirmed, not-confirmed, and inconclusive concerns.
58
-
59
- ## External analyzer role
60
-
61
- `external_analyzer_results.json` is the normalized landing zone for third-party tools such as SAST analyzers, coverage summaries, lint diagnostics, dependency scanners, and similar sources. Downstream prompts should prefer this normalized form over raw tool-native payloads.
24
+ - dispatch files for the currently active worker task
62
25
 
63
- External analyzer results now also influence:
26
+ ## Scope rule
64
27
 
65
- - risk scoring
66
- - required lenses in coverage
67
- - task priority
68
- - dedicated analyzer follow-up tasks
69
- - requeue priority
70
- - synthesis evidence and summaries
28
+ Excluded files remain visible in deterministic intake/disposition where useful,
29
+ but they must not create audit work. This includes logs, licenses, lockfiles,
30
+ generated artifacts, vendored artifacts, binaries, and trivial non-code files.
71
31
 
72
- ## Key schema notes
32
+ ## Completion rule
73
33
 
74
- - `audit_tasks.json`: each task already contains the resolved `file_paths` it covers. Use `audit-code explain-task <task_id>` when you want that task joined back to current `coverage_matrix.json` state.
75
- - `coverage_matrix.json`: each file records `classification_status`, `audit_status`, `required_lenses`, and `completed_lenses`.
76
- - `synthesis_report.json`: this is the top-level synthesis artifact. It includes `merged_findings`, semantic `root_cause_clusters`, and `work_blocks`; `work_blocks` are the primary remediation grouping.
34
+ These artifacts are transient implementation state only. When the audit
35
+ completes, `.audit-artifacts/` is removed and only repo-root `audit-report.md`
36
+ remains.
@@ -8,65 +8,86 @@ audit-code install
8
8
 
9
9
  That command installs the repo-local `/audit-code` surfaces we can automate today.
10
10
 
11
- ## What it writes
12
-
13
- Installed command surfaces:
11
+ After bootstrap, run:
14
12
 
15
- - `.github/prompts/audit-code.prompt.md` for VS Code chat prompt files, with `agent: agent`
16
- - `.opencode/commands/audit-code.md` for OpenCode custom commands, with `agent: build`
17
- - `.claude/commands/audit-code.md` for Claude Code custom slash commands
13
+ ```bash
14
+ audit-code verify-install
15
+ ```
18
16
 
19
- Installed always-on compatibility surfaces:
17
+ That smoke-tests the generated host assets plus the shared repo-local MCP launcher without waiting for a full editor walkthrough.
20
18
 
21
- - `.github/copilot-instructions.md`
22
- - `AGENTS.md`
23
- - `CLAUDE.md`
19
+ ## What it writes
24
20
 
25
- Installed repo-local canonical assets:
21
+ Installed shared surfaces:
26
22
 
27
23
  - `.audit-code/install/audit-code.import.md`
28
24
  - `.audit-code/install/SKILL.md`
29
25
  - `.audit-code/install/GETTING-STARTED.md`
26
+ - `.audit-code/install/manifest.json`
27
+ - `.audit-code/install/run-mcp-server.mjs`
28
+
29
+ Installed host-specific surfaces:
30
+
31
+ - Codex:
32
+ - `.codex/skills/audit-code/*`
33
+ - `AGENTS.md` managed block when needed
34
+ - `.audit-code/install/codex/MCP-SETUP.md`
35
+ - `.audit-code/install/codex/RE-AUDIT-AUTOMATION.md`
36
+ - Claude Desktop:
37
+ - `.audit-code/install/claude-desktop/PROJECT-TEMPLATE.md`
38
+ - `.audit-code/install/claude-desktop/remote-mcp-connector.json`
39
+ - `.audit-code/install/claude-desktop/auditor-lambda.dxt`
40
+ - `.audit-code/install/claude-desktop/auditor-lambda.mcpb`
41
+ - OpenCode:
42
+ - `.opencode/commands/audit-code.md`
43
+ - `.opencode/skills/audit-code/*`
44
+ - `opencode.json`
45
+ - `AGENTS.md` managed block when needed
46
+ - VS Code:
47
+ - `.github/prompts/audit-code.prompt.md`
48
+ - `.github/copilot-instructions.md`
49
+ - `.github/agents/auditor.agent.md`
50
+ - `.vscode/mcp.json`
51
+ - Antigravity:
52
+ - `.audit-code/install/antigravity/PLANNING-MODE.md`
53
+ - `AGENTS.md` managed block when needed
30
54
 
31
55
  The generated `GETTING-STARTED.md` now includes dedicated quick-start sections for:
32
56
 
33
- - VS Code
34
- - OpenCode
35
- - Claude Code
57
+ - Codex
36
58
  - Claude Desktop
59
+ - OpenCode
60
+ - VS Code
37
61
  - Antigravity
38
62
 
39
- Installed compatibility skill bundles:
40
-
41
- - `.opencode/skills/audit-code/*`
42
- - `.claude/skills/audit-code/*`
43
- - `.agents/skills/audit-code/*`
44
-
45
63
  ## Goal
46
64
 
47
- After bootstrap, the user should be able to open a supported conversation surface in the repository and invoke:
65
+ After bootstrap, the user should be able to open a supported host surface in the repository and invoke:
48
66
 
49
67
  ```text
50
68
  /audit-code
51
69
  ```
52
70
 
53
- without supplying extra root paths, provider flags, or model-selection arguments.
71
+ without supplying extra root paths, provider flags, or model-selection arguments, or connect through the shared MCP server when the host prefers tool-driven integration.
54
72
 
55
73
  ## What is fully automated today
56
74
 
57
- - VS Code and GitHub Copilot repo-local prompt surfaces
58
- - OpenCode project command surfaces
59
- - Claude Code project command surfaces
60
- - tool-agnostic compatibility instruction files for hosts that honor `AGENTS.md` or `CLAUDE.md`
75
+ - shared installer output, manifest generation, and repo-local MCP launcher generation
76
+ - Codex skill-bundle and AGENTS-oriented install output
77
+ - OpenCode command, skill, prompt, and config generation
78
+ - VS Code prompt, custom-agent, instruction, and MCP config generation
79
+ - Claude Desktop project-template, remote-connector, and local bundle generation
80
+ - Antigravity planning-mode guidance generation
61
81
 
62
82
  ## What is not fully automated today
63
83
 
64
- - Claude Desktop does not currently have a verified project-local slash-command install surface in this repository
65
- - Antigravity does not currently have a verified repo-local slash-command install surface in this repository
84
+ - product-level smoke validation for the generated Codex, Claude Desktop, OpenCode, and VS Code assets
85
+ - one-click proof that the generated Claude Desktop bundle installs cleanly in a real Desktop environment
86
+ - documented Antigravity artifact round-tripping back through `import_results` and `import_runtime_updates`
66
87
 
67
- For those hosts, the bootstrap command still installs compatibility assets, but the final `/audit-code` discovery behavior remains host-dependent.
88
+ For those gaps, the bootstrap command now writes the repo-local assets and guidance, but the final operator experience still needs end-to-end host verification.
68
89
 
69
- Use `.audit-code/install/GETTING-STARTED.md` as the low-guess repo-local handoff for those manual prompt-import paths and for the exact VS Code, OpenCode, and Claude Code bootstrap surfaces that were generated.
90
+ Use `.audit-code/install/GETTING-STARTED.md` as the low-guess repo-local handoff, and treat `.audit-code/install/manifest.json` as the machine-readable source of truth for what was generated.
70
91
 
71
92
  ## Narrow compatibility alias
72
93
 
@@ -77,3 +98,12 @@ audit-code install-host --host copilot
77
98
  ```
78
99
 
79
100
  Use it only when you intentionally want the smaller Copilot-only install path instead of the default bootstrap.
101
+
102
+ ## Remaining steps
103
+
104
+ The installer foundation is now in place. The remaining work is:
105
+
106
+ 1. smoke-test each claimed host in the real product, not only via file-generation tests
107
+ 2. tighten `GETTING-STARTED.md` and host-specific setup docs where those smoke tests show friction
108
+ 3. prove the Claude Desktop local bundle install path operationally
109
+ 4. document Antigravity artifact-import workflows more concretely