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 +1 @@
1
- {"version":3,"file":"intentOrdering.js","sourceRoot":"","sources":["../../../src/remediate/intent/intentOrdering.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intentOrdering.js","sourceRoot":"","sources":["../../../src/remediate/intent/intentOrdering.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,19 @@ import { OrchestratorOptions } from "../types/options.js";
3
3
  import type { RemediationOutcomesReport, RunLogger, VerificationReport } from "audit-tools/shared";
4
4
  import type { ClosingAction } from "../state/closingActions.js";
5
5
  import type { OutcomeCoverageLedger } from "../state/types.js";
6
- export declare function buildRemediationOutcomesReport(state: RemediationState, closingResult: ClosingResult): RemediationOutcomesReport;
6
+ import { type FinalGateReport } from "../../shared/types/remediationOutcome.js";
7
+ /**
8
+ * Read the run's tool-owned gate outcome for the report.
9
+ *
10
+ * The gate WRITES `final-gate-outcome.json` on every evaluation; until this
11
+ * reader existed, nothing consumed it — so a scoped-out or suppressed run
12
+ * produced a completion report byte-identical to one written after a green
13
+ * floor, which is the whole defect the record was added to close. A record that
14
+ * is missing, unreadable, or fails its schema degrades to
15
+ * {@link ABSENT_FINAL_GATE_REPORT}: stated as absent, never as green.
16
+ */
17
+ export declare function readFinalGateReport(artifactsDir: string): Promise<FinalGateReport>;
18
+ export declare function buildRemediationOutcomesReport(state: RemediationState, closingResult: ClosingResult, finalGate?: FinalGateReport): RemediationOutcomesReport;
7
19
  /**
8
20
  * Build the outcomes file's coverage-ledger section: the plan's coverage ledger
9
21
  * with every never-planned entry (cross-lens-deduped, checkpoint-dropped,
@@ -97,17 +109,60 @@ export interface StagingSelection {
97
109
  export declare function collectStagingFiles(root: string, manifest: string[], deliverables?: string[]): StagingSelection;
98
110
  export declare function executeClosingAction(state: RemediationState, options: OrchestratorOptions): ClosingResult;
99
111
  export interface CombinedTestResult {
112
+ /**
113
+ * Whether a suite actually ran. `false` means `plan.test_command` was never
114
+ * configured — a NEVER-RAN outcome, structurally distinct from `passed`, so
115
+ * a caller can no longer mistake "nothing ran" for "a real pass" (the
116
+ * vacuous-pass defect: previously `passed:true` alone claimed a real result
117
+ * even for an unrun, unconfigured suite).
118
+ */
119
+ ran: boolean;
100
120
  passed: boolean;
101
121
  duration_ms: number;
102
122
  suite_name?: string;
103
123
  /** Tail of combined stdout/stderr captured on failure (empty on pass). */
104
124
  output: string;
105
125
  }
126
+ /**
127
+ * Run the plan's combined test suite over the fully merged post-remediation
128
+ * state. Returns pass/fail plus the failure-output tail. No test_command =>
129
+ * `ran:false` (never-ran, distinct from a real pass) — `passed` still reports
130
+ * `true` so existing gates that fold `combinedTest.passed` into `fullyGreen`
131
+ * keep their vacuously-green behavior for a run with no configured suite;
132
+ * `ran` is what lets a caller (buildVerificationReport's trace) tell the two
133
+ * apart rather than rendering "combined test suite passed" for a suite that
134
+ * never executed.
135
+ */
136
+ export declare function runCombinedTestSuite(state: RemediationState, options: OrchestratorOptions): CombinedTestResult;
137
+ /**
138
+ * On a combined-test failure, selectively re-block items whose touched_files
139
+ * overlap with the failing tests' implicated paths. When attribution is
140
+ * ambiguous (no overlap found), falls back to re-blocking all resolved items.
141
+ * Returns whether any item was blocked — the caller transitions back to triage.
142
+ */
143
+ export declare function blockResolvedItemsOnCombinedFailure(state: RemediationState, testOutput: string): boolean;
106
144
  export interface E2eTestResult {
107
145
  ran: boolean;
108
146
  passed: boolean;
109
147
  output: string;
110
148
  }
149
+ /**
150
+ * {@link cleanupTempBranchesAndArtifacts}'s result — lets a caller observe a
151
+ * cleanup residue programmatically rather than only through console/log
152
+ * output. Absent (`{}`) on a clean removal, a not-fully-green close (nothing
153
+ * was attempted), or a final-state-persist failure alone.
154
+ */
155
+ export interface CleanupResult {
156
+ /**
157
+ * Set to the artifacts directory path when its recursive removal failed
158
+ * after an otherwise fully-green close — the caller must remove it
159
+ * manually. The same fact is also written to the durable structured run log
160
+ * (`runLogger`) and to the console; this field is what surfaces it in the
161
+ * function's OWN returned result too, so a caller does not have to parse
162
+ * log/console output to detect the residue.
163
+ */
164
+ artifacts_residue?: string;
165
+ }
111
166
  /**
112
167
  * Persist the completed state and clean up the artifact directory.
113
168
  *
@@ -118,7 +173,7 @@ export interface E2eTestResult {
118
173
  * closing action failed OR was skipped without completing — the artifacts
119
174
  * directory is preserved for diagnosis.
120
175
  */
121
- export declare function cleanupTempBranchesAndArtifacts(options: OrchestratorOptions, completeState: RemediationState, combinedTest: CombinedTestResult, e2eResult: E2eTestResult, closingResult: ClosingResult, runLogger?: RunLogger): Promise<void>;
176
+ export declare function cleanupTempBranchesAndArtifacts(options: OrchestratorOptions, completeState: RemediationState, combinedTest: CombinedTestResult, e2eResult: E2eTestResult, closingResult: ClosingResult, runLogger?: RunLogger): Promise<CleanupResult>;
122
177
  /**
123
178
  * Build a VerificationReport from the post-remediation state. One
124
179
  * FindingVerificationTrace per terminal finding, with trace entries for:
@@ -1 +1 @@
1
- {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/close.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/close.ts"],"names":[],"mappings":"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"}
@@ -8,19 +8,40 @@ import { FAILURE_OUTPUT_TAIL_CHARS } from "./constants.js";
8
8
  import { verifyAnalyzerLeads } from "./closeVerifyAnalyzerLeads.js";
9
9
  import { intakePaths } from "../intake.js";
10
10
  import { isAuditFindingsReport } from "./plan.js";
11
- import { dispositionToOutcomeStatus, isInProgressStatus, isSkipStatus, isUnsuccessfulEndStatus, isVerifiedCompleteStatus, statusToDisposition, } from "../state/itemStatus.js";
11
+ import { dispositionToOutcomeStatus, isSkipStatus, isTerminalStatus, isUnsuccessfulEndStatus, isVerifiedCompleteStatus, requiresVerificationEvidence, resolveDisposition, } from "../state/itemStatus.js";
12
+ // Brand-new exports of `src/shared/types/remediationOutcome.ts` (CDC-25/
13
+ // CDC-28), not yet re-exported through the `audit-tools/shared` barrel
14
+ // (outside this module's file_scope and this work item's allowed_files) — see
15
+ // the identical note in `src/remediate/state/types.ts`.
16
+ import { ABSENT_FINAL_GATE_REPORT, FinalGateReportSchema, isCompleteEvidence, mechanismContradictsOutcome, missingEvidenceParts, } from "../../shared/types/remediationOutcome.js";
17
+ // The gate record's PATH is single-sourced by the module that writes it. Leaf
18
+ // import (finalGate.ts imports only gateCommands.ts + shared), so this adds no
19
+ // cycle — and the alternative, a second `"final-gate-outcome.json"` literal
20
+ // here, is exactly the drift the layout registry exists to prevent.
21
+ import { finalGateOutcomePath } from "../steps/finalGate.js";
12
22
  // Derived from the single source so the key list can never drift from the
13
23
  // RemediationOutcomeStatus contract (A6).
14
24
  const OUTCOME_KEYS = [
15
25
  ...RemediationOutcomeStatusSchema.options,
16
26
  ];
17
- /** Retry-oriented final status per outcome (see RemediationOutcomeFinalStatus). */
27
+ /**
28
+ * Retry-oriented final status per outcome (see RemediationOutcomeFinalStatus).
29
+ * `verified_already_fixed` (CDC-25) joins `resolved`/`verified_no_change`
30
+ * under `fixed` — the code was already correct at HEAD, requiring no diff, the
31
+ * same shape as a no-change fix. `refuted` joins `inappropriate` under
32
+ * `skipped` — investigation determined the finding is not a real problem, so
33
+ * like a deemed-inappropriate finding it needs no retry; the substantive "why"
34
+ * for both new members lives in the outcome's `evidence` triple, not in this
35
+ * coarse four-value retry bucket.
36
+ */
18
37
  const FINAL_STATUS_BY_OUTCOME = {
19
38
  resolved: "fixed",
20
39
  verified_no_change: "fixed",
21
40
  inappropriate: "skipped",
22
41
  ignored: "ignored",
23
42
  blocked: "failed",
43
+ verified_already_fixed: "fixed",
44
+ refuted: "skipped",
24
45
  };
25
46
  // Skipped and ignored outcomes must always carry a non-empty reason in the
26
47
  // outcomes contract; these defaults cover items whose state lost the rationale.
@@ -65,24 +86,106 @@ function durationBetweenMs(startedAt, completedAt) {
65
86
  }
66
87
  return completed - started;
67
88
  }
68
- export function buildRemediationOutcomesReport(state, closingResult) {
89
+ /**
90
+ * Read the run's tool-owned gate outcome for the report.
91
+ *
92
+ * The gate WRITES `final-gate-outcome.json` on every evaluation; until this
93
+ * reader existed, nothing consumed it — so a scoped-out or suppressed run
94
+ * produced a completion report byte-identical to one written after a green
95
+ * floor, which is the whole defect the record was added to close. A record that
96
+ * is missing, unreadable, or fails its schema degrades to
97
+ * {@link ABSENT_FINAL_GATE_REPORT}: stated as absent, never as green.
98
+ */
99
+ export async function readFinalGateReport(artifactsDir) {
100
+ const raw = await readOptionalJsonFile(finalGateOutcomePath(artifactsDir)).catch(() => undefined);
101
+ if (raw === undefined || raw === null || typeof raw !== "object") {
102
+ return ABSENT_FINAL_GATE_REPORT;
103
+ }
104
+ // The on-disk record carries its own `schema_version`; the REPORT field does
105
+ // not (the outcomes contract has one of its own). Drop that key and keep the
106
+ // schema `.strict()` for everything else, so an unknown field is still a
107
+ // refusal rather than something that rides silently into the contract.
108
+ const { schema_version: _recordVersion, ...body } = raw;
109
+ const parsed = FinalGateReportSchema.safeParse(body);
110
+ if (!parsed.success) {
111
+ return {
112
+ ...ABSENT_FINAL_GATE_REPORT,
113
+ reason: "a gate outcome record exists but does not match the outcome contract; " +
114
+ "treated as no verdict",
115
+ };
116
+ }
117
+ // Defense in depth against a hand-edited or older record: only an EXECUTED
118
+ // gate may carry a verdict. A not-run kind asserting `passed: true` is
119
+ // normalized away here rather than reprinted into the report.
120
+ return parsed.data.outcome === "executed"
121
+ ? parsed.data
122
+ : { ...parsed.data, passed: null, commands_run: 0 };
123
+ }
124
+ export function buildRemediationOutcomesReport(state, closingResult,
125
+ // Defaults to ABSENT so every existing caller keeps compiling AND keeps
126
+ // telling the truth: a caller that supplies no gate outcome is a run with no
127
+ // gate outcome, which the contract now states outright.
128
+ finalGate = ABSENT_FINAL_GATE_REPORT) {
69
129
  const findingsById = new Map((state.plan?.findings ?? []).map((finding) => [finding.id, finding]));
70
130
  const blocksById = new Map((state.plan?.blocks ?? []).map((block) => [block.block_id, block]));
71
131
  const outcomes = [];
72
132
  const closeReason = closingStatusReason(closingResult);
73
133
  for (const item of Object.values(state.items ?? {})) {
74
- // Derive the outcome from the single status→disposition→outcome authority.
75
- // An in-progress status means the run was force-closed while the item was
76
- // still mid-flight: record it as a failed (`blocked`) outcome — never drop
77
- // it and preserve the original state so a retry sees where it stood.
134
+ // Derive the outcome from the single status→disposition→outcome
135
+ // authority. A non-terminal status in-progress, `blocked`, or an
136
+ // unanswered `needs_clarification` means the run was force-closed while
137
+ // the item was still non-terminal: record it as a failed (`blocked`)
138
+ // outcome — never drop it — and preserve the original state so a retry
139
+ // sees where it stood (every non-terminal status, not only the five
140
+ // in-progress ones — needs_clarification included).
78
141
  let outcome;
79
142
  let originalState;
80
- if (isInProgressStatus(item.status)) {
143
+ let evidence;
144
+ let recordedByModule;
145
+ let evidenceRefusalReason;
146
+ if (!isTerminalStatus(item.status)) {
81
147
  outcome = "blocked";
82
148
  originalState = item.status;
83
149
  }
84
150
  else {
85
- outcome = dispositionToOutcomeStatus(statusToDisposition(item.status));
151
+ const disposition = resolveDisposition(item.status, item.disposition_override);
152
+ if (requiresVerificationEvidence(disposition)) {
153
+ // INV-ISC-EVIDENCE-EMITTED — the writer-side backstop. REFUSE a
154
+ // `verified_already_fixed`/`refuted` terminal disposition whose
155
+ // evidence triple is incomplete, or whose complete triple's mechanism
156
+ // CONTRADICTS the disposition it is meant to establish (RED
157
+ // condition (4)'s mechanism-contradiction leg, the W4 witness) —
158
+ // record a non-terminal `blocked` outcome naming the missing or
159
+ // contradicting part instead of a green close on the audit's
160
+ // assertion alone.
161
+ const missing = missingEvidenceParts(item.evidence);
162
+ if (missing.length > 0 || !isCompleteEvidence(item.evidence)) {
163
+ outcome = "blocked";
164
+ evidenceRefusalReason = `incomplete verification evidence for disposition '${disposition}' (missing: ${missing.join(", ")})`;
165
+ }
166
+ else {
167
+ const candidateOutcome = dispositionToOutcomeStatus(disposition);
168
+ if (mechanismContradictsOutcome(candidateOutcome, item.evidence.mechanism)) {
169
+ outcome = "blocked";
170
+ evidenceRefusalReason = `evidence mechanism '${item.evidence.mechanism}' contradicts disposition '${disposition}'`;
171
+ }
172
+ else {
173
+ outcome = candidateOutcome;
174
+ evidence = item.evidence;
175
+ recordedByModule = item.recorded_by_module;
176
+ }
177
+ }
178
+ }
179
+ else {
180
+ outcome = dispositionToOutcomeStatus(disposition);
181
+ // Evidence is optional decoration for the original five dispositions,
182
+ // but when a module DID record it, round-trip it byte-exact (the
183
+ // ATTRIBUTION ROUND-TRIP) rather than silently dropping it.
184
+ if (isCompleteEvidence(item.evidence)) {
185
+ evidence = item.evidence;
186
+ recordedByModule = item.recorded_by_module;
187
+ }
188
+ }
86
189
  }
87
190
  const finding = findingsById.get(item.finding_id);
88
191
  const fileExts = [
@@ -91,12 +194,18 @@ export function buildRemediationOutcomesReport(state, closingResult) {
91
194
  .filter((ext) => ext.length > 0)),
92
195
  ].sort();
93
196
  const durationMs = durationBetweenMs(item.started_at, item.completed_at);
94
- const isNonResolved = outcome !== "resolved" && outcome !== "verified_no_change";
95
- let reason = isNonResolved ? item.failure_reason : undefined;
96
- if (originalState) {
197
+ const isSuccessfulOutcome = outcome === "resolved" ||
198
+ outcome === "verified_no_change" ||
199
+ outcome === "verified_already_fixed" ||
200
+ outcome === "refuted";
201
+ let reason = !isSuccessfulOutcome ? item.failure_reason : undefined;
202
+ if (evidenceRefusalReason) {
203
+ reason = `INV-ISC-EVIDENCE-EMITTED refusal: ${evidenceRefusalReason}.${item.failure_reason ? ` ${item.failure_reason}` : ""}`;
204
+ }
205
+ else if (originalState) {
97
206
  reason = `Force-closed while non-terminal (original state '${originalState}').${item.failure_reason ? ` ${item.failure_reason}` : ""}`;
98
207
  }
99
- else if (isNonResolved && !reason) {
208
+ else if (!isSuccessfulOutcome && !reason) {
100
209
  reason = DEFAULT_REASON_BY_OUTCOME[outcome];
101
210
  }
102
211
  const base = {
@@ -114,6 +223,8 @@ export function buildRemediationOutcomesReport(state, closingResult) {
114
223
  ...(item.mechanical_verification
115
224
  ? { mechanical_verification: item.mechanical_verification }
116
225
  : {}),
226
+ ...(evidence ? { evidence } : {}),
227
+ ...(recordedByModule ? { recorded_by_module: recordedByModule } : {}),
117
228
  };
118
229
  if (!finding) {
119
230
  // Degenerate (corrupt state): without the plan finding there is no payload
@@ -185,6 +296,7 @@ export function buildRemediationOutcomesReport(state, closingResult) {
185
296
  ...(aggregateStarted ? { started_at: aggregateStarted.value } : {}),
186
297
  ...(aggregateCompleted ? { completed_at: aggregateCompleted.value } : {}),
187
298
  ...(aggregateDuration !== undefined ? { duration_ms: aggregateDuration } : {}),
299
+ final_gate: finalGate,
188
300
  outcomes,
189
301
  };
190
302
  }
@@ -598,12 +710,17 @@ export function executeClosingAction(state, options) {
598
710
  /**
599
711
  * Run the plan's combined test suite over the fully merged post-remediation
600
712
  * state. Returns pass/fail plus the failure-output tail. No test_command =>
601
- * vacuously passing.
713
+ * `ran:false` (never-ran, distinct from a real pass) — `passed` still reports
714
+ * `true` so existing gates that fold `combinedTest.passed` into `fullyGreen`
715
+ * keep their vacuously-green behavior for a run with no configured suite;
716
+ * `ran` is what lets a caller (buildVerificationReport's trace) tell the two
717
+ * apart rather than rendering "combined test suite passed" for a suite that
718
+ * never executed.
602
719
  */
603
- function runCombinedTestSuite(state, options) {
720
+ export function runCombinedTestSuite(state, options) {
604
721
  console.log("Running full test suite on combined post-remediation state...");
605
722
  if (!state.plan?.test_command) {
606
- return { passed: true, duration_ms: 0, output: "" };
723
+ return { ran: false, passed: true, duration_ms: 0, output: "" };
607
724
  }
608
725
  const suiteName = Array.isArray(state.plan.test_command)
609
726
  ? state.plan.test_command.join(" ")
@@ -619,12 +736,12 @@ function runCombinedTestSuite(state, options) {
619
736
  });
620
737
  const durationMs = Date.now() - startedAt;
621
738
  if (result.status === 0) {
622
- return { passed: true, suite_name: suiteName, duration_ms: durationMs, output: "" };
739
+ return { ran: true, passed: true, suite_name: suiteName, duration_ms: durationMs, output: "" };
623
740
  }
624
741
  const output = ((result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? ""))
625
742
  .trim()
626
743
  .slice(-FAILURE_OUTPUT_TAIL_CHARS);
627
- return { passed: false, suite_name: suiteName, duration_ms: durationMs, output };
744
+ return { ran: true, passed: false, suite_name: suiteName, duration_ms: durationMs, output };
628
745
  }
629
746
  /**
630
747
  * Parse test output to extract implicated file paths. Looks for common test
@@ -649,13 +766,29 @@ function extractImplicatedPaths(testOutput) {
649
766
  }
650
767
  return [...paths];
651
768
  }
769
+ /**
770
+ * Whether a touched file `tf` and an implicated path `ip` (extracted from test
771
+ * output, which may be a bare/partial path) refer to the same file: exact
772
+ * match after normalization, or one is a path-SEPARATOR-anchored suffix of the
773
+ * other. Never a bare string-suffix test — `"src/myfoo.ts".endsWith("foo.ts")`
774
+ * is true but the two are unrelated files; anchoring the match to a `/`
775
+ * boundary (via `normalizeRepoPath`, which also folds case/slash direction) is
776
+ * what a real path-key join requires and a substring test does not give.
777
+ */
778
+ function touchedPathMatchesImplicated(tf, ip) {
779
+ const a = normalizeRepoPath(tf);
780
+ const b = normalizeRepoPath(ip);
781
+ if (a === b)
782
+ return true;
783
+ return a.endsWith(`/${b}`) || b.endsWith(`/${a}`);
784
+ }
652
785
  /**
653
786
  * On a combined-test failure, selectively re-block items whose touched_files
654
787
  * overlap with the failing tests' implicated paths. When attribution is
655
788
  * ambiguous (no overlap found), falls back to re-blocking all resolved items.
656
789
  * Returns whether any item was blocked — the caller transitions back to triage.
657
790
  */
658
- function blockResolvedItemsOnCombinedFailure(state, testOutput) {
791
+ export function blockResolvedItemsOnCombinedFailure(state, testOutput) {
659
792
  const resolvedItems = Object.values(state.items ?? {}).filter((i) => isVerifiedCompleteStatus(i.status));
660
793
  if (resolvedItems.length === 0)
661
794
  return false;
@@ -666,7 +799,7 @@ function blockResolvedItemsOnCombinedFailure(state, testOutput) {
666
799
  if (implicatedPaths.length > 0) {
667
800
  for (const item of resolvedItems) {
668
801
  const touchedFiles = item.item_spec?.touched_files ?? [];
669
- const overlaps = touchedFiles.some((tf) => implicatedPaths.some((ip) => tf === ip || tf.endsWith(`/${ip}`) || ip.endsWith(`/${tf}`) || tf.endsWith(ip) || ip.endsWith(tf)));
802
+ const overlaps = touchedFiles.some((tf) => implicatedPaths.some((ip) => touchedPathMatchesImplicated(tf, ip)));
670
803
  if (overlaps)
671
804
  attributed.push(item);
672
805
  }
@@ -864,6 +997,25 @@ function buildRemediationReportMarkdown(state, entries, closingResult, e2ePassed
864
997
  reportContent += `- \`${f}\`\n`;
865
998
  }
866
999
  }
1000
+ // The tool-owned repository gate, ALWAYS rendered. A run whose gate was
1001
+ // scoped out, suppressed, or never reached used to produce a report identical
1002
+ // to one written after a green floor — "the suite passed" and "no suite ran"
1003
+ // were the same document. Every branch below names which happened.
1004
+ const gate = outcomesReport.final_gate;
1005
+ reportContent += `\n## Repository Gate\n\n`;
1006
+ if (gate.outcome === "executed") {
1007
+ reportContent += `Outcome: executed — the repository build/typecheck/test floor RAN (${gate.commands_run} command(s)) and ${gate.passed ? "PASSED" : "FAILED"}.\n`;
1008
+ }
1009
+ else if (gate.outcome === "absent") {
1010
+ reportContent += `Outcome: absent — NO gate outcome was recorded for this run, so nothing here corroborates it. This is not a pass.\n`;
1011
+ }
1012
+ else {
1013
+ reportContent += `Outcome: ${gate.outcome} — the repository floor did NOT run (0 commands), so nothing here corroborates this run. This is not a pass.\n`;
1014
+ }
1015
+ if (gate.reason)
1016
+ reportContent += `Reason: ${gate.reason}\n`;
1017
+ if (gate.scope)
1018
+ reportContent += `Scope: ${gate.scope}\n`;
867
1019
  if (e2ePassed !== undefined) {
868
1020
  reportContent += `\n## End-to-End Tests\n\nResult: ${e2ePassed ? "passed" : "failed"}\n`;
869
1021
  }
@@ -938,11 +1090,15 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
938
1090
  // Only delete artifacts on a fully-green close. When any test or closing
939
1091
  // action failed, preserve the directory for diagnosis.
940
1092
  //
941
- // CE-003 force-close guard: a `blocked` or `abandoned` item means the run did
942
- // NOT fully succeed the tool-owned final gate (INV-RS-10) coarse-re-blocked
943
- // or the bounded backstop abandoned the remaining items. Such a run must never
944
- // be "landed green" (artifacts deleted as if complete); a vacuous/unset
945
- // plan.test_command (combinedTest vacuously passing) cannot mask it. Preserve
1093
+ // Force-close guard: a `blocked` or `abandoned` item means the run did NOT
1094
+ // fully succeed. It reaches close that way through triage exhausting an item's
1095
+ // retries, an operator halt, or the force-close backstop converting a
1096
+ // still-non-terminal item NOT through the tool-owned gate, which no longer
1097
+ // mutates item statuses at all (a red pauses the run instead of re-blocking or
1098
+ // abandoning). The guard is unchanged and still needed; only its causes are.
1099
+ // Such a run must never be "landed green" (artifacts deleted as if complete); a
1100
+ // vacuous/unset plan.test_command (combinedTest vacuously passing) cannot mask
1101
+ // it. Preserve
946
1102
  // the artifacts so the partial outcome is diagnosable. The predicate is
947
1103
  // single-sourced in itemStatus so this guard cannot drift from the seam that
948
1104
  // produces the statuses it defends against.
@@ -963,7 +1119,7 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
963
1119
  artifact: options.artifactsDir,
964
1120
  note: `Artifacts directory preserved for diagnosis (combinedTest.passed=${combinedTest.passed}, e2e.passed=${e2eResult.passed}, closing=${closingResult.status}, closingAction=${closingResult.action}, anyBlocked=${anyBlocked})`,
965
1121
  });
966
- return;
1122
+ return {};
967
1123
  }
968
1124
  // Archive the friction close-out record with the promoted deliverables BEFORE
969
1125
  // deleting the artifacts dir — same property as the audit side's
@@ -988,7 +1144,9 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
988
1144
  artifact: options.artifactsDir,
989
1145
  note: `Failed to clean up artifacts directory (manual removal may be needed): ${reason}`,
990
1146
  });
1147
+ return { artifacts_residue: options.artifactsDir };
991
1148
  }
1149
+ return {};
992
1150
  }
993
1151
  /**
994
1152
  * Build a VerificationReport from the post-remediation state. One
@@ -1031,16 +1189,25 @@ export function buildVerificationReport(state, options, closingResult, combinedT
1031
1189
  });
1032
1190
  continue;
1033
1191
  }
1034
- // Combined test suite trace.
1192
+ // Combined test suite trace. A never-configured suite (`ran:false`) is
1193
+ // NEVER labelled "passed" here — `combinedTest.passed` stays `true` for
1194
+ // that case only so the pre-existing fullyGreen/itemPassed formulas below
1195
+ // keep their vacuously-green behavior; this trace's own evidence/status is
1196
+ // what tells a reader "nothing ran" apart from "it ran and passed"
1197
+ // (`status` stays the file's established "failed" for any non-affirmative
1198
+ // case — see the identical choice on the skipped-item trace above — the
1199
+ // finding-level verdict is driven by `itemPassed`, not by this one trace).
1035
1200
  const suiteLabel = combinedTest.suite_name ?? "combined test suite";
1036
1201
  traces.push({
1037
1202
  trace_id: `${item.finding_id}:combined-tests`,
1038
1203
  kind: "task",
1039
1204
  label: suiteLabel,
1040
- evidence: combinedTest.passed
1041
- ? [`${suiteLabel} passed`]
1042
- : [`${suiteLabel} failed`, ...(combinedTest.output ? [combinedTest.output.slice(-500)] : [])],
1043
- status: combinedTest.passed ? "passed" : "failed",
1205
+ evidence: !combinedTest.ran
1206
+ ? ["no combined test suite configured for this run"]
1207
+ : combinedTest.passed
1208
+ ? [`${suiteLabel} passed`]
1209
+ : [`${suiteLabel} failed`, ...(combinedTest.output ? [combinedTest.output.slice(-500)] : [])],
1210
+ status: combinedTest.ran && combinedTest.passed ? "passed" : "failed",
1044
1211
  });
1045
1212
  const contractGoalId = finding?.contract_goal_id ?? state.plan?.goal_id;
1046
1213
  if (contractGoalId) {
@@ -1144,6 +1311,25 @@ export async function runClosePhase(state, options, runLogger) {
1144
1311
  if (!state.plan || !state.items || !state.closing_plan) {
1145
1312
  throw new Error("Cannot run close phase: missing plan, items, or closing_plan from state.");
1146
1313
  }
1314
+ // CDC-19 (advisory): a planned finding with no corresponding item in
1315
+ // state.items would be left uncounted by every module's INV-COVERAGE join
1316
+ // — a module that was blocked or never dispatched must not silently vanish
1317
+ // from the coverage set. Diagnostic-only: never throws, and a no-op unless a
1318
+ // runLogger is actually wired, so it changes nothing for a caller that
1319
+ // doesn't ask for it.
1320
+ {
1321
+ const findingIds = new Set((state.plan.findings ?? []).map((f) => f.id));
1322
+ const itemIds = new Set(Object.keys(state.items));
1323
+ const uncounted = [...findingIds].filter((id) => !itemIds.has(id));
1324
+ if (uncounted.length > 0) {
1325
+ runLogger?.event({
1326
+ phase: "close",
1327
+ kind: "error",
1328
+ obligation: "closing",
1329
+ note: `${uncounted.length} planned finding(s) have no corresponding item in state.items and would be left uncounted by every module's coverage join: ${uncounted.slice(0, 10).join(", ")}`,
1330
+ });
1331
+ }
1332
+ }
1147
1333
  // 1. Check whether closing action requires user confirmation (preview).
1148
1334
  // When not pre-authorized and action is confirmable, generate the file list +
1149
1335
  // commit message, attach them to closing_plan.closing_action_preview, and
@@ -1151,6 +1337,12 @@ export async function runClosePhase(state, options, runLogger) {
1151
1337
  // closing_plan.pre_authorized = true before the next next-step call.
1152
1338
  const preview = checkClosingPreview(state, options);
1153
1339
  if (preview) {
1340
+ runLogger?.event({
1341
+ phase: "close",
1342
+ kind: "state",
1343
+ obligation: "closing",
1344
+ note: `Closing action '${state.closing_plan.action}' requires confirmation before proceeding — preview attached, awaiting pre_authorized.`,
1345
+ });
1154
1346
  const updatedClosingPlan = { ...state.closing_plan, closing_action_preview: preview };
1155
1347
  return { ...state, closing_plan: updatedClosingPlan };
1156
1348
  }
@@ -1159,6 +1351,12 @@ export async function runClosePhase(state, options, runLogger) {
1159
1351
  if (!combinedTest.passed) {
1160
1352
  console.log("Full test suite failed. Transitioning back to triage.");
1161
1353
  if (blockResolvedItemsOnCombinedFailure(state, combinedTest.output)) {
1354
+ runLogger?.event({
1355
+ phase: "close",
1356
+ kind: "state",
1357
+ obligation: "closing",
1358
+ note: "Combined test suite failed — re-blocked resolved item(s), transitioning to triage.",
1359
+ });
1162
1360
  return { ...state, status: "triage" };
1163
1361
  }
1164
1362
  console.warn("Combined test suite failed but no resolved items to re-block — completing with test failure recorded in report.");
@@ -1194,15 +1392,34 @@ export async function runClosePhase(state, options, runLogger) {
1194
1392
  if (analyzerVerify.persisting.length > 0) {
1195
1393
  console.log(`Analyzer lead re-verify: ${analyzerVerify.persisting.length} lead(s) persist ` +
1196
1394
  `(${analyzerVerify.persisting.join(", ")}). Transitioning back to triage.`);
1395
+ runLogger?.event({
1396
+ phase: "close",
1397
+ kind: "state",
1398
+ obligation: "closing",
1399
+ note: `Mechanical re-verify: ${analyzerVerify.persisting.length} analyzer lead(s) persist (${analyzerVerify.persisting.join(", ")}) — transitioning to triage.`,
1400
+ });
1197
1401
  return { ...state, status: "triage" };
1198
1402
  }
1199
1403
  }
1200
- // 3. Run end-to-end tests on the fully merged post-remediation state.
1404
+ // 3. Run end-to-end tests on the fully merged post-remediation state. Mirrors
1405
+ // the combined-test-failure branch's own guard above: a failure transitions
1406
+ // to triage ONLY when something was actually re-blocked for triage to act
1407
+ // on, never unconditionally (a failure with zero verified-complete items has
1408
+ // nothing to re-block, so an unconditional triage transition would enter a
1409
+ // state with no newly-blocked item to drive it forward).
1201
1410
  const e2eResult = runE2eTests(state, options);
1202
1411
  if (!e2eResult.passed) {
1203
1412
  console.log("End-to-end tests failed. Transitioning back to triage.");
1204
- blockResolvedItemsOnCombinedFailure(state, e2eResult.output);
1205
- return { ...state, status: "triage" };
1413
+ if (blockResolvedItemsOnCombinedFailure(state, e2eResult.output)) {
1414
+ runLogger?.event({
1415
+ phase: "close",
1416
+ kind: "state",
1417
+ obligation: "closing",
1418
+ note: "End-to-end tests failed — re-blocked resolved item(s), transitioning to triage.",
1419
+ });
1420
+ return { ...state, status: "triage" };
1421
+ }
1422
+ console.warn("End-to-end tests failed but no resolved items to re-block — completing with e2e failure recorded in report.");
1206
1423
  }
1207
1424
  // 4. Execute the closing action and record exact command outcomes before
1208
1425
  // reporting success.
@@ -1211,8 +1428,15 @@ export async function runClosePhase(state, options, runLogger) {
1211
1428
  await writeJsonFile(join(options.artifactsDir, "remediation-closing-result.json"), closingResult);
1212
1429
  // 4. Generate remediation-report.md and remediation-report.json
1213
1430
  const entries = collectReportEntries(state, options);
1214
- // Phase 7B: capture per-finding outcomes (surface only).
1215
- const outcomesReport = buildRemediationOutcomesReport(state, closingResult);
1431
+ // Phase 7B: capture per-finding outcomes (surface only), carrying the run's
1432
+ // tool-owned gate outcome so the report can say which of executed / scoped-out
1433
+ // / disabled / absent this run actually was.
1434
+ const finalGate = await readFinalGateReport(options.artifactsDir);
1435
+ const outcomesReport = buildRemediationOutcomesReport(state, closingResult, finalGate);
1436
+ // No run-log line for the gate here ON PURPOSE: the gate already records its
1437
+ // own outcome at evaluation time (`recordFinalGateOutcome`), so a second line
1438
+ // at close would be a duplicate — and `kind: "outcome"` at close means "one
1439
+ // per finding", which a run-level line would quietly break.
1216
1440
  // One run-log line per outcome, plus a summary line for the artifact write.
1217
1441
  for (const outcome of outcomesReport.outcomes) {
1218
1442
  runLogger?.event({