clinkx 0.3.0 → 1.0.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 (555) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +10 -0
  3. package/README.md +82 -26
  4. package/clinkx-workflows/dist/allowed-roots.d.ts +1 -0
  5. package/clinkx-workflows/dist/allowed-roots.js +5 -0
  6. package/clinkx-workflows/dist/allowed-roots.js.map +1 -0
  7. package/clinkx-workflows/dist/artifacts.d.ts +20 -1
  8. package/clinkx-workflows/dist/artifacts.js +38 -9
  9. package/clinkx-workflows/dist/artifacts.js.map +1 -1
  10. package/clinkx-workflows/dist/backend.d.ts +4 -0
  11. package/clinkx-workflows/dist/citation-check.d.ts +40 -0
  12. package/clinkx-workflows/dist/citation-check.js +348 -0
  13. package/clinkx-workflows/dist/citation-check.js.map +1 -0
  14. package/clinkx-workflows/dist/clink-client.d.ts +2 -1
  15. package/clinkx-workflows/dist/clink-client.js +17 -4
  16. package/clinkx-workflows/dist/clink-client.js.map +1 -1
  17. package/clinkx-workflows/dist/config.d.ts +145 -16
  18. package/clinkx-workflows/dist/config.js +384 -26
  19. package/clinkx-workflows/dist/config.js.map +1 -1
  20. package/clinkx-workflows/dist/contained-file.d.ts +172 -0
  21. package/clinkx-workflows/dist/contained-file.js +483 -0
  22. package/clinkx-workflows/dist/contained-file.js.map +1 -0
  23. package/clinkx-workflows/dist/context-builder-lifecycle-contract.d.ts +416 -0
  24. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js +328 -0
  25. package/clinkx-workflows/dist/context-builder-lifecycle-contract.js.map +1 -0
  26. package/clinkx-workflows/dist/context-builder-lifecycle-router.d.ts +24 -0
  27. package/clinkx-workflows/dist/context-builder-lifecycle-router.js +39 -0
  28. package/clinkx-workflows/dist/context-builder-lifecycle-router.js.map +1 -0
  29. package/clinkx-workflows/dist/context-cache-key.d.ts +53 -0
  30. package/clinkx-workflows/dist/context-cache-key.js +91 -0
  31. package/clinkx-workflows/dist/context-cache-key.js.map +1 -0
  32. package/clinkx-workflows/dist/context-mode-resolver.d.ts +27 -0
  33. package/clinkx-workflows/dist/context-mode-resolver.js +126 -0
  34. package/clinkx-workflows/dist/context-mode-resolver.js.map +1 -0
  35. package/clinkx-workflows/dist/context-preflight.d.ts +184 -0
  36. package/clinkx-workflows/dist/context-preflight.js +91 -0
  37. package/clinkx-workflows/dist/context-preflight.js.map +1 -0
  38. package/clinkx-workflows/dist/council-expander.d.ts +1 -1
  39. package/clinkx-workflows/dist/council-expander.js +2 -1
  40. package/clinkx-workflows/dist/council-expander.js.map +1 -1
  41. package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +165 -0
  42. package/clinkx-workflows/dist/dashboard/activity-contract.js +105 -0
  43. package/clinkx-workflows/dist/dashboard/activity-contract.js.map +1 -0
  44. package/clinkx-workflows/dist/dashboard/activity-lease.d.ts +25 -0
  45. package/clinkx-workflows/dist/dashboard/activity-lease.js +34 -0
  46. package/clinkx-workflows/dist/dashboard/activity-lease.js.map +1 -0
  47. package/clinkx-workflows/dist/dashboard/activity-reader.d.ts +86 -0
  48. package/clinkx-workflows/dist/dashboard/activity-reader.js +480 -0
  49. package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
  50. package/clinkx-workflows/dist/dashboard/api-routes.d.ts +36 -0
  51. package/clinkx-workflows/dist/dashboard/api-routes.js +1047 -0
  52. package/clinkx-workflows/dist/dashboard/api-routes.js.map +1 -0
  53. package/clinkx-workflows/dist/dashboard/artifact-index.d.ts +37 -0
  54. package/clinkx-workflows/dist/dashboard/artifact-index.js +145 -0
  55. package/clinkx-workflows/dist/dashboard/artifact-index.js.map +1 -0
  56. package/clinkx-workflows/dist/dashboard/auth/challenge-store.d.ts +31 -0
  57. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js +65 -0
  58. package/clinkx-workflows/dist/dashboard/auth/challenge-store.js.map +1 -0
  59. package/clinkx-workflows/dist/dashboard/auth/controller.d.ts +26 -0
  60. package/clinkx-workflows/dist/dashboard/auth/controller.js +596 -0
  61. package/clinkx-workflows/dist/dashboard/auth/controller.js.map +1 -0
  62. package/clinkx-workflows/dist/dashboard/auth/credential-store.d.ts +60 -0
  63. package/clinkx-workflows/dist/dashboard/auth/credential-store.js +776 -0
  64. package/clinkx-workflows/dist/dashboard/auth/credential-store.js.map +1 -0
  65. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.d.ts +9 -0
  66. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js +44 -0
  67. package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js.map +1 -0
  68. package/clinkx-workflows/dist/dashboard/auth/session-store.d.ts +17 -0
  69. package/clinkx-workflows/dist/dashboard/auth/session-store.js +77 -0
  70. package/clinkx-workflows/dist/dashboard/auth/session-store.js.map +1 -0
  71. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.d.ts +25 -0
  72. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js +71 -0
  73. package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js.map +1 -0
  74. package/clinkx-workflows/dist/dashboard/context-run-liveness.d.ts +37 -0
  75. package/clinkx-workflows/dist/dashboard/context-run-liveness.js +49 -0
  76. package/clinkx-workflows/dist/dashboard/context-run-liveness.js.map +1 -0
  77. package/clinkx-workflows/dist/dashboard/context-run-reader.d.ts +222 -0
  78. package/clinkx-workflows/dist/dashboard/context-run-reader.js +1178 -0
  79. package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
  80. package/clinkx-workflows/dist/dashboard/contracts.d.ts +8936 -0
  81. package/clinkx-workflows/dist/dashboard/contracts.js +1157 -0
  82. package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -0
  83. package/clinkx-workflows/dist/dashboard/generation.d.ts +14 -0
  84. package/clinkx-workflows/dist/dashboard/generation.js +41 -0
  85. package/clinkx-workflows/dist/dashboard/generation.js.map +1 -0
  86. package/clinkx-workflows/dist/dashboard/index.d.ts +28 -0
  87. package/clinkx-workflows/dist/dashboard/index.js +16 -0
  88. package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
  89. package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +101 -0
  90. package/clinkx-workflows/dist/dashboard/lazy-content.js +748 -0
  91. package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
  92. package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +303 -0
  93. package/clinkx-workflows/dist/dashboard/progress-report-contract.js +221 -0
  94. package/clinkx-workflows/dist/dashboard/progress-report-contract.js.map +1 -0
  95. package/clinkx-workflows/dist/dashboard/progress-report-reader.d.ts +50 -0
  96. package/clinkx-workflows/dist/dashboard/progress-report-reader.js +581 -0
  97. package/clinkx-workflows/dist/dashboard/progress-report-reader.js.map +1 -0
  98. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +89 -0
  99. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js +71 -0
  100. package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js.map +1 -0
  101. package/clinkx-workflows/dist/dashboard/progress-report-status-store.d.ts +28 -0
  102. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +110 -0
  103. package/clinkx-workflows/dist/dashboard/progress-report-status-store.js.map +1 -0
  104. package/clinkx-workflows/dist/dashboard/read-model.d.ts +86 -0
  105. package/clinkx-workflows/dist/dashboard/read-model.js +440 -0
  106. package/clinkx-workflows/dist/dashboard/read-model.js.map +1 -0
  107. package/clinkx-workflows/dist/dashboard/request-admission.d.ts +31 -0
  108. package/clinkx-workflows/dist/dashboard/request-admission.js +126 -0
  109. package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
  110. package/clinkx-workflows/dist/dashboard/scanner.d.ts +75 -0
  111. package/clinkx-workflows/dist/dashboard/scanner.js +1110 -0
  112. package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
  113. package/clinkx-workflows/dist/dashboard/server-factory.d.ts +50 -0
  114. package/clinkx-workflows/dist/dashboard/server-factory.js +431 -0
  115. package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
  116. package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2611 -0
  117. package/clinkx-workflows/dist/dashboard/session-log-contract.js +480 -0
  118. package/clinkx-workflows/dist/dashboard/session-log-contract.js.map +1 -0
  119. package/clinkx-workflows/dist/dashboard/session-log-identity.d.ts +21 -0
  120. package/clinkx-workflows/dist/dashboard/session-log-identity.js +101 -0
  121. package/clinkx-workflows/dist/dashboard/session-log-identity.js.map +1 -0
  122. package/clinkx-workflows/dist/dashboard/session-log-journal.d.ts +43 -0
  123. package/clinkx-workflows/dist/dashboard/session-log-journal.js +522 -0
  124. package/clinkx-workflows/dist/dashboard/session-log-journal.js.map +1 -0
  125. package/clinkx-workflows/dist/dashboard/session-log-reader.d.ts +61 -0
  126. package/clinkx-workflows/dist/dashboard/session-log-reader.js +378 -0
  127. package/clinkx-workflows/dist/dashboard/session-log-reader.js.map +1 -0
  128. package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +6 -0
  129. package/clinkx-workflows/dist/dashboard/session-log-redaction.js +367 -0
  130. package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -0
  131. package/clinkx-workflows/dist/dashboard/session-log-retention.d.ts +23 -0
  132. package/clinkx-workflows/dist/dashboard/session-log-retention.js +212 -0
  133. package/clinkx-workflows/dist/dashboard/session-log-retention.js.map +1 -0
  134. package/clinkx-workflows/dist/dashboard/static-responses.d.ts +10 -0
  135. package/clinkx-workflows/dist/dashboard/static-responses.js +94 -0
  136. package/clinkx-workflows/dist/dashboard/static-responses.js.map +1 -0
  137. package/clinkx-workflows/dist/dashboard/worker-lock-observer.d.ts +28 -0
  138. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js +241 -0
  139. package/clinkx-workflows/dist/dashboard/worker-lock-observer.js.map +1 -0
  140. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  141. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  142. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  143. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  144. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  145. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  146. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  147. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  148. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  149. package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  150. package/clinkx-workflows/dist/dashboard-ui/assets/index-DOkMXTfB.js +25 -0
  151. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  152. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  153. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  154. package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  155. package/clinkx-workflows/dist/dashboard-ui/assets/style-ChJsn0KD.css +1 -0
  156. package/clinkx-workflows/dist/dashboard-ui/contracts/council-plan-review-input-v1.json +158 -0
  157. package/clinkx-workflows/dist/dashboard-ui/index.html +15 -0
  158. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Mono-OFL.txt +93 -0
  159. package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Sans-OFL.txt +93 -0
  160. package/clinkx-workflows/dist/dashboard-ui/licenses/JetBrains-Mono-OFL.txt +93 -0
  161. package/clinkx-workflows/dist/dashboard-ui/licenses/NOTICE.md +32 -0
  162. package/clinkx-workflows/dist/dashboard-ui/theme-init.js +8 -0
  163. package/clinkx-workflows/dist/definition-normalizer.d.ts +19 -0
  164. package/clinkx-workflows/dist/definition-normalizer.js.map +1 -1
  165. package/clinkx-workflows/dist/delegate-validate.d.ts +78 -0
  166. package/clinkx-workflows/dist/delegate-validate.js +97 -0
  167. package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
  168. package/clinkx-workflows/dist/engine.d.ts +141 -0
  169. package/clinkx-workflows/dist/engine.js +882 -28
  170. package/clinkx-workflows/dist/engine.js.map +1 -1
  171. package/clinkx-workflows/dist/errors.d.ts +2 -0
  172. package/clinkx-workflows/dist/errors.js.map +1 -1
  173. package/clinkx-workflows/dist/fingerprint.d.ts +1 -1
  174. package/clinkx-workflows/dist/fingerprint.js +1 -1
  175. package/clinkx-workflows/dist/index.d.ts +19 -0
  176. package/clinkx-workflows/dist/index.js +15 -0
  177. package/clinkx-workflows/dist/index.js.map +1 -1
  178. package/clinkx-workflows/dist/loader.d.ts +9 -3
  179. package/clinkx-workflows/dist/loader.js +92 -21
  180. package/clinkx-workflows/dist/loader.js.map +1 -1
  181. package/clinkx-workflows/dist/plan-review/admission.d.ts +160 -0
  182. package/clinkx-workflows/dist/plan-review/admission.js +290 -0
  183. package/clinkx-workflows/dist/plan-review/admission.js.map +1 -0
  184. package/clinkx-workflows/dist/plan-review/context-policy.d.ts +55 -0
  185. package/clinkx-workflows/dist/plan-review/context-policy.js +146 -0
  186. package/clinkx-workflows/dist/plan-review/context-policy.js.map +1 -0
  187. package/clinkx-workflows/dist/plan-review/contract.d.ts +763 -0
  188. package/clinkx-workflows/dist/plan-review/contract.js +289 -0
  189. package/clinkx-workflows/dist/plan-review/contract.js.map +1 -0
  190. package/clinkx-workflows/dist/plan-review/digest.d.ts +68 -0
  191. package/clinkx-workflows/dist/plan-review/digest.js +241 -0
  192. package/clinkx-workflows/dist/plan-review/digest.js.map +1 -0
  193. package/clinkx-workflows/dist/plan-review/discovery.d.ts +45 -0
  194. package/clinkx-workflows/dist/plan-review/discovery.js +36 -0
  195. package/clinkx-workflows/dist/plan-review/discovery.js.map +1 -0
  196. package/clinkx-workflows/dist/plan-review/execution-contract.d.ts +298 -0
  197. package/clinkx-workflows/dist/plan-review/execution-contract.js +194 -0
  198. package/clinkx-workflows/dist/plan-review/execution-contract.js.map +1 -0
  199. package/clinkx-workflows/dist/plan-review/expander.d.ts +48 -0
  200. package/clinkx-workflows/dist/plan-review/expander.js +243 -0
  201. package/clinkx-workflows/dist/plan-review/expander.js.map +1 -0
  202. package/clinkx-workflows/dist/plan-review/projector.d.ts +126 -0
  203. package/clinkx-workflows/dist/plan-review/projector.js +437 -0
  204. package/clinkx-workflows/dist/plan-review/projector.js.map +1 -0
  205. package/clinkx-workflows/dist/plan-review/publication.d.ts +95 -0
  206. package/clinkx-workflows/dist/plan-review/publication.js +182 -0
  207. package/clinkx-workflows/dist/plan-review/publication.js.map +1 -0
  208. package/clinkx-workflows/dist/plan-review/ranking-reducer.d.ts +34 -0
  209. package/clinkx-workflows/dist/plan-review/ranking-reducer.js +139 -0
  210. package/clinkx-workflows/dist/plan-review/ranking-reducer.js.map +1 -0
  211. package/clinkx-workflows/dist/plan-review/resume.d.ts +38 -0
  212. package/clinkx-workflows/dist/plan-review/resume.js +122 -0
  213. package/clinkx-workflows/dist/plan-review/resume.js.map +1 -0
  214. package/clinkx-workflows/dist/plan-review/rubric.d.ts +7 -0
  215. package/clinkx-workflows/dist/plan-review/rubric.js +24 -0
  216. package/clinkx-workflows/dist/plan-review/rubric.js.map +1 -0
  217. package/clinkx-workflows/dist/plan-review/run-state.d.ts +398 -0
  218. package/clinkx-workflows/dist/plan-review/run-state.js +183 -0
  219. package/clinkx-workflows/dist/plan-review/run-state.js.map +1 -0
  220. package/clinkx-workflows/dist/plan-review/runtime-policy.d.ts +74 -0
  221. package/clinkx-workflows/dist/plan-review/runtime-policy.js +186 -0
  222. package/clinkx-workflows/dist/plan-review/runtime-policy.js.map +1 -0
  223. package/clinkx-workflows/dist/plan-review/snapshot.d.ts +81 -0
  224. package/clinkx-workflows/dist/plan-review/snapshot.js +170 -0
  225. package/clinkx-workflows/dist/plan-review/snapshot.js.map +1 -0
  226. package/clinkx-workflows/dist/plan-review/stage-error.d.ts +19 -0
  227. package/clinkx-workflows/dist/plan-review/stage-error.js +20 -0
  228. package/clinkx-workflows/dist/plan-review/stage-error.js.map +1 -0
  229. package/clinkx-workflows/dist/post-processors/index.d.ts +20 -0
  230. package/clinkx-workflows/dist/post-processors/index.js +21 -0
  231. package/clinkx-workflows/dist/post-processors/index.js.map +1 -0
  232. package/clinkx-workflows/dist/prompt-budget.d.ts +7 -0
  233. package/clinkx-workflows/dist/prompt-budget.js +7 -1
  234. package/clinkx-workflows/dist/prompt-budget.js.map +1 -1
  235. package/clinkx-workflows/dist/reducers/index.js +2 -0
  236. package/clinkx-workflows/dist/reducers/index.js.map +1 -1
  237. package/clinkx-workflows/dist/run-lock-heartbeat.d.ts +2 -0
  238. package/clinkx-workflows/dist/run-lock-heartbeat.js +3 -0
  239. package/clinkx-workflows/dist/run-lock-heartbeat.js.map +1 -0
  240. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.d.ts +34 -0
  241. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js +74 -0
  242. package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js.map +1 -0
  243. package/clinkx-workflows/dist/run-summary/cards/index.js +5 -0
  244. package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -1
  245. package/clinkx-workflows/dist/run-summary.d.ts +13 -0
  246. package/clinkx-workflows/dist/run-summary.js +29 -1
  247. package/clinkx-workflows/dist/run-summary.js.map +1 -1
  248. package/clinkx-workflows/dist/schema.d.ts +76 -21
  249. package/clinkx-workflows/dist/schema.js +10 -1
  250. package/clinkx-workflows/dist/schema.js.map +1 -1
  251. package/clinkx-workflows/dist/seed-terms.d.ts +30 -0
  252. package/clinkx-workflows/dist/seed-terms.js +176 -0
  253. package/clinkx-workflows/dist/seed-terms.js.map +1 -0
  254. package/clinkx-workflows/dist/server.d.ts +5 -2
  255. package/clinkx-workflows/dist/server.js +82 -52
  256. package/clinkx-workflows/dist/server.js.map +1 -1
  257. package/clinkx-workflows/dist/shutdown.d.ts +18 -20
  258. package/clinkx-workflows/dist/shutdown.js +43 -61
  259. package/clinkx-workflows/dist/shutdown.js.map +1 -1
  260. package/clinkx-workflows/dist/state-schema.d.ts +38 -0
  261. package/clinkx-workflows/dist/state.d.ts +170 -3
  262. package/clinkx-workflows/dist/state.js +1275 -28
  263. package/clinkx-workflows/dist/state.js.map +1 -1
  264. package/clinkx-workflows/dist/transport.d.ts +15 -0
  265. package/clinkx-workflows/dist/transport.js +19 -10
  266. package/clinkx-workflows/dist/transport.js.map +1 -1
  267. package/clinkx-workflows/dist/types.d.ts +14 -2
  268. package/clinkx-workflows/dist/validators/council.d.ts +318 -85
  269. package/clinkx-workflows/dist/validators/council.js +52 -13
  270. package/clinkx-workflows/dist/validators/council.js.map +1 -1
  271. package/clinkx-workflows/dist/validators/index.d.ts +1 -0
  272. package/clinkx-workflows/dist/validators/index.js +3 -0
  273. package/clinkx-workflows/dist/validators/index.js.map +1 -1
  274. package/clinkx-workflows/dist/validators/plan-review.d.ts +398 -0
  275. package/clinkx-workflows/dist/validators/plan-review.js +316 -0
  276. package/clinkx-workflows/dist/validators/plan-review.js.map +1 -0
  277. package/clinkx-workflows/dist/workflow-receipt.js +188 -4
  278. package/clinkx-workflows/dist/workflow-receipt.js.map +1 -1
  279. package/clinkx-workflows/dist/workflow-tools.d.ts +48 -3
  280. package/clinkx-workflows/dist/workflow-tools.js +1402 -59
  281. package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
  282. package/clinkx-workflows/dist/workspace-signature.d.ts +16 -0
  283. package/clinkx-workflows/dist/workspace-signature.js +388 -0
  284. package/clinkx-workflows/dist/workspace-signature.js.map +1 -0
  285. package/clinkx-workflows/templates/council/answer-specialist.txt +2 -1
  286. package/clinkx-workflows/templates/council/code-review-chairman.txt +13 -0
  287. package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +4 -1
  288. package/clinkx-workflows/templates/council/code-review-reviewer.txt +19 -3
  289. package/clinkx-workflows/templates/council/debug-debugger.txt +2 -1
  290. package/clinkx-workflows/templates/council/discover-analyst.txt +2 -1
  291. package/clinkx-workflows/templates/council/member.txt +2 -1
  292. package/clinkx-workflows/templates/council/plan-review-chairman.txt +68 -0
  293. package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +51 -0
  294. package/clinkx-workflows/templates/council/plan-review-reviewer.txt +60 -0
  295. package/clinkx-workflows/templates/plan-review/chairman.txt +48 -0
  296. package/clinkx-workflows/templates/plan-review/cross-review.txt +52 -0
  297. package/clinkx-workflows/templates/plan-review/ranking.txt +16 -0
  298. package/clinkx-workflows/templates/plan-review/reviewer.txt +57 -0
  299. package/clinkx-workflows/workflows/council-answer.yaml +97 -8
  300. package/clinkx-workflows/workflows/council-code-review.yaml +103 -8
  301. package/clinkx-workflows/workflows/council-debug.yaml +97 -8
  302. package/clinkx-workflows/workflows/council-default.yaml +97 -8
  303. package/clinkx-workflows/workflows/council-discover.yaml +97 -8
  304. package/clinkx-workflows/workflows/council-plan-review.yaml +250 -0
  305. package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
  306. package/conf/adapters/agy.json +49 -0
  307. package/conf/adapters/claude.json +5 -0
  308. package/conf/adapters/codex-app-server.json +44 -0
  309. package/conf/adapters/codex.json +7 -2
  310. package/conf/adapters/glm.json +5 -0
  311. package/conf/adapters/grok.json +60 -0
  312. package/conf/adapters/hapi/agy.json +52 -0
  313. package/conf/adapters/hapi/claude.json +5 -0
  314. package/conf/adapters/hapi/codex.json +7 -2
  315. package/conf/adapters/hapi/glm.json +5 -0
  316. package/dist/activity-journal.d.ts +42 -0
  317. package/dist/activity-journal.js +381 -0
  318. package/dist/activity-journal.js.map +1 -0
  319. package/dist/allowed-roots.d.ts +41 -0
  320. package/dist/allowed-roots.js +125 -3
  321. package/dist/allowed-roots.js.map +1 -1
  322. package/dist/codex/activity-session-log.d.ts +14 -0
  323. package/dist/codex/activity-session-log.js +206 -0
  324. package/dist/codex/activity-session-log.js.map +1 -0
  325. package/dist/codex/agent-tools.d.ts +23 -0
  326. package/dist/codex/agent-tools.js +1270 -0
  327. package/dist/codex/agent-tools.js.map +1 -0
  328. package/dist/codex/app-server-client.d.ts +76 -0
  329. package/dist/codex/app-server-client.js +582 -0
  330. package/dist/codex/app-server-client.js.map +1 -0
  331. package/dist/codex/app-server-registry.d.ts +389 -0
  332. package/dist/codex/app-server-registry.js +1407 -0
  333. package/dist/codex/app-server-registry.js.map +1 -0
  334. package/dist/codex/client-types.d.ts +109 -0
  335. package/dist/codex/client-types.js +2 -0
  336. package/dist/codex/client-types.js.map +1 -0
  337. package/dist/codex/protocol.d.ts +5375 -0
  338. package/dist/codex/protocol.js +614 -0
  339. package/dist/codex/protocol.js.map +1 -0
  340. package/dist/codex/session.d.ts +263 -0
  341. package/dist/codex/session.js +466 -0
  342. package/dist/codex/session.js.map +1 -0
  343. package/dist/config.d.ts +185 -19
  344. package/dist/config.js +82 -16
  345. package/dist/config.js.map +1 -1
  346. package/dist/context-builder/anchors.d.ts +1 -0
  347. package/dist/context-builder/anchors.js +3 -0
  348. package/dist/context-builder/anchors.js.map +1 -1
  349. package/dist/context-builder/bundle.d.ts +35 -2
  350. package/dist/context-builder/bundle.js +342 -2417
  351. package/dist/context-builder/bundle.js.map +1 -1
  352. package/dist/context-builder/codemap.d.ts +5 -0
  353. package/dist/context-builder/codemap.js +387 -13
  354. package/dist/context-builder/codemap.js.map +1 -1
  355. package/dist/context-builder/config.d.ts +1 -0
  356. package/dist/context-builder/config.js +12 -0
  357. package/dist/context-builder/config.js.map +1 -1
  358. package/dist/context-builder/context-run-catalog.d.ts +17 -0
  359. package/dist/context-builder/context-run-catalog.js +99 -0
  360. package/dist/context-builder/context-run-catalog.js.map +1 -0
  361. package/dist/context-builder/delegate-packet.d.ts +37 -0
  362. package/dist/context-builder/delegate-packet.js +359 -67
  363. package/dist/context-builder/delegate-packet.js.map +1 -1
  364. package/dist/context-builder/delegate-validation.d.ts +10 -1
  365. package/dist/context-builder/delegate-validation.js +153 -41
  366. package/dist/context-builder/delegate-validation.js.map +1 -1
  367. package/dist/context-builder/delegate.d.ts +2 -0
  368. package/dist/context-builder/delegate.js +1 -0
  369. package/dist/context-builder/delegate.js.map +1 -1
  370. package/dist/context-builder/diagnostics.d.ts +11 -2
  371. package/dist/context-builder/diagnostics.js +39 -6
  372. package/dist/context-builder/diagnostics.js.map +1 -1
  373. package/dist/context-builder/discovery.d.ts +29 -1
  374. package/dist/context-builder/discovery.js +475 -175
  375. package/dist/context-builder/discovery.js.map +1 -1
  376. package/dist/context-builder/globs.js +10 -10
  377. package/dist/context-builder/globs.js.map +1 -1
  378. package/dist/context-builder/handler.d.ts +26 -2
  379. package/dist/context-builder/handler.js +1158 -2416
  380. package/dist/context-builder/handler.js.map +1 -1
  381. package/dist/context-builder/lifecycle-contract.d.ts +424 -0
  382. package/dist/context-builder/lifecycle-contract.js +523 -0
  383. package/dist/context-builder/lifecycle-contract.js.map +1 -0
  384. package/dist/context-builder/lifecycle-journal.d.ts +62 -0
  385. package/dist/context-builder/lifecycle-journal.js +88 -0
  386. package/dist/context-builder/lifecycle-journal.js.map +1 -0
  387. package/dist/context-builder/lifecycle-observer.d.ts +102 -0
  388. package/dist/context-builder/lifecycle-observer.js +258 -0
  389. package/dist/context-builder/lifecycle-observer.js.map +1 -0
  390. package/dist/context-builder/lifecycle-reconcile.d.ts +32 -0
  391. package/dist/context-builder/lifecycle-reconcile.js +191 -0
  392. package/dist/context-builder/lifecycle-reconcile.js.map +1 -0
  393. package/dist/context-builder/lifecycle-recovery.d.ts +2 -0
  394. package/dist/context-builder/lifecycle-recovery.js +14 -0
  395. package/dist/context-builder/lifecycle-recovery.js.map +1 -0
  396. package/dist/context-builder/path-signals.js +9 -5
  397. package/dist/context-builder/path-signals.js.map +1 -1
  398. package/dist/context-builder/progress.d.ts +3 -1
  399. package/dist/context-builder/progress.js +23 -0
  400. package/dist/context-builder/progress.js.map +1 -1
  401. package/dist/context-builder/receipt.d.ts +6 -4
  402. package/dist/context-builder/receipt.js +12 -1
  403. package/dist/context-builder/receipt.js.map +1 -1
  404. package/dist/context-builder/refine-handler.d.ts +14 -0
  405. package/dist/context-builder/refine-handler.js +790 -0
  406. package/dist/context-builder/refine-handler.js.map +1 -0
  407. package/dist/context-builder/review-coverage.d.ts +84 -0
  408. package/dist/context-builder/review-coverage.js +437 -0
  409. package/dist/context-builder/review-coverage.js.map +1 -0
  410. package/dist/context-builder/schema.d.ts +239 -1
  411. package/dist/context-builder/schema.js +112 -6
  412. package/dist/context-builder/schema.js.map +1 -1
  413. package/dist/context-builder/secrets.d.ts +28 -0
  414. package/dist/context-builder/secrets.js +1473 -44
  415. package/dist/context-builder/secrets.js.map +1 -1
  416. package/dist/context-builder/selection.d.ts +7 -3
  417. package/dist/context-builder/selection.js +200 -738
  418. package/dist/context-builder/selection.js.map +1 -1
  419. package/dist/context-builder/session-log-identity.d.ts +1 -0
  420. package/dist/context-builder/session-log-identity.js +66 -0
  421. package/dist/context-builder/session-log-identity.js.map +1 -0
  422. package/dist/context-builder/slice-range-math.d.ts +16 -0
  423. package/dist/context-builder/slice-range-math.js +137 -0
  424. package/dist/context-builder/slice-range-math.js.map +1 -0
  425. package/dist/context-builder/status.d.ts +22 -1
  426. package/dist/context-builder/status.js +59 -4
  427. package/dist/context-builder/status.js.map +1 -1
  428. package/dist/context-builder/storage.d.ts +35 -2
  429. package/dist/context-builder/storage.js +271 -14
  430. package/dist/context-builder/storage.js.map +1 -1
  431. package/dist/context-builder/token-estimate.d.ts +13 -2
  432. package/dist/context-builder/token-estimate.js +77 -4
  433. package/dist/context-builder/token-estimate.js.map +1 -1
  434. package/dist/context-builder/versions.d.ts +29 -0
  435. package/dist/context-builder/versions.js +30 -0
  436. package/dist/context-builder/versions.js.map +1 -0
  437. package/dist/context-builder/workflow-runner.d.ts +69 -0
  438. package/dist/context-builder/workflow-runner.js +1051 -0
  439. package/dist/context-builder/workflow-runner.js.map +1 -0
  440. package/dist/context-builder/write-watchdog.d.ts +14 -0
  441. package/dist/context-builder/write-watchdog.js +38 -0
  442. package/dist/context-builder/write-watchdog.js.map +1 -0
  443. package/dist/dashboard-adapter-catalog.d.ts +9 -0
  444. package/dist/dashboard-adapter-catalog.js +46 -0
  445. package/dist/dashboard-adapter-catalog.js.map +1 -0
  446. package/dist/dashboard-cli.d.ts +79 -0
  447. package/dist/dashboard-cli.js +585 -0
  448. package/dist/dashboard-cli.js.map +1 -0
  449. package/dist/dashboard-companion/client.d.ts +36 -0
  450. package/dist/dashboard-companion/client.js +210 -0
  451. package/dist/dashboard-companion/client.js.map +1 -0
  452. package/dist/dashboard-companion/config.d.ts +8 -0
  453. package/dist/dashboard-companion/config.js +52 -0
  454. package/dist/dashboard-companion/config.js.map +1 -0
  455. package/dist/dashboard-companion/http-proxy.d.ts +10 -0
  456. package/dist/dashboard-companion/http-proxy.js +234 -0
  457. package/dist/dashboard-companion/http-proxy.js.map +1 -0
  458. package/dist/dashboard-companion/protocol.d.ts +80 -0
  459. package/dist/dashboard-companion/protocol.js +455 -0
  460. package/dist/dashboard-companion/protocol.js.map +1 -0
  461. package/dist/dashboard-companion/standalone-assets.d.ts +12 -0
  462. package/dist/dashboard-companion/standalone-assets.js +72 -0
  463. package/dist/dashboard-companion/standalone-assets.js.map +1 -0
  464. package/dist/dashboard-companion/standalone-entry.d.ts +1 -0
  465. package/dist/dashboard-companion/standalone-entry.js +17 -0
  466. package/dist/dashboard-companion/standalone-entry.js.map +1 -0
  467. package/dist/dashboard-gateway/config.d.ts +9 -0
  468. package/dist/dashboard-gateway/config.js +44 -0
  469. package/dist/dashboard-gateway/config.js.map +1 -0
  470. package/dist/dashboard-gateway/index.d.ts +11 -0
  471. package/dist/dashboard-gateway/index.js +755 -0
  472. package/dist/dashboard-gateway/index.js.map +1 -0
  473. package/dist/dashboard-gateway/main.d.ts +1 -0
  474. package/dist/dashboard-gateway/main.js +25 -0
  475. package/dist/dashboard-gateway/main.js.map +1 -0
  476. package/dist/dashboard-pairing-token.d.ts +1 -0
  477. package/dist/dashboard-pairing-token.js +5 -0
  478. package/dist/dashboard-pairing-token.js.map +1 -0
  479. package/dist/elaris/client.d.ts +73 -0
  480. package/dist/elaris/client.js +825 -0
  481. package/dist/elaris/client.js.map +1 -0
  482. package/dist/elaris/config.d.ts +18 -0
  483. package/dist/elaris/config.js +75 -0
  484. package/dist/elaris/config.js.map +1 -0
  485. package/dist/elaris/errors.d.ts +41 -0
  486. package/dist/elaris/errors.js +205 -0
  487. package/dist/elaris/errors.js.map +1 -0
  488. package/dist/elaris/github-repo.d.ts +18 -0
  489. package/dist/elaris/github-repo.js +89 -0
  490. package/dist/elaris/github-repo.js.map +1 -0
  491. package/dist/elaris/index.d.ts +10 -0
  492. package/dist/elaris/index.js +11 -0
  493. package/dist/elaris/index.js.map +1 -0
  494. package/dist/elaris/redact.d.ts +89 -0
  495. package/dist/elaris/redact.js +423 -0
  496. package/dist/elaris/redact.js.map +1 -0
  497. package/dist/elaris/run-id.d.ts +5 -0
  498. package/dist/elaris/run-id.js +20 -0
  499. package/dist/elaris/run-id.js.map +1 -0
  500. package/dist/elaris/status.d.ts +45 -0
  501. package/dist/elaris/status.js +122 -0
  502. package/dist/elaris/status.js.map +1 -0
  503. package/dist/elaris/tool-schemas.d.ts +314 -0
  504. package/dist/elaris/tool-schemas.js +208 -0
  505. package/dist/elaris/tool-schemas.js.map +1 -0
  506. package/dist/elaris/tools.d.ts +73 -0
  507. package/dist/elaris/tools.js +1065 -0
  508. package/dist/elaris/tools.js.map +1 -0
  509. package/dist/elaris/types.d.ts +1541 -0
  510. package/dist/elaris/types.js +252 -0
  511. package/dist/elaris/types.js.map +1 -0
  512. package/dist/errors.d.ts +16 -0
  513. package/dist/errors.js +19 -0
  514. package/dist/errors.js.map +1 -1
  515. package/dist/handler.d.ts +4 -0
  516. package/dist/handler.js +10 -1
  517. package/dist/handler.js.map +1 -1
  518. package/dist/index.d.ts +2 -1
  519. package/dist/index.js +13 -3
  520. package/dist/index.js.map +1 -1
  521. package/dist/local-clink-backend.d.ts +3 -0
  522. package/dist/local-clink-backend.js +4 -0
  523. package/dist/local-clink-backend.js.map +1 -1
  524. package/dist/package-info.d.ts +2 -0
  525. package/dist/package-info.js +18 -0
  526. package/dist/package-info.js.map +1 -0
  527. package/dist/parsers/codex-jsonl.js +48 -3
  528. package/dist/parsers/codex-jsonl.js.map +1 -1
  529. package/dist/parsers/extract.d.ts +10 -1
  530. package/dist/parsers/extract.js +11 -3
  531. package/dist/parsers/extract.js.map +1 -1
  532. package/dist/pipeline.d.ts +4 -0
  533. package/dist/pipeline.js +129 -8
  534. package/dist/pipeline.js.map +1 -1
  535. package/dist/run-dir.d.ts +24 -0
  536. package/dist/run-dir.js +201 -2
  537. package/dist/run-dir.js.map +1 -1
  538. package/dist/runner.d.ts +13 -0
  539. package/dist/runner.js +184 -15
  540. package/dist/runner.js.map +1 -1
  541. package/dist/safety.d.ts +4 -4
  542. package/dist/safety.js +4 -4
  543. package/dist/schema.d.ts +7 -7
  544. package/dist/server.d.ts +1 -0
  545. package/dist/server.js +359 -17
  546. package/dist/server.js.map +1 -1
  547. package/dist/session-log-stream.d.ts +18 -0
  548. package/dist/session-log-stream.js +319 -0
  549. package/dist/session-log-stream.js.map +1 -0
  550. package/package.json +46 -5
  551. package/conf/adapters/gemini.json +0 -44
  552. package/conf/adapters/hapi/gemini.json +0 -47
  553. package/dist/parsers/gemini-json.d.ts +0 -2
  554. package/dist/parsers/gemini-json.js +0 -72
  555. package/dist/parsers/gemini-json.js.map +0 -1
@@ -0,0 +1,1051 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { realpathSync, statSync } from "node:fs";
3
+ import { copyFile, mkdir, readFile, realpath, rename, rm, utimes, } from "node:fs/promises";
4
+ import { isAbsolute, join, relative, resolve } from "node:path";
5
+ // ---------------------------------------------------------------------------
6
+ // Deep `clinkx-workflows/dist` imports (one-way dependency, build-order coupled)
7
+ //
8
+ // The next four imports pull cache-key, preflight-contract, config, and
9
+ // workspace-signature helpers from the COMPILED output of the sibling
10
+ // `clinkx-workflows` package rather than from a published entry point. This is
11
+ // deliberate and safe:
12
+ //
13
+ // - The dependency arrow points one way: root -> clinkx-workflows. The
14
+ // workflows package defines only the `ContextBuilderRunner` callback
15
+ // interface and never statically imports the root `context-builder/`
16
+ // modules, so there is no import cycle. See docs/architecture.md, "Module
17
+ // boundary (no dependency cycle)".
18
+ // - `clinkx-workflows` is a separate tsc project with no package `exports`
19
+ // map; its public runtime surface is its `dist/*.js` files. Importing its
20
+ // source `.ts` would violate the NodeNext + `.js`-extension ESM contract.
21
+ //
22
+ // BUILD ORDER: `clinkx-workflows/dist` MUST be built before the root package is
23
+ // built or run. `npm run build:all` enforces this (clinkx-workflows first, then
24
+ // root). A bare `npm run build` assumes dist already exists; a missing dist
25
+ // surfaces as ERR_MODULE_NOT_FOUND at import time, not a compile error.
26
+ // ---------------------------------------------------------------------------
27
+ import { computeCacheKey, computeInputsHash, deriveWfctxId, } from "../../clinkx-workflows/dist/context-cache-key.js";
28
+ import { resolveWorkspaceRoot as resolveWorkflowWorkspaceRoot } from "../../clinkx-workflows/dist/config.js";
29
+ import { createSessionLogGeneration, readSessionLogGeneration, } from "../../clinkx-workflows/dist/dashboard/session-log-identity.js";
30
+ import { getSignatureCoveredPaths, workspaceSignature as computeWorkspaceSignature, } from "../../clinkx-workflows/dist/workspace-signature.js";
31
+ import { isArtifactOnlyAllowedRootEntry, isPathWithinAllowedRoots, } from "../allowed-roots.js";
32
+ import { CancellationError, ExecutionError, InvalidParamsError } from "../errors.js";
33
+ import { logger } from "../logger.js";
34
+ import { getCurrentAllowedRoots } from "../paths.js";
35
+ import { CONTEXT_BUILDER_RENDERER_VERSION } from "./bundle.js";
36
+ import { CONTEXT_DELEGATE_PROMPT_VERSION, CONTEXT_DISCOVERY_ALGORITHM_VERSION, } from "./versions.js";
37
+ import { getSharedContextBuilderSemaphore, resolveContextBuilderRunsDir, } from "./config.js";
38
+ import { handleContextBuilder } from "./handler.js";
39
+ import { CONTEXT_BUILDER_INTENT_PROFILE_DEFAULTS, CONTEXT_BUILDER_INTENT_PROFILES, resolveContextBuilderAdapterBudgetInput, } from "./schema.js";
40
+ import { assertNoHighConfidenceSecretsInTask, resolveAllowSecrets, } from "./secrets.js";
41
+ import { CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION, CONTEXT_BUILDER_NO_DELEGATE_SCHEMA_VERSION, createContextBuilderReceipt, } from "./receipt.js";
42
+ import { notEvaluatedCoverageReport, } from "./review-coverage.js";
43
+ import { isContextBuilderRunCommitted, evictWorkflowContextRuns, promoteContextBuilderRun, resolveContextBuilderRunPaths, withContextBuilderRunMutationLease, } from "./storage.js";
44
+ import { ContextBuilderLifecycleController, ContextBuilderLifecycleObserverError, } from "./lifecycle-observer.js";
45
+ export function createWorkflowContextBuilderRunner(options = {}) {
46
+ const cb = options.handleContextBuilder ?? handleContextBuilder;
47
+ // Default to the SHARED process-wide context_builder gate so workflow
48
+ // preflight, standalone context_builder, and refine_context_run all contend
49
+ // for one CLINKX_CONTEXT_BUILDER_MAX_CONCURRENT permit pool. Tests may inject
50
+ // their own semaphore for isolation.
51
+ const semaphore = options.semaphore ?? getSharedContextBuilderSemaphore();
52
+ const runIdFactory = options.runIdFactory ?? generateWorkflowPreflightRunId;
53
+ const workspaceRootResolver = options.resolveWorkspaceRoot ?? resolveWorkflowWorkspaceRoot;
54
+ const workspaceSignature = options.workspaceSignature ?? computeWorkspaceSignature;
55
+ const signatureCoveredPaths = options.getSignatureCoveredPaths ?? getSignatureCoveredPaths;
56
+ const rendererVersion = options.rendererVersion ?? CONTEXT_BUILDER_RENDERER_VERSION;
57
+ const discoveryAlgorithmVersion = options.discoveryAlgorithmVersion ?? CONTEXT_DISCOVERY_ALGORITHM_VERSION;
58
+ const delegatePromptVersion = options.delegatePromptVersion ?? CONTEXT_DELEGATE_PROMPT_VERSION;
59
+ const registry = options.registry;
60
+ return {
61
+ assertRootsAllowed(roots) {
62
+ assertExplicitRootsWithinAllowed(roots);
63
+ },
64
+ assertTaskSecretsAllowed(variables) {
65
+ const rawFlag = variables["cb_allow_secrets"];
66
+ const explicit = typeof rawFlag === "boolean" ? rawFlag : undefined;
67
+ if (resolveAllowSecrets(explicit)) {
68
+ return;
69
+ }
70
+ for (const key of ["cb_task", "user_request"]) {
71
+ const value = variables[key];
72
+ if (typeof value === "string" && value.length > 0) {
73
+ assertNoHighConfidenceSecretsInTask(value);
74
+ }
75
+ }
76
+ },
77
+ async runOrReuse(input, opts) {
78
+ let lifecycle;
79
+ try {
80
+ throwIfAborted(opts.signal);
81
+ const mappedInput = await mapPreflightContextInput(input, {
82
+ resolveWorkspaceRoot: workspaceRootResolver,
83
+ });
84
+ const mapped = input.context_budget_adapter == null ||
85
+ input.context_budget_adapter.trim() === ""
86
+ ? mappedInput
87
+ : {
88
+ ...mappedInput,
89
+ budget: resolveContextBuilderAdapterBudgetInput({
90
+ adapterDefaults: resolveAdapterBudgetDefaults(registry, input.context_budget_adapter),
91
+ profile: mappedInput.profile,
92
+ explicit: mappedInput.budget,
93
+ }),
94
+ };
95
+ const lifecycleInjection = options.lifecycleFactory?.(input);
96
+ lifecycle = lifecycleInjection == null
97
+ ? undefined
98
+ : new ContextBuilderLifecycleController({
99
+ operationKind: "workflow_preflight",
100
+ execution: workflowLifecycleExecutionConfig(mapped),
101
+ observer: lifecycleInjection.observer,
102
+ ...(lifecycleInjection.origin == null
103
+ ? {}
104
+ : { origin: lifecycleInjection.origin }),
105
+ ...(options.lifecycleNow == null
106
+ ? {}
107
+ : { now: options.lifecycleNow }),
108
+ });
109
+ await lifecycle?.transition("resolving");
110
+ // The controller has now minted the preflight operation id
111
+ // (lifecycle.contextRunId). Pair it with a generation sidecar created under
112
+ // the workflow run dir so the dashboard can later locate the preflight's
113
+ // session-log subtree. Only the injected-lifecycle (workflow) path builds
114
+ // this; the standalone path derives its own identity from its journal.
115
+ const preflightSessionLogContext = lifecycle == null
116
+ ? undefined
117
+ : await resolvePreflightSessionLogContext(input.runDir, lifecycle.contextRunId);
118
+ const cacheInput = {
119
+ ...mapped,
120
+ roots: await normalizeCacheRoots(mapped.roots),
121
+ };
122
+ const includeSelectedContext = input.includeSelectedContext === true;
123
+ const effectiveSchemaVersion = mapped.delegate.enabled === true
124
+ ? CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION
125
+ : CONTEXT_BUILDER_NO_DELEGATE_SCHEMA_VERSION;
126
+ const cacheSchemaVersion = options.cbSchemaVersion ?? effectiveSchemaVersion;
127
+ const runsDir = await resolveContextBuilderRunsDir(options.runsDir);
128
+ let preSig = await workspaceSignature(mapped.roots);
129
+ throwIfAborted(opts.signal);
130
+ let cache = deriveCacheCoordinates(cacheInput, preSig, runsDir, {
131
+ rendererVersion,
132
+ cbSchemaVersion: cacheSchemaVersion,
133
+ discoveryAlgorithmVersion,
134
+ delegatePromptVersion,
135
+ });
136
+ let cacheReason = "cache_miss";
137
+ if (await isContextBuilderRunCommitted(cache.targetStorage.runDir)) {
138
+ const postSig = await workspaceSignature(mapped.roots);
139
+ throwIfAborted(opts.signal);
140
+ if (postSig === preSig) {
141
+ const hit = await withContextBuilderRunMutationLease(cache.targetStorage, async () => {
142
+ // The unleased probe above is only an optimization. Pruning may
143
+ // win before this lease is acquired, so re-check under the lock
144
+ // before reading the manifest or materializing any artifact.
145
+ if (!await isContextBuilderRunCommitted(cache.targetStorage.runDir)) {
146
+ return undefined;
147
+ }
148
+ // Refresh directory mtime so LRU eviction treats this as recently used.
149
+ try {
150
+ const now = new Date();
151
+ await utimes(cache.targetStorage.runDir, now, now);
152
+ }
153
+ catch {
154
+ // best-effort — a hit must not fail because utimes failed
155
+ }
156
+ return await synthesizePreflightResultFromCommittedRun({
157
+ storage: cache.targetStorage,
158
+ runDir: input.runDir,
159
+ keyPrefix: cache.keyPrefix,
160
+ schemaVersion: effectiveSchemaVersion,
161
+ budgetCaps: mapped.budget,
162
+ includeSelectedContext,
163
+ ...(lifecycle == null ? {} : { lifecycle }),
164
+ });
165
+ });
166
+ if (hit !== undefined) {
167
+ await lifecycle?.complete(workflowLifecycleTerminalStatus(hit), {
168
+ artifactRunId: hit.source_run_id,
169
+ ...workflowResultLifecyclePatch(hit, lifecycle, true),
170
+ });
171
+ return hit;
172
+ }
173
+ cacheReason = "cache_stale";
174
+ }
175
+ else {
176
+ cacheReason = "cache_stale";
177
+ preSig = postSig;
178
+ cache = deriveCacheCoordinates(cacheInput, preSig, runsDir, {
179
+ rendererVersion,
180
+ cbSchemaVersion: cacheSchemaVersion,
181
+ discoveryAlgorithmVersion,
182
+ delegatePromptVersion,
183
+ });
184
+ }
185
+ }
186
+ await lifecycle?.transition("cache_lookup", {
187
+ cache: {
188
+ lookup: "miss",
189
+ write: "not_attempted",
190
+ reason_code: cacheReason,
191
+ },
192
+ reasonCodes: [cacheReason],
193
+ });
194
+ const tempId = runIdFactory();
195
+ const tempInput = { ...mapped, run_id: tempId };
196
+ const response = await cb(tempInput, {
197
+ runsDir,
198
+ semaphore,
199
+ ...(registry == null ? {} : { registry }),
200
+ ...(input.allowRootWideDiscovery == null
201
+ ? {}
202
+ : { allowRootWideDiscovery: input.allowRootWideDiscovery }),
203
+ ...(opts.signal == null ? {} : { signal: opts.signal }),
204
+ ...(lifecycle == null ? {} : { lifecycleController: lifecycle }),
205
+ ...(preflightSessionLogContext == null
206
+ ? {}
207
+ : { sessionLogContext: preflightSessionLogContext }),
208
+ });
209
+ throwIfAborted(opts.signal);
210
+ const receipt = parseReceiptResponse(response);
211
+ const tempStorage = resolveContextBuilderRunPaths(runsDir, tempId);
212
+ // The id of the run this call will return as its live source. Eviction in
213
+ // the finally must protect it so small/zero retention bounds cannot delete
214
+ // the run whose source_artifact_dir we are about to hand back.
215
+ let liveSourceRunId = tempId;
216
+ try {
217
+ const tempManifest = await readManifest(tempStorage.manifestJson);
218
+ // Degraded fallback selections (delegate failure_policy:"fallback") must
219
+ // NEVER enter the shared wfctx cache: a cached fallback would be replayed
220
+ // for a later fail-closed failure_policy:"fail" request (silently
221
+ // succeeding instead of failing) and would mask genuine delegated
222
+ // successes. Not caching also lets a later identical request retry
223
+ // delegation rather than reusing a stale degraded bundle. The manifest
224
+ // is the authoritative persisted source; fall back to the receipt.
225
+ const fallbackUsed = tempManifest.delegate?.fallback_used === true ||
226
+ receipt.delegate?.fallback_used === true;
227
+ const selectedPaths = await resolveSelectedContextPaths(tempManifest, mapped.roots);
228
+ const gate = await evaluatePostCbPromotionGate({
229
+ roots: mapped.roots,
230
+ selectedPaths,
231
+ workspaceSignature,
232
+ signatureCoveredPaths,
233
+ });
234
+ throwIfAborted(opts.signal);
235
+ if (!fallbackUsed && gate?.selectedFilesCovered === true && gate.postSig === preSig) {
236
+ try {
237
+ await lifecycle?.transition("materializing");
238
+ const promoted = await promoteContextBuilderRun(tempStorage.runDir, cache.wfctxId);
239
+ // Promote succeeded and renamed temp → wfctx: protect the wfctx run
240
+ // immediately so a later throw (e.g. copyBundleArtifactsIntoRun) can
241
+ // never leave the freshly-promoted run unprotected against zero/small
242
+ // retention eviction in the finally.
243
+ liveSourceRunId = cache.wfctxId;
244
+ // Copy from the PROMOTED wfctx run (the temp dir is now deleted) so
245
+ // the fanned manifest's run_id matches the returned source_run_id and
246
+ // its artifact paths point at live files.
247
+ const promotedManifest = await readManifest(promoted.manifestJson);
248
+ const resultBeforeMaterialization = buildPreflightResult({
249
+ receipt: createReceiptFromManifest(promotedManifest, promoted),
250
+ sourceRunId: cache.wfctxId,
251
+ sourceArtifactDir: promoted.runDir,
252
+ cache: {
253
+ hit: false,
254
+ write: true,
255
+ target_id: cache.wfctxId,
256
+ key_prefix: cache.keyPrefix,
257
+ },
258
+ copiedPaths: [],
259
+ schemaVersion: effectiveSchemaVersion,
260
+ observability: preflightObservabilityFromManifest(tempManifest, mapped.budget),
261
+ coverage: coverageFromManifest(tempManifest),
262
+ });
263
+ const copiedPaths = await copyBundleArtifactsIntoRun(promotedManifest.artifacts, input.runDir, {
264
+ includeSelectedContext,
265
+ ...(lifecycle == null
266
+ ? {}
267
+ : {
268
+ beforeManifestCommit: async () => {
269
+ await lifecycle?.transition("committing", {
270
+ artifactRunId: resultBeforeMaterialization.source_run_id,
271
+ cache: {
272
+ lookup: "miss",
273
+ write: "written",
274
+ reason_code: cacheReason,
275
+ },
276
+ ...workflowResultLifecyclePatch(resultBeforeMaterialization, lifecycle),
277
+ });
278
+ },
279
+ }),
280
+ });
281
+ const result = {
282
+ ...resultBeforeMaterialization,
283
+ copied_paths: copiedPaths,
284
+ };
285
+ await lifecycle?.complete(workflowLifecycleTerminalStatus(result), {
286
+ artifactRunId: result.source_run_id,
287
+ ...workflowResultLifecyclePatch(result, lifecycle),
288
+ });
289
+ return result;
290
+ }
291
+ catch (error) {
292
+ if (!isPromoteClaimConflict(error)) {
293
+ throw error;
294
+ }
295
+ }
296
+ }
297
+ // Non-promote (or promote-claim-conflict) path: copy from the surviving
298
+ // temp run, which is the authoritative source for the returned id.
299
+ await lifecycle?.transition("materializing");
300
+ const resultBeforeMaterialization = buildPreflightResult({
301
+ receipt: createReceiptFromManifest(tempManifest, tempStorage),
302
+ sourceRunId: tempId,
303
+ sourceArtifactDir: tempStorage.runDir,
304
+ cache: {
305
+ hit: false,
306
+ write: false,
307
+ target_id: null,
308
+ key_prefix: cache.keyPrefix,
309
+ },
310
+ copiedPaths: [],
311
+ schemaVersion: effectiveSchemaVersion,
312
+ observability: preflightObservabilityFromManifest(tempManifest, mapped.budget),
313
+ coverage: coverageFromManifest(tempManifest),
314
+ });
315
+ const copiedPaths = await copyBundleArtifactsIntoRun(tempManifest.artifacts, input.runDir, {
316
+ includeSelectedContext,
317
+ ...(lifecycle == null
318
+ ? {}
319
+ : {
320
+ beforeManifestCommit: async () => {
321
+ await lifecycle?.transition("committing", {
322
+ artifactRunId: resultBeforeMaterialization.source_run_id,
323
+ cache: {
324
+ lookup: "miss",
325
+ write: "skipped",
326
+ reason_code: cacheReason,
327
+ },
328
+ ...workflowResultLifecyclePatch(resultBeforeMaterialization, lifecycle),
329
+ });
330
+ },
331
+ }),
332
+ });
333
+ const result = {
334
+ ...resultBeforeMaterialization,
335
+ copied_paths: copiedPaths,
336
+ };
337
+ await lifecycle?.complete(workflowLifecycleTerminalStatus(result), {
338
+ artifactRunId: result.source_run_id,
339
+ ...workflowResultLifecyclePatch(result, lifecycle),
340
+ });
341
+ return result;
342
+ }
343
+ finally {
344
+ // Best-effort, prefix-scoped/TTL-guarded eviction on every completed
345
+ // MISS path (promote and non-promote). The active source run of this
346
+ // call is protected so zero/small retention bounds cannot self-delete
347
+ // the run whose source_artifact_dir we just returned.
348
+ await evictWorkflowContextRuns(runsDir, {
349
+ protectedRunIds: [liveSourceRunId],
350
+ })
351
+ .then((eviction) => {
352
+ if (eviction.failed > 0) {
353
+ logger.warn({ runsDir, eviction }, "workflow context_builder cache eviction had delete failures");
354
+ }
355
+ })
356
+ .catch((err) => {
357
+ logger.warn({ err, runsDir }, "workflow context_builder cache eviction failed");
358
+ });
359
+ }
360
+ }
361
+ catch (error) {
362
+ if (lifecycle != null && !(error instanceof ContextBuilderLifecycleObserverError)) {
363
+ const cancelled = error instanceof CancellationError || opts.signal?.aborted === true;
364
+ const delegateFailed = workflowDelegateExecutionActive(lifecycle);
365
+ await lifecycle.fail(cancelled ? "cancelled" : "failed", {
366
+ ...workflowTerminalExecutionPatch(lifecycle, cancelled),
367
+ reasonCodes: [
368
+ cancelled
369
+ ? "operation_cancelled"
370
+ : delegateFailed
371
+ ? "delegate_failed"
372
+ : "internal_failure",
373
+ ],
374
+ ...(!cancelled && delegateFailed
375
+ ? {
376
+ fallback: {
377
+ status: "failed",
378
+ reason_code: "delegate_failed",
379
+ },
380
+ }
381
+ : {}),
382
+ });
383
+ }
384
+ // Rethrow the ORIGINAL error object, never a wrapper: markers set by
385
+ // the handler (e.g. ExecutionError.failureClass:"transient" on a
386
+ // delegate timeout) must reach the workflow engine's failure
387
+ // classifier intact.
388
+ throw error;
389
+ }
390
+ },
391
+ };
392
+ }
393
+ /**
394
+ * Subdirectory of the workflow run dir holding the preflight session-log
395
+ * generation sidecar. The dashboard reads this back to locate the preflight's
396
+ * session-log subtree and to pair it with the persisted lifecycle context_run_id.
397
+ */
398
+ const PREFLIGHT_SESSION_LOG_DIR = ".context-preflight";
399
+ /**
400
+ * Create-or-read the preflight session-log generation sidecar under the workflow
401
+ * run dir, then pair it with the controller-minted operation id. Create-or-read
402
+ * (rather than exclusive-create) keeps the generation stable across retries of
403
+ * the same run. Best-effort: any failure resolves to undefined, and the preflight
404
+ * renders without a `[ log ]` affordance (the prior telemetry-only contract).
405
+ */
406
+ async function resolvePreflightSessionLogContext(runDir, contextRunId) {
407
+ try {
408
+ const sidecarDir = join(runDir, PREFLIGHT_SESSION_LOG_DIR);
409
+ await mkdir(sidecarDir, { recursive: true, mode: 0o700 });
410
+ const existing = await readSessionLogGeneration(sidecarDir);
411
+ const contextGeneration = existing.kind === "available"
412
+ ? existing.sessionLogGeneration
413
+ : await createSessionLogGeneration(sidecarDir);
414
+ return { contextRunId, contextGeneration };
415
+ }
416
+ catch {
417
+ return undefined;
418
+ }
419
+ }
420
+ function workflowLifecycleExecutionConfig(input) {
421
+ if (input.delegate.enabled !== true) {
422
+ return {
423
+ curator: { configured: false, enabled: false },
424
+ finalizer: { configured: false, enabled: false },
425
+ };
426
+ }
427
+ const finalizerEnabled = input.delegate.finalizer.enabled ??
428
+ (input.profile == null
429
+ ? true
430
+ : CONTEXT_BUILDER_INTENT_PROFILE_DEFAULTS[input.profile].finalizer_enabled);
431
+ return {
432
+ curator: { configured: true, enabled: true },
433
+ finalizer: { configured: true, enabled: finalizerEnabled },
434
+ };
435
+ }
436
+ function workflowLifecycleTerminalStatus(result) {
437
+ return result.delegate?.fallback_used === true || result.status === "partial"
438
+ ? "partial"
439
+ : "succeeded";
440
+ }
441
+ function workflowResultLifecyclePatch(result, lifecycle, cacheHit = false) {
442
+ const coverage = result.coverage ?? notEvaluatedCoverageReport();
443
+ const required = coverage.required_when_available.length;
444
+ const missing = coverage.missing_required.length;
445
+ const snapshot = lifecycle?.snapshot;
446
+ const executionPatch = cacheHit
447
+ ? {
448
+ ...(snapshot?.curator.effective_enabled === true
449
+ ? { curatorStatus: "skipped" }
450
+ : {}),
451
+ ...(snapshot?.finalizer.effective_enabled === true
452
+ ? { finalizerStatus: "skipped" }
453
+ : {}),
454
+ }
455
+ : result.delegate?.fallback_used === true
456
+ ? {
457
+ ...(snapshot?.curator.effective_enabled === true
458
+ ? { curatorStatus: "failed" }
459
+ : {}),
460
+ ...(snapshot?.finalizer.effective_enabled === true
461
+ ? { finalizerStatus: "skipped" }
462
+ : {}),
463
+ fallback: {
464
+ status: "used",
465
+ reason_code: "delegate_fallback",
466
+ },
467
+ reasonCodes: ["delegate_fallback"],
468
+ }
469
+ : {
470
+ ...(snapshot?.curator.effective_enabled === true &&
471
+ snapshot.curator.execution_status === "pending"
472
+ ? { curatorStatus: "succeeded" }
473
+ : {}),
474
+ ...(snapshot?.finalizer.effective_enabled === true &&
475
+ snapshot.finalizer.execution_status === "pending"
476
+ ? { finalizerStatus: "succeeded" }
477
+ : {}),
478
+ };
479
+ return {
480
+ ...executionPatch,
481
+ counts: {
482
+ files_seen: cacheHit ? 0 : result.metrics.files_seen,
483
+ files_considered: cacheHit ? 0 : result.metrics.files_considered,
484
+ files_selected: result.metrics.files_selected,
485
+ files_omitted: cacheHit ? 0 : result.metrics.files_omitted,
486
+ search_results: cacheHit ? 0 : snapshot?.counts.search_results ?? 0,
487
+ bytes_read: cacheHit ? 0 : result.metrics.bytes_read,
488
+ bytes_written: result.metrics.bytes_written,
489
+ },
490
+ coverage: {
491
+ policy: coverage.policy_id,
492
+ status: coverage.status,
493
+ required,
494
+ selected: Math.max(0, required - missing),
495
+ missing,
496
+ },
497
+ ...(coverage.status === "degraded"
498
+ ? { reasonCodes: [...(executionPatch.reasonCodes ?? []), "coverage_degraded"] }
499
+ : {}),
500
+ };
501
+ }
502
+ function workflowTerminalExecutionPatch(lifecycle, cancelled) {
503
+ const snapshot = lifecycle.snapshot;
504
+ if (snapshot == null)
505
+ return {};
506
+ const terminalStatus = cancelled ? "cancelled" : "failed";
507
+ return {
508
+ ...(snapshot.curator.execution_status === "running"
509
+ ? { curatorStatus: terminalStatus }
510
+ : snapshot.curator.execution_status === "pending"
511
+ ? { curatorStatus: "skipped" }
512
+ : {}),
513
+ ...(snapshot.finalizer.execution_status === "running"
514
+ ? { finalizerStatus: terminalStatus }
515
+ : snapshot.finalizer.execution_status === "pending"
516
+ ? { finalizerStatus: "skipped" }
517
+ : {}),
518
+ };
519
+ }
520
+ function workflowDelegateExecutionActive(lifecycle) {
521
+ const snapshot = lifecycle.snapshot;
522
+ return snapshot?.curator.execution_status === "running" ||
523
+ snapshot?.finalizer.execution_status === "running";
524
+ }
525
+ export async function copyBundleIntoRun(receipt, runDir, options = {}) {
526
+ return copyBundleArtifactsIntoRun(receipt.artifacts, runDir, options);
527
+ }
528
+ export async function copyBundleArtifactsIntoRun(artifacts, runDir, options = {}) {
529
+ const runRoot = await realpath(runDir);
530
+ const contextDir = join(runRoot, "artifacts", "context");
531
+ await mkdir(contextDir, { recursive: true });
532
+ const realContextDir = await realpath(contextDir);
533
+ const bundleDest = await copyArtifactIntoContextDir(await resolveArtifactPath(artifacts, "bundle_md", "bundle.md"), realContextDir, "bundle.md");
534
+ const selectedContextDest = options.includeSelectedContext === true
535
+ ? await copyArtifactIntoContextDir(await resolveArtifactPath(artifacts, "selected_context_jsonl", "selected-context.jsonl"), realContextDir, "selected-context.jsonl")
536
+ : undefined;
537
+ const manifestSource = await resolveArtifactPath(artifacts, "manifest_json", "manifest.json");
538
+ await options.beforeManifestCommit?.();
539
+ const manifestDest = await copyArtifactIntoContextDir(manifestSource, realContextDir, "manifest.json");
540
+ return selectedContextDest == null
541
+ ? [bundleDest, manifestDest]
542
+ : [bundleDest, selectedContextDest, manifestDest];
543
+ }
544
+ export async function mapPreflightContextInput(input, options) {
545
+ assertExplicitRootsWithinAllowed(input.roots);
546
+ const task = input.cb_task.trim() === "" ? input.user_request : input.cb_task;
547
+ const roots = input.roots.length > 0
548
+ ? [...input.roots]
549
+ : [await resolveFallbackRoot(options.resolveWorkspaceRoot)];
550
+ const profile = validateProfile(input.profile);
551
+ return {
552
+ task,
553
+ roots,
554
+ focus_paths: [...input.focus_paths],
555
+ include_globs: [...input.include_globs],
556
+ exclude_globs: [...input.exclude_globs],
557
+ search_terms: [...input.search_terms],
558
+ allow_secrets: resolveAllowSecrets(input.allow_secrets),
559
+ budget: input.budget ?? {},
560
+ delegate: input.delegate ?? { enabled: false },
561
+ ...(options.run_id == null ? {} : { run_id: options.run_id }),
562
+ ...(profile == null ? {} : { profile }),
563
+ };
564
+ }
565
+ // cb_budget_adapter is intentionally backend-agnostic: this only reads numeric
566
+ // context_builder.budget_defaults and NEVER executes the adapter, so app_server
567
+ // adapters are permitted here even though they are rejected for execution.
568
+ function resolveAdapterBudgetDefaults(registry, name) {
569
+ const trimmed = name?.trim();
570
+ if (trimmed == null || trimmed === "") {
571
+ return {};
572
+ }
573
+ if (registry == null) {
574
+ throw new InvalidParamsError(`cb_budget_adapter "${trimmed}" set but no adapter registry is available`);
575
+ }
576
+ const budgetDefaults = registry.resolveAdapter(trimmed).context_builder?.budget_defaults ?? {};
577
+ return {
578
+ ...(budgetDefaults.max_estimated_tokens == null
579
+ ? {}
580
+ : { max_estimated_tokens: budgetDefaults.max_estimated_tokens }),
581
+ ...(budgetDefaults.max_files == null
582
+ ? {}
583
+ : { max_files: budgetDefaults.max_files }),
584
+ ...(budgetDefaults.max_scan_files == null
585
+ ? {}
586
+ : { max_scan_files: budgetDefaults.max_scan_files }),
587
+ ...(budgetDefaults.max_bytes_per_file == null
588
+ ? {}
589
+ : { max_bytes_per_file: budgetDefaults.max_bytes_per_file }),
590
+ ...(budgetDefaults.max_total_bytes == null
591
+ ? {}
592
+ : { max_total_bytes: budgetDefaults.max_total_bytes }),
593
+ ...(budgetDefaults.max_search_results == null
594
+ ? {}
595
+ : { max_search_results: budgetDefaults.max_search_results }),
596
+ };
597
+ }
598
+ function deriveCacheCoordinates(mappedInput, workspaceSig, runsDir, versions) {
599
+ const inputsHash = computeInputsHash(mappedInput);
600
+ const cacheKey = computeCacheKey({
601
+ inputsHash,
602
+ workspaceSig,
603
+ rendererVersion: versions.rendererVersion,
604
+ cbSchemaVersion: versions.cbSchemaVersion,
605
+ discoveryAlgorithmVersion: versions.discoveryAlgorithmVersion,
606
+ delegatePromptVersion: versions.delegatePromptVersion,
607
+ });
608
+ const wfctxId = deriveWfctxId(cacheKey);
609
+ return {
610
+ workspaceSig,
611
+ cacheKey,
612
+ wfctxId,
613
+ keyPrefix: cacheKey.slice(0, 16),
614
+ targetStorage: resolveContextBuilderRunPaths(runsDir, wfctxId),
615
+ };
616
+ }
617
+ async function synthesizePreflightResultFromCommittedRun(input) {
618
+ try {
619
+ const manifest = await readManifest(input.storage.manifestJson);
620
+ // A committed fallback bundle is degraded (delegate failure_policy:"fallback")
621
+ // and must NEVER be served, especially to a fail-closed failure_policy:"fail"
622
+ // request (failure_policy is intentionally not in the cache key). A poisoned
623
+ // wfctx entry can exist from a mixed-version/older writer, an external/manual
624
+ // artifact, or a future code path. Treat it as a cache MISS (return undefined,
625
+ // the same value the ENOENT/not-usable case returns) so runOrReuse falls
626
+ // through and re-runs the builder; a real "fail" policy then fails closed.
627
+ if (manifest.delegate?.fallback_used === true) {
628
+ return undefined;
629
+ }
630
+ const receipt = createReceiptFromManifest(manifest, input.storage);
631
+ const resultBeforeMaterialization = buildPreflightResult({
632
+ receipt,
633
+ sourceRunId: input.storage.runId,
634
+ sourceArtifactDir: input.storage.runDir,
635
+ cache: {
636
+ hit: true,
637
+ write: false,
638
+ target_id: input.storage.runId,
639
+ key_prefix: input.keyPrefix,
640
+ },
641
+ copiedPaths: [],
642
+ schemaVersion: input.schemaVersion,
643
+ observability: preflightObservabilityFromManifest(manifest, input.budgetCaps),
644
+ coverage: coverageFromManifest(manifest),
645
+ });
646
+ await input.lifecycle?.transition("cache_lookup", {
647
+ artifactRunId: resultBeforeMaterialization.source_run_id,
648
+ cache: { lookup: "hit", write: "skipped" },
649
+ ...workflowResultLifecyclePatch(resultBeforeMaterialization, input.lifecycle, true),
650
+ });
651
+ await input.lifecycle?.transition("materializing");
652
+ const copiedPaths = await copyBundleArtifactsIntoRun(manifest.artifacts, input.runDir, {
653
+ includeSelectedContext: input.includeSelectedContext,
654
+ ...(input.lifecycle == null
655
+ ? {}
656
+ : {
657
+ beforeManifestCommit: async () => {
658
+ await input.lifecycle?.transition("committing");
659
+ },
660
+ }),
661
+ });
662
+ return buildPreflightResult({
663
+ receipt,
664
+ sourceRunId: input.storage.runId,
665
+ sourceArtifactDir: input.storage.runDir,
666
+ cache: {
667
+ hit: true,
668
+ write: false,
669
+ target_id: input.storage.runId,
670
+ key_prefix: input.keyPrefix,
671
+ },
672
+ copiedPaths,
673
+ schemaVersion: input.schemaVersion,
674
+ observability: preflightObservabilityFromManifest(manifest, input.budgetCaps),
675
+ coverage: coverageFromManifest(manifest),
676
+ });
677
+ }
678
+ catch (error) {
679
+ if (isNodeError(error)
680
+ && error.code === "ENOENT"
681
+ && input.lifecycle?.snapshot?.cache.lookup !== "hit") {
682
+ return undefined;
683
+ }
684
+ throw error;
685
+ }
686
+ }
687
+ function createReceiptFromManifest(manifest, storage) {
688
+ return createContextBuilderReceipt({
689
+ run_id: storage.runId,
690
+ status: manifest.status,
691
+ artifact_dir: storage.artifactDir,
692
+ artifacts: { ...manifest.artifacts },
693
+ metrics: manifest.metrics,
694
+ warnings: [...manifest.warnings],
695
+ omissions: [...manifest.omissions],
696
+ ...(manifest.delegate == null ? {} : { delegate: manifest.delegate }),
697
+ });
698
+ }
699
+ function buildPreflightResult(input) {
700
+ // The request-derived effective schema (input.schemaVersion) must match the
701
+ // receipt's own schema. A divergence means a handler-contract violation (e.g.
702
+ // a delegate-enabled request whose handler returned a no-delegate v1 receipt),
703
+ // which would otherwise emit schema_version:2 with no delegate metadata. Fail
704
+ // loudly rather than emit a contradictory result.
705
+ if (input.schemaVersion !== input.receipt.schema_version) {
706
+ throw new ExecutionError("context_builder schema mismatch: request-derived schema_version " +
707
+ `${input.schemaVersion} does not match receipt schema_version ` +
708
+ `${input.receipt.schema_version}`);
709
+ }
710
+ // A delegate schema_version that carries no delegate metadata is contradictory
711
+ // (a delegated build that lost its delegate provenance). Fail loudly rather
712
+ // than silently emitting delegate: undefined, which would erase fallback_used.
713
+ if (input.receipt.schema_version === CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION
714
+ && input.receipt.delegate == null) {
715
+ throw new ExecutionError("context_builder receipt has delegate schema_version but no delegate metadata");
716
+ }
717
+ const delegate = input.receipt.schema_version === CONTEXT_BUILDER_DELEGATE_SCHEMA_VERSION
718
+ && input.receipt.delegate != null
719
+ ? {
720
+ enabled: true,
721
+ status: input.receipt.delegate.status,
722
+ fallback_used: input.receipt.delegate.fallback_used,
723
+ }
724
+ : undefined;
725
+ return {
726
+ receipt: input.receipt,
727
+ source_run_id: input.sourceRunId,
728
+ source_artifact_dir: input.sourceArtifactDir,
729
+ cache: input.cache,
730
+ schema_version: input.schemaVersion,
731
+ status: input.receipt.status,
732
+ copied_paths: input.copiedPaths,
733
+ coverage: input.coverage,
734
+ metrics: input.receipt.metrics,
735
+ warning_count: input.receipt.warnings.length,
736
+ omission_count: input.receipt.omissions.length,
737
+ ...(delegate == null ? {} : { delegate }),
738
+ ...(input.observability == null
739
+ ? {}
740
+ : { observability: input.observability }),
741
+ };
742
+ }
743
+ function preflightObservabilityFromManifest(manifest, budgetCaps) {
744
+ const raw = manifest["observability"];
745
+ const record = raw !== null && typeof raw === "object"
746
+ ? raw
747
+ : {};
748
+ return {
749
+ curator_ms: nullableNonNegativeNumber(record["curator_ms"]),
750
+ finalizer_ms: nullableNonNegativeNumber(record["finalizer_ms"]),
751
+ candidate_pool_size: nonNegativeInteger(record["candidate_pool_size"]),
752
+ delegate_packet_size: nonNegativeInteger(record["delegate_packet_size"]),
753
+ budget_caps: budgetCapsFromManifest(manifest["budget"], budgetCaps),
754
+ };
755
+ }
756
+ function coverageFromManifest(manifest) {
757
+ const value = manifest["coverage"];
758
+ if (value === null || typeof value !== "object") {
759
+ return notEvaluatedCoverageReport();
760
+ }
761
+ const coverage = value;
762
+ if (!isCoveragePolicyId(coverage["policy_id"])
763
+ || !isCoverageStatus(coverage["status"])
764
+ || !isEvidenceClassArray(coverage["required_when_available"])
765
+ || !isEvidenceClassArray(coverage["available"])
766
+ || !isEvidenceClassArray(coverage["selected"])
767
+ || !isEvidenceClassArray(coverage["missing_required"])
768
+ || !isEvidenceClassArray(coverage["advisory_missing"])
769
+ || !isEvidenceClassArray(coverage["unclassifiable"])) {
770
+ return notEvaluatedCoverageReport();
771
+ }
772
+ if (!isSemanticallyConsistentCoverage(coverage)) {
773
+ return notEvaluatedCoverageReport();
774
+ }
775
+ return {
776
+ policy_id: coverage["policy_id"],
777
+ status: coverage["status"],
778
+ required_when_available: [...coverage["required_when_available"]],
779
+ available: [...coverage["available"]],
780
+ selected: [...coverage["selected"]],
781
+ missing_required: [...coverage["missing_required"]],
782
+ advisory_missing: [...coverage["advisory_missing"]],
783
+ unclassifiable: [...coverage["unclassifiable"]],
784
+ };
785
+ }
786
+ function isSemanticallyConsistentCoverage(coverage) {
787
+ const policyId = coverage["policy_id"];
788
+ const status = coverage["status"];
789
+ const available = new Set(coverage["available"]);
790
+ const selected = coverage["selected"];
791
+ const missing = coverage["missing_required"];
792
+ if (policyId === null) {
793
+ return (status === "not_evaluated" &&
794
+ available.size === 0 &&
795
+ selected.length === 0 &&
796
+ missing.length === 0);
797
+ }
798
+ if (status === "not_evaluated") {
799
+ return false;
800
+ }
801
+ if (selected.some((evidenceClass) => !available.has(evidenceClass))) {
802
+ return false;
803
+ }
804
+ if (status === "satisfied") {
805
+ return missing.length === 0 && available.has("review_target");
806
+ }
807
+ return missing.length > 0;
808
+ }
809
+ function isCoveragePolicyId(value) {
810
+ return value === null || value === "review_deep_v1";
811
+ }
812
+ function isCoverageStatus(value) {
813
+ return value === "satisfied" || value === "degraded" || value === "not_evaluated";
814
+ }
815
+ function isEvidenceClassArray(value) {
816
+ return Array.isArray(value) && value.every(isEvidenceClass);
817
+ }
818
+ function isEvidenceClass(value) {
819
+ return value === "review_target"
820
+ || value === "public_entrypoint"
821
+ || value === "reverse_consumer"
822
+ || value === "configuration"
823
+ || value === "dependency"
824
+ || value === "regression_test";
825
+ }
826
+ function budgetCapsFromManifest(value, fallback) {
827
+ if (value === null || typeof value !== "object") {
828
+ return { ...fallback };
829
+ }
830
+ const record = value;
831
+ return {
832
+ ...optionalPositiveIntegerCap(record, "max_estimated_tokens"),
833
+ ...optionalPositiveIntegerCap(record, "max_files"),
834
+ ...optionalPositiveIntegerCap(record, "max_scan_files"),
835
+ ...optionalPositiveIntegerCap(record, "max_bytes_per_file"),
836
+ ...optionalPositiveIntegerCap(record, "max_total_bytes"),
837
+ ...optionalPositiveIntegerCap(record, "max_search_results"),
838
+ };
839
+ }
840
+ function optionalPositiveIntegerCap(record, key) {
841
+ const value = record[key];
842
+ return typeof value === "number" && Number.isInteger(value) && value > 0
843
+ ? { [key]: value }
844
+ : {};
845
+ }
846
+ function nullableNonNegativeNumber(value) {
847
+ return typeof value === "number" && Number.isFinite(value) && value >= 0
848
+ ? value
849
+ : null;
850
+ }
851
+ function nonNegativeInteger(value) {
852
+ return typeof value === "number" && Number.isInteger(value) && value >= 0
853
+ ? value
854
+ : 0;
855
+ }
856
+ async function readManifest(manifestPath) {
857
+ return JSON.parse(await readFile(manifestPath, "utf8"));
858
+ }
859
+ async function resolveSelectedContextPaths(manifest, roots) {
860
+ const selected = Array.isArray(manifest["selected_context"])
861
+ ? manifest["selected_context"]
862
+ : [];
863
+ const absolutePaths = [];
864
+ for (const entry of selected) {
865
+ if (entry === null || typeof entry !== "object") {
866
+ throw new ExecutionError("context_builder manifest selected_context entry is invalid");
867
+ }
868
+ const rootIndex = entry.root_index;
869
+ const selectedPath = entry.path;
870
+ if (typeof rootIndex !== "number"
871
+ || !Number.isInteger(rootIndex)
872
+ || rootIndex < 0
873
+ || rootIndex >= roots.length
874
+ || typeof selectedPath !== "string"
875
+ || selectedPath.trim() === "") {
876
+ throw new ExecutionError("context_builder manifest selected_context entry is invalid");
877
+ }
878
+ const logicalPath = resolve(roots[rootIndex], selectedPath);
879
+ const realPath = await normalizeExistingPath(logicalPath);
880
+ absolutePaths.push({
881
+ logicalPath,
882
+ realPath,
883
+ traversedSymlink: realPath !== logicalPath,
884
+ });
885
+ }
886
+ return absolutePaths;
887
+ }
888
+ async function evaluatePostCbPromotionGate(input) {
889
+ try {
890
+ const coveredPaths = await input.signatureCoveredPaths(input.roots);
891
+ const selectedFilesCovered =
892
+ // Empty selections carry no realized-file evidence, so they are not promotable.
893
+ input.selectedPaths.length > 0 &&
894
+ input.selectedPaths.every((path) => !path.traversedSymlink && coveredPaths.has(path.realPath));
895
+ const postSig = await input.workspaceSignature(input.roots);
896
+ return { selectedFilesCovered, postSig };
897
+ }
898
+ catch {
899
+ return undefined;
900
+ }
901
+ }
902
+ async function normalizeCacheRoots(roots) {
903
+ const normalized = [];
904
+ for (const root of roots.length === 0 ? [process.cwd()] : roots) {
905
+ const absolute = resolve(root);
906
+ normalized.push(await normalizeExistingPath(absolute));
907
+ }
908
+ return Array.from(new Set(normalized)).sort();
909
+ }
910
+ async function normalizeExistingPath(path) {
911
+ const absolute = resolve(path);
912
+ try {
913
+ return await realpath(absolute);
914
+ }
915
+ catch {
916
+ return absolute;
917
+ }
918
+ }
919
+ function isPromoteClaimConflict(error) {
920
+ return (error instanceof InvalidParamsError
921
+ && error.message.startsWith("context_builder run_id already exists:")) || (error instanceof ExecutionError
922
+ && error.message.startsWith("context_builder run_id conflicts with an incomplete or active run:"));
923
+ }
924
+ function throwIfAborted(signal) {
925
+ if (signal?.aborted === true) {
926
+ throw new CancellationError();
927
+ }
928
+ }
929
+ function isNodeError(error) {
930
+ return error instanceof Error && "code" in error;
931
+ }
932
+ function generateWorkflowPreflightRunId() {
933
+ return `wfpre-${randomUUID()}`;
934
+ }
935
+ async function resolveFallbackRoot(resolveWorkspaceRoot) {
936
+ const workspaceRoot = resolveWorkspaceRoot?.() ?? resolveWorkflowWorkspaceRoot();
937
+ const resolvedWorkspaceRoot = await realpath(workspaceRoot).catch(() => resolve(workspaceRoot));
938
+ const sourceAllowedRoots = getContextBuilderSourceAllowedRoots();
939
+ if (!isPathWithinAllowedRoots(resolvedWorkspaceRoot, sourceAllowedRoots)) {
940
+ throw new InvalidParamsError(`context_builder fallback root is outside source allowed roots: ${resolvedWorkspaceRoot}. ` +
941
+ `Allowed: ${sourceAllowedRoots.join(", ")}`);
942
+ }
943
+ return resolvedWorkspaceRoot;
944
+ }
945
+ function assertExplicitRootsWithinAllowed(roots) {
946
+ if (roots.length === 0)
947
+ return;
948
+ const allowed = getContextBuilderSourceAllowedRoots();
949
+ for (const root of roots) {
950
+ const resolved = realpathSyncBestEffort(resolve(process.cwd(), root));
951
+ if (!isPathWithinAllowedRoots(resolved, allowed)) {
952
+ throw new InvalidParamsError(`context_builder root is outside allowed roots: ${root}`);
953
+ }
954
+ let stat;
955
+ try {
956
+ stat = statSync(resolved);
957
+ }
958
+ catch {
959
+ throw new InvalidParamsError(`context_builder root does not exist: ${root}`);
960
+ }
961
+ if (!stat.isDirectory()) {
962
+ throw new InvalidParamsError(`context_builder root is not a directory: ${root}`);
963
+ }
964
+ }
965
+ }
966
+ function getContextBuilderSourceAllowedRoots() {
967
+ const raw = process.env["CLINKX_ALLOWED_ROOTS"];
968
+ if (raw == null || raw.trim() === "") {
969
+ return getCurrentAllowedRoots();
970
+ }
971
+ const cwd = resolve(process.cwd());
972
+ const roots = [];
973
+ const seen = new Set();
974
+ for (const entry of raw
975
+ .split(",")
976
+ .map((root) => root.trim())
977
+ .filter((root) => root.length > 0)) {
978
+ if (isArtifactOnlyAllowedRootEntry(entry)) {
979
+ continue;
980
+ }
981
+ const resolved = resolve(cwd, entry);
982
+ const canonical = realpathSyncBestEffort(resolved);
983
+ if (!seen.has(canonical)) {
984
+ seen.add(canonical);
985
+ roots.push(canonical);
986
+ }
987
+ }
988
+ return roots;
989
+ }
990
+ function realpathSyncBestEffort(path) {
991
+ try {
992
+ return realpathSync(path);
993
+ }
994
+ catch {
995
+ return path;
996
+ }
997
+ }
998
+ function validateProfile(profile) {
999
+ if (profile == null || profile.trim() === "") {
1000
+ return undefined;
1001
+ }
1002
+ if (isContextBuilderProfile(profile)) {
1003
+ return profile;
1004
+ }
1005
+ throw new InvalidParamsError(`Unknown context_builder profile "${profile}". ` +
1006
+ `Allowed: ${CONTEXT_BUILDER_INTENT_PROFILES.join(", ")}`);
1007
+ }
1008
+ function isContextBuilderProfile(profile) {
1009
+ return CONTEXT_BUILDER_INTENT_PROFILES.includes(profile);
1010
+ }
1011
+ async function resolveArtifactPath(artifacts, key, label) {
1012
+ const artifactPath = artifacts[key];
1013
+ if (typeof artifactPath !== "string" || artifactPath.trim() === "") {
1014
+ throw new ExecutionError(`context_builder receipt is missing ${label}`);
1015
+ }
1016
+ return realpath(artifactPath);
1017
+ }
1018
+ async function copyArtifactIntoContextDir(source, contextDir, fileName) {
1019
+ const target = resolve(contextDir, fileName);
1020
+ assertContainedPath(contextDir, target, `context_builder copy target escaped: ${target}`);
1021
+ const tempTarget = resolve(contextDir, `.${fileName}.${process.pid}.${randomUUID()}.tmp`);
1022
+ assertContainedPath(contextDir, tempTarget, `context_builder temp copy target escaped: ${tempTarget}`);
1023
+ try {
1024
+ await copyFile(source, tempTarget);
1025
+ await rename(tempTarget, target);
1026
+ }
1027
+ catch (error) {
1028
+ await rm(tempTarget, { force: true }).catch(() => { });
1029
+ throw error;
1030
+ }
1031
+ const realTarget = await realpath(target);
1032
+ assertContainedPath(contextDir, realTarget, `context_builder copied artifact escaped context directory: ${realTarget}`);
1033
+ return realTarget;
1034
+ }
1035
+ function assertContainedPath(parent, child, message) {
1036
+ if (!isAbsolute(child)) {
1037
+ throw new ExecutionError(message);
1038
+ }
1039
+ const rel = relative(parent, child);
1040
+ if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
1041
+ throw new ExecutionError(message);
1042
+ }
1043
+ }
1044
+ function parseReceiptResponse(response) {
1045
+ const receiptText = response.content[0]?.text;
1046
+ if (typeof receiptText !== "string") {
1047
+ throw new ExecutionError("context_builder returned no receipt text");
1048
+ }
1049
+ return JSON.parse(receiptText);
1050
+ }
1051
+ //# sourceMappingURL=workflow-runner.js.map