audit-tools 0.42.1 → 0.44.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 (237) hide show
  1. package/dispatch/merge-results.mjs +229 -140
  2. package/dispatch/validate-result.mjs +98 -40
  3. package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
  4. package/dist/audit/cli/conceptualDispatch.js +35 -3
  5. package/dist/audit/cli/conceptualDispatch.js.map +1 -1
  6. package/dist/audit/cli/dispatch/hostHandoff.d.ts +9 -1
  7. package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
  8. package/dist/audit/cli/dispatch/hostHandoff.js +94 -38
  9. package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
  10. package/dist/audit/cli/laneSubmissions.d.ts +2 -2
  11. package/dist/audit/cli/laneSubmissions.js +2 -2
  12. package/dist/audit/cli/nextStepCommand.d.ts +64 -0
  13. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  14. package/dist/audit/cli/nextStepCommand.js +877 -783
  15. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  16. package/dist/audit/cli/nextStepHelpers.d.ts +12 -36
  17. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  18. package/dist/audit/cli/nextStepHelpers.js +34 -77
  19. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  20. package/dist/audit/cli/steps.d.ts +2 -2
  21. package/dist/audit/extractors/graph.d.ts +28 -2
  22. package/dist/audit/extractors/graph.d.ts.map +1 -1
  23. package/dist/audit/extractors/graph.js +122 -11
  24. package/dist/audit/extractors/graph.js.map +1 -1
  25. package/dist/audit/extractors/graphRoutes.d.ts +8 -0
  26. package/dist/audit/extractors/graphRoutes.d.ts.map +1 -1
  27. package/dist/audit/extractors/graphRoutes.js +71 -4
  28. package/dist/audit/extractors/graphRoutes.js.map +1 -1
  29. package/dist/audit/io/artifacts.d.ts +55 -0
  30. package/dist/audit/io/artifacts.d.ts.map +1 -1
  31. package/dist/audit/io/artifacts.js +189 -12
  32. package/dist/audit/io/artifacts.js.map +1 -1
  33. package/dist/audit/io/toolingManifest.d.ts +11 -0
  34. package/dist/audit/io/toolingManifest.d.ts.map +1 -1
  35. package/dist/audit/io/toolingManifest.js +13 -3
  36. package/dist/audit/io/toolingManifest.js.map +1 -1
  37. package/dist/audit/orchestrator/advance.d.ts +64 -0
  38. package/dist/audit/orchestrator/advance.d.ts.map +1 -1
  39. package/dist/audit/orchestrator/advance.js +191 -57
  40. package/dist/audit/orchestrator/advance.js.map +1 -1
  41. package/dist/audit/orchestrator/charterClarificationExecutor.d.ts.map +1 -1
  42. package/dist/audit/orchestrator/charterClarificationExecutor.js +55 -21
  43. package/dist/audit/orchestrator/charterClarificationExecutor.js.map +1 -1
  44. package/dist/audit/orchestrator/flowCoverage.d.ts.map +1 -1
  45. package/dist/audit/orchestrator/flowCoverage.js +7 -10
  46. package/dist/audit/orchestrator/flowCoverage.js.map +1 -1
  47. package/dist/audit/orchestrator/flowPlanning.d.ts +54 -1
  48. package/dist/audit/orchestrator/flowPlanning.d.ts.map +1 -1
  49. package/dist/audit/orchestrator/flowPlanning.js +77 -18
  50. package/dist/audit/orchestrator/flowPlanning.js.map +1 -1
  51. package/dist/audit/orchestrator/flowRequeue.d.ts.map +1 -1
  52. package/dist/audit/orchestrator/flowRequeue.js +6 -10
  53. package/dist/audit/orchestrator/flowRequeue.js.map +1 -1
  54. package/dist/audit/orchestrator/requeueFold.d.ts.map +1 -1
  55. package/dist/audit/orchestrator/requeueFold.js +18 -5
  56. package/dist/audit/orchestrator/requeueFold.js.map +1 -1
  57. package/dist/audit/orchestrator/staleness.d.ts +24 -1
  58. package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
  59. package/dist/audit/orchestrator/staleness.js +147 -16
  60. package/dist/audit/orchestrator/staleness.js.map +1 -1
  61. package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts +26 -0
  62. package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts.map +1 -1
  63. package/dist/audit/orchestrator/syntaxResolutionExecutor.js +97 -12
  64. package/dist/audit/orchestrator/syntaxResolutionExecutor.js.map +1 -1
  65. package/dist/audit/orchestrator/taskBuilder.d.ts.map +1 -1
  66. package/dist/audit/orchestrator/taskBuilder.js +111 -21
  67. package/dist/audit/orchestrator/taskBuilder.js.map +1 -1
  68. package/dist/audit/orchestrator/trivialAudit.d.ts +17 -1
  69. package/dist/audit/orchestrator/trivialAudit.d.ts.map +1 -1
  70. package/dist/audit/orchestrator/trivialAudit.js +31 -4
  71. package/dist/audit/orchestrator/trivialAudit.js.map +1 -1
  72. package/dist/audit/types/analyzerCapability.d.ts +6 -6
  73. package/dist/audit/types/charterRegister.d.ts +30 -12
  74. package/dist/audit/types/charterRegister.d.ts.map +1 -1
  75. package/dist/audit/types/charterRegister.js +22 -9
  76. package/dist/audit/types/charterRegister.js.map +1 -1
  77. package/dist/audit/validation/anchorGrounding.d.ts.map +1 -1
  78. package/dist/audit/validation/anchorGrounding.js +17 -0
  79. package/dist/audit/validation/anchorGrounding.js.map +1 -1
  80. package/dist/audit/validation/auditResults.d.ts +17 -0
  81. package/dist/audit/validation/auditResults.d.ts.map +1 -1
  82. package/dist/audit/validation/auditResults.js +50 -17
  83. package/dist/audit/validation/auditResults.js.map +1 -1
  84. package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts +48 -0
  85. package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts.map +1 -1
  86. package/dist/remediate/contractPipeline/cyclicSeamResolution.js +128 -0
  87. package/dist/remediate/contractPipeline/cyclicSeamResolution.js.map +1 -1
  88. package/dist/remediate/contractPipeline/derive.d.ts +8 -5
  89. package/dist/remediate/contractPipeline/derive.d.ts.map +1 -1
  90. package/dist/remediate/contractPipeline/derive.js +8 -16
  91. package/dist/remediate/contractPipeline/derive.js.map +1 -1
  92. package/dist/remediate/index.d.ts.map +1 -1
  93. package/dist/remediate/index.js +43 -2
  94. package/dist/remediate/index.js.map +1 -1
  95. package/dist/remediate/intent/intentOrdering.d.ts +13 -5
  96. package/dist/remediate/intent/intentOrdering.d.ts.map +1 -1
  97. package/dist/remediate/intent/intentOrdering.js +56 -25
  98. package/dist/remediate/intent/intentOrdering.js.map +1 -1
  99. package/dist/remediate/phases/close.d.ts +57 -2
  100. package/dist/remediate/phases/close.d.ts.map +1 -1
  101. package/dist/remediate/phases/close.js +260 -36
  102. package/dist/remediate/phases/close.js.map +1 -1
  103. package/dist/remediate/phases/triage.d.ts.map +1 -1
  104. package/dist/remediate/phases/triage.js +14 -2
  105. package/dist/remediate/phases/triage.js.map +1 -1
  106. package/dist/remediate/state/disposition.d.ts +26 -4
  107. package/dist/remediate/state/disposition.d.ts.map +1 -1
  108. package/dist/remediate/state/itemStatus.d.ts +33 -6
  109. package/dist/remediate/state/itemStatus.d.ts.map +1 -1
  110. package/dist/remediate/state/itemStatus.js +154 -39
  111. package/dist/remediate/state/itemStatus.js.map +1 -1
  112. package/dist/remediate/state/types.d.ts +41 -2
  113. package/dist/remediate/state/types.d.ts.map +1 -1
  114. package/dist/remediate/state/types.js.map +1 -1
  115. package/dist/remediate/steps/contractPipeline.d.ts +296 -15
  116. package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
  117. package/dist/remediate/steps/contractPipeline.js +1783 -1001
  118. package/dist/remediate/steps/contractPipeline.js.map +1 -1
  119. package/dist/remediate/steps/dispatch/hostHandoff.d.ts +137 -2
  120. package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
  121. package/dist/remediate/steps/dispatch/hostHandoff.js +657 -59
  122. package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
  123. package/dist/remediate/steps/finalGate.d.ts +136 -37
  124. package/dist/remediate/steps/finalGate.d.ts.map +1 -1
  125. package/dist/remediate/steps/finalGate.js +120 -86
  126. package/dist/remediate/steps/finalGate.js.map +1 -1
  127. package/dist/remediate/steps/gateCommands.d.ts +8 -0
  128. package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
  129. package/dist/remediate/steps/gateCommands.js +40 -11
  130. package/dist/remediate/steps/gateCommands.js.map +1 -1
  131. package/dist/remediate/steps/nextStep.d.ts +96 -5
  132. package/dist/remediate/steps/nextStep.d.ts.map +1 -1
  133. package/dist/remediate/steps/nextStep.js +668 -147
  134. package/dist/remediate/steps/nextStep.js.map +1 -1
  135. package/dist/remediate/steps/types.d.ts +4 -3
  136. package/dist/remediate/steps/types.d.ts.map +1 -1
  137. package/dist/remediate/steps/types.js +10 -2
  138. package/dist/remediate/steps/types.js.map +1 -1
  139. package/dist/remediate/validation/artifacts.d.ts +20 -2
  140. package/dist/remediate/validation/artifacts.d.ts.map +1 -1
  141. package/dist/remediate/validation/artifacts.js +224 -130
  142. package/dist/remediate/validation/artifacts.js.map +1 -1
  143. package/dist/remediate/validation/contractPipelineGates.d.ts +58 -0
  144. package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
  145. package/dist/remediate/validation/contractPipelineGates.js +143 -27
  146. package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
  147. package/dist/shared/analyzers/acquisitionEngine.d.ts +72 -25
  148. package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
  149. package/dist/shared/analyzers/acquisitionEngine.js +149 -15
  150. package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
  151. package/dist/shared/analyzers/binaryAcquisition.d.ts +27 -2
  152. package/dist/shared/analyzers/binaryAcquisition.d.ts.map +1 -1
  153. package/dist/shared/analyzers/binaryAcquisition.js +149 -43
  154. package/dist/shared/analyzers/binaryAcquisition.js.map +1 -1
  155. package/dist/shared/analyzers/candidates.d.ts +9 -8
  156. package/dist/shared/analyzers/candidates.d.ts.map +1 -1
  157. package/dist/shared/analyzers/candidates.js +96 -64
  158. package/dist/shared/analyzers/candidates.js.map +1 -1
  159. package/dist/shared/analyzers/normalizeExternal.d.ts +40 -12
  160. package/dist/shared/analyzers/normalizeExternal.d.ts.map +1 -1
  161. package/dist/shared/analyzers/normalizeExternal.js +74 -18
  162. package/dist/shared/analyzers/normalizeExternal.js.map +1 -1
  163. package/dist/shared/analyzers/rubocop.d.ts +14 -13
  164. package/dist/shared/analyzers/rubocop.d.ts.map +1 -1
  165. package/dist/shared/analyzers/rubocop.js +29 -6
  166. package/dist/shared/analyzers/rubocop.js.map +1 -1
  167. package/dist/shared/analyzers/types.d.ts +196 -13
  168. package/dist/shared/analyzers/types.d.ts.map +1 -1
  169. package/dist/shared/analyzers/types.js +122 -9
  170. package/dist/shared/analyzers/types.js.map +1 -1
  171. package/dist/shared/decompose/charterClarification.d.ts +12 -1
  172. package/dist/shared/decompose/charterClarification.d.ts.map +1 -1
  173. package/dist/shared/decompose/charterClarification.js +11 -4
  174. package/dist/shared/decompose/charterClarification.js.map +1 -1
  175. package/dist/shared/decompose/charterExtraction.d.ts +20 -10
  176. package/dist/shared/decompose/charterExtraction.d.ts.map +1 -1
  177. package/dist/shared/decompose/charterExtraction.js +52 -23
  178. package/dist/shared/decompose/charterExtraction.js.map +1 -1
  179. package/dist/shared/index.d.ts +1 -0
  180. package/dist/shared/index.d.ts.map +1 -1
  181. package/dist/shared/index.js +5 -0
  182. package/dist/shared/index.js.map +1 -1
  183. package/dist/shared/intent/freeFormIntentInterpreter.d.ts +12 -2
  184. package/dist/shared/intent/freeFormIntentInterpreter.d.ts.map +1 -1
  185. package/dist/shared/intent/freeFormIntentInterpreter.js +27 -22
  186. package/dist/shared/intent/freeFormIntentInterpreter.js.map +1 -1
  187. package/dist/shared/intent/pathScope.d.ts +12 -1
  188. package/dist/shared/intent/pathScope.d.ts.map +1 -1
  189. package/dist/shared/intent/pathScope.js +56 -19
  190. package/dist/shared/intent/pathScope.js.map +1 -1
  191. package/dist/shared/intent/sharedIntentData.d.ts +19 -1
  192. package/dist/shared/intent/sharedIntentData.d.ts.map +1 -1
  193. package/dist/shared/intent/sharedIntentData.js +33 -8
  194. package/dist/shared/intent/sharedIntentData.js.map +1 -1
  195. package/dist/shared/io/fileLock.d.ts +12 -0
  196. package/dist/shared/io/fileLock.d.ts.map +1 -1
  197. package/dist/shared/io/fileLock.js +48 -5
  198. package/dist/shared/io/fileLock.js.map +1 -1
  199. package/dist/shared/io/json.d.ts +13 -0
  200. package/dist/shared/io/json.d.ts.map +1 -1
  201. package/dist/shared/io/json.js +19 -1
  202. package/dist/shared/io/json.js.map +1 -1
  203. package/dist/shared/steps/stepEmissionScaffold.d.ts +69 -0
  204. package/dist/shared/steps/stepEmissionScaffold.d.ts.map +1 -0
  205. package/dist/shared/steps/stepEmissionScaffold.js +83 -0
  206. package/dist/shared/steps/stepEmissionScaffold.js.map +1 -0
  207. package/dist/shared/submission/handRecovery.d.ts.map +1 -1
  208. package/dist/shared/submission/handRecovery.js +69 -4
  209. package/dist/shared/submission/handRecovery.js.map +1 -1
  210. package/dist/shared/submission/submissionIdentity.d.ts +10 -1
  211. package/dist/shared/submission/submissionIdentity.d.ts.map +1 -1
  212. package/dist/shared/submission/submissionIdentity.js +12 -3
  213. package/dist/shared/submission/submissionIdentity.js.map +1 -1
  214. package/dist/shared/submission/submissionLedger.d.ts +43 -2
  215. package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
  216. package/dist/shared/submission/submissionLedger.js +50 -7
  217. package/dist/shared/submission/submissionLedger.js.map +1 -1
  218. package/dist/shared/tooling/allowlistedExec.d.ts +9 -0
  219. package/dist/shared/tooling/allowlistedExec.d.ts.map +1 -1
  220. package/dist/shared/tooling/allowlistedExec.js +19 -2
  221. package/dist/shared/tooling/allowlistedExec.js.map +1 -1
  222. package/dist/shared/tooling/commandShape.d.ts +21 -0
  223. package/dist/shared/tooling/commandShape.d.ts.map +1 -0
  224. package/dist/shared/tooling/commandShape.js +120 -0
  225. package/dist/shared/tooling/commandShape.js.map +1 -0
  226. package/dist/shared/types/charter.d.ts +24 -0
  227. package/dist/shared/types/charter.d.ts.map +1 -1
  228. package/dist/shared/types/charter.js +9 -0
  229. package/dist/shared/types/charter.js.map +1 -1
  230. package/dist/shared/types/remediationOutcome.d.ts +282 -9
  231. package/dist/shared/types/remediationOutcome.d.ts.map +1 -1
  232. package/dist/shared/types/remediationOutcome.js +174 -1
  233. package/dist/shared/types/remediationOutcome.js.map +1 -1
  234. package/package.json +2 -1
  235. package/remediate-code.mjs +15 -0
  236. package/wrapper/remediate-code-wrapper-install-hosts.mjs +45 -4
  237. package/wrapper/remediate-code-wrapper-install-renderers.mjs +12 -2
@@ -1,13 +1,20 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Tool-owned final completion gate (INV-RS-10) + coarse re-block (INV-RS-09)
2
+ // Tool-owned final completion gate (INV-RS-10)
3
3
  // ---------------------------------------------------------------------------
4
4
  //
5
- // Behaviour-preserving extraction from `nextStep.ts` (CP-NODE-1): this is the
6
- // tool-owned final-gate cluster (the gate runner, its bounded coarse-reblock
7
- // backstop, and the sidecar counter I/O) lifted into a sibling leaf module so
8
- // the orchestrator god-module no longer owns it inline. `nextStep.ts` imports
9
- // and re-exports these symbols, so the public surface and existing test imports
10
- // are unchanged.
5
+ // The gate runner and its red record. A whole-repo gate red is UNATTRIBUTABLE
6
+ // by construction — nothing here computes which item or path caused it — so the
7
+ // only honest response is to record what failed and PAUSE. It does not mutate
8
+ // item statuses, does not move the run's phase, and does not close: a repeat
9
+ // next-step re-runs the gate and proceeds the moment it is green, which makes
10
+ // the pause resumable by construction rather than by a stored counter.
11
+ //
12
+ // This replaces a coarse backstop that re-opened EVERY non-skip item to
13
+ // `pending` on a red and, after a bounded number of tries, abandoned the whole
14
+ // run. It fired on 2026-08-20 against a suite reddened by an unrelated landed
15
+ // commit and wiped 21 accepted resolutions out of state.json — the failure the
16
+ // "Phase-boundary gate false abandonment" entry predicted, doing maximum damage
17
+ // on a red that had nothing to do with the run.
11
18
  //
12
19
  // INV-RS-10: the final completion gate is a TOOL-OWNED, NON-VACUOUS suite that
13
20
  // is INDEPENDENT of any `plan.test_command`. A run can only land green when this
@@ -31,14 +38,28 @@
31
38
  // gate must converge deterministically, so they are surfaced for a separate
32
39
  // pass instead of being able to strand the run.
33
40
  import { join } from "node:path";
34
- import { readOptionalJsonFile, writeJsonFile, runTracked } from "audit-tools/shared";
35
- import { isSkipStatus } from "../state/itemStatus.js";
41
+ import { writeJsonFile, runTracked } from "audit-tools/shared";
36
42
  import { isAuditToolsMonorepo, toolOwnedFinalGateCommands, } from "./gateCommands.js";
37
43
  // `FinalGateCommandSpec`, `isAuditToolsMonorepo`, and `toolOwnedFinalGateCommands`
38
44
  // are single-sourced in the leaf module `gateCommands.ts` (so `dispatch.ts` can
39
45
  // derive the same pinned merged-base check without an import cycle). Imported
40
46
  // here for local use and re-exported to preserve the public surface + test imports.
41
47
  export { isAuditToolsMonorepo, toolOwnedFinalGateCommands };
48
+ /**
49
+ * How much of a failing command's output rides into the persisted record. TAIL,
50
+ * because a suite prints its verdict last, and BOUNDED because this lands in a
51
+ * durable artifact — the standing rule against multi-KB tool output riding into
52
+ * a prompt applies to what a prompt POINTS AT as well.
53
+ */
54
+ const GATE_OUTPUT_TAIL_LIMIT = 4_000;
55
+ function outputTail(value) {
56
+ const text = value ?? "";
57
+ if (text.length === 0)
58
+ return undefined;
59
+ return text.length <= GATE_OUTPUT_TAIL_LIMIT
60
+ ? text
61
+ : `…${text.slice(text.length - GATE_OUTPUT_TAIL_LIMIT)}`;
62
+ }
42
63
  /**
43
64
  * Run the tool-owned final gate (INV-RS-10). Each command runs through the
44
65
  * shared `runTracked`, which scrubs CLAUDECODE / CLAUDE_CODE_*.
@@ -59,7 +80,16 @@ export async function runToolOwnedFinalGate(root, opts = {}) {
59
80
  if (commands.length === 0) {
60
81
  // Audit-tools-specific suite does not apply here — declared scope, not a
61
82
  // vacuous pass (it never substitutes for a real gate on the audit-tools repo).
62
- return { passed: true, results: [], scoped_out: true, runtime_residual };
83
+ // `passed: true` keeps it NON-BLOCKING, which is the declared design; the
84
+ // `outcome` beside it is what stops that non-blocking value from being
85
+ // recorded as if a floor had run green.
86
+ return {
87
+ passed: true,
88
+ results: [],
89
+ outcome: "scoped_out",
90
+ scoped_out: true,
91
+ runtime_residual,
92
+ };
63
93
  }
64
94
  const runner = opts.runner ??
65
95
  ((argv, cwd, packageDir) => {
@@ -72,106 +102,110 @@ export async function runToolOwnedFinalGate(root, opts = {}) {
72
102
  cwd: effectiveCwd,
73
103
  stdio: ["ignore", "pipe", "pipe"],
74
104
  });
75
- return { status: result.status };
105
+ // `runTracked` has always returned the captured streams; this used to read
106
+ // `status` alone and discard them, which is why a red gate persisted
107
+ // nothing an operator could read.
108
+ return {
109
+ status: result.status,
110
+ stdout: result.stdout,
111
+ stderr: result.stderr,
112
+ };
76
113
  });
77
114
  const results = [];
78
115
  let passed = true;
79
116
  for (const spec of commands) {
80
- const { status } = runner(spec.argv, root, spec.package_dir);
117
+ const { status, stdout, stderr } = runner(spec.argv, root, spec.package_dir);
81
118
  const cmdPassed = status === 0;
119
+ const stdoutTail = cmdPassed ? undefined : outputTail(stdout);
120
+ const stderrTail = cmdPassed ? undefined : outputTail(stderr);
82
121
  results.push({
83
122
  argv: spec.argv,
84
123
  layer: spec.layer,
85
124
  ...(spec.package_dir ? { package_dir: spec.package_dir } : {}),
86
125
  exit_code: status,
87
126
  passed: cmdPassed,
127
+ ...(stdoutTail === undefined ? {} : { stdout_tail: stdoutTail }),
128
+ ...(stderrTail === undefined ? {} : { stderr_tail: stderrTail }),
88
129
  });
89
130
  if (!cmdPassed) {
90
131
  passed = false;
91
132
  break; // short-circuit: later layers are meaningless on a broken floor
92
133
  }
93
134
  }
94
- return { passed, results, scoped_out: false, runtime_residual };
135
+ return {
136
+ passed,
137
+ results,
138
+ outcome: "executed",
139
+ scoped_out: false,
140
+ runtime_residual,
141
+ };
95
142
  }
143
+ const FINAL_GATE_STATE_FILENAME = "final-gate.json";
144
+ const FINAL_GATE_OUTCOME_FILENAME = "final-gate-outcome.json";
96
145
  /**
97
- * The bound on coarse re-block iterations before the run converges to a terminal
98
- * `blocked` close (CE-003). Two re-block attempts give a flaky-but-recoverable
99
- * suite a chance to settle; the third unattributable red terminates
100
- * deterministically rather than livelocking.
146
+ * Where the failing gate run is recorded, relative to the artifacts dir. The
147
+ * step prompt carries this PATH and the failing command line — never the tail
148
+ * itself, which is what keeps a multi-KB suite log out of the prompt while
149
+ * still leaving it one open away.
101
150
  */
102
- export const COARSE_REBLOCK_BOUND = 2;
103
- const FINAL_GATE_STATE_FILENAME = "final-gate.json";
104
- export async function readFinalGateSidecar(artifactsDir) {
105
- const sidecar = await readOptionalJsonFile(join(artifactsDir, FINAL_GATE_STATE_FILENAME));
106
- const n = sidecar?.coarse_reblock_count;
107
- return {
108
- count: typeof n === "number" && Number.isFinite(n) && n >= 0 ? n : 0,
109
- terminated: sidecar?.terminated === true,
110
- };
151
+ export function finalGateRecordPath(artifactsDir) {
152
+ return join(artifactsDir, FINAL_GATE_STATE_FILENAME);
111
153
  }
112
- export async function writeFinalGateSidecar(artifactsDir, count, terminated) {
113
- await writeJsonFile(join(artifactsDir, FINAL_GATE_STATE_FILENAME), {
114
- schema_version: "remediate-code-final-gate/v1alpha1",
115
- coarse_reblock_count: count,
116
- terminated,
117
- });
154
+ /**
155
+ * Where the LAST gate evaluation's outcome is recorded, relative to the
156
+ * artifacts dir. Distinct from {@link finalGateRecordPath}, which only exists
157
+ * when a gate ran and went RED: this one is written on EVERY evaluation,
158
+ * including the two that run nothing.
159
+ */
160
+ export function finalGateOutcomePath(artifactsDir) {
161
+ return join(artifactsDir, FINAL_GATE_OUTCOME_FILENAME);
118
162
  }
119
163
  /**
120
- * Coarse re-block-ALL-non-terminal on an unattributable final-gate red
121
- * (INV-RS-09) with a bounded, monotonic auto-terminate (CE-003).
122
- *
123
- * The tool-owned gate is whole-repo, so a red is inherently unattributable to a
124
- * single node. Below the bound, EVERY non-skip item (including `resolved` ones —
125
- * a resolved item's own change may have caused the red) is re-opened to `pending`
126
- * and the run re-attempts the whole repo through the rolling scheduler
127
- * (`reattempt_all` → `implementing`). At or above the bound, the run STOPS
128
- * re-attempting and converges DETERMINISTICALLY: every non-skip item becomes
129
- * terminal `blocked` and the run advances to `closing`.
164
+ * Record what a gate evaluation was. Overwrites: the file describes the CURRENT
165
+ * gate state of the run, the same way {@link writeFinalGateRedRecord} does for a
166
+ * red, and a repeat next-step re-evaluates rather than accumulating a history
167
+ * nothing reads.
130
168
  *
131
- * CE-003 no-human-host guarantee: the loop is owned entirely by the gate + the
132
- * rolling scheduler — it NEVER routes through the human triage prompt
133
- * (`waiting_for_triage`) and is bounded by `bound`, so a permanently-red sibling
134
- * converges to a terminal `blocked` close deterministically: never livelocking,
135
- * never stranding on a human prompt, and never force-closed to green (a RED gate
136
- * always leaves `blocked` items, so close.ts's `!anyBlocked` guard keeps the run
137
- * out of the fully-green path). User SKIP dispositions (ignored /
138
- * deemed_inappropriate) are settled decisions and are left alone. Pure (the
139
- * counter is supplied / returned).
169
+ * The `passed: null` normalization lives HERE rather than at each call site:
170
+ * a caller cannot record a not-run gate as a pass even by passing `true`.
140
171
  */
141
- export function applyCoarseReblock(state, currentCount, gateSummary, bound = COARSE_REBLOCK_BOUND) {
142
- const now = new Date().toISOString();
143
- if (currentCount >= bound) {
144
- // Bounded auto-terminate: converge DETERMINISTICALLY to a terminal close for a
145
- // no-human host — never livelock, never a triage prompt, never green.
146
- //
147
- // `abandoned`, NOT `blocked`: this is the force-close seam, and `blocked` is
148
- // deliberately non-terminal (triage retries it). Leaving items non-terminal here
149
- // meant the run ended with items that had reached no end state, which the close
150
- // phase then rendered as a partial-completion outcome — breaking the invariant
151
- // that remediation ends binary. `abandoned` is terminal and says which way it
152
- // ended: the tool gave up, as distinct from a settled decision not to act.
153
- for (const it of Object.values(state.items ?? {})) {
154
- if (isSkipStatus(it.status))
155
- continue; // settled user decision — never overturn
156
- it.status = "abandoned";
157
- it.started_at ??= now;
158
- it.completed_at = now;
159
- it.failure_reason =
160
- `Tool-owned final gate failed and the coarse re-block backstop reached its ` +
161
- `bound (${bound}); abandoning the remaining items (no-human host). ${gateSummary}`;
162
- }
163
- return { state, action: "terminal_blocked", next_count: currentCount };
164
- }
165
- // Below the bound: re-open every non-skip item to `pending` and re-attempt the
166
- // whole repo via the rolling scheduler (NOT the human triage prompt).
167
- for (const it of Object.values(state.items ?? {})) {
168
- if (isSkipStatus(it.status))
169
- continue;
170
- it.status = "pending";
171
- it.failure_context =
172
- `Re-attempted by the coarse final-gate backstop (unattributable whole-repo red). ${gateSummary}`;
173
- delete it.completed_at;
174
- }
175
- return { state, action: "reattempt_all", next_count: currentCount + 1 };
172
+ export async function writeFinalGateOutcomeRecord(artifactsDir, outcome) {
173
+ const path = finalGateOutcomePath(artifactsDir);
174
+ const ran = outcome.outcome === "executed";
175
+ const record = {
176
+ schema_version: "remediate-code-final-gate-outcome/v1alpha1",
177
+ scope: outcome.scope,
178
+ outcome: outcome.outcome,
179
+ passed: ran ? outcome.passed : null,
180
+ commands_run: ran ? outcome.commands_run : 0,
181
+ ...(outcome.reason === undefined ? {} : { reason: outcome.reason }),
182
+ recorded_at: new Date().toISOString(),
183
+ };
184
+ await writeJsonFile(path, record);
185
+ return path;
186
+ }
187
+ /**
188
+ * Record the failing command of a red gate run. Overwrites: the file describes
189
+ * the CURRENT reason the run is paused, and a repeat next-step that still finds
190
+ * the suite red rewrites it rather than accumulating a history nothing reads.
191
+ */
192
+ export async function writeFinalGateRedRecord(artifactsDir, scope, failed) {
193
+ const path = finalGateRecordPath(artifactsDir);
194
+ const record = {
195
+ schema_version: "remediate-code-final-gate/v1alpha1",
196
+ scope,
197
+ recorded_at: new Date().toISOString(),
198
+ failing_command: failed ? failed.argv.join(" ") : "(command not reported)",
199
+ exit_code: failed?.exit_code ?? null,
200
+ layer: failed?.layer ?? null,
201
+ ...(failed?.stdout_tail === undefined
202
+ ? {}
203
+ : { stdout_tail: failed.stdout_tail }),
204
+ ...(failed?.stderr_tail === undefined
205
+ ? {}
206
+ : { stderr_tail: failed.stderr_tail }),
207
+ };
208
+ await writeJsonFile(path, record);
209
+ return path;
176
210
  }
177
211
  //# sourceMappingURL=finalGate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"finalGate.js","sourceRoot":"","sources":["../../../src/remediate/steps/finalGate.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,iBAAiB;AACjB,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,iFAAiF;AACjF,6EAA6E;AAC7E,qEAAqE;AACrE,kCAAkC;AAClC,EAAE;AACF,oFAAoF;AACpF,oFAAoF;AACpF,mEAAmE;AACnE,iFAAiF;AACjF,+BAA+B;AAC/B,sGAAsG;AACtG,0CAA0C;AAC1C,EAAE;AACF,oEAAoE;AACpE,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,4EAA4E;AAC5E,gDAAgD;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,mBAAmB,CAAC;AAE3B,mFAAmF;AACnF,gFAAgF;AAChF,8EAA8E;AAC9E,oFAAoF;AACpF,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,CAAC;AAoC5D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAY,EACZ,OAAgC,EAAE;IAElC,MAAM,gBAAgB,GAAG;QACvB,OAAO,EAAE,8CAA8C;QACvD,QAAQ,EAAE;YACR,mCAAmC;YACnC,uCAAuC;SACxC;KACF,CAAC;IAEF,MAAM,QAAQ,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,yEAAyE;QACzE,+EAA+E;QAC/E,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;IAC3E,CAAC;IAED,MAAM,MAAM,GACV,IAAI,CAAC,MAAM;QACX,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE;YACzB,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;YAChC,4EAA4E;YAC5E,2DAA2D;YAC3D,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/D,4DAA4D;YAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE;gBAC5C,GAAG,EAAE,YAAY;gBACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,SAAS,EAAE,MAAM;YACjB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,KAAK,CAAC;YACf,MAAM,CAAC,gEAAgE;QACzE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAQpD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB;IAEpB,MAAM,OAAO,GAAG,MAAM,oBAAoB,CACxC,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAC9C,CAAC;IACF,MAAM,CAAC,GAAG,OAAO,EAAE,oBAAoB,CAAC;IACxC,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,UAAU,EAAE,OAAO,EAAE,UAAU,KAAK,IAAI;KACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,YAAoB,EACpB,KAAa,EACb,UAAmB;IAEnB,MAAM,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,EAAE;QACjE,cAAc,EAAE,oCAAoC;QACpD,oBAAoB,EAAE,KAAK;QAC3B,UAAU;KACX,CAAC,CAAC;AACL,CAAC;AAUD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAuB,EACvB,YAAoB,EACpB,WAAmB,EACnB,QAAgB,oBAAoB;IAEpC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;QAC1B,+EAA+E;QAC/E,sEAAsE;QACtE,EAAE;QACF,6EAA6E;QAC7E,iFAAiF;QACjF,gFAAgF;QAChF,+EAA+E;QAC/E,8EAA8E;QAC9E,2EAA2E;QAC3E,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YAClD,IAAI,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC;gBAAE,SAAS,CAAC,yCAAyC;YAChF,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC;YACxB,EAAE,CAAC,UAAU,KAAK,GAAG,CAAC;YACtB,EAAE,CAAC,YAAY,GAAG,GAAG,CAAC;YACtB,EAAE,CAAC,cAAc;gBACf,4EAA4E;oBAC5E,UAAU,KAAK,sDAAsD,WAAW,EAAE,CAAC;QACvF,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;IACzE,CAAC;IAED,+EAA+E;IAC/E,sEAAsE;IACtE,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QAClD,IAAI,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC;YAAE,SAAS;QACtC,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC;QACtB,EAAE,CAAC,eAAe;YAChB,mFAAmF,WAAW,EAAE,CAAC;QACnG,OAAO,EAAE,CAAC,YAAY,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,GAAG,CAAC,EAAE,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"finalGate.js","sourceRoot":"","sources":["../../../src/remediate/steps/finalGate.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,14 @@ export interface FinalGateCommandSpec {
14
14
  * commands) applies to. The gate's command list is audit-tools-specific by
15
15
  * design (this remediation run remediates the audit-tools monorepo), so it is
16
16
  * scoped to that structure rather than fabricated for an arbitrary target repo.
17
+ *
18
+ * The predicate checks every marker AND the script the gate will actually spawn.
19
+ * Checking only the layout markers made applicability a COINCIDENCE: a tree with
20
+ * the five markers but no gate script would be judged in-scope, then run
21
+ * `node <missing path>`, exit 1, and report a whole-repo RED on a healthy repo —
22
+ * precisely the false-red class this gate's pause design exists to avoid, and
23
+ * reachable because a five-marker tree is easy to construct (a test fixture is
24
+ * one). A tree that cannot run the suite is OUT of scope, not failing it.
17
25
  */
18
26
  export declare function isAuditToolsMonorepo(root: string): boolean;
19
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gateCommands.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/gateCommands.ts"],"names":[],"mappings":"AAYA,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mFAAmF;IACnF,UAAU,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAU1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAmC/E"}
1
+ {"version":3,"file":"gateCommands.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/gateCommands.ts"],"names":[],"mappings":"AAYA,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mFAAmF;IACnF,UAAU,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;CACnC;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAW1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAiD/E"}
@@ -1,11 +1,25 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ /**
4
+ * The vitest gate script the unit leg executes, repo-relative. Named once and
5
+ * used by BOTH the scoping predicate and the command list, so the file the
6
+ * predicate checks for is provably the file the gate runs.
7
+ */
8
+ const VITEST_GATE_SCRIPT = join("scripts", "shared", "run-vitest-gate.mjs");
3
9
  /**
4
10
  * Whether `root` is the audit-tools monorepo — the repo the tool-owned final
5
11
  * gate's suite (INV-RS-10, literally the audit-tools build/check/per-package
6
12
  * commands) applies to. The gate's command list is audit-tools-specific by
7
13
  * design (this remediation run remediates the audit-tools monorepo), so it is
8
14
  * scoped to that structure rather than fabricated for an arbitrary target repo.
15
+ *
16
+ * The predicate checks every marker AND the script the gate will actually spawn.
17
+ * Checking only the layout markers made applicability a COINCIDENCE: a tree with
18
+ * the five markers but no gate script would be judged in-scope, then run
19
+ * `node <missing path>`, exit 1, and report a whole-repo RED on a healthy repo —
20
+ * precisely the false-red class this gate's pause design exists to avoid, and
21
+ * reachable because a five-marker tree is easy to construct (a test fixture is
22
+ * one). A tree that cannot run the suite is OUT of scope, not failing it.
9
23
  */
10
24
  export function isAuditToolsMonorepo(root) {
11
25
  // Single-package layout: the three subsystems are inlined under src/ and both
@@ -14,7 +28,8 @@ export function isAuditToolsMonorepo(root) {
14
28
  existsSync(join(root, "src", "audit")) &&
15
29
  existsSync(join(root, "src", "remediate")) &&
16
30
  existsSync(join(root, "audit-code.mjs")) &&
17
- existsSync(join(root, "remediate-code.mjs")));
31
+ existsSync(join(root, "remediate-code.mjs")) &&
32
+ existsSync(join(root, VITEST_GATE_SCRIPT)));
18
33
  }
19
34
  /**
20
35
  * The tool-owned final-gate command list (INV-RS-10) for the audit-tools
@@ -46,17 +61,31 @@ export function toolOwnedFinalGateCommands(root) {
46
61
  // FAIL on the current tree (the .test.mjs files use vitest globals, not node:test).
47
62
  //
48
63
  // `--retry=2` is FLAKE-TOLERANCE, not flake-masking: the tool-owned gate is a
49
- // ROBUSTNESS check (did the remediation's edits break the repo?), and its red is
50
- // COARSE-REBLOCK-ALL (INV-RS-09) — a single transient timing flake in the target
51
- // suite (e.g. a rolling-dispatch "expected 1 to be 2" race under full parallel
52
- // load) otherwise reopens EVERY item to pending and, on a second flake, terminal-
53
- // blocks the whole run (CE-003 bound 2) with zero fixes landed — the exact failure
54
- // this scoping is closing. A genuinely-broken test still fails all retries → red →
55
- // reblock; only a test that PASSES on retry (i.e. was flaky, not broken) is spared.
56
- // Gate-scoped ON PURPOSE (never vitest.config `retry`, which would mask flakes in
57
- // CI / `npm test` where surfacing them is the point).
64
+ // ROBUSTNESS check (did the remediation's edits break the repo?), and a red
65
+ // HALTS the run — it pauses at the boundary until a human makes the suite
66
+ // green. A single transient timing flake in the target suite (e.g. a
67
+ // rolling-dispatch "expected 1 to be 2" race under full parallel load) would
68
+ // otherwise stop a healthy run and demand attention for a failure that does
69
+ // not reproduce. A genuinely-broken test still fails all retries → red →
70
+ // pause; only a test that PASSES on retry (i.e. was flaky, not broken) is
71
+ // spared. Gate-scoped ON PURPOSE (never vitest.config `retry`, which would
72
+ // mask flakes in CI / `npm test` where surfacing them is the point).
73
+ //
74
+ // Routed through `run-vitest-gate.mjs`, never a bare `npx vitest run`: a raw
75
+ // vitest exit code is not a verdict in this repo. It has exited 0 while
76
+ // reporting failures (the false-green defect) and exits 1 with ZERO failures
77
+ // under worker-RPC starvation (the false-RED one) — and a false RED here is
78
+ // not cosmetic, it is a whole-repo gate red on a healthy tree. The script
79
+ // decides from the token-bound outcome ledger the reporter writes and fails
80
+ // closed when it cannot prove the ledger belongs to this run, so its exit IS
81
+ // trustworthy. Declared here rather than rewritten at execution time so the
82
+ // command that is declared and the command that runs stay the same string.
58
83
  {
59
- argv: ["npx", "vitest", "run", "--retry=2"],
84
+ // Forward slashes: this is an argv token handed to a shell, not a path
85
+ // joined against the filesystem, and both platforms accept `/` here. The
86
+ // predicate above checks the same file through `join`, which is the
87
+ // platform-correct form for an existence test.
88
+ argv: ["node", "scripts/shared/run-vitest-gate.mjs", "--retry=2"],
60
89
  build_free: true,
61
90
  layer: "unit",
62
91
  },
@@ -1 +1 @@
1
- {"version":3,"file":"gateCommands.js","sourceRoot":"","sources":["../../../src/remediate/steps/gateCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsBjC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,8EAA8E;IAC9E,iFAAiF;IACjF,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACvC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QAC1C,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACxC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAY;IACrD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,OAAO;QACL,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;QACpE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;QACnE,uEAAuE;QACvE,4EAA4E;QAC5E,6EAA6E;QAC7E,wEAAwE;QACxE,uEAAuE;QACvE,8BAA8B;QAC9B,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;QACzE,8EAA8E;QAC9E,gFAAgF;QAChF,gFAAgF;QAChF,gFAAgF;QAChF,+EAA+E;QAC/E,oFAAoF;QACpF,EAAE;QACF,8EAA8E;QAC9E,iFAAiF;QACjF,iFAAiF;QACjF,+EAA+E;QAC/E,kFAAkF;QAClF,mFAAmF;QACnF,mFAAmF;QACnF,oFAAoF;QACpF,kFAAkF;QAClF,sDAAsD;QACtD;YACE,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC;YAC3C,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,MAAM;SACd;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"gateCommands.js","sourceRoot":"","sources":["../../../src/remediate/steps/gateCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsBjC;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,8EAA8E;IAC9E,iFAAiF;IACjF,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACvC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QAC1C,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACxC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC5C,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAC3C,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAY;IACrD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,OAAO;QACL,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;QACpE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;QACnE,uEAAuE;QACvE,4EAA4E;QAC5E,6EAA6E;QAC7E,wEAAwE;QACxE,uEAAuE;QACvE,8BAA8B;QAC9B,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;QACzE,8EAA8E;QAC9E,gFAAgF;QAChF,gFAAgF;QAChF,gFAAgF;QAChF,+EAA+E;QAC/E,oFAAoF;QACpF,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,0EAA0E;QAC1E,qEAAqE;QACrE,6EAA6E;QAC7E,4EAA4E;QAC5E,yEAAyE;QACzE,0EAA0E;QAC1E,2EAA2E;QAC3E,qEAAqE;QACrE,EAAE;QACF,6EAA6E;QAC7E,wEAAwE;QACxE,6EAA6E;QAC7E,4EAA4E;QAC5E,0EAA0E;QAC1E,4EAA4E;QAC5E,6EAA6E;QAC7E,4EAA4E;QAC5E,2EAA2E;QAC3E;YACE,uEAAuE;YACvE,yEAAyE;YACzE,oEAAoE;YACpE,+CAA+C;YAC/C,IAAI,EAAE,CAAC,MAAM,EAAE,oCAAoC,EAAE,WAAW,CAAC;YACjE,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,MAAM;SACd;KACF,CAAC;AACJ,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { type RemediationState } from "../state/store.js";
2
- import { type FrictionTriageDecision, type InterpretedIntent } from "audit-tools/shared";
3
- import { hostDependencyLevels } from "./dispatch/hostHandoff.js";
2
+ import type { Finding } from "../state/types.js";
3
+ import { RunLogger, type FrictionTriageDecision, type InterpretedIntent } from "audit-tools/shared";
4
+ import { hostDependencyLevels, type RemediationHostIngestSummary } from "./dispatch/hostHandoff.js";
4
5
  import type { RemediationStep } from "./types.js";
5
6
  import { isTerminalStatus, isVerifiedCompleteStatus } from "../state/itemStatus.js";
6
7
  import { type GateRunner } from "./finalGate.js";
@@ -36,6 +37,27 @@ export interface NextStepOptions {
36
37
  */
37
38
  finalGateRunner?: GateRunner;
38
39
  }
40
+ /**
41
+ * Where an autonomous run's LEFTOVER deliverable pair lands.
42
+ *
43
+ * REMEDIATION-OWNED, deliberately. This module used to write the canonical
44
+ * `.audit-tools/audit-findings.json` + `audit-report.md` pair directly and
45
+ * unarchived, which destroys the audit source `defaultInputCandidates` resolves
46
+ * FIRST — the original contract becomes unrecoverable for any external consumer
47
+ * (INV-RNF-NO-CANONICAL-PAIR-WRITE). The canonical pair belongs to
48
+ * audit-artifact-promotion-lifecycle, whose exported write-with-archive is the
49
+ * only sanctioned way to replace it.
50
+ */
51
+ export declare function autonomousLeftoverFindingsPath(root: string): string;
52
+ export declare function autonomousLeftoverReportPath(root: string): string;
53
+ /**
54
+ * The intake sources a bare `next-step` discovers, IN PRIORITY ORDER — index 0
55
+ * wins. Exported so the ordering can be asserted by CALLING it: the property
56
+ * that matters ("a real audit always beats this run's own leftovers") is a fact
57
+ * about the returned array, and a test that reads it out of the source text is
58
+ * asserting the prose, not the order.
59
+ */
60
+ export declare function defaultInputCandidates(root: string): string[];
39
61
  export type { FindingRiskTier, FindingClassification, } from "./stepUtils.js";
40
62
  export { dependencyVerifiedComplete, classifyFindingRisk, } from "./stepUtils.js";
41
63
  export { isTerminalStatus, isVerifiedCompleteStatus };
@@ -60,8 +82,77 @@ export { hostDependencyLevels };
60
82
  * checkpoint for the last/only phase.
61
83
  */
62
84
  export declare function phaseBoundaryToGate(state: RemediationState): number | null;
63
- export { isAuditToolsMonorepo, toolOwnedFinalGateCommands, runToolOwnedFinalGate, applyCoarseReblock, COARSE_REBLOCK_BOUND, } from "./finalGate.js";
64
- export type { FinalGateCommandSpec, FinalGateCommandResult, ToolOwnedFinalGateResult, GateRunner, CoarseReblockAction, CoarseReblockDecision, } from "./finalGate.js";
85
+ export { isAuditToolsMonorepo, toolOwnedFinalGateCommands, runToolOwnedFinalGate, finalGateOutcomePath, writeFinalGateOutcomeRecord, } from "./finalGate.js";
86
+ export type { FinalGateCommandSpec, FinalGateCommandResult, ToolOwnedFinalGateResult, FinalGateOutcomeKind, FinalGateOutcomeRecord, GateRunner, } from "./finalGate.js";
87
+ /**
88
+ * The re-plan carry-forward identity of a finding: canonical JSON with the
89
+ * plan-time bookkeeping keys stripped, so a re-plan whose only delta is a
90
+ * recomputed file hash or a re-evaluated grounding flag carries the prior item
91
+ * (and its `item_spec`) forward, while a real change to the finding does not.
92
+ *
93
+ * EXPORTED so the invariant suite can call THIS function. It was module-internal,
94
+ * and the suite claiming to cover the invariant declared its own copy of the key
95
+ * set, the strip and the key builder — so dropping `evidence_grounded` from the
96
+ * production set, or widening it with a real field like `severity`, left the
97
+ * block green while carry-forward regressed. A test asserting against its own
98
+ * re-implementation pins nothing about shipped behaviour.
99
+ */
100
+ export declare function findingCarryForwardKey(finding: Finding): string;
101
+ /**
102
+ * The `recover-ingest` verb's whole body: ingest the host's landed results in
103
+ * RECOVERY mode and persist through the same file-locked, atomically-writing
104
+ * store, with the same `contract_version` strip.
105
+ *
106
+ * It is a separate verb rather than a flag on `next-step` because the
107
+ * relaxation it enables must be an operator's explicit act — see
108
+ * `ingestRemediationHostResults`, which states what is waived and the residual
109
+ * risk. Nothing else here differs from the normal ingestion: the same workload,
110
+ * the same contract gates, the same eligibility frontier.
111
+ *
112
+ * ## Why this runs in two phases
113
+ *
114
+ * A required-test rerun is `spawnSync`, which blocks the event loop for its
115
+ * whole duration. Run inside the state lock, it would starve the lock's own
116
+ * heartbeat timer (`setInterval` in the shared fileLock) — the held lock's mtime
117
+ * would stop being refreshed, a second acquirer would classify it as stale at
118
+ * ~30s and steal it, and mutual exclusion would be gone precisely during the
119
+ * longest critical section in the codebase. Holding a lock across a blocking
120
+ * spawn is therefore not merely slow; it is unsound.
121
+ *
122
+ * So:
123
+ *
124
+ * - **Phase 1, UNLOCKED.** Snapshot the state, capture HEAD, and run every
125
+ * distinct required-test command exactly once
126
+ * (`precomputeRecoveryTestVerdicts`). HEAD is captured BEFORE the spawns, not
127
+ * after, because a host-authored command that MOVES HEAD would otherwise
128
+ * produce verdicts of mixed provenance and go undetected. (The guard compares
129
+ * commit shas: it sees HEAD movement, not worktree dirt — a command that only
130
+ * dirties files is invisible to it, which is acceptable because phase 2's
131
+ * corroboration is commit-based.)
132
+ * - **Phase 2, LOCKED.** Re-read HEAD and abort the whole recovery if it moved
133
+ * (`tree_moved_between_phases`) — the phase-1 verdicts would describe a tree
134
+ * that no longer exists, and nothing is accepted or appended. Otherwise ingest
135
+ * with the pre-computed verdicts, which the ingest only READS: in recovery
136
+ * mode it never spawns, and a command missing from the table fails closed.
137
+ *
138
+ * What remains inside the lock is git plumbing (ancestry, ref scan, diff-tree),
139
+ * the ledger append, and the state write — sub-second work, comfortably inside
140
+ * heartbeat coverage. The HEAD-unchanged guard closes the gap the phase split
141
+ * opens; the operational protocol is still one writer at a time, now enforced by
142
+ * a lock that cannot be stolen mid-hold instead of by convention.
143
+ *
144
+ * One accepted cost: `StateStore.mutate` always writes, so a recovery run that
145
+ * changes nothing rewrites `state.json` with identical content. Expressing a
146
+ * true no-op means plumbing the locked store's `SKIP_WRITE` sentinel through
147
+ * `StateStore.mutate`, which is a change to the store's API rather than to this
148
+ * verb. The `state_changed` flag on the returned summary stays authoritative
149
+ * for callers either way.
150
+ */
151
+ export declare function recoverIngestHostResults(options: {
152
+ readonly root: string;
153
+ readonly artifactsDir: string;
154
+ readonly runId: string;
155
+ }): Promise<RemediationHostIngestSummary>;
65
156
  /**
66
157
  * The terminal friction-TRIAGE close-out for the remediate half. Thin delegation to
67
158
  * the single-sourced `decideFrictionTriage` (`audit-tools/shared`) — the exact analog
@@ -98,5 +189,5 @@ export interface PersistedIntentInterpretation {
98
189
  * throws into the decide loop. The raw `free_form_intent` string is NOT returned
99
190
  * or threaded anywhere — only the structured `InterpretedIntent` is (INV-S04).
100
191
  */
101
- export declare function interpretConfirmedCheckpointIntent(artifactsDir: string, checkpoint: IntentCheckpoint | undefined): Promise<PersistedIntentInterpretation | null>;
192
+ export declare function interpretConfirmedCheckpointIntent(artifactsDir: string, checkpoint: IntentCheckpoint | undefined, runLogger?: RunLogger): Promise<PersistedIntentInterpretation | null>;
102
193
  //# sourceMappingURL=nextStep.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextStep.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/nextStep.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAStE,OAAO,EAuBL,KAAK,sBAAsB,EAG3B,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAa5B,OAAO,EAEL,oBAAoB,EAGrB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAyCxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAoB3D,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,UAAU,CAAC;CAC9B;AA6KD,YAAY,EACV,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAmEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAa1E;AAYD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,UAAU,EACV,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAgexB;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACnD,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAEjC;AA4yDD,wBAAsB,cAAc,CAClC,OAAO,GAAE,eAAe,GAAG,MAAW,GACrC,OAAO,CAAC,eAAe,CAAC,CAmC1B;AA6OD,uFAAuF;AACvF,eAAO,MAAM,8BAA8B,+BAA+B,CAAC;AAC3E,eAAO,MAAM,oCAAoC,kDACA,CAAC;AAElD,MAAM,WAAW,6BAA6B;IAC5C,cAAc,EAAE,OAAO,oCAAoC,CAAC;IAC5D,6EAA6E;IAC7E,WAAW,EAAE,iBAAiB,CAAC;IAC/B;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAsB,kCAAkC,CACtD,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,gBAAgB,GAAG,SAAS,GACvC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC,CA6B/C"}
1
+ {"version":3,"file":"nextStep.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/nextStep.ts"],"names":[],"mappings":"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"}