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,186 @@
1
+ import { isExcludedPlanPath } from "./context-policy.js";
2
+ import { PLAN_SNAPSHOT_BEGIN, renderPlanSnapshotBlock } from "./expander.js";
3
+ import { PlanReviewStageError } from "./stage-error.js";
4
+ const PROVIDER_STAGE_IDS = ["reviewers", "cross_review", "chairman"];
5
+ /**
6
+ * Count snapshot-block OPENINGS: the begin marker alone on its own line.
7
+ *
8
+ * Line-anchoring is load-bearing, not tidiness. All three shipped actor
9
+ * templates NAME this marker in their prose, inline and inside backticks, to
10
+ * tell the model where the plan is (`templates/plan-review/reviewer.txt:4`,
11
+ * `chairman.txt:17`, `cross-review.txt:10`). A raw substring count therefore
12
+ * scores an HONEST prompt at 2 — prose mention plus the real block — so a bare
13
+ * `=== 1` rule rejects every legitimate resumed retry. Only
14
+ * `renderPlanSnapshotBlock` puts the marker alone on a line, so line-anchoring
15
+ * counts real blocks and ignores prose that merely quotes the delimiter.
16
+ *
17
+ * `\r?` tolerates CRLF-normalized state. It is not an anti-evasion measure:
18
+ * this whole check is fail-closed integrity on HONEST state, not a boundary
19
+ * against someone who already owns the state directory (see below).
20
+ */
21
+ const PLAN_SNAPSHOT_BEGIN_LINE_RE = new RegExp(`^${PLAN_SNAPSHOT_BEGIN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\r?$`, "gm");
22
+ function countSnapshotBlockOpenings(haystack) {
23
+ return [...haystack.matchAll(PLAN_SNAPSHOT_BEGIN_LINE_RE)].length;
24
+ }
25
+ /**
26
+ * Bind the verified persisted bindings to the persisted normalized definition.
27
+ * Exact coverage is required: a missing, extra, renamed, or re-providered call
28
+ * is a corrupt execution contract and must fail pre-backend (D3 — no fallback,
29
+ * no seat substitution).
30
+ */
31
+ export function validatePlanReviewCallBindings(definition, bindings) {
32
+ const byCall = new Map();
33
+ for (const entry of bindings) {
34
+ const key = `${entry.stage_id}.${entry.call_id}`;
35
+ if (byCall.has(key)) {
36
+ throw new PlanReviewStageError("execution_contract", `Persisted call bindings contain duplicate call ${key}`);
37
+ }
38
+ byCall.set(key, entry);
39
+ }
40
+ const expected = new Set();
41
+ for (const stageId of PROVIDER_STAGE_IDS) {
42
+ const stage = definition.stages.find((candidate) => candidate.id === stageId);
43
+ if (stage === undefined || stage.calls.length === 0) {
44
+ throw new PlanReviewStageError("execution_contract", `Plan-review definition has no provider calls in ${stageId}`);
45
+ }
46
+ for (const call of stage.calls) {
47
+ const key = `${stageId}.${call.id}`;
48
+ expected.add(key);
49
+ const entry = byCall.get(key);
50
+ if (entry === undefined) {
51
+ throw new PlanReviewStageError("execution_contract", `Persisted call bindings are missing call ${key}`);
52
+ }
53
+ if (entry.cli_name !== call.cli_name) {
54
+ throw new PlanReviewStageError("execution_contract", `Persisted call binding provider mismatch for ${key}: ${entry.cli_name} != ${call.cli_name}`);
55
+ }
56
+ }
57
+ }
58
+ for (const key of byCall.keys()) {
59
+ if (!expected.has(key)) {
60
+ throw new PlanReviewStageError("execution_contract", `Persisted call bindings reference unknown call ${key}`);
61
+ }
62
+ }
63
+ return byCall;
64
+ }
65
+ /**
66
+ * Validate persisted retry identity AND D9 before any provider/backend is created.
67
+ *
68
+ * ## Why the prompt is checked here and not left to the definition
69
+ *
70
+ * `WorkflowEngine.buildCallInput` replays a persisted prepared input verbatim —
71
+ * `structuredClone(resumedInput)` with only `cli_name` re-pinned. The expanded
72
+ * DEFINITION is not what reaches an actor on a resumed retry, so asserting D9
73
+ * against the definition proves nothing about that dispatch. The plan text now
74
+ * lives in the prompt bytes, which means the prompt is the D9 surface and this
75
+ * is the seam that must hold it: it already runs on the resume path, before any
76
+ * backend is created.
77
+ *
78
+ * A LEGITIMATE persisted input always passes, because `buildCallInput` appended
79
+ * the bound snapshot block at original dispatch and persisted that exact prompt.
80
+ * So this rejects only state that was tampered with, hand-written, or carried
81
+ * over from a different plan revision.
82
+ *
83
+ * ## What this check ESTABLISHES — and what it does not
84
+ *
85
+ * It establishes exactly two things: the verified snapshot block is the prompt's
86
+ * SUFFIX, and no other block opens before it. POSITION is what makes this exact.
87
+ * Mere presence is satisfied by a prompt carrying the verified block beside a
88
+ * second, different plan revision — the resumed dispatch replays the whole
89
+ * persisted prompt, so an actor would see both and could not know which binds.
90
+ * The suffix rule rejects a revision appended AFTER the verified block; the
91
+ * prefix scan rejects one spliced in BEFORE it.
92
+ *
93
+ * Both rules are stated against what `buildCallInput` actually composes —
94
+ * `renderedPrompt + renderPlanSnapshotBlock(text)` — so every honest persisted
95
+ * input passes BY CONSTRUCTION rather than by luck, including one rendered from
96
+ * the shipped templates, whose prose quotes the delimiter inline.
97
+ *
98
+ * It does NOT establish prompt EXCLUSIVITY, and must not be read as doing so.
99
+ * Raw plan text appended WITHOUT delimiters is not detectable here: there is no
100
+ * way to distinguish it from legitimate instruction prose, and pretending
101
+ * otherwise would republish precisely the kind of unbacked claim this file's
102
+ * surrounding work exists to delete. What bounds that residue is the trust
103
+ * model, not this function: plan review is TRUSTED-INPUT-ONLY, and an actor who
104
+ * can rewrite `state.json` to append a plan can equally rewrite it
105
+ * self-consistently. This is a fail-closed integrity check on honest state, not
106
+ * a boundary against an adversary who already owns the state directory.
107
+ *
108
+ * ## What is NOT checked, and why
109
+ *
110
+ * NOT `absolute_file_paths === []`. That is true of the expanded call
111
+ * DEFINITION, and there it is load-bearing. It is NOT true of a dispatched
112
+ * input: the engine composes `absolute_file_paths` from anonymized peer
113
+ * artifacts (cross-review, chairman) plus `absolute_file_paths_from:
114
+ * [context_files, context_bundle_files]` — the caller's repo evidence
115
+ * (`workflows/plan-review-receipts.yaml:124,147,196`). Requiring an empty list
116
+ * would reject every legitimate cross-review and chairman resume. The honest
117
+ * file-side invariant is the one the policy already defines: no attached path
118
+ * may be the original plan or any plan-workspace `PLAN.md`.
119
+ */
120
+ export function validatePlanReviewPreparedInputPolicy(preparedInputs, bindingsByCall, input = {}) {
121
+ for (const [callKey, prepared] of preparedInputs) {
122
+ // Unbound calls are not actors. The only unbound call in a plan-review
123
+ // definition is `ranking_analysis`, the in-process deterministic reducer —
124
+ // the exact set the expander declines to inline a snapshot into. D9 governs
125
+ // what an ACTOR receives; nothing is spawned here.
126
+ const binding = bindingsByCall.get(callKey);
127
+ if (binding === undefined) {
128
+ continue;
129
+ }
130
+ if (prepared["cli_name"] !== binding.cli_name) {
131
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input provider mismatch for ${callKey}`);
132
+ }
133
+ // Fail closed. A caller that cannot supply the verified snapshot cannot
134
+ // establish D9 for this dispatch, and dispatching anyway would republish a
135
+ // claim nothing backs.
136
+ if (input.snapshotText === undefined || input.contextPolicy === undefined) {
137
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} cannot be checked against the ` +
138
+ "verified plan snapshot and context policy (D9): both are required " +
139
+ "whenever a bound call replays a persisted prompt");
140
+ }
141
+ const prompt = prepared["prompt"];
142
+ const verifiedBlock = renderPlanSnapshotBlock(input.snapshotText);
143
+ // POSITIONAL, not merely present. `buildCallInput` composes an actor prompt
144
+ // as exactly `renderedPrompt + renderPlanSnapshotBlock(text)` and persists
145
+ // that string (`engine.ts:1906-1908`), so the verified block is the prompt's
146
+ // SUFFIX by construction — every honest persisted input satisfies this.
147
+ // Requiring the suffix (rather than `.includes`) is what rejects a second
148
+ // revision appended AFTER the verified one.
149
+ if (typeof prompt !== "string" || !prompt.endsWith(verifiedBlock)) {
150
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} does not end with the verified plan ` +
151
+ "snapshot block (D9). A resumed retry dispatches its persisted prompt verbatim, " +
152
+ "so a prompt that does not close with the bound snapshot would review a plan " +
153
+ "this run never verified, or would carry text appended after it.", "schema_mismatch");
154
+ }
155
+ // The suffix check alone still admits a SECOND, different revision spliced
156
+ // in BEFORE the verified block: the actor would receive two candidate plans
157
+ // and no way to tell which binds. So no block may open anywhere but the
158
+ // suffix. Scanning only the prefix is deliberate — the verified block's own
159
+ // body is digest-verified plan text, and a plan that legitimately quotes the
160
+ // delimiter on its own line must not brick an honest run.
161
+ const prefix = prompt.slice(0, prompt.length - verifiedBlock.length);
162
+ const strayBlocks = countSnapshotBlockOpenings(prefix);
163
+ if (strayBlocks !== 0) {
164
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} opens ${String(strayBlocks)} plan ` +
165
+ "snapshot block(s) before the verified one; exactly one block, at the end, " +
166
+ "is permitted (D9). A prompt with a second block would dispatch a plan " +
167
+ "revision beside the verified one.", "schema_mismatch");
168
+ }
169
+ const attached = prepared["absolute_file_paths"];
170
+ if (attached !== undefined) {
171
+ if (!Array.isArray(attached)) {
172
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} has a non-array absolute_file_paths`, "schema_mismatch");
173
+ }
174
+ for (const path of attached) {
175
+ if (typeof path !== "string") {
176
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} has a non-string absolute_file_paths entry`, "schema_mismatch");
177
+ }
178
+ if (isExcludedPlanPath(input.contextPolicy, path)) {
179
+ throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} attaches force-excluded plan path ${path} ` +
180
+ "(D9/A-7): the verified snapshot is the only plan text an actor may receive.", "schema_mismatch");
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ //# sourceMappingURL=runtime-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-policy.js","sourceRoot":"","sources":["../../src/plan-review/runtime-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * A-6 — immutable plan snapshot discipline.
3
+ *
4
+ * The whole point is that `plan_file` is read EXACTLY ONCE, through one
5
+ * no-follow handle, and never again: every actor (and every resume) is served
6
+ * the runtime-owned canonical copy. That closes the path/digest TOCTOU — a
7
+ * swap of `plan_file` after admission cannot change what the reviewers saw,
8
+ * because nothing re-reads it.
9
+ */
10
+ /** Run-relative location of the runtime-owned canonical plan snapshot. */
11
+ export declare const PLAN_SNAPSHOT_RELPATH: string;
12
+ export declare const MAX_PLAN_SNAPSHOT_BYTES = 524288;
13
+ /** Run-relative location of the persisted normalized execution contract. */
14
+ export declare const EXECUTION_CONTRACT_RELPATH: string;
15
+ /** Hard cap for both initial serialization and resume reads. */
16
+ export declare const MAX_EXECUTION_CONTRACT_BYTES = 262144;
17
+ export interface ReadCanonicalPlanSnapshotInput {
18
+ readonly planFile: string;
19
+ readonly allowedRoots: readonly string[];
20
+ /** The caller's claimed checkpoint-text-v1 digest, re-verified here. */
21
+ readonly claimedDigest: string;
22
+ }
23
+ export interface MaterializePlanSnapshotInput extends ReadCanonicalPlanSnapshotInput {
24
+ readonly runDir: string;
25
+ }
26
+ export interface MaterializedPlanSnapshot {
27
+ readonly relPath: string;
28
+ readonly absolutePath: string;
29
+ /** SHA-256 of the snapshot file bytes (corruption check). */
30
+ readonly sha256: string;
31
+ /** checkpoint-text-v1 digest of the canonical bytes (identity). */
32
+ readonly planDigest: string;
33
+ readonly bytes: number;
34
+ /** The canonical snapshot TEXT — what the expander inlines (A-6/D9). */
35
+ readonly text: string;
36
+ }
37
+ /** The verified canonical plan, held in memory and not yet persisted. */
38
+ export interface CanonicalPlanSnapshot {
39
+ readonly canonicalBytes: Buffer;
40
+ readonly planDigest: string;
41
+ readonly text: string;
42
+ }
43
+ /**
44
+ * Read `plan_file` EXACTLY ONCE (contained, no-follow, regular-file only),
45
+ * canonicalize it, and verify the caller's claimed digest — without writing
46
+ * anything.
47
+ *
48
+ * The read is split from the write because the expander now inlines the
49
+ * snapshot TEXT into every actor's prompt (D9), so the verified text must exist
50
+ * before the run's definition is composed, while the run directory that holds
51
+ * the persisted copy cannot exist until the state store creates it. Splitting
52
+ * keeps `plan_file` read once and keeps the digest verified BEFORE the text is
53
+ * used for anything.
54
+ *
55
+ * Failure classes map to the plan's post-state pre-seat stages:
56
+ * - containment / symlink / non-regular / unreadable / invalid text → `snapshot`
57
+ * - canonical digest ≠ claimed digest → `digest`
58
+ */
59
+ export declare function readCanonicalPlanSnapshot(input: ReadCanonicalPlanSnapshotInput): Promise<CanonicalPlanSnapshot>;
60
+ /** Copy already-verified canonical bytes into the runtime-owned run directory. */
61
+ export declare function persistCanonicalPlanSnapshot(runDir: string, canonical: CanonicalPlanSnapshot): Promise<MaterializedPlanSnapshot>;
62
+ /** Read + verify + persist in one step. The composition callers used before. */
63
+ export declare function materializePlanSnapshot(input: MaterializePlanSnapshotInput): Promise<MaterializedPlanSnapshot>;
64
+ /**
65
+ * Re-verify the persisted snapshot from run-owned storage alone. Used on resume:
66
+ * it re-reads the SNAPSHOT (never `plan_file`) through the contained no-follow
67
+ * reader and recomputes both the file hash and the checkpoint digest.
68
+ *
69
+ * Returns the verified snapshot rather than discarding the bytes it already
70
+ * read. Resume needs the canonical TEXT — it is the only thing a persisted
71
+ * prepared input's prompt can be checked against (D9), and the check must run
72
+ * before any provider exists. Returning it here keeps the snapshot read ONCE:
73
+ * re-reading it at the validation seam would reopen a D9-class TOCTOU between
74
+ * verification and use.
75
+ */
76
+ export declare function verifyPersistedPlanSnapshot(runDir: string, relPath: string, expectedSha256: string, expectedPlanDigest: string): Promise<CanonicalPlanSnapshot>;
77
+ /** Persist the normalized execution contract into runtime-owned storage. */
78
+ export declare function writeExecutionContractSnapshot(runDir: string, contract: unknown): Promise<{
79
+ relPath: string;
80
+ sha256: string;
81
+ }>;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * A-6 — immutable plan snapshot discipline.
3
+ *
4
+ * The whole point is that `plan_file` is read EXACTLY ONCE, through one
5
+ * no-follow handle, and never again: every actor (and every resume) is served
6
+ * the runtime-owned canonical copy. That closes the path/digest TOCTOU — a
7
+ * swap of `plan_file` after admission cannot change what the reviewers saw,
8
+ * because nothing re-reads it.
9
+ */
10
+ import { createHash } from "node:crypto";
11
+ import { mkdir, writeFile } from "node:fs/promises";
12
+ import { dirname, join } from "node:path";
13
+ import { ContainedFilePolicyError, readContainedAbsoluteFile, readContainedRelativeFile, } from "../contained-file.js";
14
+ import { CheckpointTextError, computeCheckpointDigest } from "./digest.js";
15
+ import { PlanReviewStageError } from "./stage-error.js";
16
+ /** Run-relative location of the runtime-owned canonical plan snapshot. */
17
+ export const PLAN_SNAPSHOT_RELPATH = join("plan-review", "plan.snapshot.md");
18
+ export const MAX_PLAN_SNAPSHOT_BYTES = 524_288;
19
+ /** Run-relative location of the persisted normalized execution contract. */
20
+ export const EXECUTION_CONTRACT_RELPATH = join("plan-review", "execution-contract.json");
21
+ /** Hard cap for both initial serialization and resume reads. */
22
+ export const MAX_EXECUTION_CONTRACT_BYTES = 262_144;
23
+ function sha256Hex(bytes) {
24
+ return createHash("sha256").update(bytes).digest("hex");
25
+ }
26
+ /**
27
+ * The generic containment error names allowed roots without saying WHICH roots,
28
+ * which reads as `CLINKX_ALLOWED_ROOTS` — but plan_file is bound to the
29
+ * workflows workspace root alone. Name the root that actually applies.
30
+ *
31
+ * Only allowed-roots rejections get the hint; a symlink/non-regular rejection
32
+ * from the same error class is not a roots problem. Gated on the STRUCTURED
33
+ * `reason` discriminator rather than message wording: substring-matching the
34
+ * message coupled this hint to prose that is free to be reworded, and would
35
+ * false-positive on any path whose own name happens to contain the phrase.
36
+ */
37
+ function planRootHint(err) {
38
+ if (err.reason !== "outside_allowed_roots")
39
+ return "";
40
+ return (" — plan_file must live under the workflows workspace root" +
41
+ " (CLINKX_WORKFLOWS_WORKSPACE_ROOT, defaulting to the server's process.cwd())." +
42
+ " CLINKX_ALLOWED_ROOTS is NOT consulted for plan_file and cannot widen plan-source admission.");
43
+ }
44
+ /**
45
+ * Read `plan_file` EXACTLY ONCE (contained, no-follow, regular-file only),
46
+ * canonicalize it, and verify the caller's claimed digest — without writing
47
+ * anything.
48
+ *
49
+ * The read is split from the write because the expander now inlines the
50
+ * snapshot TEXT into every actor's prompt (D9), so the verified text must exist
51
+ * before the run's definition is composed, while the run directory that holds
52
+ * the persisted copy cannot exist until the state store creates it. Splitting
53
+ * keeps `plan_file` read once and keeps the digest verified BEFORE the text is
54
+ * used for anything.
55
+ *
56
+ * Failure classes map to the plan's post-state pre-seat stages:
57
+ * - containment / symlink / non-regular / unreadable / invalid text → `snapshot`
58
+ * - canonical digest ≠ claimed digest → `digest`
59
+ */
60
+ export async function readCanonicalPlanSnapshot(input) {
61
+ let raw;
62
+ try {
63
+ const read = await readContainedAbsoluteFile(input.allowedRoots, input.planFile, { wantBytes: true, requireRegular: true, maxBytes: MAX_PLAN_SNAPSHOT_BYTES });
64
+ raw = read.bytes;
65
+ }
66
+ catch (err) {
67
+ if (err instanceof ContainedFilePolicyError) {
68
+ throw new PlanReviewStageError("snapshot", `${err.message}${planRootHint(err)}`, "invalid_output");
69
+ }
70
+ throw new PlanReviewStageError("snapshot", `plan_file could not be read: ${err instanceof Error ? err.message : String(err)}`, "no_artifact");
71
+ }
72
+ let canonical;
73
+ let planDigest;
74
+ try {
75
+ const computed = computeCheckpointDigest(raw);
76
+ canonical = computed.canonicalBytes;
77
+ planDigest = computed.digest;
78
+ }
79
+ catch (err) {
80
+ if (err instanceof CheckpointTextError) {
81
+ throw new PlanReviewStageError("snapshot", `plan_file is not valid checkpoint-text-v1 input: ${err.message}`, "invalid_output");
82
+ }
83
+ throw err;
84
+ }
85
+ // checkpoint-text-v1 appends a final LF when absent. Bound the canonical
86
+ // bytes that are persisted and resumed, not merely the raw source bytes.
87
+ if (canonical.byteLength > MAX_PLAN_SNAPSHOT_BYTES) {
88
+ throw new PlanReviewStageError("snapshot", `canonical plan snapshot exceeds ${String(MAX_PLAN_SNAPSHOT_BYTES)} bytes`, "invalid_output");
89
+ }
90
+ if (planDigest !== input.claimedDigest) {
91
+ throw new PlanReviewStageError("digest", `plan_file digest ${planDigest} does not match the bound plan_review.digest ${input.claimedDigest}`, "schema_mismatch");
92
+ }
93
+ return { canonicalBytes: canonical, planDigest, text: canonical.toString("utf-8") };
94
+ }
95
+ /** Copy already-verified canonical bytes into the runtime-owned run directory. */
96
+ export async function persistCanonicalPlanSnapshot(runDir, canonical) {
97
+ const absolutePath = join(runDir, PLAN_SNAPSHOT_RELPATH);
98
+ await mkdir(dirname(absolutePath), { recursive: true });
99
+ // `wx` — the snapshot is written exactly once per run and never overwritten.
100
+ await writeFile(absolutePath, canonical.canonicalBytes, { flag: "wx" });
101
+ return {
102
+ relPath: PLAN_SNAPSHOT_RELPATH,
103
+ absolutePath,
104
+ sha256: sha256Hex(canonical.canonicalBytes),
105
+ planDigest: canonical.planDigest,
106
+ bytes: canonical.canonicalBytes.byteLength,
107
+ text: canonical.text,
108
+ };
109
+ }
110
+ /** Read + verify + persist in one step. The composition callers used before. */
111
+ export async function materializePlanSnapshot(input) {
112
+ return await persistCanonicalPlanSnapshot(input.runDir, await readCanonicalPlanSnapshot(input));
113
+ }
114
+ /**
115
+ * Re-verify the persisted snapshot from run-owned storage alone. Used on resume:
116
+ * it re-reads the SNAPSHOT (never `plan_file`) through the contained no-follow
117
+ * reader and recomputes both the file hash and the checkpoint digest.
118
+ *
119
+ * Returns the verified snapshot rather than discarding the bytes it already
120
+ * read. Resume needs the canonical TEXT — it is the only thing a persisted
121
+ * prepared input's prompt can be checked against (D9), and the check must run
122
+ * before any provider exists. Returning it here keeps the snapshot read ONCE:
123
+ * re-reading it at the validation seam would reopen a D9-class TOCTOU between
124
+ * verification and use.
125
+ */
126
+ export async function verifyPersistedPlanSnapshot(runDir, relPath, expectedSha256, expectedPlanDigest) {
127
+ let bytes;
128
+ try {
129
+ const read = await readContainedRelativeFile(runDir, relPath, {
130
+ wantBytes: true,
131
+ requireRegular: true,
132
+ maxBytes: MAX_PLAN_SNAPSHOT_BYTES,
133
+ });
134
+ bytes = read.bytes;
135
+ }
136
+ catch (err) {
137
+ throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} is unreadable: ${err instanceof Error ? err.message : String(err)}`, err instanceof ContainedFilePolicyError ? "invalid_output" : "no_artifact");
138
+ }
139
+ if (sha256Hex(bytes) !== expectedSha256) {
140
+ throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} failed its hash check`, "schema_mismatch");
141
+ }
142
+ // Recompute the checkpoint digest from the persisted bytes rather than trust
143
+ // the recorded value: the snapshot must still BE the bound plan revision.
144
+ let canonicalBytes;
145
+ let planDigest;
146
+ try {
147
+ const computed = computeCheckpointDigest(bytes);
148
+ canonicalBytes = computed.canonicalBytes;
149
+ planDigest = computed.digest;
150
+ }
151
+ catch (err) {
152
+ throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} is not canonical checkpoint text: ${err instanceof Error ? err.message : String(err)}`, "invalid_output");
153
+ }
154
+ if (planDigest !== expectedPlanDigest) {
155
+ throw new PlanReviewStageError("digest", `Persisted plan snapshot digest ${planDigest} does not match the bound digest ${expectedPlanDigest}`, "schema_mismatch");
156
+ }
157
+ return { canonicalBytes, planDigest, text: canonicalBytes.toString("utf-8") };
158
+ }
159
+ /** Persist the normalized execution contract into runtime-owned storage. */
160
+ export async function writeExecutionContractSnapshot(runDir, contract) {
161
+ const absolutePath = join(runDir, EXECUTION_CONTRACT_RELPATH);
162
+ const bytes = Buffer.from(`${JSON.stringify(contract, null, 2)}\n`, "utf-8");
163
+ if (bytes.byteLength > MAX_EXECUTION_CONTRACT_BYTES) {
164
+ throw new PlanReviewStageError("execution_contract", `serialized execution contract exceeds ${String(MAX_EXECUTION_CONTRACT_BYTES)} bytes`, "invalid_output");
165
+ }
166
+ await mkdir(dirname(absolutePath), { recursive: true });
167
+ await writeFile(absolutePath, bytes, { flag: "wx" });
168
+ return { relPath: EXECUTION_CONTRACT_RELPATH, sha256: sha256Hex(bytes) };
169
+ }
170
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/plan-review/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { z } from "zod";
2
+ import type { PlanReviewErrorReasonSchema } from "./contract.js";
3
+ import type { CouncilPlanReviewErrorSchema } from "./publication.js";
4
+ export type PlanReviewErrorStage = z.infer<typeof CouncilPlanReviewErrorSchema>["stage"];
5
+ export type PlanReviewErrorReason = z.infer<typeof PlanReviewErrorReasonSchema>;
6
+ /**
7
+ * A post-state, pre-seat plan-review failure.
8
+ *
9
+ * `stage` — NOT `reason` — is what disambiguates which check failed, because the
10
+ * seat `error.reason` enum has no dedicated snapshot/digest member (see the
11
+ * plan's §Error surface). Carrying the stage on the throw is what lets the
12
+ * caller record `RunState.status=failed` and later surface a bounded
13
+ * `council-plan-review-error-v1` inline; it is never a result sidecar.
14
+ */
15
+ export declare class PlanReviewStageError extends Error {
16
+ readonly stage: PlanReviewErrorStage;
17
+ readonly reason: PlanReviewErrorReason;
18
+ constructor(stage: PlanReviewErrorStage, message: string, reason?: PlanReviewErrorReason);
19
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A post-state, pre-seat plan-review failure.
3
+ *
4
+ * `stage` — NOT `reason` — is what disambiguates which check failed, because the
5
+ * seat `error.reason` enum has no dedicated snapshot/digest member (see the
6
+ * plan's §Error surface). Carrying the stage on the throw is what lets the
7
+ * caller record `RunState.status=failed` and later surface a bounded
8
+ * `council-plan-review-error-v1` inline; it is never a result sidecar.
9
+ */
10
+ export class PlanReviewStageError extends Error {
11
+ stage;
12
+ reason;
13
+ constructor(stage, message, reason = "internal_error") {
14
+ super(message);
15
+ this.name = "PlanReviewStageError";
16
+ this.stage = stage;
17
+ this.reason = reason;
18
+ }
19
+ }
20
+ //# sourceMappingURL=stage-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-error.js","sourceRoot":"","sources":["../../src/plan-review/stage-error.ts"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,KAAK,CAAuB;IAC5B,MAAM,CAAwB;IAEvC,YACE,KAA2B,EAC3B,OAAe,EACf,SAAgC,gBAAgB;QAEhD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Post-processor registry for deterministic transforms applied to a validated
3
+ * call output BEFORE it is persisted as an artifact.
4
+ *
5
+ * A call opts in via `post_processor: <name>` in its workflow definition. The
6
+ * engine looks the name up here after JSON validation; if found, the returned
7
+ * value replaces `validated` before the artifact is written. Unknown names fail
8
+ * fast: the loader's static validation (`validatePostProcessors`) throws at
9
+ * workflow load time, and the engine also throws as defense-in-depth if an
10
+ * unregistered name ever reaches execution.
11
+ */
12
+ /** Inputs available to a post-processor. */
13
+ export type PostProcessorContext = {
14
+ allowlist: Set<string>;
15
+ schemaId: string;
16
+ };
17
+ /** A post-processor transforms a validated artifact value deterministically. */
18
+ export type PostProcessorFn = (validated: unknown, ctx: PostProcessorContext) => unknown;
19
+ export declare function getPostProcessor(id: string): PostProcessorFn | undefined;
20
+ export declare function registerPostProcessor(id: string, fn: PostProcessorFn): void;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Post-processor registry for deterministic transforms applied to a validated
3
+ * call output BEFORE it is persisted as an artifact.
4
+ *
5
+ * A call opts in via `post_processor: <name>` in its workflow definition. The
6
+ * engine looks the name up here after JSON validation; if found, the returned
7
+ * value replaces `validated` before the artifact is written. Unknown names fail
8
+ * fast: the loader's static validation (`validatePostProcessors`) throws at
9
+ * workflow load time, and the engine also throws as defense-in-depth if an
10
+ * unregistered name ever reaches execution.
11
+ */
12
+ import { citationCheck } from "../citation-check.js";
13
+ const registry = new Map();
14
+ registry.set("citation_check", citationCheck);
15
+ export function getPostProcessor(id) {
16
+ return registry.get(id);
17
+ }
18
+ export function registerPostProcessor(id, fn) {
19
+ registry.set(id, fn);
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/post-processors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAWrD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;AACpD,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAU,EAAE,EAAmB;IACnE,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC"}
@@ -26,6 +26,13 @@ export interface PromptBudgetInput {
26
26
  readonly reserveBytes?: number | undefined;
27
27
  readonly maxBytes?: number | undefined;
28
28
  }
29
+ /**
30
+ * Reserve margin for child-side prompt assembly overhead, applied to every
31
+ * dispatched call whose caller supplies no explicit `reserveBytes` (nothing
32
+ * currently does). Exported so a pre-dispatch guard can DERIVE the same reserve
33
+ * the engine will actually bill rather than re-literal it and drift.
34
+ */
35
+ export declare const DEFAULT_RESERVE_BYTES = 100000;
29
36
  export declare function estimatePromptBudget(input: PromptBudgetInput): PromptBudgetEstimate;
30
37
  export declare function createPathContributor(label: string, path: string, kind: "context" | "file" | "image"): PromptBudgetContributor;
31
38
  export declare function enforcePromptBudget(estimate: PromptBudgetEstimate): void;
@@ -8,7 +8,13 @@
8
8
  import { statSync } from "node:fs";
9
9
  import { getMaxPromptBytes } from "./config.js";
10
10
  import { WorkflowError } from "./errors.js";
11
- const DEFAULT_RESERVE_BYTES = 100_000;
11
+ /**
12
+ * Reserve margin for child-side prompt assembly overhead, applied to every
13
+ * dispatched call whose caller supplies no explicit `reserveBytes` (nothing
14
+ * currently does). Exported so a pre-dispatch guard can DERIVE the same reserve
15
+ * the engine will actually bill rather than re-literal it and drift.
16
+ */
17
+ export const DEFAULT_RESERVE_BYTES = 100_000;
12
18
  export function estimatePromptBudget(input) {
13
19
  const contributors = [
14
20
  {
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-budget.js","sourceRoot":"","sources":["../src/prompt-budget.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-budget.js","sourceRoot":"","sources":["../src/prompt-budget.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,11 @@
3
3
  *
4
4
  * Reducers run in place of LLM calls when a call specifies a `reducer` ID.
5
5
  */
6
+ import { planReviewRankingReducer } from "../plan-review/ranking-reducer.js";
6
7
  import { councilRankingReducer } from "../ranking-reducer.js";
7
8
  const registry = new Map();
8
9
  registry.set("council_ranking_v1", councilRankingReducer);
10
+ registry.set("plan_review_ranking_v1", planReviewRankingReducer);
9
11
  export function getReducer(id) {
10
12
  return registry.get(id);
11
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reducers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAC9C,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;AAE1D,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reducers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAC9C,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;AAC1D,QAAQ,CAAC,GAAG,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC;AAEjE,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Reader/producer floor for run.lock heartbeat staleness (10 s cadence × 6). */
2
+ export declare const RUN_LOCK_HEARTBEAT_STALE_FLOOR_MS = 60000;
@@ -0,0 +1,3 @@
1
+ /** Reader/producer floor for run.lock heartbeat staleness (10 s cadence × 6). */
2
+ export const RUN_LOCK_HEARTBEAT_STALE_FLOOR_MS = 60_000;
3
+ //# sourceMappingURL=run-lock-heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-lock-heartbeat.js","sourceRoot":"","sources":["../src/run-lock-heartbeat.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC"}