audit-tools 0.52.2 → 0.52.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/README.md +31 -1
  2. package/dist/audit/cli/args.d.ts.map +1 -1
  3. package/dist/audit/cli/args.js +6 -2
  4. package/dist/audit/cli/args.js.map +1 -1
  5. package/dist/audit/cli/argumentContract.d.ts +11 -0
  6. package/dist/audit/cli/argumentContract.d.ts.map +1 -0
  7. package/dist/audit/cli/argumentContract.js +45 -0
  8. package/dist/audit/cli/argumentContract.js.map +1 -0
  9. package/dist/audit/cli/auditReviewBindings.d.ts +49 -0
  10. package/dist/audit/cli/auditReviewBindings.d.ts.map +1 -0
  11. package/dist/audit/cli/auditReviewBindings.js +61 -0
  12. package/dist/audit/cli/auditReviewBindings.js.map +1 -0
  13. package/dist/audit/cli/auditStep.d.ts +1 -27
  14. package/dist/audit/cli/auditStep.d.ts.map +1 -1
  15. package/dist/audit/cli/auditStep.js +7 -32
  16. package/dist/audit/cli/auditStep.js.map +1 -1
  17. package/dist/audit/cli/charterComparisonPrompt.d.ts +2 -0
  18. package/dist/audit/cli/charterComparisonPrompt.d.ts.map +1 -1
  19. package/dist/audit/cli/charterComparisonPrompt.js +9 -0
  20. package/dist/audit/cli/charterComparisonPrompt.js.map +1 -1
  21. package/dist/audit/cli/charterExtractionPrompt.d.ts.map +1 -1
  22. package/dist/audit/cli/charterExtractionPrompt.js +17 -3
  23. package/dist/audit/cli/charterExtractionPrompt.js.map +1 -1
  24. package/dist/audit/cli/conceptualDispatch.d.ts +1 -1
  25. package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
  26. package/dist/audit/cli/conceptualDispatch.js +15 -2
  27. package/dist/audit/cli/conceptualDispatch.js.map +1 -1
  28. package/dist/audit/cli/confirmIntentStep.d.ts.map +1 -1
  29. package/dist/audit/cli/confirmIntentStep.js +17 -21
  30. package/dist/audit/cli/confirmIntentStep.js.map +1 -1
  31. package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
  32. package/dist/audit/cli/dispatch/hostHandoff.js +233 -231
  33. package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
  34. package/dist/audit/cli/explainTaskCommand.d.ts.map +1 -1
  35. package/dist/audit/cli/explainTaskCommand.js +3 -1
  36. package/dist/audit/cli/explainTaskCommand.js.map +1 -1
  37. package/dist/audit/cli/fanoutLanes.d.ts +10 -14
  38. package/dist/audit/cli/fanoutLanes.d.ts.map +1 -1
  39. package/dist/audit/cli/fanoutLanes.js +50 -16
  40. package/dist/audit/cli/fanoutLanes.js.map +1 -1
  41. package/dist/audit/cli/functionalPreflight.d.ts +96 -0
  42. package/dist/audit/cli/functionalPreflight.d.ts.map +1 -0
  43. package/dist/audit/cli/functionalPreflight.js +103 -0
  44. package/dist/audit/cli/functionalPreflight.js.map +1 -0
  45. package/dist/audit/cli/laneSubmissions.d.ts +5 -1
  46. package/dist/audit/cli/laneSubmissions.d.ts.map +1 -1
  47. package/dist/audit/cli/laneSubmissions.js +45 -34
  48. package/dist/audit/cli/laneSubmissions.js.map +1 -1
  49. package/dist/audit/cli/nextStepCommand.d.ts +1 -9
  50. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  51. package/dist/audit/cli/nextStepCommand.js +104 -39
  52. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  53. package/dist/audit/cli/nextStepHelpers.d.ts +10 -25
  54. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  55. package/dist/audit/cli/nextStepHelpers.js +57 -67
  56. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  57. package/dist/audit/cli/prompts.d.ts.map +1 -1
  58. package/dist/audit/cli/prompts.js +9 -4
  59. package/dist/audit/cli/prompts.js.map +1 -1
  60. package/dist/audit/cli/recoverSubmissionCommand.d.ts.map +1 -1
  61. package/dist/audit/cli/recoverSubmissionCommand.js +8 -1
  62. package/dist/audit/cli/recoverSubmissionCommand.js.map +1 -1
  63. package/dist/audit/cli/reviewRun.js +1 -1
  64. package/dist/audit/cli/reviewRun.js.map +1 -1
  65. package/dist/audit/cli/reviewSubmission.d.ts +24 -0
  66. package/dist/audit/cli/reviewSubmission.d.ts.map +1 -0
  67. package/dist/audit/cli/reviewSubmission.js +97 -0
  68. package/dist/audit/cli/reviewSubmission.js.map +1 -0
  69. package/dist/audit/cli/sampleRunCommand.d.ts +3 -3
  70. package/dist/audit/cli/steps.d.ts +18 -18
  71. package/dist/audit/cli/steps.d.ts.map +1 -1
  72. package/dist/audit/cli/steps.js +1 -0
  73. package/dist/audit/cli/steps.js.map +1 -1
  74. package/dist/audit/cli/unacceptResultsCommand.d.ts.map +1 -1
  75. package/dist/audit/cli/unacceptResultsCommand.js +2 -1
  76. package/dist/audit/cli/unacceptResultsCommand.js.map +1 -1
  77. package/dist/audit/cli.d.ts +2 -1
  78. package/dist/audit/cli.d.ts.map +1 -1
  79. package/dist/audit/cli.js +27 -19
  80. package/dist/audit/cli.js.map +1 -1
  81. package/dist/audit/contracts/findingContractPrompt.d.ts +1 -1
  82. package/dist/audit/contracts/findingContractPrompt.d.ts.map +1 -1
  83. package/dist/audit/contracts/findingContractPrompt.js +6 -4
  84. package/dist/audit/contracts/findingContractPrompt.js.map +1 -1
  85. package/dist/audit/contracts/workerSchemas.d.ts +10 -10
  86. package/dist/audit/contracts/wrapperResponse.d.ts +34 -34
  87. package/dist/audit/extractors/commentDecomposition.d.ts +14 -0
  88. package/dist/audit/extractors/commentDecomposition.d.ts.map +1 -1
  89. package/dist/audit/extractors/commentDecomposition.js +2 -1
  90. package/dist/audit/extractors/commentDecomposition.js.map +1 -1
  91. package/dist/audit/extractors/graph.d.ts +1 -1
  92. package/dist/audit/extractors/graph.d.ts.map +1 -1
  93. package/dist/audit/extractors/graph.js +12 -7
  94. package/dist/audit/extractors/graph.js.map +1 -1
  95. package/dist/audit/extractors/graphPythonImports.d.ts +3 -0
  96. package/dist/audit/extractors/graphPythonImports.d.ts.map +1 -1
  97. package/dist/audit/extractors/graphPythonImports.js +24 -5
  98. package/dist/audit/extractors/graphPythonImports.js.map +1 -1
  99. package/dist/audit/extractors/graphRouteSources.d.ts +7 -0
  100. package/dist/audit/extractors/graphRouteSources.d.ts.map +1 -0
  101. package/dist/audit/extractors/graphRouteSources.js +208 -0
  102. package/dist/audit/extractors/graphRouteSources.js.map +1 -0
  103. package/dist/audit/extractors/graphRoutes.d.ts +1 -1
  104. package/dist/audit/extractors/graphRoutes.d.ts.map +1 -1
  105. package/dist/audit/extractors/graphRoutes.js +65 -68
  106. package/dist/audit/extractors/graphRoutes.js.map +1 -1
  107. package/dist/audit/io/artifacts.d.ts +1 -0
  108. package/dist/audit/io/artifacts.d.ts.map +1 -1
  109. package/dist/audit/io/artifacts.js +29 -10
  110. package/dist/audit/io/artifacts.js.map +1 -1
  111. package/dist/audit/io/runArtifacts.d.ts +1 -1
  112. package/dist/audit/io/runArtifacts.d.ts.map +1 -1
  113. package/dist/audit/io/runArtifacts.js +3 -0
  114. package/dist/audit/io/runArtifacts.js.map +1 -1
  115. package/dist/audit/io/toolingManifest.d.ts.map +1 -1
  116. package/dist/audit/io/toolingManifest.js +11 -32
  117. package/dist/audit/io/toolingManifest.js.map +1 -1
  118. package/dist/audit/orchestrator/acquisitionExecutor.d.ts +2 -3
  119. package/dist/audit/orchestrator/acquisitionExecutor.d.ts.map +1 -1
  120. package/dist/audit/orchestrator/acquisitionExecutor.js.map +1 -1
  121. package/dist/audit/orchestrator/advanceTypes.d.ts +1 -2
  122. package/dist/audit/orchestrator/advanceTypes.d.ts.map +1 -1
  123. package/dist/audit/orchestrator/autoFixExecutor.d.ts +2 -2
  124. package/dist/audit/orchestrator/autoFixExecutor.d.ts.map +1 -1
  125. package/dist/audit/orchestrator/autoFixExecutor.js +2 -2
  126. package/dist/audit/orchestrator/autoFixExecutor.js.map +1 -1
  127. package/dist/audit/orchestrator/charterFidelityPacket.d.ts +2 -0
  128. package/dist/audit/orchestrator/charterFidelityPacket.d.ts.map +1 -1
  129. package/dist/audit/orchestrator/charterFidelityPacket.js +6 -1
  130. package/dist/audit/orchestrator/charterFidelityPacket.js.map +1 -1
  131. package/dist/audit/orchestrator/charterPackets.d.ts +2 -0
  132. package/dist/audit/orchestrator/charterPackets.d.ts.map +1 -1
  133. package/dist/audit/orchestrator/charterPackets.js +6 -0
  134. package/dist/audit/orchestrator/charterPackets.js.map +1 -1
  135. package/dist/audit/orchestrator/designReviewProjection.d.ts +5 -8
  136. package/dist/audit/orchestrator/designReviewProjection.d.ts.map +1 -1
  137. package/dist/audit/orchestrator/designReviewProjection.js +7 -1
  138. package/dist/audit/orchestrator/designReviewProjection.js.map +1 -1
  139. package/dist/audit/orchestrator/designReviewPrompt.d.ts +3 -47
  140. package/dist/audit/orchestrator/designReviewPrompt.d.ts.map +1 -1
  141. package/dist/audit/orchestrator/designReviewPrompt.js +28 -135
  142. package/dist/audit/orchestrator/designReviewPrompt.js.map +1 -1
  143. package/dist/audit/orchestrator/designReviewSnapshot.d.ts +24 -1
  144. package/dist/audit/orchestrator/designReviewSnapshot.d.ts.map +1 -1
  145. package/dist/audit/orchestrator/designReviewSnapshot.js +8 -2
  146. package/dist/audit/orchestrator/designReviewSnapshot.js.map +1 -1
  147. package/dist/audit/orchestrator/designReviewTask.d.ts +46 -0
  148. package/dist/audit/orchestrator/designReviewTask.d.ts.map +1 -0
  149. package/dist/audit/orchestrator/designReviewTask.js +44 -0
  150. package/dist/audit/orchestrator/designReviewTask.js.map +1 -0
  151. package/dist/audit/orchestrator/intentCheckpointGate.d.ts +1 -1
  152. package/dist/audit/orchestrator/intentCheckpointGate.d.ts.map +1 -1
  153. package/dist/audit/orchestrator/intentCheckpointGate.js +4 -2
  154. package/dist/audit/orchestrator/intentCheckpointGate.js.map +1 -1
  155. package/dist/audit/orchestrator/intentEquivalenceExecutor.d.ts +3 -0
  156. package/dist/audit/orchestrator/intentEquivalenceExecutor.d.ts.map +1 -1
  157. package/dist/audit/orchestrator/intentEquivalenceExecutor.js +2 -0
  158. package/dist/audit/orchestrator/intentEquivalenceExecutor.js.map +1 -1
  159. package/dist/audit/orchestrator/intentInterpreter.d.ts +1 -9
  160. package/dist/audit/orchestrator/intentInterpreter.d.ts.map +1 -1
  161. package/dist/audit/orchestrator/intentInterpreter.js +6 -11
  162. package/dist/audit/orchestrator/intentInterpreter.js.map +1 -1
  163. package/dist/audit/orchestrator/selectiveDeepening/shared.d.ts +2 -2
  164. package/dist/audit/orchestrator/selectiveDeepening/shared.d.ts.map +1 -1
  165. package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
  166. package/dist/audit/orchestrator/staleness.js +32 -40
  167. package/dist/audit/orchestrator/staleness.js.map +1 -1
  168. package/dist/audit/orchestrator/state.d.ts.map +1 -1
  169. package/dist/audit/orchestrator/state.js +8 -14
  170. package/dist/audit/orchestrator/state.js.map +1 -1
  171. package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts +19 -0
  172. package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts.map +1 -1
  173. package/dist/audit/orchestrator/systemicChallengeExecutor.js +15 -1
  174. package/dist/audit/orchestrator/systemicChallengeExecutor.js.map +1 -1
  175. package/dist/audit/reporting/criticalFlowFallbackPrompt.d.ts +1 -1
  176. package/dist/audit/reporting/criticalFlowFallbackPrompt.d.ts.map +1 -1
  177. package/dist/audit/reporting/criticalFlowFallbackPrompt.js +4 -2
  178. package/dist/audit/reporting/criticalFlowFallbackPrompt.js.map +1 -1
  179. package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
  180. package/dist/audit/reporting/mergeFindings.js +43 -2
  181. package/dist/audit/reporting/mergeFindings.js.map +1 -1
  182. package/dist/audit/types/auditScope.d.ts +2 -2
  183. package/dist/audit/types/auditState.d.ts +6 -6
  184. package/dist/audit/types/conceptualAdjudication.d.ts +19 -19
  185. package/dist/audit/types/conceptualAdjudication.d.ts.map +1 -1
  186. package/dist/audit/types/conceptualAdjudication.js +3 -3
  187. package/dist/audit/types/conceptualAdjudication.js.map +1 -1
  188. package/dist/audit/types.d.ts +17 -19
  189. package/dist/audit/types.d.ts.map +1 -1
  190. package/dist/audit/types.js +19 -20
  191. package/dist/audit/types.js.map +1 -1
  192. package/dist/remediate/contractPipeline/artifactStore.d.ts +3 -1
  193. package/dist/remediate/contractPipeline/artifactStore.d.ts.map +1 -1
  194. package/dist/remediate/contractPipeline/artifactStore.js +26 -31
  195. package/dist/remediate/contractPipeline/artifactStore.js.map +1 -1
  196. package/dist/remediate/contractPipeline/changeClassification.d.ts.map +1 -1
  197. package/dist/remediate/contractPipeline/changeClassification.js +20 -8
  198. package/dist/remediate/contractPipeline/changeClassification.js.map +1 -1
  199. package/dist/remediate/contractPipeline/contractReviewBinding.d.ts +28 -0
  200. package/dist/remediate/contractPipeline/contractReviewBinding.d.ts.map +1 -0
  201. package/dist/remediate/contractPipeline/contractReviewBinding.js +75 -0
  202. package/dist/remediate/contractPipeline/contractReviewBinding.js.map +1 -0
  203. package/dist/remediate/contractPipeline/repairState.d.ts +3 -1
  204. package/dist/remediate/contractPipeline/repairState.d.ts.map +1 -1
  205. package/dist/remediate/contractPipeline/repairState.js +1 -0
  206. package/dist/remediate/contractPipeline/repairState.js.map +1 -1
  207. package/dist/remediate/contractPipeline/sketchSource.d.ts +1 -0
  208. package/dist/remediate/contractPipeline/sketchSource.d.ts.map +1 -1
  209. package/dist/remediate/contractPipeline/sketchSource.js +1 -0
  210. package/dist/remediate/contractPipeline/sketchSource.js.map +1 -1
  211. package/dist/remediate/dedup/crossLensDedup.d.ts +1 -2
  212. package/dist/remediate/dedup/crossLensDedup.d.ts.map +1 -1
  213. package/dist/remediate/dedup/crossLensDedup.js +1 -0
  214. package/dist/remediate/dedup/crossLensDedup.js.map +1 -1
  215. package/dist/remediate/index.d.ts.map +1 -1
  216. package/dist/remediate/index.js +92 -52
  217. package/dist/remediate/index.js.map +1 -1
  218. package/dist/remediate/intake.d.ts +54 -0
  219. package/dist/remediate/intake.d.ts.map +1 -1
  220. package/dist/remediate/intake.js +15 -1
  221. package/dist/remediate/intake.js.map +1 -1
  222. package/dist/remediate/intakeSelection.d.ts +27 -0
  223. package/dist/remediate/intakeSelection.d.ts.map +1 -0
  224. package/dist/remediate/intakeSelection.js +37 -0
  225. package/dist/remediate/intakeSelection.js.map +1 -0
  226. package/dist/remediate/intent/intentPersistence.d.ts +41 -0
  227. package/dist/remediate/intent/intentPersistence.d.ts.map +1 -0
  228. package/dist/remediate/intent/intentPersistence.js +129 -0
  229. package/dist/remediate/intent/intentPersistence.js.map +1 -0
  230. package/dist/remediate/phases/close.d.ts +2 -1
  231. package/dist/remediate/phases/close.d.ts.map +1 -1
  232. package/dist/remediate/phases/close.js +19 -2
  233. package/dist/remediate/phases/close.js.map +1 -1
  234. package/dist/remediate/phases/closeReviewProvenance.d.ts +4 -0
  235. package/dist/remediate/phases/closeReviewProvenance.d.ts.map +1 -0
  236. package/dist/remediate/phases/closeReviewProvenance.js +16 -0
  237. package/dist/remediate/phases/closeReviewProvenance.js.map +1 -0
  238. package/dist/remediate/phases/triage.d.ts.map +1 -1
  239. package/dist/remediate/phases/triage.js +3 -1
  240. package/dist/remediate/phases/triage.js.map +1 -1
  241. package/dist/remediate/review/filterDispositions.d.ts +13 -0
  242. package/dist/remediate/review/filterDispositions.d.ts.map +1 -0
  243. package/dist/remediate/review/filterDispositions.js +32 -0
  244. package/dist/remediate/review/filterDispositions.js.map +1 -0
  245. package/dist/remediate/state/runIdentity.d.ts +27 -0
  246. package/dist/remediate/state/runIdentity.d.ts.map +1 -0
  247. package/dist/remediate/state/runIdentity.js +38 -0
  248. package/dist/remediate/state/runIdentity.js.map +1 -0
  249. package/dist/remediate/state/store.d.ts +80 -1
  250. package/dist/remediate/state/store.d.ts.map +1 -1
  251. package/dist/remediate/state/store.js +82 -1
  252. package/dist/remediate/state/store.js.map +1 -1
  253. package/dist/remediate/state/types.d.ts +215 -42
  254. package/dist/remediate/state/types.d.ts.map +1 -1
  255. package/dist/remediate/state/types.js +11 -3
  256. package/dist/remediate/state/types.js.map +1 -1
  257. package/dist/remediate/steps/contractPipeline.d.ts +61 -3
  258. package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
  259. package/dist/remediate/steps/contractPipeline.js +121 -47
  260. package/dist/remediate/steps/contractPipeline.js.map +1 -1
  261. package/dist/remediate/steps/contractPipelinePrompts.d.ts +27 -4
  262. package/dist/remediate/steps/contractPipelinePrompts.d.ts.map +1 -1
  263. package/dist/remediate/steps/contractPipelinePrompts.js +34 -32
  264. package/dist/remediate/steps/contractPipelinePrompts.js.map +1 -1
  265. package/dist/remediate/steps/dispatch/contractConformanceReview.d.ts +31 -0
  266. package/dist/remediate/steps/dispatch/contractConformanceReview.d.ts.map +1 -0
  267. package/dist/remediate/steps/dispatch/contractConformanceReview.js +98 -0
  268. package/dist/remediate/steps/dispatch/contractConformanceReview.js.map +1 -0
  269. package/dist/remediate/steps/dispatch/hostContracts.d.ts +133 -0
  270. package/dist/remediate/steps/dispatch/hostContracts.d.ts.map +1 -0
  271. package/dist/remediate/steps/dispatch/hostContracts.js +104 -0
  272. package/dist/remediate/steps/dispatch/hostContracts.js.map +1 -0
  273. package/dist/remediate/steps/dispatch/hostCorroboration.d.ts +70 -0
  274. package/dist/remediate/steps/dispatch/hostCorroboration.d.ts.map +1 -0
  275. package/dist/remediate/steps/dispatch/hostCorroboration.js +350 -0
  276. package/dist/remediate/steps/dispatch/hostCorroboration.js.map +1 -0
  277. package/dist/remediate/steps/dispatch/hostHandoff.d.ts +8 -162
  278. package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
  279. package/dist/remediate/steps/dispatch/hostHandoff.js +137 -690
  280. package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
  281. package/dist/remediate/steps/dispatch/requiredTests.d.ts +83 -0
  282. package/dist/remediate/steps/dispatch/requiredTests.d.ts.map +1 -0
  283. package/dist/remediate/steps/dispatch/requiredTests.js +262 -0
  284. package/dist/remediate/steps/dispatch/requiredTests.js.map +1 -0
  285. package/dist/remediate/steps/finalGate.d.ts +8 -7
  286. package/dist/remediate/steps/finalGate.d.ts.map +1 -1
  287. package/dist/remediate/steps/finalGate.js +14 -11
  288. package/dist/remediate/steps/finalGate.js.map +1 -1
  289. package/dist/remediate/steps/frictionCloseout.d.ts +34 -0
  290. package/dist/remediate/steps/frictionCloseout.d.ts.map +1 -0
  291. package/dist/remediate/steps/frictionCloseout.js +113 -0
  292. package/dist/remediate/steps/frictionCloseout.js.map +1 -0
  293. package/dist/remediate/steps/gateCommands.d.ts +7 -9
  294. package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
  295. package/dist/remediate/steps/gateCommands.js +37 -11
  296. package/dist/remediate/steps/gateCommands.js.map +1 -1
  297. package/dist/remediate/steps/intakeResolver.d.ts +2 -0
  298. package/dist/remediate/steps/intakeResolver.d.ts.map +1 -1
  299. package/dist/remediate/steps/intakeResolver.js +36 -11
  300. package/dist/remediate/steps/intakeResolver.js.map +1 -1
  301. package/dist/remediate/steps/nextStep.d.ts +23 -110
  302. package/dist/remediate/steps/nextStep.d.ts.map +1 -1
  303. package/dist/remediate/steps/nextStep.js +232 -508
  304. package/dist/remediate/steps/nextStep.js.map +1 -1
  305. package/dist/remediate/steps/prompts.d.ts +1 -1
  306. package/dist/remediate/steps/prompts.d.ts.map +1 -1
  307. package/dist/remediate/steps/prompts.js +7 -2
  308. package/dist/remediate/steps/prompts.js.map +1 -1
  309. package/dist/remediate/steps/recoverIngest.d.ts +57 -0
  310. package/dist/remediate/steps/recoverIngest.d.ts.map +1 -0
  311. package/dist/remediate/steps/recoverIngest.js +171 -0
  312. package/dist/remediate/steps/recoverIngest.js.map +1 -0
  313. package/dist/remediate/steps/stepWriter.d.ts +5 -4
  314. package/dist/remediate/steps/stepWriter.d.ts.map +1 -1
  315. package/dist/remediate/steps/stepWriter.js +2 -1
  316. package/dist/remediate/steps/stepWriter.js.map +1 -1
  317. package/dist/remediate/steps/types.d.ts +2 -3
  318. package/dist/remediate/steps/types.d.ts.map +1 -1
  319. package/dist/remediate/steps/types.js.map +1 -1
  320. package/dist/remediate/validation/artifacts.d.ts.map +1 -1
  321. package/dist/remediate/validation/artifacts.js +5 -12
  322. package/dist/remediate/validation/artifacts.js.map +1 -1
  323. package/dist/remediate/validation/contractPipeline.d.ts.map +1 -1
  324. package/dist/remediate/validation/contractPipeline.js +10 -7
  325. package/dist/remediate/validation/contractPipeline.js.map +1 -1
  326. package/dist/remediate/validation/contractPipelineGates.d.ts +13 -67
  327. package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
  328. package/dist/remediate/validation/contractPipelineGates.js +65 -139
  329. package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
  330. package/dist/remediate/validation/remediationState.d.ts.map +1 -1
  331. package/dist/remediate/validation/remediationState.js +9 -3
  332. package/dist/remediate/validation/remediationState.js.map +1 -1
  333. package/dist/shared/agentReflections.d.ts +2 -2
  334. package/dist/shared/analyzerPolicy.d.ts +2 -16
  335. package/dist/shared/analyzerPolicy.d.ts.map +1 -1
  336. package/dist/shared/analyzerPolicy.js +22 -24
  337. package/dist/shared/analyzerPolicy.js.map +1 -1
  338. package/dist/shared/analyzerRunConsent.d.ts +33 -0
  339. package/dist/shared/analyzerRunConsent.d.ts.map +1 -0
  340. package/dist/shared/analyzerRunConsent.js +42 -0
  341. package/dist/shared/analyzerRunConsent.js.map +1 -0
  342. package/dist/shared/analyzers/acquisitionEngine.d.ts +3 -8
  343. package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
  344. package/dist/shared/analyzers/acquisitionEngine.js +1 -0
  345. package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
  346. package/dist/shared/decompose/charterExtraction.d.ts +8 -8
  347. package/dist/shared/decompose/systemicChallenge.d.ts +12 -12
  348. package/dist/shared/engine/obligationEngine.d.ts +2 -2
  349. package/dist/shared/findings/dedupe.d.ts.map +1 -1
  350. package/dist/shared/findings/dedupe.js +16 -0
  351. package/dist/shared/findings/dedupe.js.map +1 -1
  352. package/dist/shared/graph/orderedReachability.d.ts +9 -0
  353. package/dist/shared/graph/orderedReachability.d.ts.map +1 -0
  354. package/dist/shared/graph/orderedReachability.js +21 -0
  355. package/dist/shared/graph/orderedReachability.js.map +1 -0
  356. package/dist/shared/index.d.ts +9 -3
  357. package/dist/shared/index.d.ts.map +1 -1
  358. package/dist/shared/index.js +6 -3
  359. package/dist/shared/index.js.map +1 -1
  360. package/dist/shared/intake/guidanceBootstrap.d.ts +2 -0
  361. package/dist/shared/intake/guidanceBootstrap.d.ts.map +1 -1
  362. package/dist/shared/intake/guidanceBootstrap.js +10 -1
  363. package/dist/shared/intake/guidanceBootstrap.js.map +1 -1
  364. package/dist/shared/intent/constraintClauses.d.ts +3 -0
  365. package/dist/shared/intent/constraintClauses.d.ts.map +1 -1
  366. package/dist/shared/intent/constraintClauses.js +9 -0
  367. package/dist/shared/intent/constraintClauses.js.map +1 -1
  368. package/dist/shared/io/artifactTreeHold.d.ts +5 -0
  369. package/dist/shared/io/artifactTreeHold.d.ts.map +1 -0
  370. package/dist/shared/io/artifactTreeHold.js +13 -0
  371. package/dist/shared/io/artifactTreeHold.js.map +1 -0
  372. package/dist/shared/io/auditToolsPaths.d.ts +3 -1
  373. package/dist/shared/io/auditToolsPaths.d.ts.map +1 -1
  374. package/dist/shared/io/auditToolsPaths.js +6 -1
  375. package/dist/shared/io/auditToolsPaths.js.map +1 -1
  376. package/dist/shared/io/collectFilesSorted.d.ts +10 -0
  377. package/dist/shared/io/collectFilesSorted.d.ts.map +1 -0
  378. package/dist/shared/io/collectFilesSorted.js +38 -0
  379. package/dist/shared/io/collectFilesSorted.js.map +1 -0
  380. package/dist/shared/io/json.d.ts.map +1 -1
  381. package/dist/shared/io/json.js +11 -4
  382. package/dist/shared/io/json.js.map +1 -1
  383. package/dist/shared/io/stepContractWriter.d.ts.map +1 -1
  384. package/dist/shared/io/stepContractWriter.js +8 -0
  385. package/dist/shared/io/stepContractWriter.js.map +1 -1
  386. package/dist/shared/loopCorePaths.d.ts.map +1 -1
  387. package/dist/shared/loopCorePaths.js +9 -0
  388. package/dist/shared/loopCorePaths.js.map +1 -1
  389. package/dist/shared/observability/rootLogObservations.d.ts +10 -0
  390. package/dist/shared/observability/rootLogObservations.d.ts.map +1 -0
  391. package/dist/shared/observability/rootLogObservations.js +147 -0
  392. package/dist/shared/observability/rootLogObservations.js.map +1 -0
  393. package/dist/shared/prompts.d.ts +11 -9
  394. package/dist/shared/prompts.d.ts.map +1 -1
  395. package/dist/shared/prompts.js +18 -13
  396. package/dist/shared/prompts.js.map +1 -1
  397. package/dist/shared/submission/submissionLedger.d.ts +7 -1
  398. package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
  399. package/dist/shared/submission/submissionLedger.js +8 -0
  400. package/dist/shared/submission/submissionLedger.js.map +1 -1
  401. package/dist/shared/tooling/testCommand.d.ts +1 -0
  402. package/dist/shared/tooling/testCommand.d.ts.map +1 -1
  403. package/dist/shared/tooling/testCommand.js +4 -0
  404. package/dist/shared/tooling/testCommand.js.map +1 -1
  405. package/dist/shared/types/charter.d.ts +8 -8
  406. package/dist/shared/types/conceptualPerspective.d.ts +66 -0
  407. package/dist/shared/types/conceptualPerspective.d.ts.map +1 -0
  408. package/dist/shared/types/conceptualPerspective.js +135 -0
  409. package/dist/shared/types/conceptualPerspective.js.map +1 -0
  410. package/dist/shared/types/contractPipeline/design.d.ts +5 -0
  411. package/dist/shared/types/contractPipeline/design.d.ts.map +1 -1
  412. package/dist/shared/types/contractPipeline/design.js +6 -0
  413. package/dist/shared/types/contractPipeline/design.js.map +1 -1
  414. package/dist/shared/types/contractPipeline/implementation.d.ts +54 -0
  415. package/dist/shared/types/contractPipeline/implementation.d.ts.map +1 -1
  416. package/dist/shared/types/contractPipeline/implementation.js +10 -5
  417. package/dist/shared/types/contractPipeline/implementation.js.map +1 -1
  418. package/dist/shared/types/contractPipeline/obligations.d.ts +21 -10
  419. package/dist/shared/types/contractPipeline/obligations.d.ts.map +1 -1
  420. package/dist/shared/types/contractPipeline/obligations.js +13 -1
  421. package/dist/shared/types/contractPipeline/obligations.js.map +1 -1
  422. package/dist/shared/types/disposition.d.ts +6 -6
  423. package/dist/shared/types/finding.d.ts +50 -50
  424. package/dist/shared/types/intentCheckpoint.d.ts +66 -11
  425. package/dist/shared/types/intentCheckpoint.d.ts.map +1 -1
  426. package/dist/shared/types/intentCheckpoint.js +10 -2
  427. package/dist/shared/types/intentCheckpoint.js.map +1 -1
  428. package/dist/shared/types/remediationOutcome.d.ts +252 -24
  429. package/dist/shared/types/remediationOutcome.d.ts.map +1 -1
  430. package/dist/shared/types/remediationOutcome.js +4 -0
  431. package/dist/shared/types/remediationOutcome.js.map +1 -1
  432. package/dist/shared/types/reviewIndependence.d.ts +225 -0
  433. package/dist/shared/types/reviewIndependence.d.ts.map +1 -0
  434. package/dist/shared/types/reviewIndependence.js +67 -0
  435. package/dist/shared/types/reviewIndependence.js.map +1 -0
  436. package/dist/shared/types/stepContract.d.ts +8 -2
  437. package/dist/shared/types/stepContract.d.ts.map +1 -1
  438. package/dist/shared/types/stepContract.js +4 -1
  439. package/dist/shared/types/stepContract.js.map +1 -1
  440. package/dist/shared/validation/findingsReport.d.ts.map +1 -1
  441. package/dist/shared/validation/findingsReport.js +13 -0
  442. package/dist/shared/validation/findingsReport.js.map +1 -1
  443. package/docs/audit-pkg/contracts.md +38 -2
  444. package/docs/audit-pkg/operator-guide.md +59 -4
  445. package/package.json +5 -6
  446. package/skills/audit-code/audit-code.prompt.md +1 -31
  447. package/skills/remediate-code/remediate-code.prompt.md +12 -6
@@ -1,3 +1,4 @@
1
+ import { recordHostRootLogBoundary } from "../../../shared/observability/rootLogObservations.js";
1
2
  // sites-pinned: tests/audit/host-handoff.test.ts
2
3
  // (the steward-lane verification contract: the lane-aware prompt, the one
3
4
  // optional envelope key, the refusal of that key on a lane whose contract never
@@ -5,7 +6,7 @@
5
6
  // task-bindings version bump whose refusal names the remedy)
6
7
  import { mkdir } from "node:fs/promises";
7
8
  import { join } from "node:path";
8
- import { createMemoizedSourceReader, appendSubmissionEvent, SUBMISSION_LEDGER_EVENT_CONTRACT_VERSION, bindingIdentity, compareCodeUnits, contentSha256, firstDuplicateIdentity, hasExactKeys, hostHandoffResultPath, identityFailureDiagnostic, isFileMissingError, isRecord, isSha256, LaneDemandSchema, parseAllWorkloadItems, parseWorkloadEnvelope, bindWorkerPrompt, deriveResultId, workerPromptBindingHolds, enrichMissingSubmissionIssues, readTrailingSubmissionRefusals, readJsonFile, repoRelativePath, requireNonEmptyString, resolveContainedPath, resolveHostHandoffPaths, resultMapIdentity, scanBoundSubmission, siblingLockPath, sameStrings, stableStringify, verifyFindingGrounding, withFileLock, writeBlockedStepContract, writeJsonFile, } from "audit-tools/shared";
9
+ import { createMemoizedSourceReader, appendSubmissionEvent, SUBMISSION_LEDGER_EVENT_CONTRACT_VERSION, bindingIdentity, compareCodeUnits, contentSha256, firstDuplicateIdentity, hasExactKeys, hostHandoffResultPath, identityFailureDiagnostic, isFileMissingError, isJsonParseError, isRecord, isSha256, LaneDemandSchema, parseAllWorkloadItems, parseWorkloadEnvelope, bindWorkerPrompt, deriveResultId, workerPromptBindingHolds, enrichMissingSubmissionIssues, readTrailingSubmissionRefusals, readJsonFile, repoRelativePath, requireNonEmptyString, resolveContainedPath, resolveHostHandoffPaths, resultMapIdentity, scanBoundSubmission, siblingLockPath, sameStrings, stableStringify, verifyFindingGrounding, withFileLock, writeBlockedStepContract, writeJsonFile, } from "audit-tools/shared";
9
10
  import { findingContractPromptLines } from "../../contracts/findingContractPrompt.js";
10
11
  import { WORKER_REFUSED_FINDING_VERDICTS, WorkerFindingSchema, } from "../../contracts/workerSchemas.js";
11
12
  import { AuditResultSchema, AuditTaskSchema, } from "../../types.js";
@@ -142,7 +143,7 @@ function resolveBoundaryPaths(params) {
142
143
  };
143
144
  }
144
145
  /**
145
- * The accepted-results read-modify-write, SERIALIZED.
146
+ * The binding publication, ingestion reads, and accepted-results write, SERIALIZED.
146
147
  *
147
148
  * `host-accepted-results.json` and its ledger are one logical record written as
148
149
  * two files, and both prepare and ingest used to load a snapshot, work from it,
@@ -151,7 +152,9 @@ function resolveBoundaryPaths(params) {
151
152
  * predates the earlier writer's additions, and every duplicate-binding and
152
153
  * duplicate-result_id guard downstream derives from that stale snapshot.
153
154
  *
154
- * So the read, the merge and both writes happen inside ONE acquisition of the
155
+ * The workload/bindings/map publish and ingest read set also share this hold,
156
+ * so a concurrent prepare cannot replace a binding during acceptance.
157
+ * The read, the merge and both writes happen inside ONE acquisition of the
155
158
  * shared lock substrate. No backoff, retry or stale-lock logic lives here — all
156
159
  * of it is `withFileLock`'s, and the caller's RunLogger is threaded straight
157
160
  * through so the primitive's heartbeat and stale-lock-reclaim events land in the
@@ -342,8 +345,8 @@ function buildPrompt(task, resultPath, workloadPath) {
342
345
  // Required is the honest reading: a steward returns `findings: []`, so a
343
346
  // steward with no `verification` carries no answer at all and is
344
347
  // indistinguishable from a lane that failed.
345
- ? "Result contract: audit-host-result/v1alpha1 with exactly result_id, run_id, work_item_id, prompt_sha256, file_coverage, findings, reviewed_clean, and verification in addition to contract_version. On this lane verification is REQUIRED."
346
- : "Result contract: audit-host-result/v1alpha1 with exactly result_id, run_id, work_item_id, prompt_sha256, file_coverage, and findings in addition to contract_version, plus reviewed_clean when findings is empty.",
348
+ ? "Result contract: audit-host-result/v1alpha1 with exactly result_id, run_id, work_item_id, prompt_sha256, file_coverage, findings, and verification in addition to contract_version. On this lane verification is REQUIRED."
349
+ : "Result contract: audit-host-result/v1alpha1 with exactly result_id, run_id, work_item_id, prompt_sha256, file_coverage, and findings in addition to contract_version.",
347
350
  "Each file_coverage entry must contain exactly path, reviewed_lines, and total_lines.",
348
351
  // The finding contract is CARRIED, not referenced: it is rendered from the
349
352
  // very schema ingestion enforces, so a host never has to remember or fetch it.
@@ -640,20 +643,6 @@ export async function prepareAuditHostHandoff(params) {
640
643
  }),
641
644
  };
642
645
  await mkdir(paths.resultDir, { recursive: true });
643
- await writeJsonFile(paths.taskBindingsPath, taskBindings);
644
- // Say out loud whether this wave has drained. The caller hands in the run's
645
- // still-OWED partition, so an EMPTY one is the wave's own statement that every
646
- // work item it published has been accepted — and that is the only evidence
647
- // there is: from the review-run resolution, a fully-accepted wave and a wave
648
- // with one lane still out look identical (both are "fewer pending than
649
- // published"). The next wave's identity is derived from this, so it is written
650
- // where the run itself lives and never inferred. A comment stating this does
651
- // NOT survive; the marker is what does.
652
- await writeJsonFile(reviewWaveClosedPath(params.artifactsDir, params.runId), {
653
- contract_version: REVIEW_WAVE_CLOSED_CONTRACT_VERSION,
654
- run_id: params.runId,
655
- closed: allWorkItems.length === 0,
656
- });
657
646
  // What is PUBLISHED is every task this caller handed in. This boundary does
658
647
  // not suppress work items the accepted ledger names, and deliberately so —
659
648
  // the ledger records what ARRIVED, it never decides what is still OWED.
@@ -668,6 +657,22 @@ export async function prepareAuditHostHandoff(params) {
668
657
  // acquisition: a prepare that snapshotted before a concurrent ingest's
669
658
  // additions must not replace them with its stale copy.
670
659
  return withAcceptedResultsLock(paths, params.logger, async (accepted) => {
660
+ if (allWorkItems.length > 0)
661
+ await recordHostRootLogBoundary({ ...paths, phase: "prepare", logger: params.logger });
662
+ await writeJsonFile(paths.taskBindingsPath, taskBindings);
663
+ // Say out loud whether this wave has drained. The caller hands in the run's
664
+ // still-OWED partition, so an EMPTY one is the wave's own statement that every
665
+ // work item it published has been accepted — and that is the only evidence
666
+ // there is: from the review-run resolution, a fully-accepted wave and a wave
667
+ // with one lane still out look identical (both are "fewer pending than
668
+ // published"). The next wave's identity is derived from this, so it is written
669
+ // where the run itself lives and never inferred. A comment stating this does
670
+ // NOT survive; the marker is what does.
671
+ await writeJsonFile(reviewWaveClosedPath(params.artifactsDir, params.runId), {
672
+ contract_version: REVIEW_WAVE_CLOSED_CONTRACT_VERSION,
673
+ run_id: params.runId,
674
+ closed: allWorkItems.length === 0,
675
+ });
671
676
  const workload = {
672
677
  contract_version: WORKLOAD_CONTRACT_VERSION,
673
678
  run_id: params.runId,
@@ -863,7 +868,7 @@ function parseResultMap(value, runId) {
863
868
  typeof entry.work_item_id === "string" &&
864
869
  isSha256(entry.prompt_sha256) &&
865
870
  typeof entry.result_path === "string")) {
866
- throw new Error("Invalid audit host result map");
871
+ throw bindingFailure("workload_binding", "Invalid audit host result map");
867
872
  }
868
873
  return value;
869
874
  }
@@ -911,7 +916,7 @@ function parseTaskBindings(value, runId) {
911
916
  !hasExactKeys(value, ["contract_version", "entries", "run_id"]) ||
912
917
  value.run_id !== runId ||
913
918
  !Array.isArray(value.entries)) {
914
- throw new Error("Invalid audit host task bindings");
919
+ throw bindingFailure("workload_binding", "Invalid audit host task bindings");
915
920
  }
916
921
  // The VERSION is checked on its OWN, before the shape walk, so a binding set
917
922
  // written under an older version is refused for THAT reason and carries the
@@ -927,7 +932,7 @@ function parseTaskBindings(value, runId) {
927
932
  for (const rawEntry of value.entries) {
928
933
  const entry = parseTaskBinding(rawEntry);
929
934
  if (entry === null || bindings.has(entry.work_item_id)) {
930
- throw new Error("Invalid or duplicate audit host task binding");
935
+ throw bindingFailure("workload_binding", "Invalid or duplicate audit host task binding");
931
936
  }
932
937
  bindings.set(entry.work_item_id, entry);
933
938
  }
@@ -966,14 +971,19 @@ function validateHandoffBinding(paths, workload, resultMap, taskBindings) {
966
971
  }
967
972
  return items;
968
973
  }
969
- /**
970
- * A persisted-binding failure is a THROW, not an issue: nothing about a host
971
- * result can be judged until the tool's own workload, result map and task
972
- * bindings re-derive. The check id is what the throw cites, so the failure is
973
- * still attributable to a registered ingestion check.
974
- */
974
+ /** Recognized tool-owned binding corruption; the owning emitter can re-prepare it. */
975
+ class AuditHostBindingError extends Error {
976
+ check;
977
+ code = "workload_stale";
978
+ constructor(check, message) {
979
+ super(`${message} [${check}]; re-prepare the handoff to restore its canonical binding set. ` +
980
+ "No submission was accepted against these invalid bindings.");
981
+ this.check = check;
982
+ this.name = "AuditHostBindingError";
983
+ }
984
+ }
975
985
  function bindingFailure(check, message) {
976
- return new Error(`${message} [${check}]`);
986
+ return new AuditHostBindingError(check, message);
977
987
  }
978
988
  /** `check` names the registered ingestion check that failed; `detail` is its prose. */
979
989
  function refuse(check, detail) {
@@ -1225,228 +1235,220 @@ function auditScanMessages(workItemId) {
1225
1235
  }
1226
1236
  export async function ingestAuditHostResults(params) {
1227
1237
  const paths = resolveBoundaryPaths(params);
1228
- const accepted = await loadAcceptedResults(paths.acceptedLedgerPath, params.runId);
1229
- // A STALE persisted document is refused as a CLASSIFIED ISSUE, never as a
1230
- // throw. These are the refusals with a named repair — re-prepare, which this
1231
- // fold performs on its way to the next emission — so they must reach the host
1232
- // as rendered diagnostics rather than as unclassified stacks out of the fold.
1233
- // Nothing is accepted: a document this build did not mint cannot be
1234
- // re-derived, so no submission has a binding to be judged against.
1235
- //
1236
- // The BINDING SET is in this class for one more reason than the workload is:
1237
- // on the fold, a throw here lands BEFORE the one path that re-prepares, so it
1238
- // wedges the run rather than surfacing anything (see
1239
- // {@link StaleAuditHostTaskBindingsError}). A result the host already wrote
1240
- // under the old bindings is therefore REFUSED as stale — it is never accepted
1241
- // against the new contract, because the new contract's binding is what the
1242
- // re-prepare mints, and the item is re-published under it.
1243
- const stale = (error) => ({
1244
- accepted_count: 0,
1245
- accepted_results: accepted.entries.map((entry) => entry.audit_result),
1246
- accepted_results_path: paths.acceptedResultsPath,
1247
- completed_work_item_ids: [
1248
- ...new Set(accepted.entries.map((entry) => entry.work_item_id)),
1249
- ].sort(compareCodeUnits),
1250
- issues: [error],
1251
- raw_issues: [error],
1252
- validation_warnings: [],
1253
- });
1254
- let workload;
1255
- try {
1256
- workload = parseWorkload(await readJsonFile(paths.workloadPath), params.runId);
1257
- }
1258
- catch (error) {
1259
- if (!(error instanceof StaleAuditHostWorkloadError))
1260
- throw error;
1261
- return stale(error);
1262
- }
1263
- const resultMap = parseResultMap(await readJsonFile(paths.resultMapPath), params.runId);
1264
- let taskBindings;
1265
- try {
1266
- taskBindings = parseTaskBindings(await readJsonFile(paths.taskBindingsPath), params.runId);
1267
- }
1268
- catch (error) {
1269
- if (!(error instanceof StaleAuditHostTaskBindingsError))
1270
- throw error;
1271
- return stale(error);
1272
- }
1273
- const items = validateHandoffBinding(paths, workload, resultMap, taskBindings);
1274
- const acceptedBindings = new Set(accepted.entries.map(bindingIdentity));
1275
- const resultIds = new Set(accepted.entries.map((entry) => entry.result_id));
1276
- const additions = [];
1277
- const issues = [];
1278
- const validation_warnings = [];
1279
- // One memoized reader for the whole ingest: N findings citing one file read it once.
1280
- const readSource = createMemoizedSourceReader();
1281
- const activeTaskIds = new Set(params.auditTasks.map((task) => task.task_id));
1282
- for (const entry of resultMap.entries) {
1283
- if (acceptedBindings.has(bindingIdentity(entry)))
1284
- continue;
1285
- const item = items.get(entry.work_item_id);
1286
- const binding = taskBindings.get(entry.work_item_id);
1287
- if (item === undefined || binding === undefined)
1288
- continue;
1289
- const outcome = await scanBoundSubmission({
1290
- root: paths.root,
1291
- artifactsDir: paths.artifactsDir,
1292
- workItemId: entry.work_item_id,
1293
- resultPath: entry.result_path,
1294
- parse: (value) => {
1295
- const parsed = parseHostResult(value, params.runId, item, binding);
1296
- return parsed.ok ? { ok: true, parsed: parsed.result } : parsed;
1297
- },
1298
- resultId: (result) => result.result_id,
1299
- // CHECK only. The id is consumed further down, after conversion,
1300
- // validation and grounding — a result refused there must stay re-submittable.
1301
- seen: (resultId) => resultIds.has(resultId),
1302
- messages: auditScanMessages(entry.work_item_id),
1238
+ return withAcceptedResultsLock(paths, params.logger, async (accepted) => {
1239
+ // A STALE persisted document is refused as a CLASSIFIED ISSUE, never as a
1240
+ // throw. These are the refusals with a named repair — re-prepare, which this
1241
+ // fold performs on its way to the next emission — so they must reach the host
1242
+ // as rendered diagnostics rather than as unclassified stacks out of the fold.
1243
+ // Nothing is accepted: a document this build did not mint cannot be
1244
+ // re-derived, so no submission has a binding to be judged against.
1245
+ //
1246
+ // The BINDING SET is in this class for one more reason than the workload is:
1247
+ // on the fold, a throw here lands BEFORE the one path that re-prepares, so it
1248
+ // wedges the run rather than surfacing anything (see
1249
+ // {@link StaleAuditHostTaskBindingsError}). A result the host already wrote
1250
+ // under the old bindings is therefore REFUSED as stale — it is never accepted
1251
+ // against the new contract, because the new contract's binding is what the
1252
+ // re-prepare mints, and the item is re-published under it.
1253
+ const stale = (error) => ({
1254
+ accepted_count: 0,
1255
+ accepted_results: accepted.entries.map((entry) => entry.audit_result),
1256
+ accepted_results_path: paths.acceptedResultsPath,
1257
+ completed_work_item_ids: [
1258
+ ...new Set(accepted.entries.map((entry) => entry.work_item_id)),
1259
+ ].sort(compareCodeUnits),
1260
+ issues: [error],
1261
+ raw_issues: [error],
1262
+ validation_warnings: [],
1303
1263
  });
1304
- if (!outcome.ok) {
1305
- issues.push(outcome.issue);
1306
- continue;
1264
+ let workload;
1265
+ let resultMap;
1266
+ let taskBindings;
1267
+ let items;
1268
+ try {
1269
+ workload = parseWorkload(await readJsonFile(paths.workloadPath), params.runId);
1270
+ resultMap = parseResultMap(await readJsonFile(paths.resultMapPath), params.runId);
1271
+ taskBindings = parseTaskBindings(await readJsonFile(paths.taskBindingsPath), params.runId);
1272
+ items = validateHandoffBinding(paths, workload, resultMap, taskBindings);
1307
1273
  }
1308
- const result = outcome.parsed;
1309
- const converted = toAuditResult(result, binding);
1310
- if (!converted.ok) {
1311
- issues.push({
1312
- code: "submission_contract_invalid",
1313
- check: "result_schema",
1314
- message: `work item '${entry.work_item_id}' submitted a result that does not convert to ` +
1315
- `an AuditResult: ${converted.detail}`,
1316
- work_item_id: entry.work_item_id,
1317
- result_path: entry.result_path,
1318
- });
1319
- continue;
1320
- }
1321
- // VALIDATE BEFORE ACCEPT. The conversion above proves only the envelope
1322
- // contract (`FindingSchema` admits an evidence-less finding); these are the
1323
- // per-result rules the downstream batch gate applies, applied HERE so an
1324
- // error-severity issue never reaches the accepted pair. A rejected item is
1325
- // simply never in the ledger, so the corrected file at the same bound path
1326
- // is re-read on the next fold — acceptance used to be terminal instead, and
1327
- // a failed batch gate then wedged the run permanently.
1328
- //
1329
- // Orphans (task pruned by a re-plan) pass through UNVALIDATED with the same
1330
- // stderr notice the batch gate uses — never newly rejected: refusing one
1331
- // here would strand it outside the append-only ledger entirely.
1332
- if (!activeTaskIds.has(entry.work_item_id)) {
1333
- process.stderr.write(`audit host-handoff ingest: result for '${entry.work_item_id}' is not in the ` +
1334
- `active task manifest (orphaned by re-planning); retained in the accepted pair ` +
1335
- `but skipped at the validation gate\n`);
1274
+ catch (error) {
1275
+ if (error instanceof StaleAuditHostWorkloadError ||
1276
+ error instanceof StaleAuditHostTaskBindingsError ||
1277
+ error instanceof AuditHostBindingError)
1278
+ return stale(error);
1279
+ if (isJsonParseError(error)) {
1280
+ return stale(new AuditHostBindingError("workload_binding", error.message));
1281
+ }
1282
+ // Infrastructure failures and corrupt accepted ledgers remain strict.
1283
+ throw error;
1336
1284
  }
1337
- else {
1338
- const validationIssues = validateOneAuditResult(converted.auditResult, [
1339
- ...params.auditTasks,
1340
- ], {
1341
- lineIndex: params.lineIndex,
1285
+ const acceptedBindings = new Set(accepted.entries.map(bindingIdentity));
1286
+ const resultIds = new Set(accepted.entries.map((entry) => entry.result_id));
1287
+ const additions = [];
1288
+ const issues = [];
1289
+ const validation_warnings = [];
1290
+ // One memoized reader for the whole ingest: N findings citing one file read it once.
1291
+ const readSource = createMemoizedSourceReader();
1292
+ const activeTaskIds = new Set(params.auditTasks.map((task) => task.task_id));
1293
+ for (const entry of resultMap.entries) {
1294
+ if (acceptedBindings.has(bindingIdentity(entry)))
1295
+ continue;
1296
+ const item = items.get(entry.work_item_id);
1297
+ const binding = taskBindings.get(entry.work_item_id);
1298
+ if (item === undefined || binding === undefined)
1299
+ continue;
1300
+ const outcome = await scanBoundSubmission({
1301
+ root: paths.root,
1302
+ artifactsDir: paths.artifactsDir,
1303
+ workItemId: entry.work_item_id,
1304
+ resultPath: entry.result_path,
1305
+ parse: (value) => {
1306
+ const parsed = parseHostResult(value, params.runId, item, binding);
1307
+ return parsed.ok ? { ok: true, parsed: parsed.result } : parsed;
1308
+ },
1309
+ resultId: (result) => result.result_id,
1310
+ // CHECK only. The id is consumed further down, after conversion,
1311
+ // validation and grounding — a result refused there must stay re-submittable.
1312
+ seen: (resultId) => resultIds.has(resultId),
1313
+ messages: auditScanMessages(entry.work_item_id),
1342
1314
  });
1343
- const errors = validationIssues.filter((issue) => issue.severity === "error");
1344
- if (errors.length > 0) {
1315
+ if (!outcome.ok) {
1316
+ issues.push(outcome.issue);
1317
+ continue;
1318
+ }
1319
+ const result = outcome.parsed;
1320
+ const converted = toAuditResult(result, binding);
1321
+ if (!converted.ok) {
1345
1322
  issues.push({
1346
- code: "result_validation_failed",
1347
- check: "result_validation",
1348
- message: `work item '${entry.work_item_id}' failed audit-results validation ` +
1349
- `(${errors.length} error(s)); fix the result file at its bound path and call next-step again: ` +
1350
- formatAuditResultIssues(errors),
1323
+ code: "submission_contract_invalid",
1324
+ check: "result_schema",
1325
+ message: `work item '${entry.work_item_id}' submitted a result that does not convert to ` +
1326
+ `an AuditResult: ${converted.detail}`,
1351
1327
  work_item_id: entry.work_item_id,
1352
1328
  result_path: entry.result_path,
1353
1329
  });
1354
1330
  continue;
1355
1331
  }
1356
- // Warnings are NOT rejections: an accepted result never refused anything,
1357
- // so a warning must never reach the rejection-classified issue list — the
1358
- // ONE ledger recorder would otherwise record kind:'rejected' for a result
1359
- // that was accepted, manufacturing a repair story that never happened.
1360
- // They ride the separate advisory channel instead (rendered for the
1361
- // operator; never counted as a submission that could not be accepted).
1362
- validation_warnings.push(...validationIssues
1363
- .filter((issue) => issue.severity === "warning")
1364
- .map((warning) => ({
1332
+ // VALIDATE BEFORE ACCEPT. The conversion above proves only the envelope
1333
+ // contract (`FindingSchema` admits an evidence-less finding); these are the
1334
+ // per-result rules the downstream batch gate applies, applied HERE so an
1335
+ // error-severity issue never reaches the accepted pair. A rejected item is
1336
+ // simply never in the ledger, so the corrected file at the same bound path
1337
+ // is re-read on the next fold — acceptance used to be terminal instead, and
1338
+ // a failed batch gate then wedged the run permanently.
1339
+ //
1340
+ // Orphans (task pruned by a re-plan) pass through UNVALIDATED with the same
1341
+ // stderr notice the batch gate uses — never newly rejected: refusing one
1342
+ // here would strand it outside the append-only ledger entirely.
1343
+ if (!activeTaskIds.has(entry.work_item_id)) {
1344
+ process.stderr.write(`audit host-handoff ingest: result for '${entry.work_item_id}' is not in the ` +
1345
+ `active task manifest (orphaned by re-planning); retained in the accepted pair ` +
1346
+ `but skipped at the validation gate\n`);
1347
+ }
1348
+ else {
1349
+ const validationIssues = validateOneAuditResult(converted.auditResult, [
1350
+ ...params.auditTasks,
1351
+ ], {
1352
+ lineIndex: params.lineIndex,
1353
+ });
1354
+ const errors = validationIssues.filter((issue) => issue.severity === "error");
1355
+ if (errors.length > 0) {
1356
+ issues.push({
1357
+ code: "result_validation_failed",
1358
+ check: "result_validation",
1359
+ message: `work item '${entry.work_item_id}' failed audit-results validation ` +
1360
+ `(${errors.length} error(s)); fix the result file at its bound path and call next-step again: ` +
1361
+ formatAuditResultIssues(errors),
1362
+ work_item_id: entry.work_item_id,
1363
+ result_path: entry.result_path,
1364
+ });
1365
+ continue;
1366
+ }
1367
+ // Warnings are NOT rejections: an accepted result never refused anything,
1368
+ // so a warning must never reach the rejection-classified issue list — the
1369
+ // ONE ledger recorder would otherwise record kind:'rejected' for a result
1370
+ // that was accepted, manufacturing a repair story that never happened.
1371
+ // They ride the separate advisory channel instead (rendered for the
1372
+ // operator; never counted as a submission that could not be accepted).
1373
+ validation_warnings.push(...validationIssues
1374
+ .filter((issue) => issue.severity === "warning")
1375
+ .map((warning) => ({
1376
+ work_item_id: entry.work_item_id,
1377
+ result_path: entry.result_path,
1378
+ message: `${warning.message} (${warning.field})`,
1379
+ })));
1380
+ }
1381
+ // S7 quote-and-verify: the tool re-reads each cited span from disk and
1382
+ // stamps the verdict. It NEVER rejects — a quote that does not re-verify
1383
+ // rides through as `ungrounded` and synthesis surfaces it under "Ungrounded
1384
+ // Findings (not confirmed)"; refusing here would discard the whole
1385
+ // submission over one bad citation.
1386
+ for (const finding of converted.auditResult.findings) {
1387
+ finding.grounding = await verifyFindingGrounding(paths.root, finding, readSource);
1388
+ }
1389
+ resultIds.add(result.result_id);
1390
+ // construction-site: AuditResult
1391
+ // construction-site: Finding (the `findings` array; `lens` defaults from the enclosing contract, already spread in)
1392
+ additions.push({
1365
1393
  work_item_id: entry.work_item_id,
1394
+ prompt_sha256: entry.prompt_sha256,
1366
1395
  result_path: entry.result_path,
1367
- message: `${warning.message} (${warning.field})`,
1368
- })));
1369
- }
1370
- // S7 quote-and-verify: the tool re-reads each cited span from disk and
1371
- // stamps the verdict. It NEVER rejects — a quote that does not re-verify
1372
- // rides through as `ungrounded` and synthesis surfaces it under "Ungrounded
1373
- // Findings (not confirmed)"; refusing here would discard the whole
1374
- // submission over one bad citation.
1375
- for (const finding of converted.auditResult.findings) {
1376
- finding.grounding = await verifyFindingGrounding(paths.root, finding, readSource);
1396
+ result_id: result.result_id,
1397
+ result_sha256: contentSha256(result),
1398
+ result,
1399
+ audit_result: converted.auditResult,
1400
+ });
1377
1401
  }
1378
- resultIds.add(result.result_id);
1379
- // construction-site: AuditResult
1380
- // construction-site: Finding (the `findings` array; `lens` defaults from the enclosing contract, already spread in)
1381
- additions.push({
1382
- work_item_id: entry.work_item_id,
1383
- prompt_sha256: entry.prompt_sha256,
1384
- result_path: entry.result_path,
1385
- result_id: result.result_id,
1386
- result_sha256: contentSha256(result),
1387
- result,
1388
- audit_result: converted.auditResult,
1389
- });
1390
- }
1391
- // The submission reading, contract checking and grounding re-verification
1392
- // above run UNLOCKED — they only read. The read-modify-write does not: the
1393
- // ledger is re-read under the lock and the additions are re-filtered against
1394
- // that fresh copy, so a concurrent writer's entries are merged rather than
1395
- // replaced, and a binding or result id it accepted in the meantime is not
1396
- // accepted a second time here.
1397
- let landed = [];
1398
- const ledger = await withAcceptedResultsLock(paths, params.logger, async (current) => {
1399
- const currentBindings = new Set(current.entries.map(bindingIdentity));
1400
- const currentResultIds = new Set(current.entries.map((entry) => entry.result_id));
1401
- landed = additions.filter((addition) => !currentBindings.has(bindingIdentity(addition)) &&
1402
+ // Binding reads, validation and this accepted pair write share ONE hold.
1403
+ // A concurrent prepare cannot replace the task bindings mid-ingestion.
1404
+ const currentBindings = new Set(accepted.entries.map(bindingIdentity));
1405
+ const currentResultIds = new Set(accepted.entries.map((entry) => entry.result_id));
1406
+ const landed = additions.filter((addition) => !currentBindings.has(bindingIdentity(addition)) &&
1402
1407
  !currentResultIds.has(addition.result_id));
1403
- if (landed.length === 0)
1404
- return current;
1405
- const next = {
1408
+ const ledger = {
1406
1409
  contract_version: ACCEPTED_RESULTS_CONTRACT_VERSION,
1407
1410
  run_id: params.runId,
1408
- entries: [...current.entries, ...landed].sort((left, right) => {
1411
+ entries: [...accepted.entries, ...landed].sort((left, right) => {
1409
1412
  const item = compareCodeUnits(left.work_item_id, right.work_item_id);
1410
- return item !== 0
1411
- ? item
1412
- : compareCodeUnits(left.prompt_sha256, right.prompt_sha256);
1413
+ return item !== 0 ? item : compareCodeUnits(left.prompt_sha256, right.prompt_sha256);
1413
1414
  }),
1414
1415
  };
1415
- await writeAcceptedResults(paths, next);
1416
- return next;
1416
+ if (landed.length > 0)
1417
+ await writeAcceptedResults(paths, ledger);
1418
+ for (const addition of additions) {
1419
+ if (landed.includes(addition))
1420
+ continue;
1421
+ issues.push({
1422
+ code: "duplicate_submission_id",
1423
+ message: `work item '${addition.work_item_id}' was already accepted by a concurrent ` +
1424
+ `ingest of this run, so this submission was not accepted a second time`,
1425
+ work_item_id: addition.work_item_id,
1426
+ result_path: addition.result_path,
1427
+ });
1428
+ }
1429
+ // Ledger recording is NOT done here. The shared submission ledger is written
1430
+ // by the ONE recorder, `recordHostResultOutcomes`, at this ingest's only
1431
+ // production caller — fed these very `issues` and `completed_work_item_ids` —
1432
+ // so every rejection below already lands there in arrival order. A second
1433
+ // writer inside the boundary would double-record the same fact.
1434
+ const raw_issues = [...issues];
1435
+ const refusals = await readTrailingSubmissionRefusals(paths.artifactsDir, raw_issues
1436
+ .map((issue) => issue.work_item_id ?? issue.submission_id)
1437
+ .filter((id) => id !== undefined));
1438
+ const reportedIssues = enrichMissingSubmissionIssues(raw_issues, refusals, "submission_rejected");
1439
+ await recordHostRootLogBoundary({ ...paths, phase: "ingest", logger: params.logger });
1440
+ return {
1441
+ accepted_count: landed.length,
1442
+ accepted_results: ledger.entries.map((entry) => entry.audit_result),
1443
+ accepted_results_path: paths.acceptedResultsPath,
1444
+ validation_warnings,
1445
+ completed_work_item_ids: [
1446
+ ...new Set(ledger.entries.map((entry) => entry.work_item_id)),
1447
+ ].sort(compareCodeUnits),
1448
+ issues: reportedIssues,
1449
+ raw_issues,
1450
+ };
1417
1451
  });
1418
- for (const addition of additions) {
1419
- if (landed.includes(addition))
1420
- continue;
1421
- issues.push({
1422
- code: "duplicate_submission_id",
1423
- message: `work item '${addition.work_item_id}' was already accepted by a concurrent ` +
1424
- `ingest of this run, so this submission was not accepted a second time`,
1425
- work_item_id: addition.work_item_id,
1426
- result_path: addition.result_path,
1427
- });
1428
- }
1429
- // Ledger recording is NOT done here. The shared submission ledger is written
1430
- // by the ONE recorder, `recordHostResultOutcomes`, at this ingest's only
1431
- // production caller — fed these very `issues` and `completed_work_item_ids` —
1432
- // so every rejection below already lands there in arrival order. A second
1433
- // writer inside the boundary would double-record the same fact.
1434
- const raw_issues = [...issues];
1435
- const refusals = await readTrailingSubmissionRefusals(paths.artifactsDir, raw_issues
1436
- .map((issue) => issue.work_item_id ?? issue.submission_id)
1437
- .filter((id) => id !== undefined));
1438
- const reportedIssues = enrichMissingSubmissionIssues(raw_issues, refusals, "submission_rejected");
1439
- return {
1440
- accepted_count: landed.length,
1441
- accepted_results: ledger.entries.map((entry) => entry.audit_result),
1442
- accepted_results_path: paths.acceptedResultsPath,
1443
- validation_warnings,
1444
- completed_work_item_ids: [
1445
- ...new Set(ledger.entries.map((entry) => entry.work_item_id)),
1446
- ].sort(compareCodeUnits),
1447
- issues: reportedIssues,
1448
- raw_issues,
1449
- };
1450
1452
  }
1451
1453
  /**
1452
1454
  * Remove accepted entries — the supported way back out of an acceptance.