@kilnai/cli 1.0.7 → 2.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 (546) hide show
  1. package/README.md +31 -8
  2. package/dist/application/__tests__/session-report.test.d.ts +2 -0
  3. package/dist/application/__tests__/session-report.test.d.ts.map +1 -0
  4. package/dist/application/__tests__/session-report.test.js +100 -0
  5. package/dist/application/__tests__/session-report.test.js.map +1 -0
  6. package/dist/application/agent-loader.d.ts +30 -2
  7. package/dist/application/agent-loader.d.ts.map +1 -1
  8. package/dist/application/agent-loader.js +99 -3
  9. package/dist/application/agent-loader.js.map +1 -1
  10. package/dist/application/agent-loader.test.js +112 -18
  11. package/dist/application/agent-loader.test.js.map +1 -1
  12. package/dist/application/agent-skill-context.d.ts +12 -0
  13. package/dist/application/agent-skill-context.d.ts.map +1 -0
  14. package/dist/application/agent-skill-context.js +32 -0
  15. package/dist/application/agent-skill-context.js.map +1 -0
  16. package/dist/application/agent-skill-context.test.d.ts +2 -0
  17. package/dist/application/agent-skill-context.test.d.ts.map +1 -0
  18. package/dist/application/agent-skill-context.test.js +156 -0
  19. package/dist/application/agent-skill-context.test.js.map +1 -0
  20. package/dist/application/benchmark-session-executor.d.ts +14 -0
  21. package/dist/application/benchmark-session-executor.d.ts.map +1 -0
  22. package/dist/application/benchmark-session-executor.js +210 -0
  23. package/dist/application/benchmark-session-executor.js.map +1 -0
  24. package/dist/application/config-apply-tool.d.ts +30 -0
  25. package/dist/application/config-apply-tool.d.ts.map +1 -0
  26. package/dist/application/config-apply-tool.js +68 -0
  27. package/dist/application/config-apply-tool.js.map +1 -0
  28. package/dist/application/config-apply.d.ts +9 -0
  29. package/dist/application/config-apply.d.ts.map +1 -0
  30. package/dist/application/config-apply.js +146 -0
  31. package/dist/application/config-apply.js.map +1 -0
  32. package/dist/application/config-approval.d.ts +10 -0
  33. package/dist/application/config-approval.d.ts.map +1 -0
  34. package/dist/application/config-approval.js +30 -0
  35. package/dist/application/config-approval.js.map +1 -0
  36. package/dist/application/config-mutation-store.d.ts +25 -0
  37. package/dist/application/config-mutation-store.d.ts.map +1 -0
  38. package/dist/application/config-mutation-store.js +59 -0
  39. package/dist/application/config-mutation-store.js.map +1 -0
  40. package/dist/application/config-proposal.d.ts +22 -0
  41. package/dist/application/config-proposal.d.ts.map +1 -0
  42. package/dist/application/config-proposal.js +395 -0
  43. package/dist/application/config-proposal.js.map +1 -0
  44. package/dist/application/config-propose-tool.d.ts +30 -0
  45. package/dist/application/config-propose-tool.d.ts.map +1 -0
  46. package/dist/application/config-propose-tool.js +63 -0
  47. package/dist/application/config-propose-tool.js.map +1 -0
  48. package/dist/application/config-read-tool.d.ts +26 -0
  49. package/dist/application/config-read-tool.d.ts.map +1 -0
  50. package/dist/application/config-read-tool.js +51 -0
  51. package/dist/application/config-read-tool.js.map +1 -0
  52. package/dist/application/config-status.d.ts +9 -0
  53. package/dist/application/config-status.d.ts.map +1 -0
  54. package/dist/application/config-status.js +361 -0
  55. package/dist/application/config-status.js.map +1 -0
  56. package/dist/application/config-tools.d.ts +3 -0
  57. package/dist/application/config-tools.d.ts.map +1 -0
  58. package/dist/application/config-tools.js +11 -0
  59. package/dist/application/config-tools.js.map +1 -0
  60. package/dist/application/context-types.d.ts +4 -17
  61. package/dist/application/context-types.d.ts.map +1 -1
  62. package/dist/application/context-types.js.map +1 -1
  63. package/dist/application/first-party-agent-defaults.d.ts +3 -0
  64. package/dist/application/first-party-agent-defaults.d.ts.map +1 -0
  65. package/dist/application/first-party-agent-defaults.js +135 -0
  66. package/dist/application/first-party-agent-defaults.js.map +1 -0
  67. package/dist/application/instruction-profile-context.d.ts +15 -0
  68. package/dist/application/instruction-profile-context.d.ts.map +1 -0
  69. package/dist/application/instruction-profile-context.js +80 -0
  70. package/dist/application/instruction-profile-context.js.map +1 -0
  71. package/dist/application/instruction-profile-loader.d.ts +20 -0
  72. package/dist/application/instruction-profile-loader.d.ts.map +1 -0
  73. package/dist/application/instruction-profile-loader.js +132 -0
  74. package/dist/application/instruction-profile-loader.js.map +1 -0
  75. package/dist/application/instruction-profile-loader.test.d.ts +2 -0
  76. package/dist/application/instruction-profile-loader.test.d.ts.map +1 -0
  77. package/dist/application/instruction-profile-loader.test.js +100 -0
  78. package/dist/application/instruction-profile-loader.test.js.map +1 -0
  79. package/dist/application/operator-theme-preferences.d.ts +11 -0
  80. package/dist/application/operator-theme-preferences.d.ts.map +1 -0
  81. package/dist/application/operator-theme-preferences.js +49 -0
  82. package/dist/application/operator-theme-preferences.js.map +1 -0
  83. package/dist/application/project-context.d.ts +22 -0
  84. package/dist/application/project-context.d.ts.map +1 -0
  85. package/dist/application/project-context.js +139 -0
  86. package/dist/application/project-context.js.map +1 -0
  87. package/dist/application/project-root-resolver.d.ts +14 -0
  88. package/dist/application/project-root-resolver.d.ts.map +1 -0
  89. package/dist/application/project-root-resolver.js +71 -0
  90. package/dist/application/project-root-resolver.js.map +1 -0
  91. package/dist/application/repo-shim-projection.d.ts +48 -0
  92. package/dist/application/repo-shim-projection.d.ts.map +1 -0
  93. package/dist/application/repo-shim-projection.js +536 -0
  94. package/dist/application/repo-shim-projection.js.map +1 -0
  95. package/dist/application/resume-sidebar-info.d.ts +9 -0
  96. package/dist/application/resume-sidebar-info.d.ts.map +1 -0
  97. package/dist/application/resume-sidebar-info.js +40 -0
  98. package/dist/application/resume-sidebar-info.js.map +1 -0
  99. package/dist/application/resume-strategy-feedback.d.ts.map +1 -1
  100. package/dist/application/resume-strategy-feedback.js +2 -1
  101. package/dist/application/resume-strategy-feedback.js.map +1 -1
  102. package/dist/application/run-session.d.ts +15 -0
  103. package/dist/application/run-session.d.ts.map +1 -1
  104. package/dist/application/run-session.js +110 -19
  105. package/dist/application/run-session.js.map +1 -1
  106. package/dist/application/runtime-session-rehydration.d.ts +9 -0
  107. package/dist/application/runtime-session-rehydration.d.ts.map +1 -0
  108. package/dist/application/runtime-session-rehydration.js +115 -0
  109. package/dist/application/runtime-session-rehydration.js.map +1 -0
  110. package/dist/application/session-context-artifacts.d.ts +19 -0
  111. package/dist/application/session-context-artifacts.d.ts.map +1 -0
  112. package/dist/application/session-context-artifacts.js +60 -0
  113. package/dist/application/session-context-artifacts.js.map +1 -0
  114. package/dist/application/session-metadata.d.ts +35 -0
  115. package/dist/application/session-metadata.d.ts.map +1 -0
  116. package/dist/application/session-metadata.js +157 -0
  117. package/dist/application/session-metadata.js.map +1 -0
  118. package/dist/application/session-report.d.ts.map +1 -1
  119. package/dist/application/session-report.js +8 -0
  120. package/dist/application/session-report.js.map +1 -1
  121. package/dist/application/session-resume.d.ts +1 -1
  122. package/dist/application/session-resume.d.ts.map +1 -1
  123. package/dist/application/session-resume.js +4 -4
  124. package/dist/application/session-resume.js.map +1 -1
  125. package/dist/application/work-governance-context.d.ts +7 -0
  126. package/dist/application/work-governance-context.d.ts.map +1 -0
  127. package/dist/application/work-governance-context.js +64 -0
  128. package/dist/application/work-governance-context.js.map +1 -0
  129. package/dist/application/work-governance-context.test.d.ts +2 -0
  130. package/dist/application/work-governance-context.test.d.ts.map +1 -0
  131. package/dist/application/work-governance-context.test.js +55 -0
  132. package/dist/application/work-governance-context.test.js.map +1 -0
  133. package/dist/application/work-governance-policy.d.ts +15 -0
  134. package/dist/application/work-governance-policy.d.ts.map +1 -0
  135. package/dist/application/work-governance-policy.js +53 -0
  136. package/dist/application/work-governance-policy.js.map +1 -0
  137. package/dist/application/work-governance-tool.d.ts +421 -0
  138. package/dist/application/work-governance-tool.d.ts.map +1 -0
  139. package/dist/application/work-governance-tool.js +937 -0
  140. package/dist/application/work-governance-tool.js.map +1 -0
  141. package/dist/application/work-governance-tool.test.d.ts +2 -0
  142. package/dist/application/work-governance-tool.test.d.ts.map +1 -0
  143. package/dist/application/work-governance-tool.test.js +935 -0
  144. package/dist/application/work-governance-tool.test.js.map +1 -0
  145. package/dist/application/work-governance-workflows.d.ts +23 -0
  146. package/dist/application/work-governance-workflows.d.ts.map +1 -0
  147. package/dist/application/work-governance-workflows.js +177 -0
  148. package/dist/application/work-governance-workflows.js.map +1 -0
  149. package/dist/application/workflow-snapshot-export.d.ts +81 -0
  150. package/dist/application/workflow-snapshot-export.d.ts.map +1 -0
  151. package/dist/application/workflow-snapshot-export.js +141 -0
  152. package/dist/application/workflow-snapshot-export.js.map +1 -0
  153. package/dist/commands/auth.d.ts.map +1 -1
  154. package/dist/commands/auth.js +242 -24
  155. package/dist/commands/auth.js.map +1 -1
  156. package/dist/commands/benchmark.d.ts +8 -0
  157. package/dist/commands/benchmark.d.ts.map +1 -0
  158. package/dist/commands/benchmark.js +287 -0
  159. package/dist/commands/benchmark.js.map +1 -0
  160. package/dist/commands/config.d.ts +1 -1
  161. package/dist/commands/config.d.ts.map +1 -1
  162. package/dist/commands/config.js +369 -39
  163. package/dist/commands/config.js.map +1 -1
  164. package/dist/commands/config.test.d.ts +2 -0
  165. package/dist/commands/config.test.d.ts.map +1 -0
  166. package/dist/commands/config.test.js +86 -0
  167. package/dist/commands/config.test.js.map +1 -0
  168. package/dist/commands/goal.d.ts +12 -0
  169. package/dist/commands/goal.d.ts.map +1 -0
  170. package/dist/commands/goal.js +469 -0
  171. package/dist/commands/goal.js.map +1 -0
  172. package/dist/commands/goal.test.d.ts +2 -0
  173. package/dist/commands/goal.test.d.ts.map +1 -0
  174. package/dist/commands/goal.test.js +317 -0
  175. package/dist/commands/goal.test.js.map +1 -0
  176. package/dist/commands/gui-options.d.ts +5 -0
  177. package/dist/commands/gui-options.d.ts.map +1 -0
  178. package/dist/commands/gui-options.js +18 -0
  179. package/dist/commands/gui-options.js.map +1 -0
  180. package/dist/commands/gui-session-detail.d.ts +4 -0
  181. package/dist/commands/gui-session-detail.d.ts.map +1 -0
  182. package/dist/commands/gui-session-detail.js +32 -0
  183. package/dist/commands/gui-session-detail.js.map +1 -0
  184. package/dist/commands/gui-session-summaries.d.ts +5 -0
  185. package/dist/commands/gui-session-summaries.d.ts.map +1 -0
  186. package/dist/commands/gui-session-summaries.js +62 -0
  187. package/dist/commands/gui-session-summaries.js.map +1 -0
  188. package/dist/commands/gui-shutdown-monitor.d.ts +8 -0
  189. package/dist/commands/gui-shutdown-monitor.d.ts.map +1 -0
  190. package/dist/commands/gui-shutdown-monitor.js +50 -0
  191. package/dist/commands/gui-shutdown-monitor.js.map +1 -0
  192. package/dist/commands/gui-window.d.ts +42 -0
  193. package/dist/commands/gui-window.d.ts.map +1 -0
  194. package/dist/commands/gui-window.js +287 -0
  195. package/dist/commands/gui-window.js.map +1 -0
  196. package/dist/commands/gui-workspace.d.ts +3 -0
  197. package/dist/commands/gui-workspace.d.ts.map +1 -0
  198. package/dist/commands/gui-workspace.js +297 -0
  199. package/dist/commands/gui-workspace.js.map +1 -0
  200. package/dist/commands/gui.d.ts +14 -0
  201. package/dist/commands/gui.d.ts.map +1 -0
  202. package/dist/commands/gui.js +392 -0
  203. package/dist/commands/gui.js.map +1 -0
  204. package/dist/commands/import-native.d.ts +34 -0
  205. package/dist/commands/import-native.d.ts.map +1 -0
  206. package/dist/commands/import-native.js +302 -0
  207. package/dist/commands/import-native.js.map +1 -0
  208. package/dist/commands/init-templates.d.ts.map +1 -1
  209. package/dist/commands/init-templates.js +13 -12
  210. package/dist/commands/init-templates.js.map +1 -1
  211. package/dist/commands/init.js +1 -1
  212. package/dist/commands/init.js.map +1 -1
  213. package/dist/commands/mcp-config.d.ts.map +1 -1
  214. package/dist/commands/mcp-config.js +6 -3
  215. package/dist/commands/mcp-config.js.map +1 -1
  216. package/dist/commands/memory.d.ts +1 -1
  217. package/dist/commands/memory.d.ts.map +1 -1
  218. package/dist/commands/memory.js +188 -39
  219. package/dist/commands/memory.js.map +1 -1
  220. package/dist/commands/project.d.ts +3 -0
  221. package/dist/commands/project.d.ts.map +1 -0
  222. package/dist/commands/project.js +64 -0
  223. package/dist/commands/project.js.map +1 -0
  224. package/dist/commands/route.d.ts +3 -0
  225. package/dist/commands/route.d.ts.map +1 -0
  226. package/dist/commands/route.js +19 -0
  227. package/dist/commands/route.js.map +1 -0
  228. package/dist/commands/run.d.ts +23 -1
  229. package/dist/commands/run.d.ts.map +1 -1
  230. package/dist/commands/run.js +416 -81
  231. package/dist/commands/run.js.map +1 -1
  232. package/dist/commands/skill-capture.js +34 -14
  233. package/dist/commands/skill-capture.js.map +1 -1
  234. package/dist/commands/skill.d.ts.map +1 -1
  235. package/dist/commands/skill.js +10 -9
  236. package/dist/commands/skill.js.map +1 -1
  237. package/dist/commands/status.d.ts +5 -1
  238. package/dist/commands/status.d.ts.map +1 -1
  239. package/dist/commands/status.js +134 -5
  240. package/dist/commands/status.js.map +1 -1
  241. package/dist/commands/sync.d.ts +8 -6
  242. package/dist/commands/sync.d.ts.map +1 -1
  243. package/dist/commands/sync.js +173 -48
  244. package/dist/commands/sync.js.map +1 -1
  245. package/dist/commands/tools.d.ts +2 -0
  246. package/dist/commands/tools.d.ts.map +1 -1
  247. package/dist/commands/tools.js +34 -15
  248. package/dist/commands/tools.js.map +1 -1
  249. package/dist/commands/tui.d.ts +6 -4
  250. package/dist/commands/tui.d.ts.map +1 -1
  251. package/dist/commands/tui.js +594 -94
  252. package/dist/commands/tui.js.map +1 -1
  253. package/dist/commands/uninstall.d.ts +13 -0
  254. package/dist/commands/uninstall.d.ts.map +1 -0
  255. package/dist/commands/uninstall.js +111 -0
  256. package/dist/commands/uninstall.js.map +1 -0
  257. package/dist/config/builtin-tool-surface-config.d.ts +6 -0
  258. package/dist/config/builtin-tool-surface-config.d.ts.map +1 -0
  259. package/dist/config/builtin-tool-surface-config.js +27 -0
  260. package/dist/config/builtin-tool-surface-config.js.map +1 -0
  261. package/dist/config/config-merger.d.ts +1 -1
  262. package/dist/config/config-merger.d.ts.map +1 -1
  263. package/dist/config/config-merger.js +21 -4
  264. package/dist/config/config-merger.js.map +1 -1
  265. package/dist/config/config-merger.test.js +202 -7
  266. package/dist/config/config-merger.test.js.map +1 -1
  267. package/dist/config/global-config.d.ts +59 -13
  268. package/dist/config/global-config.d.ts.map +1 -1
  269. package/dist/config/global-config.js +580 -5
  270. package/dist/config/global-config.js.map +1 -1
  271. package/dist/config/global-config.test.js +481 -8
  272. package/dist/config/global-config.test.js.map +1 -1
  273. package/dist/config/harness-integration-capabilities.d.ts +27 -0
  274. package/dist/config/harness-integration-capabilities.d.ts.map +1 -0
  275. package/dist/config/harness-integration-capabilities.js +64 -0
  276. package/dist/config/harness-integration-capabilities.js.map +1 -0
  277. package/dist/config/interactive-use-config.d.ts +25 -0
  278. package/dist/config/interactive-use-config.d.ts.map +1 -0
  279. package/dist/config/interactive-use-config.js +210 -0
  280. package/dist/config/interactive-use-config.js.map +1 -0
  281. package/dist/config/json-comments.d.ts +2 -0
  282. package/dist/config/json-comments.d.ts.map +1 -0
  283. package/dist/config/json-comments.js +21 -0
  284. package/dist/config/json-comments.js.map +1 -0
  285. package/dist/config/managed-agent-direct-adapters.d.ts +15 -0
  286. package/dist/config/managed-agent-direct-adapters.d.ts.map +1 -0
  287. package/dist/config/managed-agent-direct-adapters.js +54 -0
  288. package/dist/config/managed-agent-direct-adapters.js.map +1 -0
  289. package/dist/config/managed-agent-provider-models.d.ts +3 -0
  290. package/dist/config/managed-agent-provider-models.d.ts.map +1 -0
  291. package/dist/config/managed-agent-provider-models.js +12 -0
  292. package/dist/config/managed-agent-provider-models.js.map +1 -0
  293. package/dist/config/managed-agent-routes.d.ts +49 -0
  294. package/dist/config/managed-agent-routes.d.ts.map +1 -0
  295. package/dist/config/managed-agent-routes.js +578 -0
  296. package/dist/config/managed-agent-routes.js.map +1 -0
  297. package/dist/config/managed-invocation-context-resolver.d.ts +10 -0
  298. package/dist/config/managed-invocation-context-resolver.d.ts.map +1 -0
  299. package/dist/config/managed-invocation-context-resolver.js +98 -0
  300. package/dist/config/managed-invocation-context-resolver.js.map +1 -0
  301. package/dist/config/managed-invocation-context-resolver.test.d.ts +2 -0
  302. package/dist/config/managed-invocation-context-resolver.test.d.ts.map +1 -0
  303. package/dist/config/managed-invocation-context-resolver.test.js +133 -0
  304. package/dist/config/managed-invocation-context-resolver.test.js.map +1 -0
  305. package/dist/config/model-task-suitability.d.ts +9 -0
  306. package/dist/config/model-task-suitability.d.ts.map +1 -0
  307. package/dist/config/model-task-suitability.js +40 -0
  308. package/dist/config/model-task-suitability.js.map +1 -0
  309. package/dist/config/native-agent-projection.d.ts +16 -0
  310. package/dist/config/native-agent-projection.d.ts.map +1 -0
  311. package/dist/config/native-agent-projection.js +242 -0
  312. package/dist/config/native-agent-projection.js.map +1 -0
  313. package/dist/config/native-hook-projection.d.ts +11 -0
  314. package/dist/config/native-hook-projection.d.ts.map +1 -0
  315. package/dist/config/native-hook-projection.js +180 -0
  316. package/dist/config/native-hook-projection.js.map +1 -0
  317. package/dist/config/native-permission-projection.d.ts +12 -0
  318. package/dist/config/native-permission-projection.d.ts.map +1 -0
  319. package/dist/config/native-permission-projection.js +162 -0
  320. package/dist/config/native-permission-projection.js.map +1 -0
  321. package/dist/config/native-projection-backup.d.ts +8 -0
  322. package/dist/config/native-projection-backup.d.ts.map +1 -0
  323. package/dist/config/native-projection-backup.js +19 -0
  324. package/dist/config/native-projection-backup.js.map +1 -0
  325. package/dist/config/native-projection-policy.d.ts +10 -0
  326. package/dist/config/native-projection-policy.d.ts.map +1 -0
  327. package/dist/config/native-projection-policy.js +9 -0
  328. package/dist/config/native-projection-policy.js.map +1 -0
  329. package/dist/config/native-projection-state.d.ts +57 -0
  330. package/dist/config/native-projection-state.d.ts.map +1 -0
  331. package/dist/config/native-projection-state.js +199 -0
  332. package/dist/config/native-projection-state.js.map +1 -0
  333. package/dist/config/native-skill-projection.d.ts +24 -0
  334. package/dist/config/native-skill-projection.d.ts.map +1 -0
  335. package/dist/config/native-skill-projection.js +170 -0
  336. package/dist/config/native-skill-projection.js.map +1 -0
  337. package/dist/config/operator-identity-context.d.ts +7 -0
  338. package/dist/config/operator-identity-context.d.ts.map +1 -0
  339. package/dist/config/operator-identity-context.js +46 -0
  340. package/dist/config/operator-identity-context.js.map +1 -0
  341. package/dist/config/operator-identity-context.test.d.ts +2 -0
  342. package/dist/config/operator-identity-context.test.d.ts.map +1 -0
  343. package/dist/config/operator-identity-context.test.js +61 -0
  344. package/dist/config/operator-identity-context.test.js.map +1 -0
  345. package/dist/config/operator-voice.d.ts +10 -0
  346. package/dist/config/operator-voice.d.ts.map +1 -0
  347. package/dist/config/operator-voice.js +29 -0
  348. package/dist/config/operator-voice.js.map +1 -0
  349. package/dist/config/provider-route-candidates.d.ts +20 -0
  350. package/dist/config/provider-route-candidates.d.ts.map +1 -0
  351. package/dist/config/provider-route-candidates.js +211 -0
  352. package/dist/config/provider-route-candidates.js.map +1 -0
  353. package/dist/config/provider-route-candidates.test.d.ts +2 -0
  354. package/dist/config/provider-route-candidates.test.d.ts.map +1 -0
  355. package/dist/config/provider-route-candidates.test.js +150 -0
  356. package/dist/config/provider-route-candidates.test.js.map +1 -0
  357. package/dist/config/skill-registry.d.ts +9 -0
  358. package/dist/config/skill-registry.d.ts.map +1 -0
  359. package/dist/config/skill-registry.js +13 -0
  360. package/dist/config/skill-registry.js.map +1 -0
  361. package/dist/config/skill-registry.test.d.ts +2 -0
  362. package/dist/config/skill-registry.test.d.ts.map +1 -0
  363. package/dist/config/skill-registry.test.js +64 -0
  364. package/dist/config/skill-registry.test.js.map +1 -0
  365. package/dist/config/task-skill-selection.d.ts +24 -0
  366. package/dist/config/task-skill-selection.d.ts.map +1 -0
  367. package/dist/config/task-skill-selection.js +79 -0
  368. package/dist/config/task-skill-selection.js.map +1 -0
  369. package/dist/config/translators/claude-translator.d.ts +7 -0
  370. package/dist/config/translators/claude-translator.d.ts.map +1 -0
  371. package/dist/config/translators/claude-translator.js +30 -0
  372. package/dist/config/translators/claude-translator.js.map +1 -0
  373. package/dist/config/translators/codex-translator.d.ts +7 -0
  374. package/dist/config/translators/codex-translator.d.ts.map +1 -0
  375. package/dist/config/translators/codex-translator.js +20 -0
  376. package/dist/config/translators/codex-translator.js.map +1 -0
  377. package/dist/config/translators/opencode-translator.d.ts +7 -0
  378. package/dist/config/translators/opencode-translator.d.ts.map +1 -0
  379. package/dist/config/translators/opencode-translator.js +19 -0
  380. package/dist/config/translators/opencode-translator.js.map +1 -0
  381. package/dist/config/translators/permission-projection.d.ts +26 -0
  382. package/dist/config/translators/permission-projection.d.ts.map +1 -0
  383. package/dist/config/translators/permission-projection.js +22 -0
  384. package/dist/config/translators/permission-projection.js.map +1 -0
  385. package/dist/config/web-tools-config.d.ts +45 -0
  386. package/dist/config/web-tools-config.d.ts.map +1 -0
  387. package/dist/config/web-tools-config.js +846 -0
  388. package/dist/config/web-tools-config.js.map +1 -0
  389. package/dist/config.d.ts +4 -0
  390. package/dist/config.d.ts.map +1 -1
  391. package/dist/config.js.map +1 -1
  392. package/dist/engines/engine-registry.d.ts +45 -0
  393. package/dist/engines/engine-registry.d.ts.map +1 -0
  394. package/dist/engines/engine-registry.js +125 -0
  395. package/dist/engines/engine-registry.js.map +1 -0
  396. package/dist/index.d.ts +2 -2
  397. package/dist/index.d.ts.map +1 -1
  398. package/dist/index.js +141 -18
  399. package/dist/index.js.map +1 -1
  400. package/dist/kiln-yaml-types.d.ts +207 -1
  401. package/dist/kiln-yaml-types.d.ts.map +1 -1
  402. package/dist/kiln-yaml-types.js +29 -0
  403. package/dist/kiln-yaml-types.js.map +1 -1
  404. package/dist/kiln-yaml.d.ts +1 -1
  405. package/dist/kiln-yaml.d.ts.map +1 -1
  406. package/dist/kiln-yaml.js +93 -0
  407. package/dist/kiln-yaml.js.map +1 -1
  408. package/dist/mcp/config-generator.d.ts.map +1 -1
  409. package/dist/mcp/config-generator.js +8 -7
  410. package/dist/mcp/config-generator.js.map +1 -1
  411. package/dist/mcp/index.d.ts +2 -25
  412. package/dist/mcp/index.d.ts.map +1 -1
  413. package/dist/mcp/index.js +1 -103
  414. package/dist/mcp/index.js.map +1 -1
  415. package/dist/wrapper/__tests__/session-manager-context-governor.test.d.ts +2 -0
  416. package/dist/wrapper/__tests__/session-manager-context-governor.test.d.ts.map +1 -0
  417. package/dist/wrapper/__tests__/session-manager-context-governor.test.js +210 -0
  418. package/dist/wrapper/__tests__/session-manager-context-governor.test.js.map +1 -0
  419. package/dist/wrapper/claude-code-process.d.ts +1 -0
  420. package/dist/wrapper/claude-code-process.d.ts.map +1 -1
  421. package/dist/wrapper/claude-code-process.js +32 -19
  422. package/dist/wrapper/claude-code-process.js.map +1 -1
  423. package/dist/wrapper/cleanup-registry.d.ts.map +1 -1
  424. package/dist/wrapper/cleanup-registry.js +3 -1
  425. package/dist/wrapper/cleanup-registry.js.map +1 -1
  426. package/dist/wrapper/codex-session.d.ts +3 -0
  427. package/dist/wrapper/codex-session.d.ts.map +1 -1
  428. package/dist/wrapper/codex-session.js +193 -85
  429. package/dist/wrapper/codex-session.js.map +1 -1
  430. package/dist/wrapper/debug.d.ts.map +1 -1
  431. package/dist/wrapper/debug.js +2 -0
  432. package/dist/wrapper/debug.js.map +1 -1
  433. package/dist/wrapper/direct-provider-adapter-factory.d.ts +12 -0
  434. package/dist/wrapper/direct-provider-adapter-factory.d.ts.map +1 -0
  435. package/dist/wrapper/direct-provider-adapter-factory.js +99 -0
  436. package/dist/wrapper/direct-provider-adapter-factory.js.map +1 -0
  437. package/dist/wrapper/index.d.ts +0 -2
  438. package/dist/wrapper/index.d.ts.map +1 -1
  439. package/dist/wrapper/index.js +0 -1
  440. package/dist/wrapper/index.js.map +1 -1
  441. package/dist/wrapper/opencode-session.d.ts +4 -0
  442. package/dist/wrapper/opencode-session.d.ts.map +1 -1
  443. package/dist/wrapper/opencode-session.js +245 -38
  444. package/dist/wrapper/opencode-session.js.map +1 -1
  445. package/dist/wrapper/permission-evaluator.d.ts +2 -1
  446. package/dist/wrapper/permission-evaluator.d.ts.map +1 -1
  447. package/dist/wrapper/permission-evaluator.js +54 -0
  448. package/dist/wrapper/permission-evaluator.js.map +1 -1
  449. package/dist/wrapper/permission-normalizer.d.ts +5 -1
  450. package/dist/wrapper/permission-normalizer.d.ts.map +1 -1
  451. package/dist/wrapper/permission-normalizer.js +17 -0
  452. package/dist/wrapper/permission-normalizer.js.map +1 -1
  453. package/dist/wrapper/permission-policy-authorizer.d.ts +1 -1
  454. package/dist/wrapper/permission-policy-authorizer.js +1 -1
  455. package/dist/wrapper/pooled-harness-session.d.ts +24 -0
  456. package/dist/wrapper/pooled-harness-session.d.ts.map +1 -0
  457. package/dist/wrapper/pooled-harness-session.js +123 -0
  458. package/dist/wrapper/pooled-harness-session.js.map +1 -0
  459. package/dist/wrapper/preamble-builder.d.ts +4 -1
  460. package/dist/wrapper/preamble-builder.d.ts.map +1 -1
  461. package/dist/wrapper/preamble-builder.js +48 -20
  462. package/dist/wrapper/preamble-builder.js.map +1 -1
  463. package/dist/wrapper/provider-session.d.ts +25 -5
  464. package/dist/wrapper/provider-session.d.ts.map +1 -1
  465. package/dist/wrapper/provider-session.js +562 -138
  466. package/dist/wrapper/provider-session.js.map +1 -1
  467. package/dist/wrapper/session-manager.d.ts.map +1 -1
  468. package/dist/wrapper/session-manager.js +16 -5
  469. package/dist/wrapper/session-manager.js.map +1 -1
  470. package/dist/wrapper/session-registry.d.ts +11 -1
  471. package/dist/wrapper/session-registry.d.ts.map +1 -1
  472. package/dist/wrapper/session-registry.js +167 -259
  473. package/dist/wrapper/session-registry.js.map +1 -1
  474. package/dist/wrapper/session-store.d.ts +33 -10
  475. package/dist/wrapper/session-store.d.ts.map +1 -1
  476. package/dist/wrapper/session-store.js +327 -84
  477. package/dist/wrapper/session-store.js.map +1 -1
  478. package/dist/wrapper/session.d.ts +55 -2
  479. package/dist/wrapper/session.d.ts.map +1 -1
  480. package/dist/wrapper/session.js +11 -2
  481. package/dist/wrapper/session.js.map +1 -1
  482. package/package.json +6 -5
  483. package/dist/application/__tests__/plan-exit-tool.test.d.ts +0 -2
  484. package/dist/application/__tests__/plan-exit-tool.test.d.ts.map +0 -1
  485. package/dist/application/__tests__/plan-exit-tool.test.js +0 -12
  486. package/dist/application/__tests__/plan-exit-tool.test.js.map +0 -1
  487. package/dist/application/context-governor.d.ts +0 -26
  488. package/dist/application/context-governor.d.ts.map +0 -1
  489. package/dist/application/context-governor.js +0 -164
  490. package/dist/application/context-governor.js.map +0 -1
  491. package/dist/application/plan-exit-tool.d.ts +0 -19
  492. package/dist/application/plan-exit-tool.d.ts.map +0 -1
  493. package/dist/application/plan-exit-tool.js +0 -13
  494. package/dist/application/plan-exit-tool.js.map +0 -1
  495. package/dist/commands/serve.d.ts +0 -7
  496. package/dist/commands/serve.d.ts.map +0 -1
  497. package/dist/commands/serve.js +0 -24
  498. package/dist/commands/serve.js.map +0 -1
  499. package/dist/mcp/server.d.ts +0 -36
  500. package/dist/mcp/server.d.ts.map +0 -1
  501. package/dist/mcp/server.js +0 -156
  502. package/dist/mcp/server.js.map +0 -1
  503. package/dist/mcp/transports.d.ts +0 -28
  504. package/dist/mcp/transports.d.ts.map +0 -1
  505. package/dist/mcp/transports.js +0 -108
  506. package/dist/mcp/transports.js.map +0 -1
  507. package/dist/mcp-entry.d.ts +0 -3
  508. package/dist/mcp-entry.d.ts.map +0 -1
  509. package/dist/mcp-entry.js +0 -19
  510. package/dist/mcp-entry.js.map +0 -1
  511. package/dist/sync/agent-sync.d.ts +0 -13
  512. package/dist/sync/agent-sync.d.ts.map +0 -1
  513. package/dist/sync/agent-sync.js +0 -130
  514. package/dist/sync/agent-sync.js.map +0 -1
  515. package/dist/sync/agent-sync.test.d.ts +0 -2
  516. package/dist/sync/agent-sync.test.d.ts.map +0 -1
  517. package/dist/sync/agent-sync.test.js +0 -130
  518. package/dist/sync/agent-sync.test.js.map +0 -1
  519. package/dist/sync/agents-md-sync.d.ts +0 -7
  520. package/dist/sync/agents-md-sync.d.ts.map +0 -1
  521. package/dist/sync/agents-md-sync.js +0 -44
  522. package/dist/sync/agents-md-sync.js.map +0 -1
  523. package/dist/sync/agents-md-sync.test.d.ts +0 -2
  524. package/dist/sync/agents-md-sync.test.d.ts.map +0 -1
  525. package/dist/sync/agents-md-sync.test.js +0 -154
  526. package/dist/sync/agents-md-sync.test.js.map +0 -1
  527. package/dist/sync/hook-sync.d.ts +0 -8
  528. package/dist/sync/hook-sync.d.ts.map +0 -1
  529. package/dist/sync/hook-sync.js +0 -90
  530. package/dist/sync/hook-sync.js.map +0 -1
  531. package/dist/sync/security-sync.d.ts +0 -9
  532. package/dist/sync/security-sync.d.ts.map +0 -1
  533. package/dist/sync/security-sync.js +0 -161
  534. package/dist/sync/security-sync.js.map +0 -1
  535. package/dist/sync/skill-sync.d.ts +0 -10
  536. package/dist/sync/skill-sync.d.ts.map +0 -1
  537. package/dist/sync/skill-sync.js +0 -87
  538. package/dist/sync/skill-sync.js.map +0 -1
  539. package/dist/sync/skill-sync.test.d.ts +0 -2
  540. package/dist/sync/skill-sync.test.d.ts.map +0 -1
  541. package/dist/sync/skill-sync.test.js +0 -163
  542. package/dist/sync/skill-sync.test.js.map +0 -1
  543. package/dist/wrapper/executable-provider-session.d.ts +0 -26
  544. package/dist/wrapper/executable-provider-session.d.ts.map +0 -1
  545. package/dist/wrapper/executable-provider-session.js +0 -214
  546. package/dist/wrapper/executable-provider-session.js.map +0 -1
@@ -0,0 +1,935 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { GoalRunStore, WorkItemStore } from "@kilnai/core";
3
+ import { assessWorkGovernance } from "./work-governance-policy.js";
4
+ import { createWorkGovernanceTools, WorkGovernanceAssessTool } from "./work-governance-tool.js";
5
+ describe("work-governance-tool", () => {
6
+ const policy = {
7
+ defaultPosture: "orchestrate",
8
+ directExecution: {
9
+ maxFiles: 1,
10
+ maxRisk: "low",
11
+ },
12
+ requireDelegationFor: ["architecture", "ui"],
13
+ requiredEvidence: ["surface-map", "residual-risk"],
14
+ };
15
+ it("recommends orchestration when a configured trigger matches", () => {
16
+ const assessment = assessWorkGovernance(policy, {
17
+ summary: "Update GUI layout",
18
+ estimatedFiles: 1,
19
+ risk: "low",
20
+ triggers: ["ui"],
21
+ });
22
+ expect(assessment.recommendation).toBe("orchestrate");
23
+ expect(assessment.reasons).toContain("default posture is orchestrate");
24
+ expect(assessment.reasons).toContain("delegation trigger matched: ui");
25
+ expect(assessment.requiredEvidence).toContain("browser-qa");
26
+ });
27
+ it("recommends direct execution inside a direct policy envelope", () => {
28
+ const assessment = assessWorkGovernance({
29
+ defaultPosture: "direct",
30
+ directExecution: {
31
+ maxFiles: 1,
32
+ maxRisk: "low",
33
+ },
34
+ }, {
35
+ summary: "Fix typo",
36
+ estimatedFiles: 1,
37
+ risk: "low",
38
+ triggers: [],
39
+ });
40
+ expect(assessment).toMatchObject({
41
+ recommendation: "direct",
42
+ reasons: ["inside direct-execution envelope"],
43
+ });
44
+ });
45
+ it("returns a readable tool result with required evidence", async () => {
46
+ const tool = new WorkGovernanceAssessTool(policy);
47
+ const result = await tool.execute({
48
+ name: "work_governance.assess",
49
+ input: {
50
+ summary: "Refactor managed agent route selection",
51
+ estimatedFiles: 4,
52
+ risk: "medium",
53
+ triggers: ["managed-agents", "cross-surface"],
54
+ },
55
+ });
56
+ expect(result.isError).toBe(false);
57
+ expect(result.output).toContain("recommendation: orchestrate");
58
+ expect(result.output).toContain("estimated file count 4 exceeds direct max 1");
59
+ expect(result.output).toContain("managed-agent-review");
60
+ });
61
+ it("lists workflow profiles with UI evidence gates", async () => {
62
+ const tools = createWorkGovernanceTools(policy);
63
+ const tool = tools.find((candidate) => candidate.name === "work_profile.list");
64
+ const result = await tool?.execute({
65
+ name: "work_profile.list",
66
+ input: { trigger: "ui" },
67
+ });
68
+ expect(result?.isError).toBe(false);
69
+ expect(result?.output).toContain('"id": "ui-change"');
70
+ expect(result?.output).toContain('"browser-qa"');
71
+ expect(result?.output).toContain('"evidenceMatrix"');
72
+ expect(result?.output).toContain('"browser QA screenshot or interaction proof"');
73
+ });
74
+ it("materializes expected evidence and verification gates from the profile evidence matrix", async () => {
75
+ const tools = createWorkGovernanceTools(policy);
76
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
77
+ const created = await updateTool?.execute({
78
+ name: "work_item.update",
79
+ input: {
80
+ summary: "Validate managed agent replay evidence.",
81
+ workflowProfile: "managed-agent-change",
82
+ triggers: ["managed-agents", "provider-routing"],
83
+ },
84
+ });
85
+ expect(created?.isError).toBe(false);
86
+ const parsed = JSON.parse(created?.output ?? "{}");
87
+ expect(parsed.item.expectedEvidence).toEqual(expect.arrayContaining([
88
+ "managed-agent-review",
89
+ "tests",
90
+ "typecheck",
91
+ "residual-risk",
92
+ ]));
93
+ expect(parsed.item.verificationGates).toEqual(expect.arrayContaining([
94
+ "managed child live or simulated evidence",
95
+ "route/provider identity check",
96
+ "typecheck/build",
97
+ ]));
98
+ });
99
+ it("blocks work item completion until expected evidence and residual risk are present", async () => {
100
+ const tools = createWorkGovernanceTools(policy);
101
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
102
+ const completeTool = tools.find((candidate) => candidate.name === "work_item.complete");
103
+ const created = await updateTool?.execute({
104
+ name: "work_item.update",
105
+ input: {
106
+ summary: "Fix GUI approval UX",
107
+ risk: "medium",
108
+ triggers: ["ui", "cross-surface"],
109
+ },
110
+ });
111
+ expect(created?.isError).toBe(false);
112
+ const parsed = JSON.parse(created?.output ?? "{}");
113
+ const blocked = await completeTool?.execute({
114
+ name: "work_item.complete",
115
+ input: {
116
+ id: parsed.item.id,
117
+ providedEvidence: ["surface-map"],
118
+ },
119
+ });
120
+ expect(blocked?.isError).toBe(true);
121
+ expect(blocked?.output).toContain("browser-qa");
122
+ expect(blocked?.output).toContain("residual-risk closeout");
123
+ expect(blocked?.metadata).toMatchObject({
124
+ kind: "work_item",
125
+ operation: "complete",
126
+ status: "blocked",
127
+ errorCode: "missing_evidence",
128
+ });
129
+ });
130
+ it("completes work items when all evidence is supplied", async () => {
131
+ const tools = createWorkGovernanceTools(policy);
132
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
133
+ const completeTool = tools.find((candidate) => candidate.name === "work_item.complete");
134
+ const created = await updateTool?.execute({
135
+ name: "work_item.update",
136
+ input: {
137
+ summary: "Small docs correction",
138
+ workflowProfile: "small-fix",
139
+ triggers: [],
140
+ expectedEvidence: [],
141
+ },
142
+ });
143
+ expect(created?.isError).toBe(false);
144
+ const parsed = JSON.parse(created?.output ?? "{}");
145
+ const completed = await completeTool?.execute({
146
+ name: "work_item.complete",
147
+ input: {
148
+ id: parsed.item.id,
149
+ providedEvidence: parsed.item.expectedEvidence,
150
+ residualRisk: "No known residual risk after focused verification.",
151
+ },
152
+ });
153
+ expect(completed?.isError).toBe(false);
154
+ expect(completed?.output).toContain('"status": "completed"');
155
+ expect(completed?.metadata).toMatchObject({
156
+ kind: "work_item",
157
+ operation: "complete",
158
+ status: "completed",
159
+ });
160
+ });
161
+ it("blocks direct work item completion when a verification gate is skipped without residual risk", async () => {
162
+ const tools = createWorkGovernanceTools(policy);
163
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
164
+ const completeTool = tools.find((candidate) => candidate.name === "work_item.complete");
165
+ const created = await updateTool?.execute({
166
+ name: "work_item.update",
167
+ input: {
168
+ summary: "Verify skipped direct closeout.",
169
+ workflowProfile: "small-fix",
170
+ triggers: [],
171
+ expectedEvidence: ["tests"],
172
+ verificationGates: ["bun test", "bun run typecheck"],
173
+ },
174
+ });
175
+ expect(created?.isError).toBe(false);
176
+ const parsed = JSON.parse(created?.output ?? "{}");
177
+ const blocked = await completeTool?.execute({
178
+ name: "work_item.complete",
179
+ input: {
180
+ id: parsed.item.id,
181
+ providedEvidence: parsed.item.expectedEvidence,
182
+ skippedVerificationGates: ["bun run typecheck"],
183
+ },
184
+ });
185
+ expect(blocked?.isError).toBe(true);
186
+ expect(blocked?.output).toContain("residual-risk closeout");
187
+ expect(blocked?.metadata).toMatchObject({
188
+ kind: "work_item",
189
+ operation: "complete",
190
+ status: "blocked",
191
+ missingEvidence: [],
192
+ missingResidualRisk: true,
193
+ errorCode: "missing_evidence",
194
+ item: {
195
+ skippedVerificationGates: ["bun run typecheck"],
196
+ },
197
+ });
198
+ });
199
+ it("shares work item state with the caller-provided session store", async () => {
200
+ const workItemStore = new WorkItemStore();
201
+ const tools = createWorkGovernanceTools(policy, { workItemStore });
202
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
203
+ await updateTool?.execute({
204
+ name: "work_item.update",
205
+ input: {
206
+ summary: "Track runtime evidence",
207
+ workflowProfile: "managed-agent-change",
208
+ triggers: ["managed-agents"],
209
+ },
210
+ });
211
+ expect(workItemStore.snapshot().items).toHaveLength(1);
212
+ expect(workItemStore.snapshot().items[0]).toMatchObject({
213
+ summary: "Track runtime evidence",
214
+ workflowProfile: "managed-agent-change",
215
+ });
216
+ });
217
+ it("starts and finishes goal-bound work item execution attempts through tools", async () => {
218
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
219
+ const workItemStore = new WorkItemStore({ now: fixedNow });
220
+ const item = workItemStore.upsert({
221
+ id: "work-execute",
222
+ summary: "Execute governed work.",
223
+ workflowProfile: "verification-heavy",
224
+ triggers: ["verification-heavy"],
225
+ expectedEvidence: ["tests"],
226
+ verificationGates: ["bun test"],
227
+ goalRunId: "goal-execute",
228
+ });
229
+ const goal = goalRunStore.create({
230
+ id: "goal-execute",
231
+ objective: "Execute approved work.",
232
+ ownerSessionId: "session-1",
233
+ planId: "plan-1",
234
+ workItemIds: [item.id],
235
+ authorityEnvelope: {
236
+ maximumAuthority: "audited",
237
+ escalationPolicy: "approval_required",
238
+ reason: "Approved plan.",
239
+ },
240
+ routePolicy: { workflowProfile: "verification-heavy" },
241
+ evidenceRequirements: [],
242
+ });
243
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
244
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
245
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
246
+ const started = await startTool?.execute({
247
+ name: "work_item.execution.start",
248
+ input: {
249
+ goalRunId: goal.id,
250
+ summary: "Start direct execution.",
251
+ },
252
+ });
253
+ expect(started?.isError).toBe(false);
254
+ expect(started?.metadata).toMatchObject({
255
+ kind: "work_item",
256
+ operation: "execution_started",
257
+ id: item.id,
258
+ status: "in_progress",
259
+ attempt: {
260
+ id: "goal-execute:work-execute:attempt:1",
261
+ executionMode: "direct",
262
+ status: "started",
263
+ },
264
+ });
265
+ const finished = await finishTool?.execute({
266
+ name: "work_item.execution.finish",
267
+ input: {
268
+ goalRunId: goal.id,
269
+ workItemId: item.id,
270
+ attemptId: "goal-execute:work-execute:attempt:1",
271
+ providedEvidence: ["tests"],
272
+ summary: "Finished with tests.",
273
+ closeoutSummary: "Goal execution finished.",
274
+ },
275
+ });
276
+ expect(finished?.isError).toBe(false);
277
+ expect(finished?.metadata).toMatchObject({
278
+ kind: "work_item",
279
+ operation: "execution_finished",
280
+ id: item.id,
281
+ status: "completed",
282
+ attempt: {
283
+ id: "goal-execute:work-execute:attempt:1",
284
+ status: "completed",
285
+ providedEvidence: ["tests"],
286
+ },
287
+ missingEvidence: [],
288
+ missingResidualRisk: false,
289
+ });
290
+ expect(goalRunStore.get(goal.id)?.status).toBe("completed");
291
+ });
292
+ it("returns generated goal closeout summary when final execution omits manual summary", async () => {
293
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
294
+ const workItemStore = new WorkItemStore({ now: fixedNow });
295
+ const item = workItemStore.upsert({
296
+ id: "work-generated-closeout",
297
+ summary: "Verify generated closeout summary.",
298
+ workflowProfile: "verification-heavy",
299
+ triggers: ["verification-heavy"],
300
+ expectedEvidence: ["tests", "typecheck"],
301
+ verificationGates: ["bun test", "bun run typecheck"],
302
+ goalRunId: "goal-generated-closeout",
303
+ });
304
+ const goal = goalRunStore.create({
305
+ id: "goal-generated-closeout",
306
+ objective: "Generate closeout from evidence.",
307
+ ownerSessionId: "session-1",
308
+ planId: "plan-1",
309
+ workItemIds: [item.id],
310
+ authorityEnvelope: {
311
+ maximumAuthority: "audited",
312
+ escalationPolicy: "approval_required",
313
+ reason: "Approved plan.",
314
+ },
315
+ routePolicy: { workflowProfile: "verification-heavy" },
316
+ evidenceRequirements: [],
317
+ });
318
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
319
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
320
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
321
+ await startTool?.execute({
322
+ name: "work_item.execution.start",
323
+ input: { goalRunId: goal.id },
324
+ });
325
+ const finished = await finishTool?.execute({
326
+ name: "work_item.execution.finish",
327
+ input: {
328
+ goalRunId: goal.id,
329
+ workItemId: item.id,
330
+ attemptId: "goal-generated-closeout:work-generated-closeout:attempt:1",
331
+ providedEvidence: ["tests", "typecheck"],
332
+ verificationGateResults: [
333
+ { gate: "bun test", status: "passed" },
334
+ { gate: "bun run typecheck", status: "passed" },
335
+ ],
336
+ },
337
+ });
338
+ expect(finished?.isError).toBe(false);
339
+ expect(finished?.output).toContain("Goal goal-generated-closeout completed from canonical evidence.");
340
+ expect(finished?.output).toContain("Evidence: tests, typecheck.");
341
+ expect(finished?.output).toContain("Passed gates: bun test, bun run typecheck.");
342
+ });
343
+ it("blocks goal-bound execution finish until evidence and residual risk are present", async () => {
344
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
345
+ const workItemStore = new WorkItemStore({ now: fixedNow });
346
+ const item = workItemStore.upsert({
347
+ id: "work-blocked-finish",
348
+ summary: "Verify governed closeout.",
349
+ workflowProfile: "verification-heavy",
350
+ triggers: ["verification-heavy"],
351
+ expectedEvidence: ["tests", "typecheck", "residual-risk"],
352
+ verificationGates: ["bun test", "bun run typecheck"],
353
+ goalRunId: "goal-blocked-finish",
354
+ });
355
+ const goal = goalRunStore.create({
356
+ id: "goal-blocked-finish",
357
+ objective: "Execute closeout-gated work.",
358
+ ownerSessionId: "session-1",
359
+ planId: "plan-1",
360
+ workItemIds: [item.id],
361
+ authorityEnvelope: {
362
+ maximumAuthority: "audited",
363
+ escalationPolicy: "approval_required",
364
+ reason: "Approved plan.",
365
+ },
366
+ routePolicy: { workflowProfile: "verification-heavy" },
367
+ evidenceRequirements: [],
368
+ });
369
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
370
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
371
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
372
+ const started = await startTool?.execute({
373
+ name: "work_item.execution.start",
374
+ input: {
375
+ goalRunId: goal.id,
376
+ summary: "Start closeout-gated execution.",
377
+ },
378
+ });
379
+ expect(started?.isError).toBe(false);
380
+ const blocked = await finishTool?.execute({
381
+ name: "work_item.execution.finish",
382
+ input: {
383
+ goalRunId: goal.id,
384
+ workItemId: item.id,
385
+ attemptId: "goal-blocked-finish:work-blocked-finish:attempt:1",
386
+ providedEvidence: ["tests"],
387
+ summary: "Only tests completed.",
388
+ },
389
+ });
390
+ expect(blocked?.isError).toBe(true);
391
+ expect(blocked?.output).toContain('"status": "blocked"');
392
+ expect(blocked?.output).toContain("typecheck");
393
+ expect(blocked?.output).toContain("residual-risk closeout");
394
+ expect(blocked?.metadata).toMatchObject({
395
+ kind: "work_item",
396
+ operation: "execution_finished",
397
+ id: item.id,
398
+ status: "blocked",
399
+ missingEvidence: ["typecheck", "residual-risk"],
400
+ missingResidualRisk: true,
401
+ errorCode: "missing_evidence",
402
+ attempt: {
403
+ id: "goal-blocked-finish:work-blocked-finish:attempt:1",
404
+ status: "blocked",
405
+ providedEvidence: ["tests"],
406
+ },
407
+ });
408
+ expect(workItemStore.get(item.id)?.status).toBe("blocked");
409
+ expect(goalRunStore.get(goal.id)?.currentPhase).toBe("paused:work-blocked-finish");
410
+ });
411
+ it("blocks skipped verification gates until residual risk is documented", async () => {
412
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
413
+ const workItemStore = new WorkItemStore({ now: fixedNow });
414
+ const item = workItemStore.upsert({
415
+ id: "work-skipped-gate",
416
+ summary: "Verify skipped gate closeout.",
417
+ workflowProfile: "verification-heavy",
418
+ triggers: ["verification-heavy"],
419
+ expectedEvidence: ["tests"],
420
+ verificationGates: ["bun test", "bun run typecheck"],
421
+ goalRunId: "goal-skipped-gate",
422
+ });
423
+ const goal = goalRunStore.create({
424
+ id: "goal-skipped-gate",
425
+ objective: "Execute closeout-gated work.",
426
+ ownerSessionId: "session-1",
427
+ planId: "plan-1",
428
+ workItemIds: [item.id],
429
+ authorityEnvelope: {
430
+ maximumAuthority: "audited",
431
+ escalationPolicy: "approval_required",
432
+ reason: "Approved plan.",
433
+ },
434
+ routePolicy: { workflowProfile: "verification-heavy" },
435
+ evidenceRequirements: [],
436
+ });
437
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
438
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
439
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
440
+ await startTool?.execute({
441
+ name: "work_item.execution.start",
442
+ input: {
443
+ goalRunId: goal.id,
444
+ summary: "Start closeout-gated execution.",
445
+ },
446
+ });
447
+ const blocked = await finishTool?.execute({
448
+ name: "work_item.execution.finish",
449
+ input: {
450
+ goalRunId: goal.id,
451
+ workItemId: item.id,
452
+ attemptId: "goal-skipped-gate:work-skipped-gate:attempt:1",
453
+ providedEvidence: ["tests"],
454
+ skippedVerificationGates: ["bun run typecheck"],
455
+ summary: "Tests passed; typecheck was skipped.",
456
+ },
457
+ });
458
+ expect(blocked?.isError).toBe(true);
459
+ expect(blocked?.output).toContain("residual-risk closeout");
460
+ expect(blocked?.metadata).toMatchObject({
461
+ kind: "work_item",
462
+ operation: "execution_finished",
463
+ id: item.id,
464
+ status: "blocked",
465
+ missingEvidence: [],
466
+ missingResidualRisk: true,
467
+ errorCode: "missing_evidence",
468
+ attempt: {
469
+ id: "goal-skipped-gate:work-skipped-gate:attempt:1",
470
+ skippedVerificationGates: ["bun run typecheck"],
471
+ },
472
+ item: {
473
+ skippedVerificationGates: ["bun run typecheck"],
474
+ },
475
+ });
476
+ expect(goalRunStore.get(goal.id)?.currentPhase).toBe("paused:work-skipped-gate");
477
+ });
478
+ it("blocks final goal closeout when required goal evidence is missing", async () => {
479
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
480
+ const workItemStore = new WorkItemStore({ now: fixedNow });
481
+ const item = workItemStore.upsert({
482
+ id: "work-goal-evidence",
483
+ summary: "Complete item evidence only.",
484
+ workflowProfile: "verification-heavy",
485
+ triggers: ["verification-heavy"],
486
+ expectedEvidence: ["tests"],
487
+ verificationGates: ["bun test"],
488
+ goalRunId: "goal-evidence-closeout",
489
+ });
490
+ const goal = goalRunStore.create({
491
+ id: "goal-evidence-closeout",
492
+ objective: "Close only with goal-level evidence.",
493
+ ownerSessionId: "session-1",
494
+ planId: "plan-1",
495
+ workItemIds: [item.id],
496
+ authorityEnvelope: {
497
+ maximumAuthority: "audited",
498
+ escalationPolicy: "approval_required",
499
+ reason: "Approved plan.",
500
+ },
501
+ routePolicy: { workflowProfile: "verification-heavy" },
502
+ evidenceRequirements: [
503
+ { id: "tests", description: "Focused tests pass.", required: true },
504
+ { id: "typecheck", description: "Typecheck passes.", required: true },
505
+ ],
506
+ });
507
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
508
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
509
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
510
+ await startTool?.execute({
511
+ name: "work_item.execution.start",
512
+ input: {
513
+ goalRunId: goal.id,
514
+ },
515
+ });
516
+ const blocked = await finishTool?.execute({
517
+ name: "work_item.execution.finish",
518
+ input: {
519
+ goalRunId: goal.id,
520
+ workItemId: item.id,
521
+ attemptId: "goal-evidence-closeout:work-goal-evidence:attempt:1",
522
+ providedEvidence: ["tests"],
523
+ closeoutSummary: "Should not close without typecheck.",
524
+ },
525
+ });
526
+ expect(blocked?.isError).toBe(true);
527
+ expect(blocked?.output).toContain("typecheck");
528
+ expect(blocked?.metadata).toMatchObject({
529
+ kind: "work_item",
530
+ operation: "execution_finished",
531
+ id: item.id,
532
+ status: "completed",
533
+ missingEvidence: [],
534
+ missingGoalEvidence: ["typecheck"],
535
+ errorCode: "missing_evidence",
536
+ });
537
+ expect(goalRunStore.get(goal.id)).toMatchObject({
538
+ status: "active",
539
+ currentPhase: "paused:goal-closeout",
540
+ });
541
+ });
542
+ it("records verification gate results and blocks failed gates", async () => {
543
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
544
+ const workItemStore = new WorkItemStore({ now: fixedNow });
545
+ const item = workItemStore.upsert({
546
+ id: "work-gate-results",
547
+ summary: "Record verification gate results.",
548
+ workflowProfile: "verification-heavy",
549
+ triggers: ["verification-heavy"],
550
+ expectedEvidence: ["tests", "typecheck"],
551
+ verificationGates: ["bun test", "bun run typecheck"],
552
+ goalRunId: "goal-gate-results",
553
+ });
554
+ const goal = goalRunStore.create({
555
+ id: "goal-gate-results",
556
+ objective: "Execute closeout-gated work.",
557
+ ownerSessionId: "session-1",
558
+ planId: "plan-1",
559
+ workItemIds: [item.id],
560
+ authorityEnvelope: {
561
+ maximumAuthority: "audited",
562
+ escalationPolicy: "approval_required",
563
+ reason: "Approved plan.",
564
+ },
565
+ routePolicy: { workflowProfile: "verification-heavy" },
566
+ evidenceRequirements: [],
567
+ });
568
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
569
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
570
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
571
+ await startTool?.execute({
572
+ name: "work_item.execution.start",
573
+ input: { goalRunId: goal.id },
574
+ });
575
+ const blocked = await finishTool?.execute({
576
+ name: "work_item.execution.finish",
577
+ input: {
578
+ goalRunId: goal.id,
579
+ workItemId: item.id,
580
+ attemptId: "goal-gate-results:work-gate-results:attempt:1",
581
+ providedEvidence: ["tests", "typecheck"],
582
+ verificationGateResults: [
583
+ { gate: "bun test", status: "passed", summary: "Focused tests passed." },
584
+ { gate: "bun run typecheck", status: "failed", summary: "TypeScript error in workflow projection." },
585
+ ],
586
+ summary: "Typecheck failed.",
587
+ },
588
+ });
589
+ expect(blocked?.isError).toBe(true);
590
+ expect(blocked?.output).toContain("failed gate: bun run typecheck");
591
+ expect(blocked?.metadata).toMatchObject({
592
+ kind: "work_item",
593
+ operation: "execution_finished",
594
+ id: item.id,
595
+ status: "blocked",
596
+ failedVerificationGates: ["bun run typecheck"],
597
+ errorCode: "missing_evidence",
598
+ attempt: {
599
+ verificationGateResults: [
600
+ { gate: "bun test", status: "passed" },
601
+ { gate: "bun run typecheck", status: "failed" },
602
+ ],
603
+ },
604
+ item: {
605
+ verificationGateResults: [
606
+ { gate: "bun test", status: "passed" },
607
+ { gate: "bun run typecheck", status: "failed" },
608
+ ],
609
+ },
610
+ });
611
+ expect(goalRunStore.get(goal.id)?.currentPhase).toBe("paused:work-gate-results");
612
+ });
613
+ it("blocks risky profile closeout until reviewer gates pass", async () => {
614
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
615
+ const workItemStore = new WorkItemStore({ now: fixedNow });
616
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
617
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
618
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
619
+ const finishTool = tools.find((candidate) => candidate.name === "work_item.execution.finish");
620
+ const created = await updateTool?.execute({
621
+ name: "work_item.update",
622
+ input: {
623
+ id: "work-review-gate",
624
+ summary: "Verify managed-agent review closeout.",
625
+ workflowProfile: "managed-agent-change",
626
+ triggers: ["managed-agents"],
627
+ goalRunId: "goal-review-gate",
628
+ },
629
+ });
630
+ expect(created?.isError).toBe(false);
631
+ const item = workItemStore.get("work-review-gate");
632
+ expect(item?.verificationGates).toContain("adversarial managed-agent review");
633
+ const goal = goalRunStore.create({
634
+ id: "goal-review-gate",
635
+ objective: "Execute risky profile work.",
636
+ ownerSessionId: "session-1",
637
+ planId: "plan-1",
638
+ workItemIds: ["work-review-gate"],
639
+ authorityEnvelope: {
640
+ maximumAuthority: "audited",
641
+ escalationPolicy: "approval_required",
642
+ reason: "Approved plan.",
643
+ },
644
+ routePolicy: { workflowProfile: "managed-agent-change" },
645
+ evidenceRequirements: [],
646
+ });
647
+ await startTool?.execute({
648
+ name: "work_item.execution.start",
649
+ input: { goalRunId: goal.id },
650
+ });
651
+ const blocked = await finishTool?.execute({
652
+ name: "work_item.execution.finish",
653
+ input: {
654
+ goalRunId: goal.id,
655
+ workItemId: "work-review-gate",
656
+ attemptId: "goal-review-gate:work-review-gate:attempt:1",
657
+ providedEvidence: item?.expectedEvidence ?? [],
658
+ verificationGateResults: [
659
+ { gate: "managed child live or simulated evidence", status: "passed" },
660
+ { gate: "route/provider identity check", status: "passed" },
661
+ { gate: "typecheck/build", status: "passed" },
662
+ ],
663
+ },
664
+ });
665
+ expect(blocked?.isError).toBe(true);
666
+ expect(blocked?.output).toContain("missing gate: adversarial managed-agent review");
667
+ expect(blocked?.metadata).toMatchObject({
668
+ kind: "work_item",
669
+ operation: "execution_finished",
670
+ status: "blocked",
671
+ missingVerificationGates: ["adversarial managed-agent review"],
672
+ errorCode: "missing_evidence",
673
+ });
674
+ });
675
+ it("blocks UI profile closeout until browser QA gates pass", async () => {
676
+ const tools = createWorkGovernanceTools(policy);
677
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
678
+ const completeTool = tools.find((candidate) => candidate.name === "work_item.complete");
679
+ const created = await updateTool?.execute({
680
+ name: "work_item.update",
681
+ input: {
682
+ summary: "Verify browser QA closeout.",
683
+ workflowProfile: "ui-change",
684
+ triggers: ["ui"],
685
+ },
686
+ });
687
+ expect(created?.isError).toBe(false);
688
+ const parsed = JSON.parse(created?.output ?? "{}");
689
+ const blocked = await completeTool?.execute({
690
+ name: "work_item.complete",
691
+ input: {
692
+ id: parsed.item.id,
693
+ providedEvidence: parsed.item.expectedEvidence,
694
+ residualRisk: "No known residual risk after UI verification.",
695
+ verificationGateResults: [
696
+ { gate: "typecheck", status: "passed" },
697
+ ],
698
+ },
699
+ });
700
+ expect(blocked?.isError).toBe(true);
701
+ expect(blocked?.output).toContain("missing gate: browser QA screenshot or interaction proof");
702
+ expect(blocked?.output).toContain("missing gate: accessibility/overflow check");
703
+ expect(blocked?.metadata).toMatchObject({
704
+ kind: "work_item",
705
+ operation: "complete",
706
+ status: "blocked",
707
+ missingVerificationGates: [
708
+ "browser QA screenshot or interaction proof",
709
+ "accessibility/overflow check",
710
+ ],
711
+ errorCode: "missing_evidence",
712
+ });
713
+ });
714
+ it("does not start an explicit work item before earlier dependencies are complete", async () => {
715
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
716
+ const workItemStore = new WorkItemStore({ now: fixedNow });
717
+ const first = workItemStore.upsert({
718
+ id: "work-first",
719
+ summary: "First work.",
720
+ workflowProfile: "verification-heavy",
721
+ triggers: ["verification-heavy"],
722
+ expectedEvidence: ["tests"],
723
+ verificationGates: ["bun test"],
724
+ goalRunId: "goal-ordered",
725
+ });
726
+ const second = workItemStore.upsert({
727
+ id: "work-second",
728
+ summary: "Second work.",
729
+ workflowProfile: "verification-heavy",
730
+ triggers: ["verification-heavy"],
731
+ expectedEvidence: ["tests"],
732
+ verificationGates: ["bun test"],
733
+ dependencies: [first.id],
734
+ goalRunId: "goal-ordered",
735
+ });
736
+ const goal = goalRunStore.create({
737
+ id: "goal-ordered",
738
+ objective: "Execute ordered work.",
739
+ ownerSessionId: "session-1",
740
+ planId: "plan-1",
741
+ workItemIds: [first.id, second.id],
742
+ authorityEnvelope: {
743
+ maximumAuthority: "audited",
744
+ escalationPolicy: "approval_required",
745
+ reason: "Approved plan.",
746
+ },
747
+ routePolicy: { workflowProfile: "verification-heavy" },
748
+ evidenceRequirements: [],
749
+ });
750
+ const startTool = createWorkGovernanceTools(policy, { workItemStore, goalRunStore })
751
+ .find((candidate) => candidate.name === "work_item.execution.start");
752
+ const blocked = await startTool?.execute({
753
+ name: "work_item.execution.start",
754
+ input: {
755
+ goalRunId: goal.id,
756
+ workItemId: second.id,
757
+ },
758
+ });
759
+ expect(blocked?.isError).toBe(true);
760
+ expect(blocked?.output).toContain("Explicit work item is not the next ready item");
761
+ expect(workItemStore.get(second.id)?.status).toBe("pending");
762
+ });
763
+ it("pauses execution on unresolved work item requirements and resumes after update resolves them", async () => {
764
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
765
+ const workItemStore = new WorkItemStore({ now: fixedNow });
766
+ const tools = createWorkGovernanceTools(policy, { workItemStore, goalRunStore });
767
+ const updateTool = tools.find((candidate) => candidate.name === "work_item.update");
768
+ const startTool = tools.find((candidate) => candidate.name === "work_item.execution.start");
769
+ const created = await updateTool?.execute({
770
+ name: "work_item.update",
771
+ input: {
772
+ id: "work-paused",
773
+ summary: "Execute after credentials are available.",
774
+ workflowProfile: "verification-heavy",
775
+ triggers: ["verification-heavy"],
776
+ expectedEvidence: ["tests"],
777
+ pauseRequirements: [
778
+ {
779
+ id: "credential-access",
780
+ kind: "credentials",
781
+ summary: "Provide test service credentials.",
782
+ status: "pending",
783
+ },
784
+ ],
785
+ },
786
+ });
787
+ expect(created?.isError).toBe(false);
788
+ goalRunStore.create({
789
+ id: "goal-paused-requirement",
790
+ objective: "Execute approved work.",
791
+ ownerSessionId: "session-1",
792
+ planId: "plan-1",
793
+ workItemIds: ["work-paused"],
794
+ authorityEnvelope: {
795
+ maximumAuthority: "audited",
796
+ escalationPolicy: "approval_required",
797
+ reason: "Approved plan.",
798
+ },
799
+ routePolicy: { workflowProfile: "verification-heavy" },
800
+ evidenceRequirements: [],
801
+ });
802
+ const paused = await startTool?.execute({
803
+ name: "work_item.execution.start",
804
+ input: {
805
+ goalRunId: "goal-paused-requirement",
806
+ },
807
+ });
808
+ expect(paused?.isError).toBe(true);
809
+ expect(paused?.output).toContain("pause_requirements_unresolved");
810
+ expect(paused?.output).toContain("credential-access");
811
+ expect(workItemStore.get("work-paused")?.status).toBe("pending");
812
+ const resolved = await updateTool?.execute({
813
+ name: "work_item.update",
814
+ input: {
815
+ id: "work-paused",
816
+ summary: "Execute after credentials are available.",
817
+ workflowProfile: "verification-heavy",
818
+ triggers: ["verification-heavy"],
819
+ expectedEvidence: ["tests"],
820
+ pauseRequirements: [
821
+ {
822
+ id: "credential-access",
823
+ kind: "credentials",
824
+ summary: "Provide test service credentials.",
825
+ status: "resolved",
826
+ resolvedBy: "operator",
827
+ resolvedAt: "2026-05-12T20:00:00.000Z",
828
+ resolution: "Credentials supplied through approved channel.",
829
+ },
830
+ ],
831
+ },
832
+ });
833
+ expect(resolved?.isError).toBe(false);
834
+ const started = await startTool?.execute({
835
+ name: "work_item.execution.start",
836
+ input: {
837
+ goalRunId: "goal-paused-requirement",
838
+ },
839
+ });
840
+ expect(started?.isError).toBe(false);
841
+ expect(started?.metadata).toMatchObject({
842
+ operation: "execution_started",
843
+ id: "work-paused",
844
+ status: "in_progress",
845
+ });
846
+ });
847
+ it("requires a managed invocation id before starting managed-delegation execution", async () => {
848
+ const goalRunStore = new GoalRunStore({ now: fixedNow });
849
+ const workItemStore = new WorkItemStore({ now: fixedNow });
850
+ const item = workItemStore.upsert({
851
+ id: "work-managed",
852
+ summary: "Execute delegated work.",
853
+ workflowProfile: "managed-agent-change",
854
+ triggers: ["managed-agents"],
855
+ expectedEvidence: ["managed-agent-review"],
856
+ verificationGates: ["review child handoff"],
857
+ goalRunId: "goal-managed",
858
+ routeId: "opencode-readonly",
859
+ assignedAgentProfile: "coder",
860
+ authorityProfile: "foundation-propose-writes",
861
+ });
862
+ const goal = goalRunStore.create({
863
+ id: "goal-managed",
864
+ objective: "Execute delegated work.",
865
+ ownerSessionId: "session-1",
866
+ planId: "plan-1",
867
+ workItemIds: [item.id],
868
+ authorityEnvelope: {
869
+ maximumAuthority: "audited",
870
+ escalationPolicy: "approval_required",
871
+ reason: "Approved plan.",
872
+ },
873
+ routePolicy: {
874
+ workflowProfile: "managed-agent-change",
875
+ preferredRouteId: "opencode-readonly",
876
+ managedAgentProfile: "coder",
877
+ },
878
+ evidenceRequirements: [],
879
+ });
880
+ const startTool = createWorkGovernanceTools(policy, { workItemStore, goalRunStore })
881
+ .find((candidate) => candidate.name === "work_item.execution.start");
882
+ const missingInvocation = await startTool?.execute({
883
+ name: "work_item.execution.start",
884
+ input: {
885
+ goalRunId: goal.id,
886
+ governanceRecommendation: "orchestrate",
887
+ managedProviderId: "opencode",
888
+ managedModel: "opencode-default-model",
889
+ },
890
+ });
891
+ expect(missingInvocation?.isError).toBe(true);
892
+ expect(missingInvocation?.output).toContain("managedInvocationId is required");
893
+ const missingInvocationOutput = JSON.parse(missingInvocation?.output ?? "{}");
894
+ expect(missingInvocationOutput.nextTool).toBe("managed_agent.invoke");
895
+ expect(missingInvocationOutput.managedInvocationRequest).toMatchObject({
896
+ profile: "foundation-propose-writes",
897
+ routeId: "opencode-readonly",
898
+ providerRoute: {
899
+ providerId: "opencode",
900
+ model: "opencode-default-model",
901
+ },
902
+ requestedAuthority: "audited",
903
+ summary: "Execute delegated work.",
904
+ workItemId: "work-managed",
905
+ agentProfile: "coder",
906
+ roleIntent: "Execute governed work item work-managed for goal goal-managed.",
907
+ expectedEvidence: ["managed-agent-review"],
908
+ requiredResultFields: ["summary", "evidence", "checks"],
909
+ doneCriteria: ["review child handoff", "Produce required evidence: managed-agent-review."],
910
+ residualRiskRequired: false,
911
+ });
912
+ expect(missingInvocationOutput.managedInvocationRequest?.task).toContain("Execute delegated work.");
913
+ expect(workItemStore.get(item.id)?.status).toBe("pending");
914
+ const started = await startTool?.execute({
915
+ name: "work_item.execution.start",
916
+ input: {
917
+ goalRunId: goal.id,
918
+ governanceRecommendation: "orchestrate",
919
+ managedInvocationId: "invocation-managed-1",
920
+ },
921
+ });
922
+ expect(started?.isError).toBe(false);
923
+ expect(started?.metadata).toMatchObject({
924
+ operation: "execution_started",
925
+ attempt: {
926
+ executionMode: "managed_delegation",
927
+ managedInvocationId: "invocation-managed-1",
928
+ },
929
+ });
930
+ });
931
+ });
932
+ function fixedNow() {
933
+ return "2026-05-12T20:00:00.000Z";
934
+ }
935
+ //# sourceMappingURL=work-governance-tool.test.js.map