kiokuko-dsh 0.2.39 → 0.2.41

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 (540) hide show
  1. package/PERMISSIONS.md +2 -2
  2. package/README.ja.md +17 -5
  3. package/README.ko.md +17 -5
  4. package/README.md +17 -5
  5. package/README.zh-CN.md +17 -5
  6. package/dist/akinator/skill-discovery-attempt.d.ts +3 -1
  7. package/dist/akinator/skill-discovery-attempt.d.ts.map +1 -1
  8. package/dist/akinator/skill-discovery-attempt.js +12 -11
  9. package/dist/akinator/skill-discovery-attempt.js.map +1 -1
  10. package/dist/client.cjs +7 -10
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/context/continuity-view.d.ts +0 -11
  13. package/dist/context/continuity-view.d.ts.map +1 -1
  14. package/dist/context/continuity-view.js +5 -9
  15. package/dist/context/continuity-view.js.map +1 -1
  16. package/dist/deep-thinker/controller.d.ts +4 -1
  17. package/dist/deep-thinker/controller.d.ts.map +1 -1
  18. package/dist/deep-thinker/controller.js +10 -0
  19. package/dist/deep-thinker/controller.js.map +1 -1
  20. package/dist/deep-thinker/core/contracts.d.ts +11 -11
  21. package/dist/deep-thinker/memory-finalizer.d.ts +1 -1
  22. package/dist/deep-thinker/native-executor.d.ts +1 -1
  23. package/dist/deep-thinker/native-executor.d.ts.map +1 -1
  24. package/dist/deep-thinker/prompts.js +1 -1
  25. package/dist/deep-thinker/prompts.js.map +1 -1
  26. package/dist/deep-thinker/quality-prompts.js +1 -1
  27. package/dist/deep-thinker/quality-prompts.js.map +1 -1
  28. package/dist/deep-thinker/report.d.ts +1 -1
  29. package/dist/deep-thinker/store.d.ts +1 -1
  30. package/dist/dsh/agenticreplay-hooks.d.ts.map +1 -1
  31. package/dist/dsh/agenticreplay-hooks.js +13 -0
  32. package/dist/dsh/agenticreplay-hooks.js.map +1 -1
  33. package/dist/dsh/agenticreplay-recorder.d.ts +5 -0
  34. package/dist/dsh/agenticreplay-recorder.d.ts.map +1 -1
  35. package/dist/dsh/agenticreplay-recorder.js +19 -0
  36. package/dist/dsh/agenticreplay-recorder.js.map +1 -1
  37. package/dist/dsh/coding-workflow/contracts.d.ts +2 -5
  38. package/dist/dsh/coding-workflow/contracts.d.ts.map +1 -1
  39. package/dist/dsh/coding-workflow/contracts.js +1 -1
  40. package/dist/dsh/coding-workflow/contracts.js.map +1 -1
  41. package/dist/dsh/coding-workflow/host.d.ts.map +1 -1
  42. package/dist/dsh/coding-workflow/host.js +1 -4
  43. package/dist/dsh/coding-workflow/host.js.map +1 -1
  44. package/dist/dsh/coding-workflow/intent.d.ts.map +1 -1
  45. package/dist/dsh/coding-workflow/intent.js +0 -6
  46. package/dist/dsh/coding-workflow/intent.js.map +1 -1
  47. package/dist/dsh/coding-workflow/service.d.ts +4 -8
  48. package/dist/dsh/coding-workflow/service.d.ts.map +1 -1
  49. package/dist/dsh/coding-workflow/service.js +5 -57
  50. package/dist/dsh/coding-workflow/service.js.map +1 -1
  51. package/dist/dsh/completion-report.d.ts +0 -31
  52. package/dist/dsh/completion-report.d.ts.map +1 -1
  53. package/dist/dsh/completion-report.js +16 -94
  54. package/dist/dsh/completion-report.js.map +1 -1
  55. package/dist/dsh/composition.d.ts +1 -3
  56. package/dist/dsh/composition.d.ts.map +1 -1
  57. package/dist/dsh/composition.js +13 -34
  58. package/dist/dsh/composition.js.map +1 -1
  59. package/dist/dsh/config.d.ts +1 -22
  60. package/dist/dsh/config.d.ts.map +1 -1
  61. package/dist/dsh/config.js +0 -8
  62. package/dist/dsh/config.js.map +1 -1
  63. package/dist/dsh/context-injection.d.ts +1 -11
  64. package/dist/dsh/context-injection.d.ts.map +1 -1
  65. package/dist/dsh/context-injection.js +3 -24
  66. package/dist/dsh/context-injection.js.map +1 -1
  67. package/dist/dsh/continuity-adapter.d.ts +0 -5
  68. package/dist/dsh/continuity-adapter.d.ts.map +1 -1
  69. package/dist/dsh/continuity-adapter.js +1 -39
  70. package/dist/dsh/continuity-adapter.js.map +1 -1
  71. package/dist/dsh/decisions/contracts.d.ts +0 -1
  72. package/dist/dsh/decisions/contracts.d.ts.map +1 -1
  73. package/dist/dsh/decisions/contracts.js +1 -1
  74. package/dist/dsh/decisions/contracts.js.map +1 -1
  75. package/dist/dsh/decisions/diagnostics.d.ts +8 -11
  76. package/dist/dsh/decisions/diagnostics.d.ts.map +1 -1
  77. package/dist/dsh/decisions/diagnostics.js +1 -9
  78. package/dist/dsh/decisions/diagnostics.js.map +1 -1
  79. package/dist/dsh/decisions/intent-assessment.d.ts +2 -5
  80. package/dist/dsh/decisions/intent-assessment.d.ts.map +1 -1
  81. package/dist/dsh/decisions/intent-assessment.js +17 -9
  82. package/dist/dsh/decisions/intent-assessment.js.map +1 -1
  83. package/dist/dsh/efficiency.d.ts +0 -3
  84. package/dist/dsh/efficiency.d.ts.map +1 -1
  85. package/dist/dsh/efficiency.js +1 -9
  86. package/dist/dsh/efficiency.js.map +1 -1
  87. package/dist/dsh/execution-selection.d.ts +6 -7
  88. package/dist/dsh/execution-selection.d.ts.map +1 -1
  89. package/dist/dsh/execution-selection.js +10 -15
  90. package/dist/dsh/execution-selection.js.map +1 -1
  91. package/dist/dsh/execution-support.d.ts +0 -4
  92. package/dist/dsh/execution-support.d.ts.map +1 -1
  93. package/dist/dsh/execution-support.js +3 -15
  94. package/dist/dsh/execution-support.js.map +1 -1
  95. package/dist/dsh/harness/factory.d.ts +109 -0
  96. package/dist/dsh/harness/factory.d.ts.map +1 -0
  97. package/dist/dsh/harness/factory.js +566 -0
  98. package/dist/dsh/harness/factory.js.map +1 -0
  99. package/dist/dsh/harness/inbox.d.ts +22 -0
  100. package/dist/dsh/harness/inbox.d.ts.map +1 -0
  101. package/dist/dsh/harness/inbox.js +61 -0
  102. package/dist/dsh/harness/inbox.js.map +1 -0
  103. package/dist/dsh/harness/index.d.ts +19 -0
  104. package/dist/dsh/harness/index.d.ts.map +1 -0
  105. package/dist/dsh/harness/index.js +26 -0
  106. package/dist/dsh/harness/index.js.map +1 -0
  107. package/dist/dsh/harness/lifecycle.d.ts +26 -0
  108. package/dist/dsh/harness/lifecycle.d.ts.map +1 -0
  109. package/dist/dsh/harness/lifecycle.js +21 -0
  110. package/dist/dsh/harness/lifecycle.js.map +1 -0
  111. package/dist/dsh/harness/projections.d.ts +16 -0
  112. package/dist/dsh/harness/projections.d.ts.map +1 -0
  113. package/dist/dsh/harness/projections.js +34 -0
  114. package/dist/dsh/harness/projections.js.map +1 -0
  115. package/dist/dsh/head-worker-configuration.d.ts +1 -2
  116. package/dist/dsh/head-worker-configuration.d.ts.map +1 -1
  117. package/dist/dsh/head-worker-configuration.js +0 -5
  118. package/dist/dsh/head-worker-configuration.js.map +1 -1
  119. package/dist/dsh/host-adapter/admission.d.ts +1 -8
  120. package/dist/dsh/host-adapter/admission.d.ts.map +1 -1
  121. package/dist/dsh/host-adapter/admission.js +51 -260
  122. package/dist/dsh/host-adapter/admission.js.map +1 -1
  123. package/dist/dsh/host-adapter/boundaries.d.ts +1 -28
  124. package/dist/dsh/host-adapter/boundaries.d.ts.map +1 -1
  125. package/dist/dsh/host-adapter/boundaries.js +27 -328
  126. package/dist/dsh/host-adapter/boundaries.js.map +1 -1
  127. package/dist/dsh/host-adapter/context.d.ts +1 -7
  128. package/dist/dsh/host-adapter/context.d.ts.map +1 -1
  129. package/dist/dsh/host-adapter/context.js +5 -28
  130. package/dist/dsh/host-adapter/context.js.map +1 -1
  131. package/dist/dsh/host-adapter/efficiency-host.d.ts +0 -2
  132. package/dist/dsh/host-adapter/efficiency-host.d.ts.map +1 -1
  133. package/dist/dsh/host-adapter/efficiency-host.js +2 -2
  134. package/dist/dsh/host-adapter/efficiency-host.js.map +1 -1
  135. package/dist/dsh/host-adapter/lifecycle.d.ts +0 -7
  136. package/dist/dsh/host-adapter/lifecycle.d.ts.map +1 -1
  137. package/dist/dsh/host-adapter/lifecycle.js +58 -71
  138. package/dist/dsh/host-adapter/lifecycle.js.map +1 -1
  139. package/dist/dsh/host-adapter/memory-application-host.d.ts +0 -2
  140. package/dist/dsh/host-adapter/memory-application-host.d.ts.map +1 -1
  141. package/dist/dsh/host-adapter/memory-application-host.js +2 -2
  142. package/dist/dsh/host-adapter/memory-application-host.js.map +1 -1
  143. package/dist/dsh/host-adapter/routing.d.ts +1 -5
  144. package/dist/dsh/host-adapter/routing.d.ts.map +1 -1
  145. package/dist/dsh/host-adapter/routing.js +21 -73
  146. package/dist/dsh/host-adapter/routing.js.map +1 -1
  147. package/dist/dsh/host-adapter/session-observation.d.ts +1 -8
  148. package/dist/dsh/host-adapter/session-observation.d.ts.map +1 -1
  149. package/dist/dsh/host-adapter/session-observation.js +2 -55
  150. package/dist/dsh/host-adapter/session-observation.js.map +1 -1
  151. package/dist/dsh/host-adapter/tool-host.d.ts +3 -41
  152. package/dist/dsh/host-adapter/tool-host.d.ts.map +1 -1
  153. package/dist/dsh/host-adapter/tool-host.js +14 -243
  154. package/dist/dsh/host-adapter/tool-host.js.map +1 -1
  155. package/dist/dsh/host-adapter/turn-state.d.ts +0 -4
  156. package/dist/dsh/host-adapter/turn-state.d.ts.map +1 -1
  157. package/dist/dsh/host-adapter/turn-state.js +16 -93
  158. package/dist/dsh/host-adapter/turn-state.js.map +1 -1
  159. package/dist/dsh/host-adapter.d.ts +0 -11
  160. package/dist/dsh/host-adapter.d.ts.map +1 -1
  161. package/dist/dsh/host-adapter.js +17 -179
  162. package/dist/dsh/host-adapter.js.map +1 -1
  163. package/dist/dsh/index.d.ts +3 -16
  164. package/dist/dsh/index.d.ts.map +1 -1
  165. package/dist/dsh/index.js +0 -6
  166. package/dist/dsh/index.js.map +1 -1
  167. package/dist/dsh/lifecycle-memory.d.ts +3 -0
  168. package/dist/dsh/lifecycle-memory.d.ts.map +1 -1
  169. package/dist/dsh/lifecycle-memory.js +67 -45
  170. package/dist/dsh/lifecycle-memory.js.map +1 -1
  171. package/dist/dsh/lisp/candidate.d.ts +2 -2
  172. package/dist/dsh/lisp/code-intelligence-contracts.d.ts +1 -1
  173. package/dist/dsh/lisp/compiled-cache.d.ts.map +1 -1
  174. package/dist/dsh/lisp/compiled-cache.js +27 -6
  175. package/dist/dsh/lisp/compiled-cache.js.map +1 -1
  176. package/dist/dsh/lisp/host-tool-dispatch.d.ts.map +1 -1
  177. package/dist/dsh/lisp/host-tool-dispatch.js +14 -5
  178. package/dist/dsh/lisp/host-tool-dispatch.js.map +1 -1
  179. package/dist/dsh/lisp/manager.d.ts +7 -4
  180. package/dist/dsh/lisp/manager.d.ts.map +1 -1
  181. package/dist/dsh/lisp/manager.js +132 -103
  182. package/dist/dsh/lisp/manager.js.map +1 -1
  183. package/dist/dsh/lisp/sandbox.d.ts.map +1 -1
  184. package/dist/dsh/lisp/sandbox.js +1 -5
  185. package/dist/dsh/lisp/sandbox.js.map +1 -1
  186. package/dist/dsh/lisp/supervision.d.ts +33 -0
  187. package/dist/dsh/lisp/supervision.d.ts.map +1 -0
  188. package/dist/dsh/lisp/supervision.js +89 -0
  189. package/dist/dsh/lisp/supervision.js.map +1 -0
  190. package/dist/dsh/lisp/surface.d.ts +2 -2
  191. package/dist/dsh/lisp/surface.d.ts.map +1 -1
  192. package/dist/dsh/lisp/surface.js +105 -11
  193. package/dist/dsh/lisp/surface.js.map +1 -1
  194. package/dist/dsh/lisp/worker.d.ts +2 -1
  195. package/dist/dsh/lisp/worker.d.ts.map +1 -1
  196. package/dist/dsh/lisp/worker.js +7 -1
  197. package/dist/dsh/lisp/worker.js.map +1 -1
  198. package/dist/dsh/loop-guard.d.ts +0 -8
  199. package/dist/dsh/loop-guard.d.ts.map +1 -1
  200. package/dist/dsh/loop-guard.js +0 -51
  201. package/dist/dsh/loop-guard.js.map +1 -1
  202. package/dist/dsh/memory-application.d.ts.map +1 -1
  203. package/dist/dsh/memory-application.js +0 -6
  204. package/dist/dsh/memory-application.js.map +1 -1
  205. package/dist/dsh/message-sources.d.ts +2 -12
  206. package/dist/dsh/message-sources.d.ts.map +1 -1
  207. package/dist/dsh/message-sources.js +20 -39
  208. package/dist/dsh/message-sources.js.map +1 -1
  209. package/dist/dsh/model-configuration.d.ts +6 -24
  210. package/dist/dsh/model-configuration.d.ts.map +1 -1
  211. package/dist/dsh/model-configuration.js +1 -78
  212. package/dist/dsh/model-configuration.js.map +1 -1
  213. package/dist/dsh/model-routing.d.ts +1 -3
  214. package/dist/dsh/model-routing.d.ts.map +1 -1
  215. package/dist/dsh/model-routing.js +0 -11
  216. package/dist/dsh/model-routing.js.map +1 -1
  217. package/dist/dsh/model-selection-ui.d.ts +1 -2
  218. package/dist/dsh/model-selection-ui.d.ts.map +1 -1
  219. package/dist/dsh/model-selection-ui.js +48 -309
  220. package/dist/dsh/model-selection-ui.js.map +1 -1
  221. package/dist/dsh/models/contracts.d.ts +2 -2
  222. package/dist/dsh/models/service.d.ts +1 -1
  223. package/dist/dsh/modules/legacy-bindings.d.ts +3 -1
  224. package/dist/dsh/modules/legacy-bindings.d.ts.map +1 -1
  225. package/dist/dsh/modules/legacy-bindings.js +5 -5
  226. package/dist/dsh/modules/legacy-bindings.js.map +1 -1
  227. package/dist/dsh/modules/lisp.js +1 -1
  228. package/dist/dsh/modules/lisp.js.map +1 -1
  229. package/dist/dsh/native-execution-ownership.d.ts.map +1 -1
  230. package/dist/dsh/native-execution-ownership.js +0 -2
  231. package/dist/dsh/native-execution-ownership.js.map +1 -1
  232. package/dist/dsh/native-worker-routing.d.ts.map +1 -1
  233. package/dist/dsh/native-worker-routing.js +7 -2
  234. package/dist/dsh/native-worker-routing.js.map +1 -1
  235. package/dist/dsh/on-demand-intake.d.ts.map +1 -1
  236. package/dist/dsh/on-demand-intake.js +17 -8
  237. package/dist/dsh/on-demand-intake.js.map +1 -1
  238. package/dist/dsh/orchestration/execution-owner.d.ts +3 -1
  239. package/dist/dsh/orchestration/execution-owner.d.ts.map +1 -1
  240. package/dist/dsh/orchestration/execution-owner.js.map +1 -1
  241. package/dist/dsh/owned-execution.js +1 -1
  242. package/dist/dsh/owned-execution.js.map +1 -1
  243. package/dist/dsh/replay-memory-extract.d.ts.map +1 -1
  244. package/dist/dsh/replay-memory-extract.js +15 -1
  245. package/dist/dsh/replay-memory-extract.js.map +1 -1
  246. package/dist/dsh/repository-learning.d.ts.map +1 -1
  247. package/dist/dsh/repository-learning.js +3 -0
  248. package/dist/dsh/repository-learning.js.map +1 -1
  249. package/dist/dsh/runtime.d.ts +10 -2
  250. package/dist/dsh/runtime.d.ts.map +1 -1
  251. package/dist/dsh/runtime.js +22 -43
  252. package/dist/dsh/runtime.js.map +1 -1
  253. package/dist/dsh/semantic-compaction/policy.js +1 -1
  254. package/dist/dsh/semantic-compaction/policy.js.map +1 -1
  255. package/dist/dsh/session-bridge.d.ts +1 -1
  256. package/dist/dsh/session-bridge.d.ts.map +1 -1
  257. package/dist/dsh/session-bridge.js +1 -1
  258. package/dist/dsh/session-bridge.js.map +1 -1
  259. package/dist/dsh/session-memory-finalizer.js +1 -1
  260. package/dist/dsh/session-memory-finalizer.js.map +1 -1
  261. package/dist/dsh/session-review-context.d.ts.map +1 -1
  262. package/dist/dsh/session-review-context.js +3 -16
  263. package/dist/dsh/session-review-context.js.map +1 -1
  264. package/dist/dsh/setup.d.ts +1 -1
  265. package/dist/dsh/setup.d.ts.map +1 -1
  266. package/dist/dsh/skill-compiler.js +1 -1
  267. package/dist/dsh/skill-compiler.js.map +1 -1
  268. package/dist/dsh/skill-prompt-contracts.d.ts +2 -2
  269. package/dist/dsh/skill-prompt-contracts.js +1 -1
  270. package/dist/dsh/skill-prompts.json +1 -1
  271. package/dist/dsh/standard-skills.d.ts +1 -8
  272. package/dist/dsh/standard-skills.d.ts.map +1 -1
  273. package/dist/dsh/standard-skills.js +1 -8
  274. package/dist/dsh/standard-skills.js.map +1 -1
  275. package/dist/dsh/task-authority-context.d.ts +3 -0
  276. package/dist/dsh/task-authority-context.d.ts.map +1 -1
  277. package/dist/dsh/task-authority-context.js +3 -0
  278. package/dist/dsh/task-authority-context.js.map +1 -1
  279. package/dist/dsh/task-completion-guidance.d.ts +1 -5
  280. package/dist/dsh/task-completion-guidance.d.ts.map +1 -1
  281. package/dist/dsh/task-completion-guidance.js +4 -6
  282. package/dist/dsh/task-completion-guidance.js.map +1 -1
  283. package/dist/dsh/task-completion-host.js +4 -4
  284. package/dist/dsh/task-completion-host.js.map +1 -1
  285. package/dist/dsh/task-completion.d.ts +1 -13
  286. package/dist/dsh/task-completion.d.ts.map +1 -1
  287. package/dist/dsh/task-completion.js +9 -104
  288. package/dist/dsh/task-completion.js.map +1 -1
  289. package/dist/dsh/task-intake.d.ts +2 -3
  290. package/dist/dsh/task-intake.d.ts.map +1 -1
  291. package/dist/dsh/task-intake.js +90 -86
  292. package/dist/dsh/task-intake.js.map +1 -1
  293. package/dist/dsh/task-state.d.ts.map +1 -1
  294. package/dist/dsh/task-state.js +0 -8
  295. package/dist/dsh/task-state.js.map +1 -1
  296. package/dist/dsh/tool-exposure.d.ts +1 -1
  297. package/dist/dsh/tool-exposure.d.ts.map +1 -1
  298. package/dist/dsh/tool-exposure.js +0 -2
  299. package/dist/dsh/tool-exposure.js.map +1 -1
  300. package/dist/dsh/tool-policy.d.ts +5 -8
  301. package/dist/dsh/tool-policy.d.ts.map +1 -1
  302. package/dist/dsh/tool-policy.js +3 -35
  303. package/dist/dsh/tool-policy.js.map +1 -1
  304. package/dist/dsh/tools.d.ts +2 -6
  305. package/dist/dsh/tools.d.ts.map +1 -1
  306. package/dist/dsh/tools.js +7 -63
  307. package/dist/dsh/tools.js.map +1 -1
  308. package/dist/dsh/turn-process.d.ts +0 -93
  309. package/dist/dsh/turn-process.d.ts.map +1 -1
  310. package/dist/dsh/turn-process.js +1 -307
  311. package/dist/dsh/turn-process.js.map +1 -1
  312. package/dist/dsh/user-interaction.d.ts +9 -16
  313. package/dist/dsh/user-interaction.d.ts.map +1 -1
  314. package/dist/dsh/user-interaction.js +19 -158
  315. package/dist/dsh/user-interaction.js.map +1 -1
  316. package/dist/index.js +2 -19
  317. package/dist/ledger/types.d.ts +1 -1
  318. package/dist/ledger/types.d.ts.map +1 -1
  319. package/dist/ledger/types.js +0 -7
  320. package/dist/ledger/types.js.map +1 -1
  321. package/dist/locale/en.json +1 -1
  322. package/dist/locale/ja.json +1 -1
  323. package/dist/locale/ko.json +1 -1
  324. package/dist/locale/zh-CN.json +1 -1
  325. package/dist/memory/correction-contract.d.ts +4 -4
  326. package/dist/memory/lifecycle.d.ts +1 -1
  327. package/dist/memory/review/evidence.js +1 -1
  328. package/dist/memory/review/evidence.js.map +1 -1
  329. package/dist/model-tools/contracts.d.ts +0 -437
  330. package/dist/model-tools/contracts.d.ts.map +1 -1
  331. package/dist/model-tools/contracts.js +0 -13
  332. package/dist/model-tools/contracts.js.map +1 -1
  333. package/dist/model-tools/names.d.ts +1 -1
  334. package/dist/model-tools/names.d.ts.map +1 -1
  335. package/dist/model-tools/names.js +0 -7
  336. package/dist/model-tools/names.js.map +1 -1
  337. package/dist/model-tools/registry.js +1 -1
  338. package/dist/model-tools/registry.js.map +1 -1
  339. package/dist/models-client.cjs +2 -2
  340. package/dist/models-client.js +2 -2
  341. package/dist/models-client.js.map +1 -1
  342. package/docs/README.ja.md +0 -1
  343. package/docs/README.md +0 -1
  344. package/docs/agenticreplay-recording.md +1 -1
  345. package/docs/agenticreplay-verification.md +1 -1
  346. package/docs/answer-review.md +2 -2
  347. package/docs/architecture.md +4 -7
  348. package/docs/auto-memory-review.md +3 -3
  349. package/docs/coding-workflow.md +1 -1
  350. package/docs/concepts.ja.md +3 -5
  351. package/docs/concepts.md +3 -5
  352. package/docs/core-modules.md +5 -16
  353. package/docs/database.md +5 -10
  354. package/docs/decision-diagnostics.md +1 -2
  355. package/docs/deep-planning.md +3 -3
  356. package/docs/dsh-plugin.md +42 -178
  357. package/docs/execution-ledger.md +1 -2
  358. package/docs/execution-support.md +6 -7
  359. package/docs/harness-map.md +1 -1
  360. package/docs/japanese-output.md +1 -1
  361. package/docs/keyboard-shortcuts.md +1 -1
  362. package/docs/kiokuko-harness.md +71 -0
  363. package/docs/kiokuko-models.md +4 -9
  364. package/docs/lisp-hot-tools.md +12 -7
  365. package/docs/lisp.md +43 -9
  366. package/docs/memory-application.md +5 -5
  367. package/docs/memory-delivery.md +1 -1
  368. package/docs/memory-reuse.md +1 -1
  369. package/docs/model-selection.ja.md +40 -123
  370. package/docs/model-selection.md +45 -114
  371. package/docs/on-demand-intake.md +2 -2
  372. package/docs/owned-execution.md +7 -7
  373. package/docs/pr72-ci-verification.md +2 -2
  374. package/docs/pstack-adaptation.json +0 -34
  375. package/docs/pstack-skills.md +1 -1
  376. package/docs/semantic-compaction.md +2 -2
  377. package/docs/session-history-repair.md +2 -2
  378. package/docs/skill-compiler.md +2 -4
  379. package/docs/tool-exposure.md +1 -1
  380. package/docs/typed-decisions.md +1 -9
  381. package/docs/verification.md +11 -7
  382. package/dsh/cordis.legacy.patch.yml +7 -0
  383. package/dsh/cordis.patch.yml +6 -1
  384. package/lisp/supervisor.mjs +16 -7
  385. package/lisp/tools.lisp +1 -1
  386. package/migrations/051_drop_enno.sql +19 -0
  387. package/package.json +5 -14
  388. package/scripts/session-history-codec.mjs +1 -1
  389. package/skills/coding-ideal-routine-skill/SKILL.md +1 -1
  390. package/skills/kiokuko-lisp/SKILL.md +11 -5
  391. package/skills/kiokuko-single-purpose-functions/SKILL.md +1 -1
  392. package/skills/kiokuko-ui-design-soul/SKILL.md +2 -2
  393. package/skills/one-shot-software-completion/SKILL.md +4 -7
  394. package/skills/one-shot-software-completion/references/boundaries-and-lifecycle.md +3 -5
  395. package/dist/dsh/advisory-runner.d.ts +0 -32
  396. package/dist/dsh/advisory-runner.d.ts.map +0 -1
  397. package/dist/dsh/advisory-runner.js +0 -116
  398. package/dist/dsh/advisory-runner.js.map +0 -1
  399. package/dist/dsh/completion-verifiers.d.ts +0 -45
  400. package/dist/dsh/completion-verifiers.d.ts.map +0 -1
  401. package/dist/dsh/completion-verifiers.js +0 -9
  402. package/dist/dsh/completion-verifiers.js.map +0 -1
  403. package/dist/dsh/continuation.d.ts +0 -24
  404. package/dist/dsh/continuation.d.ts.map +0 -1
  405. package/dist/dsh/continuation.js +0 -215
  406. package/dist/dsh/continuation.js.map +0 -1
  407. package/dist/dsh/decisions/check-model.d.ts +0 -6
  408. package/dist/dsh/decisions/check-model.d.ts.map +0 -1
  409. package/dist/dsh/decisions/check-model.js +0 -36
  410. package/dist/dsh/decisions/check-model.js.map +0 -1
  411. package/dist/dsh/decisions/plan-review.d.ts +0 -17
  412. package/dist/dsh/decisions/plan-review.d.ts.map +0 -1
  413. package/dist/dsh/decisions/plan-review.js +0 -68
  414. package/dist/dsh/decisions/plan-review.js.map +0 -1
  415. package/dist/dsh/directive-projection.d.ts +0 -7
  416. package/dist/dsh/directive-projection.d.ts.map +0 -1
  417. package/dist/dsh/directive-projection.js +0 -32
  418. package/dist/dsh/directive-projection.js.map +0 -1
  419. package/dist/dsh/enno-controller.d.ts +0 -132
  420. package/dist/dsh/enno-controller.d.ts.map +0 -1
  421. package/dist/dsh/enno-controller.js +0 -368
  422. package/dist/dsh/enno-controller.js.map +0 -1
  423. package/dist/dsh/enno-delegation.d.ts +0 -36
  424. package/dist/dsh/enno-delegation.d.ts.map +0 -1
  425. package/dist/dsh/enno-delegation.js +0 -203
  426. package/dist/dsh/enno-delegation.js.map +0 -1
  427. package/dist/dsh/enno-memory-refresh-store.d.ts +0 -26
  428. package/dist/dsh/enno-memory-refresh-store.d.ts.map +0 -1
  429. package/dist/dsh/enno-memory-refresh-store.js +0 -45
  430. package/dist/dsh/enno-memory-refresh-store.js.map +0 -1
  431. package/dist/dsh/enno-memory-refresh.d.ts +0 -57
  432. package/dist/dsh/enno-memory-refresh.d.ts.map +0 -1
  433. package/dist/dsh/enno-memory-refresh.js +0 -280
  434. package/dist/dsh/enno-memory-refresh.js.map +0 -1
  435. package/dist/dsh/host-adapter/enno-memory-host.d.ts +0 -29
  436. package/dist/dsh/host-adapter/enno-memory-host.d.ts.map +0 -1
  437. package/dist/dsh/host-adapter/enno-memory-host.js +0 -49
  438. package/dist/dsh/host-adapter/enno-memory-host.js.map +0 -1
  439. package/dist/dsh/modules/enno.d.ts +0 -70
  440. package/dist/dsh/modules/enno.d.ts.map +0 -1
  441. package/dist/dsh/modules/enno.js +0 -22
  442. package/dist/dsh/modules/enno.js.map +0 -1
  443. package/dist/dsh/verification-identity.d.ts +0 -3
  444. package/dist/dsh/verification-identity.d.ts.map +0 -1
  445. package/dist/dsh/verification-identity.js +0 -15
  446. package/dist/dsh/verification-identity.js.map +0 -1
  447. package/dist/enno-oduno/advisory-store.d.ts +0 -31
  448. package/dist/enno-oduno/advisory-store.d.ts.map +0 -1
  449. package/dist/enno-oduno/advisory-store.js +0 -105
  450. package/dist/enno-oduno/advisory-store.js.map +0 -1
  451. package/dist/enno-oduno/advisory.d.ts +0 -18
  452. package/dist/enno-oduno/advisory.d.ts.map +0 -1
  453. package/dist/enno-oduno/advisory.js +0 -311
  454. package/dist/enno-oduno/advisory.js.map +0 -1
  455. package/dist/enno-oduno/coding-workflow.d.ts +0 -39
  456. package/dist/enno-oduno/coding-workflow.d.ts.map +0 -1
  457. package/dist/enno-oduno/coding-workflow.js +0 -33
  458. package/dist/enno-oduno/coding-workflow.js.map +0 -1
  459. package/dist/enno-oduno/confirmation.d.ts +0 -4
  460. package/dist/enno-oduno/confirmation.d.ts.map +0 -1
  461. package/dist/enno-oduno/confirmation.js +0 -146
  462. package/dist/enno-oduno/confirmation.js.map +0 -1
  463. package/dist/enno-oduno/directives.d.ts +0 -10
  464. package/dist/enno-oduno/directives.d.ts.map +0 -1
  465. package/dist/enno-oduno/directives.js +0 -294
  466. package/dist/enno-oduno/directives.js.map +0 -1
  467. package/dist/enno-oduno/experts.d.ts +0 -3
  468. package/dist/enno-oduno/experts.d.ts.map +0 -1
  469. package/dist/enno-oduno/experts.js +0 -28
  470. package/dist/enno-oduno/experts.js.map +0 -1
  471. package/dist/enno-oduno/handoff.d.ts +0 -4
  472. package/dist/enno-oduno/handoff.d.ts.map +0 -1
  473. package/dist/enno-oduno/handoff.js +0 -18
  474. package/dist/enno-oduno/handoff.js.map +0 -1
  475. package/dist/enno-oduno/language.d.ts +0 -4
  476. package/dist/enno-oduno/language.d.ts.map +0 -1
  477. package/dist/enno-oduno/language.js +0 -6
  478. package/dist/enno-oduno/language.js.map +0 -1
  479. package/dist/enno-oduno/memory-focus.d.ts +0 -32
  480. package/dist/enno-oduno/memory-focus.d.ts.map +0 -1
  481. package/dist/enno-oduno/memory-focus.js +0 -87
  482. package/dist/enno-oduno/memory-focus.js.map +0 -1
  483. package/dist/enno-oduno/memory-refresh-policy.d.ts +0 -17
  484. package/dist/enno-oduno/memory-refresh-policy.d.ts.map +0 -1
  485. package/dist/enno-oduno/memory-refresh-policy.js +0 -11
  486. package/dist/enno-oduno/memory-refresh-policy.js.map +0 -1
  487. package/dist/enno-oduno/memory-verification.d.ts +0 -7
  488. package/dist/enno-oduno/memory-verification.d.ts.map +0 -1
  489. package/dist/enno-oduno/memory-verification.js +0 -59
  490. package/dist/enno-oduno/memory-verification.js.map +0 -1
  491. package/dist/enno-oduno/plan-draft.d.ts +0 -15
  492. package/dist/enno-oduno/plan-draft.d.ts.map +0 -1
  493. package/dist/enno-oduno/plan-draft.js +0 -20
  494. package/dist/enno-oduno/plan-draft.js.map +0 -1
  495. package/dist/enno-oduno/plan-recovery.d.ts +0 -44
  496. package/dist/enno-oduno/plan-recovery.d.ts.map +0 -1
  497. package/dist/enno-oduno/plan-recovery.js +0 -160
  498. package/dist/enno-oduno/plan-recovery.js.map +0 -1
  499. package/dist/enno-oduno/repository-state.d.ts +0 -10
  500. package/dist/enno-oduno/repository-state.d.ts.map +0 -1
  501. package/dist/enno-oduno/repository-state.js +0 -146
  502. package/dist/enno-oduno/repository-state.js.map +0 -1
  503. package/dist/enno-oduno/sanitize.d.ts +0 -17
  504. package/dist/enno-oduno/sanitize.d.ts.map +0 -1
  505. package/dist/enno-oduno/sanitize.js +0 -88
  506. package/dist/enno-oduno/sanitize.js.map +0 -1
  507. package/dist/enno-oduno/schemas.d.ts +0 -968
  508. package/dist/enno-oduno/schemas.d.ts.map +0 -1
  509. package/dist/enno-oduno/schemas.js +0 -622
  510. package/dist/enno-oduno/schemas.js.map +0 -1
  511. package/dist/enno-oduno/service.d.ts +0 -62
  512. package/dist/enno-oduno/service.d.ts.map +0 -1
  513. package/dist/enno-oduno/service.js +0 -1505
  514. package/dist/enno-oduno/service.js.map +0 -1
  515. package/dist/enno-oduno/skills.d.ts +0 -22
  516. package/dist/enno-oduno/skills.d.ts.map +0 -1
  517. package/dist/enno-oduno/skills.js +0 -127
  518. package/dist/enno-oduno/skills.js.map +0 -1
  519. package/dist/enno-oduno/store.d.ts +0 -109
  520. package/dist/enno-oduno/store.d.ts.map +0 -1
  521. package/dist/enno-oduno/store.js +0 -833
  522. package/dist/enno-oduno/store.js.map +0 -1
  523. package/dist/enno-oduno/types.d.ts +0 -457
  524. package/dist/enno-oduno/types.d.ts.map +0 -1
  525. package/dist/enno-oduno/types.js +0 -66
  526. package/dist/enno-oduno/types.js.map +0 -1
  527. package/dist/enno-oduno/validation-errors.d.ts +0 -93
  528. package/dist/enno-oduno/validation-errors.d.ts.map +0 -1
  529. package/dist/enno-oduno/validation-errors.js +0 -159
  530. package/dist/enno-oduno/validation-errors.js.map +0 -1
  531. package/dist/enno-oduno/verifier.d.ts +0 -16
  532. package/dist/enno-oduno/verifier.d.ts.map +0 -1
  533. package/dist/enno-oduno/verifier.js +0 -271
  534. package/dist/enno-oduno/verifier.js.map +0 -1
  535. package/docs/enno-memory-benchmark.json +0 -761
  536. package/docs/enno-memory-evaluation.md +0 -137
  537. package/docs/enno-oduno.ja.md +0 -68
  538. package/docs/enno-oduno.md +0 -94
  539. package/skills/kiokuko-enno-oduno/SKILL.md +0 -64
  540. package/skills/kiokuko-enno-oduno/enno-oduno.png +0 -0
@@ -1,1505 +0,0 @@
1
- import { runMemoryAwareVerifiers } from './memory-verification.js';
2
- import { findSecretInValue } from '../memory/secrets.js';
3
- import { advisoryContributionSchemaPublic } from './schemas.js';
4
- import { planCandidate, readPlanDraft } from './plan-draft.js';
5
- import { readExecutionSelection } from '../dsh/execution-selection.js';
6
- import { createHash } from 'node:crypto';
7
- import { withImmediateTransaction } from '../db/transaction.js';
8
- import { KiokukoError } from '../errors.js';
9
- import { assertCapabilityCatalogBinding } from '../akinator/capability-binding.js';
10
- import { normalizeCapabilityCatalog } from '../akinator/capabilities.js';
11
- import { getAkinatorStateService } from '../akinator/service.js';
12
- import { claimAgentTaskSkillDiscoveryAttempt, completeAgentTaskSkillDiscoveryAttempt, failAgentTaskSkillDiscoveryAttempt, readAgentTaskSkillDiscoveryAttempt, } from '../akinator/skill-discovery-attempt.js';
13
- import { captureProjectManifestSnapshot, resolveProjectFingerprint, } from '../repository/project-fingerprint.js';
14
- import { discoverSkills } from '../skills/discovery-service.js';
15
- import { canonicalContentHash, canonicalJson } from '../serialization/validate.js';
16
- import { sanitizeJson } from '../security/sanitize.js';
17
- import { LedgerStore } from '../ledger/store.js';
18
- import { directiveForIntake, directiveForRun } from './directives.js';
19
- import { advisoryContextForSnapshot, advisoryInputDigest, advisoryPhaseForStatus, normalizeAdvisoryContributions } from './advisory.js';
20
- import { createAdvisoryRoundInTransaction, ensureAdvisoryRoundConsumedInTransaction, readAdvisoryRound, readSubmittedAdvisoryRound, } from './advisory-store.js';
21
- import { assertWorkPlanExpertCoverage } from './experts.js';
22
- import { buildEnnoRequestHandoff } from './handoff.js';
23
- import { assertContractVerifierCwds, parseEnnoAnswer, parseAdviceRead, parseAdviceSubmission, parseFinishRequest, parseIdealSubmission, parseMeditationSubmission, parsePlanSubmission, parseVerificationPrepare, parseWorkReport, } from './schemas.js';
24
- import { completeRequiredSkillList, createSkillSetEntries, orderedUniqueSkillNames, unavailableRequiredSkills, } from './skills.js';
25
- import { appendEnnoEventInTransaction, assertExecutionLeaseInTransaction, claimExecutionLeaseInTransaction, completeOperationInTransaction, createEnnoDraft, finishVerifierRunsInTransaction, readEnnoSnapshot, readFreshFinalVerifierResults, readOperationReceipt, releaseExecutionLeaseInTransaction, renewExecutionLeaseInTransaction, resolveEnnoIdentity, replaceWorkUnitsInTransaction, setWorkUnitStatusInTransaction, startOperationInTransaction, startVerifierRunsInTransaction, operationLeaseMsForVerifiers, terminalizeLedgerRunInTransaction, updateContractInTransaction, } from './store.js';
26
- import { ENNO_APPLICABLE_TASK_TYPES, ENNO_MAX_EXTERNAL_SKILLS, ENNO_MAX_TOTAL_SKILL_QUERIES, ENNO_PROVENANCE_KEYS, } from './types.js';
27
- import { RepositoryAuditError } from './verifier.js';
28
- import { planStartRecoveryBlocker, planStartRecoveryError, planStartRecoveryReasonFromBlocker, } from './plan-recovery.js';
29
- import { ennoValidationError } from './validation-errors.js';
30
- import { captureRepositoryState } from './repository-state.js';
31
- import { saveTaskCompletionReceipt, taskCompletionBlocksClose } from '../dsh/task-completion.js';
32
- import { sanitizeEnnoAnswer, sanitizeFinishRequest, sanitizeIdealSubmission, sanitizeMeditationSubmission, sanitizePlanSubmission, sanitizeWorkReport, } from './sanitize.js';
33
- import { STANDARD_FUNCTION_SKILL_NAME, STANDARD_SOUL_SKILL_NAME, STANDARD_UI_SKILL_NAME, } from '../dsh/standard-skills.js';
34
- export function stateForSnapshot(snapshot) {
35
- let nextAction;
36
- if (snapshot.status === 'intake')
37
- nextAction = 'answer_intake';
38
- else if (snapshot.status === 'oduno_ideal')
39
- nextAction = 'submit_ideal';
40
- else if (snapshot.status === 'zenki_planning')
41
- nextAction = snapshot.planDraft?.status === 'reviewed' ? 'submit_plan' : 'review_plan';
42
- else if (snapshot.status === 'needs_confirmation')
43
- nextAction = 'ask_user_confirmation';
44
- else if (snapshot.status === 'goki_executing')
45
- nextAction = 'execute_work_unit';
46
- else if (snapshot.status === 'enno_verifying')
47
- nextAction = snapshot.finalEvidenceReady ? 'submit_final_review' : 'run_final_verification';
48
- else if (snapshot.status === 'oduno_meditation')
49
- nextAction = 'submit_meditation';
50
- else if (snapshot.status === 'blocked')
51
- nextAction = 'report_blocker';
52
- else
53
- nextAction = 'complete';
54
- const directive = directiveForRun(snapshot);
55
- return {
56
- applicable: true,
57
- status: snapshot.status,
58
- orchestrationId: snapshot.orchestrationId,
59
- dshSessionId: snapshot.dshSessionId,
60
- contractRevision: snapshot.revision,
61
- routeEpoch: snapshot.routeEpoch ?? 0,
62
- ideal: snapshot.ideal,
63
- meditation: snapshot.meditation,
64
- currentRole: directive?.role ?? null,
65
- directive,
66
- nextAction,
67
- advisoryPhaseState: snapshot.advisoryPhaseState ?? { state: 'not_started' },
68
- };
69
- }
70
- function intakeEnnoState(input) {
71
- const directive = directiveForIntake(input);
72
- return {
73
- applicable: true,
74
- status: 'intake',
75
- orchestrationId: input.orchestrationId,
76
- dshSessionId: input.dshSessionId,
77
- contractRevision: null,
78
- routeEpoch: null,
79
- ideal: null,
80
- meditation: null,
81
- currentRole: 'enno-oduno',
82
- directive,
83
- nextAction: 'answer_intake',
84
- advisoryPhaseState: { state: 'not_started' },
85
- };
86
- }
87
- export function inapplicableEnnoState() {
88
- return {
89
- applicable: false,
90
- status: 'intake',
91
- orchestrationId: null,
92
- dshSessionId: null,
93
- contractRevision: null,
94
- routeEpoch: null,
95
- ideal: null,
96
- meditation: null,
97
- currentRole: null,
98
- directive: null,
99
- nextAction: 'complete',
100
- advisoryPhaseState: { state: 'not_started' },
101
- };
102
- }
103
- export function ennoStateForPreparedTask(database, prepared, dshSessionId) {
104
- const execution = readExecutionSelection(database, prepared.run.runId)?.value;
105
- if (execution && (execution.mode !== 'enno' || execution.status !== 'ready'))
106
- return inapplicableEnnoState();
107
- const taskType = prepared.intake.profile.taskType;
108
- if (prepared.intake.status === 'needs_answer' && taskType === null) {
109
- return intakeEnnoState({
110
- runId: prepared.run.runId,
111
- orchestrationId: prepared.intake.sessionId,
112
- dshSessionId,
113
- question: prepared.intake.question,
114
- });
115
- }
116
- if (taskType === null || !ENNO_APPLICABLE_TASK_TYPES.includes(taskType)) {
117
- return inapplicableEnnoState();
118
- }
119
- if (prepared.intake.status === 'needs_answer') {
120
- return intakeEnnoState({
121
- runId: prepared.run.runId,
122
- orchestrationId: prepared.intake.sessionId,
123
- dshSessionId,
124
- question: prepared.intake.question,
125
- });
126
- }
127
- const handoff = buildEnnoRequestHandoff(prepared.intake.profile, prepared.intake.reasoning);
128
- const snapshot = createEnnoDraft(database, {
129
- runId: prepared.run.runId,
130
- workspace: prepared.project.workspace,
131
- orchestrationId: prepared.intake.sessionId,
132
- repositoryRoot: prepared.project.repositoryRoot,
133
- taskType: taskType,
134
- taskTarget: prepared.intake.profile.target,
135
- taskExpected: prepared.intake.profile.expected,
136
- handoff,
137
- skillDiscovery: prepared.skillDiscovery,
138
- dshSessionId,
139
- });
140
- return stateForSnapshot(snapshot);
141
- }
142
- function operationIdentity(operation, idempotencyKey, input) {
143
- const semanticInput = typeof input === 'object' && input !== null && !Array.isArray(input)
144
- ? Object.fromEntries(Object.entries(input)
145
- .filter(([key]) => !['workspace', 'orchestrationId', 'resumeToken', 'idempotencyKey'].includes(key)))
146
- : input;
147
- return {
148
- operation,
149
- idempotencyKey,
150
- requestDigest: canonicalContentHash({ version: 1, operation, input: semanticInput }),
151
- };
152
- }
153
- function advisoryContextForSubmission(snapshot, phase) {
154
- if (advisoryPhaseForStatus(snapshot.status) !== phase
155
- || (phase === 'final_review' && !snapshot.finalEvidenceReady)) {
156
- throw new KiokukoError('CONFLICT', 'Advisory round is not valid for the current Enno phase');
157
- }
158
- return advisoryContextForSnapshot(snapshot, phase);
159
- }
160
- function assertAdvisoryRoundInput(snapshot, phase, mutationRevision, context, inputDigest, validationOperation) {
161
- if (snapshot.mutationRevision !== mutationRevision) {
162
- throw new KiokukoError('CONFLICT', 'Enno mutation revision changed');
163
- }
164
- const expectedContext = advisoryContextForSubmission(snapshot, phase);
165
- if (canonicalJson(expectedContext) !== canonicalJson(context)) {
166
- throw new KiokukoError('CONFLICT', 'Advisory context does not match the current Enno phase');
167
- }
168
- const expectedDigest = advisoryInputDigest({
169
- phase,
170
- contractRevision: snapshot.revision,
171
- mutationRevision,
172
- allowlistedContext: context,
173
- });
174
- if (expectedDigest !== inputDigest) {
175
- if (validationOperation !== undefined) {
176
- throw ennoValidationError(validationOperation, [{
177
- path: ['advisoryRoundDigest'],
178
- reasonCode: 'advisory_digest_stale',
179
- }], 'refresh_state');
180
- }
181
- throw new KiokukoError('CONFLICT', 'Advisory round digest does not match the current contract');
182
- }
183
- }
184
- function requireAdvisoryRound(database, snapshot, phase, mutationRevision, context, inputDigest) {
185
- const operation = phase === 'planning' ? 'plan_submit' : phase === 'ideal' ? 'ideal_submit' : 'finish';
186
- assertAdvisoryRoundInput(snapshot, phase, mutationRevision, context, inputDigest, operation);
187
- const round = readAdvisoryRound(database, {
188
- runId: snapshot.runId,
189
- contractRevision: snapshot.revision,
190
- mutationRevision,
191
- phase,
192
- inputDigest,
193
- });
194
- if (round === undefined)
195
- throw new KiokukoError('CONFLICT', 'Required advisory round was not submitted');
196
- }
197
- function assertDispositionCoversRound(operation, round, dispositions) {
198
- const expected = new Set(round.contributions.map((contribution) => contribution.slotId));
199
- const covered = new Set();
200
- for (const [index, disposition] of dispositions.entries()) {
201
- if (!expected.has(disposition.slotId)) {
202
- throw ennoValidationError(operation, [{
203
- path: ['advisoryDisposition', index, 'slotId'],
204
- reasonCode: 'advisory_slot_missing',
205
- expected: { requiredSlotIds: [...expected] },
206
- }]);
207
- }
208
- if (covered.has(disposition.slotId)) {
209
- throw ennoValidationError(operation, [{
210
- path: ['advisoryDisposition', index, 'slotId'],
211
- reasonCode: 'advisory_slot_duplicate',
212
- expected: { requiredSlotIds: [...expected] },
213
- }]);
214
- }
215
- const contribution = round.contributions.find((item) => item.slotId === disposition.slotId);
216
- const compatible = contribution.outcome === 'completed'
217
- ? disposition.disposition === 'adopted' || disposition.disposition === 'not_adopted'
218
- : disposition.disposition === 'unavailable';
219
- if (!compatible) {
220
- throw ennoValidationError(operation, [{
221
- path: ['advisoryDisposition', index, 'disposition'],
222
- reasonCode: 'invalid_enum',
223
- expected: { allowedValues: contribution.outcome === 'completed' ? ['adopted', 'not_adopted'] : ['unavailable'] },
224
- }]);
225
- }
226
- covered.add(disposition.slotId);
227
- }
228
- for (const slotId of expected) {
229
- if (!covered.has(slotId)) {
230
- throw ennoValidationError(operation, [{
231
- path: ['advisoryDisposition'],
232
- reasonCode: 'advisory_slot_missing',
233
- expected: { requiredSlotIds: [...expected] },
234
- }]);
235
- }
236
- }
237
- }
238
- function consumeAdvisoryRoundIfPresent(database, snapshot, phase, mutationRevision, context, inputDigest, disposition) {
239
- if (inputDigest === undefined) {
240
- const submitted = readSubmittedAdvisoryRound(database, {
241
- runId: snapshot.runId,
242
- contractRevision: snapshot.revision,
243
- mutationRevision,
244
- phase,
245
- });
246
- if (submitted !== undefined) {
247
- throw ennoValidationError(phase === 'planning' ? 'plan_submit' : phase === 'ideal' ? 'ideal_submit' : 'finish', [{
248
- path: ['advisoryRoundDigest'],
249
- reasonCode: 'advisory_consumption_required',
250
- expected: { requiredSlotIds: submitted.contributions.map((item) => item.slotId) },
251
- }]);
252
- }
253
- return undefined;
254
- }
255
- if (context === undefined) {
256
- throw new KiokukoError('CONFLICT', 'Advisory round is not valid for the current Enno phase');
257
- }
258
- const operation = phase === 'planning' ? 'plan_submit' : phase === 'ideal' ? 'ideal_submit' : 'finish';
259
- assertAdvisoryRoundInput(snapshot, phase, mutationRevision, context, inputDigest, operation);
260
- const dispositions = disposition ?? [];
261
- if (dispositions.length === 0) {
262
- throw ennoValidationError(phase === 'planning' ? 'plan_submit' : phase === 'ideal' ? 'ideal_submit' : 'finish', [{
263
- path: ['advisoryDisposition'],
264
- reasonCode: 'advisory_digest_requires_disposition',
265
- }]);
266
- }
267
- const pendingRound = readAdvisoryRound(database, {
268
- runId: snapshot.runId,
269
- contractRevision: snapshot.revision,
270
- mutationRevision,
271
- phase,
272
- inputDigest,
273
- });
274
- if (pendingRound === undefined)
275
- throw new KiokukoError('CONFLICT', 'Required advisory round was not submitted');
276
- assertDispositionCoversRound(operation, pendingRound, dispositions);
277
- const round = ensureAdvisoryRoundConsumedInTransaction(database, {
278
- runId: snapshot.runId,
279
- contractRevision: snapshot.revision,
280
- mutationRevision,
281
- phase,
282
- inputDigest,
283
- });
284
- appendEnnoEventInTransaction(database, snapshot.runId, 'enno.advice_disposition', 'enno-oduno', 'recorded', {
285
- phase,
286
- contractRevision: snapshot.revision,
287
- mutationRevision,
288
- inputDigest,
289
- dispositions: dispositions.map((entry) => ({ slotId: entry.slotId, disposition: entry.disposition, rationale: entry.rationale })),
290
- });
291
- return round;
292
- }
293
- export function submitEnnoAdvice(database, rawInput) {
294
- const parsedInput = parseAdviceSubmission(rawInput);
295
- const input = {
296
- ...parsedInput,
297
- contributions: normalizeAdvisoryContributions(parsedInput.phase, parsedInput.contributions),
298
- };
299
- const before = readEnnoSnapshot(database, identity(database, input));
300
- const operation = operationIdentity('advice_submit', input.idempotencyKey, input);
301
- const replay = readOperationReceipt(database, input.runId, operation);
302
- if (replay !== undefined)
303
- return replay;
304
- const expectedPhase = advisoryPhaseForStatus(before.status);
305
- if (expectedPhase !== input.phase)
306
- throw new KiokukoError('CONFLICT', 'Advisory phase does not match the current Enno state');
307
- const context = input.allowlistedContext;
308
- const inputDigest = advisoryInputDigest({
309
- phase: input.phase,
310
- contractRevision: before.revision,
311
- mutationRevision: input.mutationRevision,
312
- allowlistedContext: context,
313
- });
314
- return withImmediateTransaction(database, () => {
315
- const replayed = readOperationReceipt(database, input.runId, operation);
316
- if (replayed !== undefined)
317
- return replayed;
318
- const current = readEnnoSnapshot(database, identity(database, input));
319
- assertExpected(current, input.expectedRevision, [
320
- input.phase === 'ideal' ? 'oduno_ideal' : input.phase === 'planning' ? 'zenki_planning' : 'enno_verifying',
321
- ]);
322
- assertAdvisoryRoundInput(current, input.phase, input.mutationRevision, context, inputDigest);
323
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
324
- const existing = readAdvisoryRound(database, {
325
- runId: input.runId,
326
- contractRevision: current.revision,
327
- mutationRevision: input.mutationRevision,
328
- phase: input.phase,
329
- inputDigest,
330
- });
331
- let round;
332
- if (existing !== undefined) {
333
- const incoming = normalizeAdvisoryContributions(input.phase, input.contributions);
334
- if (canonicalJson(existing.contributions) !== canonicalJson(incoming)) {
335
- throw new KiokukoError('CONFLICT', 'Advisory round was already submitted with different contributions');
336
- }
337
- round = existing;
338
- }
339
- else {
340
- round = createAdvisoryRoundInTransaction(database, {
341
- runId: input.runId,
342
- contractRevision: current.revision,
343
- mutationRevision: input.mutationRevision,
344
- phase: input.phase,
345
- inputDigest,
346
- contributions: input.contributions,
347
- });
348
- }
349
- appendEnnoEventInTransaction(database, input.runId, 'enno.advice_submitted', 'enno-oduno', 'aggregated', {
350
- phase: input.phase,
351
- contractRevision: current.revision,
352
- mutationRevision: input.mutationRevision,
353
- inputDigest,
354
- degraded: round.degraded,
355
- });
356
- const response = {
357
- ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))),
358
- advisoryRound: round,
359
- };
360
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
361
- return response;
362
- });
363
- }
364
- export function readPendingEnnoAdvice(database, rawInput) {
365
- const input = parseAdviceRead(rawInput);
366
- const snapshot = readEnnoSnapshot(database, identity(database, input));
367
- if (snapshot.revision !== input.expectedRevision) {
368
- throw new KiokukoError('CONFLICT', 'Enno contract revision changed');
369
- }
370
- const phase = advisoryPhaseForStatus(snapshot.status);
371
- if (phase === null || (phase === 'final_review' && !snapshot.finalEvidenceReady)) {
372
- throw new KiokukoError('CONFLICT', 'Advisory round is not valid for the current Enno phase');
373
- }
374
- if (snapshot.advisoryPhaseState?.state !== 'aggregated') {
375
- throw new KiokukoError('CONFLICT', 'Required advisory round is not aggregated');
376
- }
377
- if (snapshot.advisoryPhaseState.inputDigest !== input.advisoryRoundDigest) {
378
- throw ennoValidationError('advice_read', [{
379
- path: ['advisoryRoundDigest'],
380
- reasonCode: 'advisory_digest_stale',
381
- }], 'refresh_state');
382
- }
383
- const allowlistedContext = advisoryContextForSnapshot(snapshot, phase);
384
- const expectedDigest = advisoryInputDigest({
385
- phase,
386
- contractRevision: snapshot.revision,
387
- mutationRevision: snapshot.mutationRevision,
388
- allowlistedContext,
389
- });
390
- if (expectedDigest !== input.advisoryRoundDigest) {
391
- throw ennoValidationError('advice_read', [{
392
- path: ['advisoryRoundDigest'],
393
- reasonCode: 'advisory_digest_stale',
394
- }], 'refresh_state');
395
- }
396
- const advisoryRound = readAdvisoryRound(database, {
397
- runId: snapshot.runId,
398
- contractRevision: snapshot.revision,
399
- mutationRevision: snapshot.mutationRevision,
400
- phase,
401
- inputDigest: input.advisoryRoundDigest,
402
- });
403
- if (advisoryRound === undefined) {
404
- throw new KiokukoError('INTEGRITY_ERROR', 'Stored pending advisory round is missing');
405
- }
406
- if (advisoryRound.state !== 'aggregated') {
407
- throw new KiokukoError('CONFLICT', 'Advisory round is no longer pending');
408
- }
409
- return {
410
- protocolVersion: 1,
411
- advisoryRound,
412
- allowlistedContext,
413
- };
414
- }
415
- function identity(database, input) {
416
- return resolveEnnoIdentity(database, input);
417
- }
418
- function assertExpected(snapshot, expectedRevision, statuses) {
419
- if (snapshot.revision !== expectedRevision)
420
- throw new KiokukoError('CONFLICT', 'Enno contract revision changed');
421
- if (!statuses.includes(snapshot.status))
422
- throw new KiokukoError('CONFLICT', 'Enno run is not in the required state');
423
- }
424
- function firstReadyUnit(snapshot) {
425
- const completed = new Set(snapshot.workUnits.filter((unit) => unit.status === 'completed').map((unit) => unit.workUnit.id));
426
- return snapshot.workUnits.find((unit) => unit.status === 'pending'
427
- && unit.workUnit.dependencies.every((dependency) => completed.has(dependency)));
428
- }
429
- function startFirstReadyUnit(database, snapshot) {
430
- const next = firstReadyUnit(snapshot);
431
- if (next === undefined) {
432
- if (snapshot.workUnits.every((unit) => unit.status === 'completed'))
433
- return undefined;
434
- throw new KiokukoError('CONFLICT', 'Enno WorkPlan dependencies cannot advance');
435
- }
436
- setWorkUnitStatusInTransaction(database, {
437
- runId: snapshot.runId,
438
- contractRevision: snapshot.revision,
439
- workUnitId: next.workUnit.id,
440
- from: 'pending',
441
- to: 'in_progress',
442
- });
443
- appendEnnoEventInTransaction(database, snapshot.runId, 'goki.work_started', 'goki', 'started', {
444
- workUnitId: next.workUnit.id,
445
- contractRevision: snapshot.revision,
446
- });
447
- if (snapshot.dshSessionId === null)
448
- return undefined;
449
- return claimExecutionLeaseInTransaction(database, snapshot, next.workUnit.id, {
450
- dshSessionId: snapshot.dshSessionId,
451
- });
452
- }
453
- function requiresConfirmation(provenance) {
454
- return ENNO_PROVENANCE_KEYS.some((key) => provenance[key] !== 'explicit_user');
455
- }
456
- async function readRunTaskContext(database, snapshot) {
457
- const row = database.prepare(`
458
- SELECT r.repository_id AS repositoryId, ri.session_id AS sessionId
459
- FROM repositories AS r
460
- JOIN repository_locations AS l ON l.repository_id = r.repository_id
461
- JOIN run_intakes AS ri ON ri.run_id = ?
462
- WHERE r.workspace = ? AND l.canonical_root = ?
463
- LIMIT 1
464
- `).get(snapshot.runId, snapshot.workspace, snapshot.repositoryRoot);
465
- if (row === undefined)
466
- throw new KiokukoError('CONFLICT', 'Enno repository or intake binding changed');
467
- const context = await getAkinatorStateService(database, {
468
- workspace: snapshot.workspace,
469
- sessionId: row.sessionId,
470
- });
471
- const project = {
472
- workspace: snapshot.workspace,
473
- repositoryRoot: snapshot.repositoryRoot,
474
- repositoryId: row.repositoryId,
475
- source: 'location',
476
- };
477
- const manifest = captureProjectManifestSnapshot(project);
478
- return {
479
- project,
480
- fingerprint: resolveProjectFingerprint(database, project, manifest),
481
- task: context.session.task,
482
- profile: context.session.profile,
483
- recommendedTags: context.recommendedTags,
484
- };
485
- }
486
- function emptyDiscovery(mode) {
487
- return { attempted: false, mode, requirements: [], queries: [], cacheHits: 0, candidates: 0, selected: [], failures: [] };
488
- }
489
- async function discoverZenkiSkills(database, snapshot, plan, dependencies) {
490
- const intake = snapshot.contract.skillSet.intakeDiscovery;
491
- if (intake.mode === 'off')
492
- return emptyDiscovery(intake.mode);
493
- const context = await readRunTaskContext(database, snapshot);
494
- const attempt = {
495
- runId: snapshot.runId,
496
- phase: 'zenki',
497
- mode: intake.mode,
498
- requestDigest: canonicalContentHash({
499
- version: 2,
500
- runId: snapshot.runId,
501
- revision: snapshot.revision,
502
- mode: intake.mode,
503
- workPlan: plan.workPlan,
504
- capabilities: plan.capabilities ?? null,
505
- skillRequirements: plan.skillRequirements,
506
- }),
507
- };
508
- const replay = readAgentTaskSkillDiscoveryAttempt(database, attempt);
509
- if (replay !== undefined)
510
- return replay.summary;
511
- const claimed = claimAgentTaskSkillDiscoveryAttempt(database, attempt, {
512
- queryBudget: ENNO_MAX_TOTAL_SKILL_QUERIES,
513
- selectionBudget: ENNO_MAX_EXTERNAL_SKILLS,
514
- });
515
- if (claimed.kind === 'replay')
516
- return claimed.summary;
517
- if (claimed.queryBudget === 0 || claimed.selectionBudget === 0) {
518
- return completeAgentTaskSkillDiscoveryAttempt(database, attempt, emptyDiscovery(intake.mode), () => {
519
- assertExpected(readEnnoSnapshot(database, identity(database, plan)), plan.expectedRevision, ['zenki_planning']);
520
- });
521
- }
522
- try {
523
- const summary = await (dependencies.discoverSkills ?? discoverSkills)(database, {
524
- ...context,
525
- task: `${context.task}\n${plan.workPlan.objective}`,
526
- capabilities: plan.capabilities,
527
- mode: intake.mode,
528
- maxQueries: claimed.queryBudget,
529
- maxSelectedSkills: claimed.selectionBudget,
530
- ...(dependencies.fetchImpl === undefined ? {} : { fetchImpl: dependencies.fetchImpl }),
531
- }, {
532
- ...(dependencies.fetchImpl === undefined ? {} : { fetchImpl: dependencies.fetchImpl }),
533
- assertBeforePersist: () => assertExpected(readEnnoSnapshot(database, identity(database, plan)), plan.expectedRevision, ['zenki_planning']),
534
- });
535
- return completeAgentTaskSkillDiscoveryAttempt(database, attempt, summary, () => {
536
- assertExpected(readEnnoSnapshot(database, identity(database, plan)), plan.expectedRevision, ['zenki_planning']);
537
- });
538
- }
539
- catch (error) {
540
- failAgentTaskSkillDiscoveryAttempt(database, attempt, error);
541
- }
542
- }
543
- function planChangesCode(plan, taskType) {
544
- return plan.workPlan.units.some((unit) => unit.routes.includes('code') || unit.routes.includes('ui'))
545
- || (taskType !== 'review' && plan.skillRequirements.some((skill) => skill.purposes.includes('implementation')));
546
- }
547
- function planHasUi(plan) {
548
- return plan.workPlan.units.some((unit) => unit.routes.includes('ui'));
549
- }
550
- function assertIdealSkillCoverage(snapshot, ideal) {
551
- const expected = snapshot.contract.skillSet.intakeDiscovery.selected.map((skill) => skill.name);
552
- if (new Set(expected).size !== expected.length) {
553
- throw new KiokukoError('INTEGRITY_ERROR', 'Akinator-discovered Skill identities are inconsistent');
554
- }
555
- const actual = ideal.skillContributions.map((contribution) => contribution.skillName);
556
- if (actual.length !== expected.length || expected.some((name) => !actual.includes(name))) {
557
- throw ennoValidationError('ideal_submit', [{
558
- path: ['ideal', 'skillContributions'],
559
- reasonCode: actual.length < expected.length ? 'too_few_items' : 'undeclared_skill',
560
- expected: { minItems: expected.length, maxItems: expected.length, allowedValues: expected },
561
- }]);
562
- }
563
- }
564
- function planCapabilityRecoveryReason(database, input, workspace) {
565
- if (input.capabilities === undefined)
566
- return 'environment_information_missing';
567
- const run = new LedgerStore(database).readRun(input.runId, workspace);
568
- if (run === undefined)
569
- throw new KiokukoError('INTEGRITY_ERROR', 'Enno ledger run disappeared during plan validation');
570
- try {
571
- assertCapabilityCatalogBinding(run.metadata, input.capabilities);
572
- return null;
573
- }
574
- catch (error) {
575
- if (error instanceof KiokukoError && error.code === 'CONFLICT') {
576
- return 'environment_changed';
577
- }
578
- throw error;
579
- }
580
- }
581
- function pausePlanStartRecovery(database, snapshot, reason) {
582
- withImmediateTransaction(database, () => {
583
- const updated = database.prepare(`
584
- UPDATE enno_contracts
585
- SET blocker = ?, updated_at = ?
586
- WHERE run_id = ? AND revision = ? AND status = 'zenki_planning'
587
- RETURNING run_id AS runId
588
- `).get(planStartRecoveryBlocker(reason), new Date().toISOString(), snapshot.runId, snapshot.revision);
589
- if (updated?.runId !== snapshot.runId)
590
- throw new KiokukoError('CONFLICT', 'Enno plan state changed concurrently');
591
- });
592
- throw planStartRecoveryError(reason);
593
- }
594
- function endedBeforeWorkBecausePlanCatalogWasLost(database, snapshot, capabilities) {
595
- if (capabilities === undefined
596
- || snapshot.status !== 'blocked'
597
- || snapshot.blocker?.startsWith('Required Skills unavailable:') !== true
598
- || snapshot.workUnits.length === 0
599
- || snapshot.workUnits.some((unit) => unit.status !== 'pending'))
600
- return false;
601
- const soulEntry = snapshot.contract.skillSet.entries.find((entry) => (entry.name.normalize('NFKC').toLowerCase() === STANDARD_SOUL_SKILL_NAME));
602
- if (soulEntry?.required !== true || soulEntry.availability !== 'unavailable')
603
- return false;
604
- const catalog = normalizeCapabilityCatalog(capabilities);
605
- if (!catalog.skills.some((skill) => skill.name.normalize('NFKC').toLowerCase() === STANDARD_SOUL_SKILL_NAME)) {
606
- return false;
607
- }
608
- const run = new LedgerStore(database).readRun(snapshot.runId, snapshot.workspace);
609
- if (run === undefined)
610
- return false;
611
- try {
612
- assertCapabilityCatalogBinding(run.metadata, capabilities);
613
- return true;
614
- }
615
- catch (error) {
616
- if (error instanceof KiokukoError && error.code === 'CONFLICT')
617
- return false;
618
- throw error;
619
- }
620
- }
621
- export function submitOdunoIdeal(database, rawInput) {
622
- const parsedInput = parseIdealSubmission(rawInput);
623
- const before = readEnnoSnapshot(database, identity(database, parsedInput));
624
- const input = sanitizeIdealSubmission(parsedInput, before.repositoryRoot);
625
- const operation = operationIdentity('ideal_submit', input.idempotencyKey, input);
626
- const replay = readOperationReceipt(database, input.runId, operation);
627
- if (replay !== undefined)
628
- return replay;
629
- assertExpected(before, input.expectedRevision, ['oduno_ideal']);
630
- if (input.advisoryRoundDigest !== undefined) {
631
- requireAdvisoryRound(database, before, 'ideal', before.mutationRevision, advisoryContextForSubmission(before, 'ideal'), input.advisoryRoundDigest);
632
- }
633
- const ideal = input.ideal;
634
- assertIdealSkillCoverage(before, ideal);
635
- return withImmediateTransaction(database, () => {
636
- const replayed = readOperationReceipt(database, input.runId, operation);
637
- if (replayed !== undefined)
638
- return replayed;
639
- const current = readEnnoSnapshot(database, identity(database, input));
640
- assertExpected(current, input.expectedRevision, ['oduno_ideal']);
641
- assertIdealSkillCoverage(current, ideal);
642
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
643
- const advisoryRound = consumeAdvisoryRoundIfPresent(database, current, 'ideal', current.mutationRevision, advisoryContextForSubmission(current, 'ideal'), input.advisoryRoundDigest, input.advisoryDisposition);
644
- updateContractInTransaction(database, current, {
645
- contract: current.contract,
646
- status: 'zenki_planning',
647
- confirmationState: current.confirmationState,
648
- ideal,
649
- });
650
- appendEnnoEventInTransaction(database, input.runId, 'oduno.ideal_derived', 'enno-oduno', 'derived', {
651
- contractRevision: current.revision,
652
- discoveredSkillCount: ideal.skillContributions.length,
653
- principleCount: ideal.principles.length,
654
- successSignalCount: ideal.successSignals.length,
655
- });
656
- const response = {
657
- ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))),
658
- ...(advisoryRound === undefined ? {} : { advisoryRound }),
659
- };
660
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
661
- return response;
662
- });
663
- }
664
- function assertReviewedPlan(database, snapshot, input) {
665
- const draft = readPlanDraft(database, snapshot);
666
- if (!draft || draft.status !== 'reviewed' || draft.digest !== canonicalContentHash(planCandidate(input))
667
- || draft.catalogDigest !== canonicalContentHash(input.capabilities ?? []) || !draft.reviewDigest || input.advisoryRoundDigest !== draft.reviewDigest) {
668
- throw new KiokukoError('CONFLICT', 'Review the exact current candidate with enno_plan_review before submission. Changed drafts require another review.');
669
- }
670
- }
671
- /** Host-only reviewer dependency has no execution or approval authority. */
672
- export async function reviewEnnoPlan(database, rawInput, review, signal, assertCurrent = async () => { }) {
673
- signal.throwIfAborted();
674
- const parsed = parsePlanSubmission(rawInput);
675
- const before = readEnnoSnapshot(database, identity(database, parsed));
676
- assertExpected(before, parsed.expectedRevision, ['zenki_planning']);
677
- const input = sanitizePlanSubmission(parsed, before.repositoryRoot);
678
- const recovery = planCapabilityRecoveryReason(database, input, before.workspace);
679
- if (recovery !== null)
680
- pausePlanStartRecovery(database, before, recovery);
681
- assertWorkPlanExpertCoverage(input.workPlan);
682
- assertContractVerifierCwds(before.repositoryRoot, { workPlan: input.workPlan, finalVerifiers: input.finalVerifiers });
683
- const candidate = planCandidate(input), digest = canonicalContentHash(candidate), catalogDigest = canonicalContentHash(input.capabilities ?? []);
684
- if (findSecretInValue(candidate) !== undefined)
685
- throw new KiokukoError('VALIDATION_ERROR', 'Plan review contains unsafe evidence');
686
- const existing = readPlanDraft(database, before);
687
- if (existing?.status === 'reviewed' && existing.digest === digest && existing.catalogDigest === catalogDigest) {
688
- return { ennoOduno: stateForSnapshot(before), advisoryRound: readAdvisoryRound(database, { runId: before.runId, contractRevision: before.revision, mutationRevision: before.mutationRevision, phase: 'planning', inputDigest: existing.reviewDigest }) };
689
- }
690
- const draftRevision = withImmediateTransaction(database, () => {
691
- const current = readEnnoSnapshot(database, identity(database, input));
692
- assertExpected(current, input.expectedRevision, ['zenki_planning']);
693
- if (current.mutationRevision !== before.mutationRevision)
694
- throw new KiokukoError('CONFLICT', 'Plan review mutation binding changed');
695
- const revision = (readPlanDraft(database, current)?.revision ?? 0) + 1;
696
- database.prepare(`INSERT INTO enno_plan_drafts (run_id,contract_revision,mutation_revision,draft_revision,candidate_json,draft_digest,catalog_digest,catalog_json,status)
697
- VALUES (?,?,?,?,?,?,?,?,'reviewing') ON CONFLICT(run_id) DO UPDATE SET contract_revision=excluded.contract_revision,mutation_revision=excluded.mutation_revision,draft_revision=excluded.draft_revision,candidate_json=excluded.candidate_json,draft_digest=excluded.draft_digest,catalog_digest=excluded.catalog_digest,catalog_json=excluded.catalog_json,review_digest=NULL,backend_json=NULL,status='reviewing'`)
698
- .run(before.runId, before.revision, before.mutationRevision, revision, canonicalJson(candidate), digest, catalogDigest, canonicalJson((input.capabilities ?? []).filter((c) => typeof c === 'object' && c !== null && c.kind === 'skill' && typeof c.name === 'string').map(c => c.name)));
699
- return revision;
700
- });
701
- try {
702
- const context = advisoryContextForSubmission(readEnnoSnapshot(database, identity(database, input)), 'planning');
703
- const result = await review(context, signal);
704
- signal.throwIfAborted();
705
- await assertCurrent();
706
- signal.throwIfAborted();
707
- if (findSecretInValue(result.backend) !== undefined || Buffer.byteLength(canonicalJson(result.backend)) > 8192)
708
- throw new KiokukoError('VALIDATION_ERROR', 'Unsafe plan review metadata');
709
- const normalized = normalizeAdvisoryContributions('planning', result.contributions.map(c => advisoryContributionSchemaPublic.parse(c)));
710
- if (result.contributions.length !== 3 || normalized.some(c => c.outcome !== 'completed'))
711
- throw new KiokukoError('SERVICE_UNAVAILABLE', 'The complete plan review is unavailable. The draft remains unsubmitted.');
712
- return withImmediateTransaction(database, () => {
713
- signal.throwIfAborted();
714
- const current = readEnnoSnapshot(database, identity(database, input));
715
- assertExpected(current, input.expectedRevision, ['zenki_planning']);
716
- const draft = readPlanDraft(database, current);
717
- if (current.mutationRevision !== before.mutationRevision || draft?.revision !== draftRevision || draft.digest !== digest || draft.catalogDigest !== catalogDigest || draft.status !== 'reviewing')
718
- throw new KiokukoError('CONFLICT', 'Plan review was superseded');
719
- const reviewDigest = advisoryInputDigest({ phase: 'planning', contractRevision: before.revision, mutationRevision: before.mutationRevision, allowlistedContext: context });
720
- database.prepare("UPDATE enno_plan_drafts SET status='reviewed',review_digest=?,backend_json=? WHERE run_id=?").run(reviewDigest, canonicalJson(result.backend), before.runId);
721
- const roundIdentity = { runId: before.runId, contractRevision: before.revision, mutationRevision: before.mutationRevision, phase: 'planning', inputDigest: reviewDigest };
722
- const round = readAdvisoryRound(database, roundIdentity) ?? createAdvisoryRoundInTransaction(database, { ...roundIdentity, contributions: normalized });
723
- appendEnnoEventInTransaction(database, input.runId, 'enno.advice_submitted', 'zenki', 'aggregated', { draftDigest: digest, reviewDigest, draftRevision });
724
- return { ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))), advisoryRound: round };
725
- });
726
- }
727
- catch (error) {
728
- database.prepare("UPDATE enno_plan_drafts SET status='failed' WHERE run_id=? AND contract_revision=? AND mutation_revision=? AND draft_revision=? AND draft_digest=? AND status='reviewing'").run(before.runId, before.revision, before.mutationRevision, draftRevision, digest);
729
- throw error;
730
- }
731
- }
732
- export async function submitEnnoPlan(database, rawInput, dependencies = {}) {
733
- const parsedInput = parsePlanSubmission(rawInput);
734
- const current = readEnnoSnapshot(database, identity(database, parsedInput));
735
- const input = sanitizePlanSubmission(parsedInput, current.repositoryRoot);
736
- if (endedBeforeWorkBecausePlanCatalogWasLost(database, current, input.capabilities)) {
737
- throw planStartRecoveryError('previous_attempt_ended');
738
- }
739
- const operation = operationIdentity('plan_submit', input.idempotencyKey, input);
740
- const replay = readOperationReceipt(database, input.runId, operation);
741
- if (replay !== undefined)
742
- return replay;
743
- const before = current;
744
- assertExpected(before, input.expectedRevision, ['zenki_planning']);
745
- const pendingRecovery = planStartRecoveryReasonFromBlocker(before.blocker);
746
- if (pendingRecovery === 'environment_information_missing') {
747
- if (input.recoveryAction === undefined)
748
- throw planStartRecoveryError(pendingRecovery);
749
- }
750
- else if (pendingRecovery !== null) {
751
- throw planStartRecoveryError(pendingRecovery);
752
- }
753
- else if (input.recoveryAction !== undefined) {
754
- throw new KiokukoError('CONFLICT', 'Enno plan has no pending same-run recovery choice');
755
- }
756
- if (input.maxAttempts <= before.attempts) {
757
- throw ennoValidationError('plan_submit', [{
758
- path: ['maxAttempts'],
759
- reasonCode: 'too_few_items',
760
- expected: { minItems: before.attempts + 1 },
761
- }]);
762
- }
763
- if (before.planDraft)
764
- assertReviewedPlan(database, before, input);
765
- const recoveryReason = planCapabilityRecoveryReason(database, input, before.workspace);
766
- if (recoveryReason !== null)
767
- pausePlanStartRecovery(database, before, recoveryReason);
768
- if (input.advisoryRoundDigest !== undefined) {
769
- requireAdvisoryRound(database, before, 'planning', before.mutationRevision, advisoryContextForSubmission(before, 'planning'), input.advisoryRoundDigest);
770
- }
771
- assertReviewedPlan(database, before, input);
772
- const includesCodeChanges = planChangesCode(input, before.taskType);
773
- const includesUiWork = planHasUi(input);
774
- assertWorkPlanExpertCoverage(input.workPlan);
775
- assertContractVerifierCwds(before.repositoryRoot, {
776
- workPlan: input.workPlan,
777
- finalVerifiers: input.finalVerifiers,
778
- });
779
- const zenkiDiscovery = await discoverZenkiSkills(database, before, input, dependencies);
780
- const requirements = completeRequiredSkillList({
781
- requested: input.skillRequirements,
782
- includesCodeChanges,
783
- includesUiWork,
784
- });
785
- const entries = createSkillSetEntries(database, {
786
- requirements,
787
- capabilities: input.capabilities,
788
- discoveries: [before.contract.skillSet.intakeDiscovery, zenkiDiscovery],
789
- });
790
- const unavailable = unavailableRequiredSkills(entries);
791
- const nextRevision = input.expectedRevision + 1;
792
- const contract = {
793
- revision: nextRevision,
794
- scope: [...input.scope],
795
- exclusions: [...input.exclusions],
796
- acceptanceCriteria: input.acceptanceCriteria.map((item) => ({ ...item })),
797
- workPlan: {
798
- objective: input.workPlan.objective,
799
- units: input.workPlan.units.map((unit) => ({
800
- ...unit,
801
- scope: [...unit.scope],
802
- dependencies: [...unit.dependencies],
803
- routes: [...unit.routes],
804
- skillNames: orderedUniqueSkillNames([
805
- STANDARD_SOUL_SKILL_NAME,
806
- ...(unit.routes.includes('code') || unit.routes.includes('ui') ? [STANDARD_FUNCTION_SKILL_NAME] : []),
807
- ...(unit.routes.includes('ui') ? [STANDARD_UI_SKILL_NAME] : []),
808
- ], unit.skillNames),
809
- expertRefs: unit.expertRefs.map((reference) => ({ ...reference })),
810
- acceptanceCriteria: [...unit.acceptanceCriteria],
811
- focusedVerifiers: unit.focusedVerifiers.map((verifier) => ({ ...verifier, args: [...verifier.args] })),
812
- })),
813
- },
814
- skillSet: {
815
- entries,
816
- intakeDiscovery: before.contract.skillSet.intakeDiscovery,
817
- zenkiDiscovery,
818
- },
819
- finalVerifiers: input.finalVerifiers.map((verifier) => ({ ...verifier, args: [...verifier.args] })),
820
- maxAttempts: input.maxAttempts,
821
- provenance: { ...input.provenance },
822
- };
823
- assertContractVerifierCwds(before.repositoryRoot, contract);
824
- const needsConfirmation = requiresConfirmation(contract.provenance);
825
- return withImmediateTransaction(database, () => {
826
- const replayed = readOperationReceipt(database, input.runId, operation);
827
- if (replayed !== undefined)
828
- return replayed;
829
- const current = readEnnoSnapshot(database, identity(database, input));
830
- assertExpected(current, input.expectedRevision, ['zenki_planning']);
831
- assertReviewedPlan(database, current, input);
832
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
833
- const advisoryRound = consumeAdvisoryRoundIfPresent(database, current, 'planning', current.mutationRevision, advisoryContextForSubmission(current, 'planning'), input.advisoryRoundDigest, input.advisoryDisposition);
834
- const status = unavailable.length > 0
835
- ? 'blocked'
836
- : needsConfirmation ? 'needs_confirmation' : 'goki_executing';
837
- const blocker = unavailable.length === 0
838
- ? null
839
- : `Required Skills unavailable: ${unavailable.map((skill) => skill.name).join(', ')}`;
840
- updateContractInTransaction(database, current, {
841
- contract,
842
- status,
843
- confirmationState: needsConfirmation ? 'pending' : 'not_required',
844
- blocker,
845
- planDigest: canonicalContentHash(contract.workPlan),
846
- });
847
- database.prepare("UPDATE enno_plan_drafts SET status='submitted' WHERE run_id=?").run(input.runId);
848
- replaceWorkUnitsInTransaction(database, input.runId, nextRevision, contract.workPlan);
849
- appendEnnoEventInTransaction(database, input.runId, 'zenki.plan_created', 'zenki', 'created', {
850
- contractRevision: nextRevision,
851
- workUnitIds: contract.workPlan.units.map((unit) => unit.id),
852
- });
853
- let updated = readEnnoSnapshot(database, identity(database, input));
854
- let executionLease;
855
- if (status === 'blocked') {
856
- appendEnnoEventInTransaction(database, input.runId, 'enno.blocked', 'enno-oduno', 'blocked', {
857
- reason: blocker,
858
- contractRevision: nextRevision,
859
- });
860
- terminalizeLedgerRunInTransaction(database, input.runId, 'failed');
861
- }
862
- else if (status === 'goki_executing') {
863
- appendEnnoEventInTransaction(database, input.runId, 'enno.plan_confirmed', 'enno-oduno', 'not_required', {
864
- contractRevision: nextRevision,
865
- });
866
- executionLease = startFirstReadyUnit(database, updated);
867
- updated = readEnnoSnapshot(database, identity(database, input));
868
- }
869
- const response = {
870
- ennoOduno: stateForSnapshot(updated),
871
- ...(advisoryRound === undefined ? {} : { advisoryRound }),
872
- ...(executionLease === undefined ? {} : { executionLease }),
873
- };
874
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
875
- return response;
876
- });
877
- }
878
- export function answerEnno(database, rawInput) {
879
- const parsedInput = parseEnnoAnswer(rawInput);
880
- const before = readEnnoSnapshot(database, identity(database, parsedInput));
881
- const input = sanitizeEnnoAnswer(parsedInput, before.repositoryRoot);
882
- const operation = operationIdentity('answer', input.idempotencyKey, input);
883
- const replay = readOperationReceipt(database, input.runId, operation);
884
- if (replay !== undefined)
885
- return replay;
886
- return withImmediateTransaction(database, () => {
887
- const current = readEnnoSnapshot(database, identity(database, input));
888
- assertExpected(current, input.expectedRevision, input.action === 'cancel' ? ['needs_confirmation', 'zenki_planning'] : ['needs_confirmation']);
889
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
890
- let next;
891
- let executionLease;
892
- if (input.action === 'approve') {
893
- updateContractInTransaction(database, current, {
894
- contract: current.contract,
895
- status: 'goki_executing',
896
- confirmationState: 'approved',
897
- });
898
- appendEnnoEventInTransaction(database, input.runId, 'enno.plan_confirmed', 'enno-oduno', 'approved', {
899
- contractRevision: current.revision,
900
- });
901
- next = readEnnoSnapshot(database, identity(database, input));
902
- executionLease = startFirstReadyUnit(database, next);
903
- next = readEnnoSnapshot(database, identity(database, input));
904
- }
905
- else if (input.action === 'revise') {
906
- const revisedContract = {
907
- ...current.contract,
908
- revision: current.revision + 1,
909
- };
910
- updateContractInTransaction(database, current, {
911
- contract: revisedContract,
912
- status: 'zenki_planning',
913
- confirmationState: 'revision_requested',
914
- blocker: input.requestedChanges ?? null,
915
- });
916
- next = readEnnoSnapshot(database, identity(database, input));
917
- }
918
- else {
919
- updateContractInTransaction(database, current, {
920
- contract: current.contract,
921
- status: 'cancelled',
922
- confirmationState: 'cancelled',
923
- });
924
- appendEnnoEventInTransaction(database, input.runId, 'enno.cancelled', 'enno-oduno', 'cancelled', {
925
- contractRevision: current.revision,
926
- });
927
- terminalizeLedgerRunInTransaction(database, input.runId, 'cancelled');
928
- next = readEnnoSnapshot(database, identity(database, input));
929
- }
930
- const response = {
931
- ennoOduno: stateForSnapshot(next),
932
- ...(executionLease === undefined ? {} : { executionLease }),
933
- };
934
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
935
- return response;
936
- });
937
- }
938
- function sanitizedVerifierResults(results, repositoryRoot) {
939
- return results.map((result) => {
940
- const sanitized = sanitizeJson({
941
- stdoutPreview: result.stdoutPreview,
942
- stderrPreview: result.stderrPreview,
943
- }, { workspace: repositoryRoot }).value;
944
- return {
945
- ...result,
946
- stdoutPreview: sanitized.stdoutPreview,
947
- stderrPreview: sanitized.stderrPreview,
948
- };
949
- });
950
- }
951
- function spawnFailedVerifierResults(verifiers) {
952
- const emptyDigest = createHash('sha256').digest('hex');
953
- return verifiers.map((verifier) => ({
954
- verifier: { ...verifier, args: [...verifier.args] },
955
- status: 'spawn_failed',
956
- exitCode: null,
957
- signal: null,
958
- durationMs: 0,
959
- stdoutPreview: '',
960
- stderrPreview: '',
961
- stdoutDigest: emptyDigest,
962
- stderrDigest: emptyDigest,
963
- }));
964
- }
965
- function finalReviewFeedback(revision, reviewSummary, results) {
966
- const failed = results.filter((result) => result.status !== 'passed');
967
- const evidence = failed.length === 0
968
- ? 'all final verifiers passed'
969
- : failed.map((result) => {
970
- const exit = result.exitCode === null ? '' : `,exit=${result.exitCode}`;
971
- return `${result.verifier.id}=${result.status}${exit}`;
972
- }).join('; ');
973
- return `Enno-Oduno review rejected contract revision ${revision}: ${reviewSummary}. Verifier evidence: ${evidence}. Zenki must revise the WorkPlan; Goki must not resume the rejected plan.`
974
- .slice(0, 16_384);
975
- }
976
- function sanitizedReviewSummary(summary, repositoryRoot) {
977
- return sanitizeJson({ summary }, { workspace: repositoryRoot }).value.summary;
978
- }
979
- function blockedForAttemptLimit(database, snapshot, operation) {
980
- const operationOwner = startOperationInTransaction(database, snapshot.runId, operation);
981
- const activeUnit = snapshot.workUnits.find((candidate) => candidate.status === 'in_progress');
982
- if (activeUnit !== undefined) {
983
- setWorkUnitStatusInTransaction(database, {
984
- runId: snapshot.runId,
985
- contractRevision: snapshot.revision,
986
- workUnitId: activeUnit.workUnit.id,
987
- from: 'in_progress',
988
- to: 'blocked',
989
- attemptCount: activeUnit.attemptCount,
990
- result: activeUnit.result,
991
- });
992
- }
993
- releaseExecutionLeaseInTransaction(database, snapshot.runId);
994
- updateContractInTransaction(database, snapshot, {
995
- contract: snapshot.contract,
996
- status: 'blocked',
997
- confirmationState: snapshot.confirmationState,
998
- blocker: 'Enno attempt limit reached',
999
- });
1000
- appendEnnoEventInTransaction(database, snapshot.runId, 'enno.blocked', 'enno-oduno', 'blocked', {
1001
- reason: 'attempt_limit',
1002
- attempts: snapshot.attempts,
1003
- });
1004
- terminalizeLedgerRunInTransaction(database, snapshot.runId, 'failed');
1005
- const response = { ennoOduno: stateForSnapshot(readEnnoSnapshot(database, {
1006
- runId: snapshot.runId,
1007
- workspace: snapshot.workspace,
1008
- orchestrationId: snapshot.orchestrationId,
1009
- })) };
1010
- completeOperationInTransaction(database, snapshot.runId, operation, operationOwner, response);
1011
- return response;
1012
- }
1013
- export async function reportEnnoWork(database, rawInput, dependencies = {}) {
1014
- const parsedInput = parseWorkReport(rawInput);
1015
- const initial = readEnnoSnapshot(database, identity(database, parsedInput));
1016
- const input = sanitizeWorkReport(parsedInput, initial.repositoryRoot);
1017
- const operation = operationIdentity('work_report', input.idempotencyKey, input);
1018
- const replay = readOperationReceipt(database, input.runId, operation);
1019
- if (replay !== undefined)
1020
- return replay;
1021
- const before = initial;
1022
- assertExpected(before, input.expectedRevision, ['goki_executing']);
1023
- const unit = before.workUnits.find((candidate) => candidate.workUnit.id === input.workUnitId);
1024
- if (unit === undefined || unit.status !== 'in_progress')
1025
- throw new KiokukoError('CONFLICT', 'Reported Enno WorkUnit is not active');
1026
- if (before.attempts >= before.contract.maxAttempts) {
1027
- return withImmediateTransaction(database, () => {
1028
- const current = readEnnoSnapshot(database, identity(database, input));
1029
- assertExpected(current, input.expectedRevision, ['goki_executing']);
1030
- assertExecutionLeaseInTransaction(database, current, input);
1031
- return blockedForAttemptLimit(database, current, operation);
1032
- });
1033
- }
1034
- if (input.result.outcome !== 'completed') {
1035
- return withImmediateTransaction(database, () => {
1036
- const current = readEnnoSnapshot(database, identity(database, input));
1037
- assertExpected(current, input.expectedRevision, ['goki_executing']);
1038
- assertExecutionLeaseInTransaction(database, current, input);
1039
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
1040
- const currentUnit = current.workUnits.find((candidate) => candidate.workUnit.id === input.workUnitId);
1041
- const attempts = current.attempts + 1;
1042
- const mustBlock = input.result.outcome === 'blocked' || attempts >= current.contract.maxAttempts;
1043
- setWorkUnitStatusInTransaction(database, {
1044
- runId: input.runId,
1045
- contractRevision: current.revision,
1046
- workUnitId: input.workUnitId,
1047
- from: 'in_progress',
1048
- to: mustBlock ? 'blocked' : 'in_progress',
1049
- attemptCount: currentUnit.attemptCount + 1,
1050
- result: input.result,
1051
- });
1052
- updateContractInTransaction(database, current, {
1053
- contract: current.contract,
1054
- status: mustBlock ? 'blocked' : 'goki_executing',
1055
- confirmationState: current.confirmationState,
1056
- attempts,
1057
- blocker: mustBlock ? input.result.summary : null,
1058
- });
1059
- appendEnnoEventInTransaction(database, input.runId, 'goki.work_failed', 'goki', input.result.outcome, {
1060
- workUnitId: input.workUnitId,
1061
- attempt: attempts,
1062
- });
1063
- let executionLease;
1064
- if (mustBlock) {
1065
- releaseExecutionLeaseInTransaction(database, input.runId);
1066
- appendEnnoEventInTransaction(database, input.runId, 'enno.blocked', 'enno-oduno', 'blocked', {
1067
- reason: input.result.summary,
1068
- });
1069
- terminalizeLedgerRunInTransaction(database, input.runId, 'failed');
1070
- }
1071
- else {
1072
- const retry = readEnnoSnapshot(database, identity(database, input));
1073
- if (retry.dshSessionId !== null) {
1074
- executionLease = claimExecutionLeaseInTransaction(database, retry, input.workUnitId, {
1075
- dshSessionId: retry.dshSessionId,
1076
- });
1077
- }
1078
- }
1079
- const response = {
1080
- ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))),
1081
- ...(executionLease === undefined ? {} : { executionLease }),
1082
- };
1083
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1084
- return response;
1085
- });
1086
- }
1087
- let verifierRunIds = [];
1088
- let operationOwner = '';
1089
- const verifierLeaseMs = operationLeaseMsForVerifiers(unit.workUnit.focusedVerifiers);
1090
- withImmediateTransaction(database, () => {
1091
- const current = readEnnoSnapshot(database, identity(database, input));
1092
- assertExpected(current, input.expectedRevision, ['goki_executing']);
1093
- renewExecutionLeaseInTransaction(database, current, input, verifierLeaseMs);
1094
- operationOwner = startOperationInTransaction(database, input.runId, operation, verifierLeaseMs);
1095
- const currentUnit = current.workUnits.find((candidate) => candidate.workUnit.id === input.workUnitId);
1096
- if (currentUnit === undefined || currentUnit.status !== 'in_progress') {
1097
- throw new KiokukoError('CONFLICT', 'Reported Enno WorkUnit changed concurrently');
1098
- }
1099
- verifierRunIds = startVerifierRunsInTransaction(database, {
1100
- runId: input.runId,
1101
- workUnitId: input.workUnitId,
1102
- revision: current.revision,
1103
- mutationRevision: current.mutationRevision + (input.result.mutated ? 1 : 0),
1104
- verifiers: currentUnit.workUnit.focusedVerifiers,
1105
- });
1106
- });
1107
- let rawResults;
1108
- try {
1109
- rawResults = await runMemoryAwareVerifiers(database, input.runId, unit.workUnit.focusedVerifiers, before.repositoryRoot, dependencies);
1110
- }
1111
- catch {
1112
- rawResults = spawnFailedVerifierResults(unit.workUnit.focusedVerifiers);
1113
- }
1114
- const results = sanitizedVerifierResults(rawResults, before.repositoryRoot);
1115
- return withImmediateTransaction(database, () => {
1116
- const current = readEnnoSnapshot(database, identity(database, input));
1117
- assertExpected(current, input.expectedRevision, ['goki_executing']);
1118
- assertExecutionLeaseInTransaction(database, current, input);
1119
- finishVerifierRunsInTransaction(database, verifierRunIds, results);
1120
- const passed = results.every((result) => result.status === 'passed');
1121
- const unsafe = results.some((result) => result.status === 'spawn_failed');
1122
- const attempts = current.attempts + 1;
1123
- const mustBlock = unsafe || (!passed && attempts >= current.contract.maxAttempts);
1124
- const currentUnit = current.workUnits.find((candidate) => candidate.workUnit.id === input.workUnitId);
1125
- setWorkUnitStatusInTransaction(database, {
1126
- runId: input.runId,
1127
- contractRevision: current.revision,
1128
- workUnitId: input.workUnitId,
1129
- from: 'in_progress',
1130
- to: passed ? 'completed' : mustBlock ? 'blocked' : 'in_progress',
1131
- attemptCount: currentUnit.attemptCount + 1,
1132
- result: input.result,
1133
- });
1134
- updateContractInTransaction(database, current, {
1135
- contract: current.contract,
1136
- status: mustBlock ? 'blocked' : 'goki_executing',
1137
- confirmationState: current.confirmationState,
1138
- attempts,
1139
- mutationRevision: current.mutationRevision + (input.result.mutated ? 1 : 0),
1140
- blocker: mustBlock
1141
- ? unsafe ? 'Focused verifier could not be started safely' : 'Focused verification failed at the attempt limit'
1142
- : null,
1143
- });
1144
- appendEnnoEventInTransaction(database, input.runId, passed ? 'goki.work_completed' : 'goki.work_failed', 'goki', passed ? 'completed' : 'verification_failed', {
1145
- workUnitId: input.workUnitId,
1146
- mutated: input.result.mutated,
1147
- changedPaths: input.result.changedPaths,
1148
- });
1149
- releaseExecutionLeaseInTransaction(database, input.runId);
1150
- let next = readEnnoSnapshot(database, identity(database, input));
1151
- let executionLease;
1152
- if (mustBlock) {
1153
- appendEnnoEventInTransaction(database, input.runId, 'enno.blocked', 'enno-oduno', 'blocked', {
1154
- reason: unsafe ? 'spawn_failed' : 'focused_verification_failed',
1155
- });
1156
- terminalizeLedgerRunInTransaction(database, input.runId, 'failed');
1157
- }
1158
- else if (passed) {
1159
- if (next.workUnits.every((candidate) => candidate.status === 'completed')) {
1160
- updateContractInTransaction(database, next, {
1161
- contract: next.contract,
1162
- status: 'enno_verifying',
1163
- confirmationState: next.confirmationState,
1164
- });
1165
- }
1166
- else {
1167
- executionLease = startFirstReadyUnit(database, next);
1168
- }
1169
- next = readEnnoSnapshot(database, identity(database, input));
1170
- }
1171
- else if (next.dshSessionId !== null) {
1172
- // A failed focused verifier leaves the same WorkUnit in progress so the
1173
- // host can correct it. The report lease was consumed above; return a
1174
- // fresh lease in the same response or the advertised execute_work_unit
1175
- // continuation can only fail with lease_required.
1176
- executionLease = claimExecutionLeaseInTransaction(database, next, input.workUnitId, {
1177
- dshSessionId: next.dshSessionId,
1178
- });
1179
- }
1180
- const response = {
1181
- ennoOduno: stateForSnapshot(next),
1182
- verifierResults: results,
1183
- ...(executionLease === undefined ? {} : { executionLease }),
1184
- };
1185
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1186
- return response;
1187
- });
1188
- }
1189
- export async function prepareEnnoVerification(database, rawInput, dependencies = {}) {
1190
- const input = parseVerificationPrepare(rawInput);
1191
- const before = readEnnoSnapshot(database, identity(database, input));
1192
- const operation = operationIdentity('verify_prepare', input.idempotencyKey, input);
1193
- const replay = readOperationReceipt(database, input.runId, operation);
1194
- if (replay !== undefined)
1195
- return replay;
1196
- assertExpected(before, input.expectedRevision, ['enno_verifying']);
1197
- const preRepositoryState = captureRepositoryState(before.repositoryRoot);
1198
- const verifierSpecDigest = canonicalContentHash(before.contract.finalVerifiers);
1199
- // The last permitted work report may have succeeded. Its final verification
1200
- // is still required; failure below blocks instead of granting another attempt.
1201
- if (before.attempts > before.contract.maxAttempts) {
1202
- return withImmediateTransaction(database, () => blockedForAttemptLimit(database, readEnnoSnapshot(database, identity(database, input)), operation));
1203
- }
1204
- let verifierRunIds = [];
1205
- let operationOwner = '';
1206
- let cachedResults;
1207
- const verifierLeaseMs = operationLeaseMsForVerifiers(before.contract.finalVerifiers);
1208
- withImmediateTransaction(database, () => {
1209
- const current = readEnnoSnapshot(database, identity(database, input));
1210
- assertExpected(current, input.expectedRevision, ['enno_verifying']);
1211
- operationOwner = startOperationInTransaction(database, input.runId, operation, verifierLeaseMs);
1212
- cachedResults = readFreshFinalVerifierResults(database, {
1213
- runId: input.runId,
1214
- revision: current.revision,
1215
- mutationRevision: current.mutationRevision,
1216
- verifiers: current.contract.finalVerifiers,
1217
- repositoryDigest: preRepositoryState.digest,
1218
- });
1219
- if (cachedResults === undefined) {
1220
- verifierRunIds = startVerifierRunsInTransaction(database, {
1221
- runId: input.runId,
1222
- workUnitId: null,
1223
- revision: current.revision,
1224
- mutationRevision: current.mutationRevision,
1225
- verifiers: current.contract.finalVerifiers,
1226
- repositoryEvidence: {
1227
- policyVersion: preRepositoryState.policyVersion,
1228
- preDigest: preRepositoryState.digest,
1229
- verifierSpecDigest,
1230
- },
1231
- });
1232
- }
1233
- appendEnnoEventInTransaction(database, input.runId, 'enno.verification_started', 'enno-oduno', cachedResults === undefined ? 'started' : 'reused', {
1234
- contractRevision: current.revision,
1235
- mutationRevision: current.mutationRevision,
1236
- verifierIds: current.contract.finalVerifiers.map((verifier) => verifier.id),
1237
- });
1238
- });
1239
- let results;
1240
- let auditUnavailable = false;
1241
- if (cachedResults !== undefined) {
1242
- results = cachedResults;
1243
- }
1244
- else {
1245
- try {
1246
- results = sanitizedVerifierResults(await runMemoryAwareVerifiers(database, input.runId, before.contract.finalVerifiers, before.repositoryRoot, dependencies), before.repositoryRoot);
1247
- }
1248
- catch (error) {
1249
- auditUnavailable = error instanceof RepositoryAuditError;
1250
- results = error instanceof RepositoryAuditError && error.results.length === before.contract.finalVerifiers.length
1251
- ? sanitizedVerifierResults(error.results, before.repositoryRoot)
1252
- : spawnFailedVerifierResults(before.contract.finalVerifiers);
1253
- }
1254
- }
1255
- const postRepositoryState = captureRepositoryState(before.repositoryRoot);
1256
- const changedDuringVerification = postRepositoryState.digest !== preRepositoryState.digest
1257
- || results.some((result) => result.changedDuringVerification === true);
1258
- results = auditUnavailable ? results : results.map((result) => ({
1259
- ...result,
1260
- repositoryStatePolicyVersion: postRepositoryState.policyVersion,
1261
- repositoryStateDigest: postRepositoryState.digest,
1262
- changedDuringVerification,
1263
- }));
1264
- return withImmediateTransaction(database, () => {
1265
- const current = readEnnoSnapshot(database, identity(database, input));
1266
- assertExpected(current, input.expectedRevision, ['enno_verifying']);
1267
- if (verifierRunIds.length > 0)
1268
- finishVerifierRunsInTransaction(database, verifierRunIds, results, auditUnavailable ? undefined : {
1269
- postDigest: postRepositoryState.digest,
1270
- changedDuringVerification,
1271
- });
1272
- const verified = readEnnoSnapshot(database, identity(database, input));
1273
- if (auditUnavailable || !verified.finalEvidenceReady) {
1274
- // Finishing a process is not the same as preparing admissible evidence.
1275
- // Actual input changes require fresh evidence. An unavailable audit is
1276
- // a host failure, not a reason to revise the plan or repeat completed work.
1277
- const attempts = current.attempts + 1;
1278
- const mustBlock = auditUnavailable || attempts >= current.contract.maxAttempts;
1279
- const reason = auditUnavailable
1280
- ? 'Repository verification audit is unavailable. Check filesystem access and workspace stability. This is not evidence of repository changes; do not rewrite the verifier, repeat completed work, or request plan approval to repair this host audit failure.'
1281
- : changedDuringVerification
1282
- ? 'Repository changes were observed during final verification. Identify the affected inputs and whether the verifier or concurrent activity changed them before revising the plan. Preserve meaningful checks; do not replace them with existence-only checks, bypass freshness checks, or delete user files.'
1283
- : 'Final verification evidence no longer matches the current repository. Reconcile the changes and revise the verification plan before retrying.';
1284
- updateContractInTransaction(database, current, {
1285
- contract: mustBlock ? current.contract : { ...current.contract, revision: current.revision + 1 },
1286
- status: mustBlock ? 'blocked' : 'zenki_planning',
1287
- confirmationState: mustBlock ? current.confirmationState : 'revision_requested',
1288
- attempts,
1289
- blocker: reason,
1290
- });
1291
- appendEnnoEventInTransaction(database, input.runId, 'enno.verification_failed', 'enno-oduno', 'failed', {
1292
- contractRevision: current.revision,
1293
- mutationRevision: current.mutationRevision,
1294
- reason: auditUnavailable ? 'repository_audit_unavailable' : changedDuringVerification ? 'repository_changed_during_verification' : 'stale_verification_evidence',
1295
- statuses: results.map(result => ({ verifierId: result.verifier.id, status: result.status })),
1296
- });
1297
- if (mustBlock) {
1298
- appendEnnoEventInTransaction(database, input.runId, 'enno.blocked', 'enno-oduno', 'blocked', { reason: auditUnavailable ? 'repository_audit_unavailable' : 'attempt_limit' });
1299
- terminalizeLedgerRunInTransaction(database, input.runId, 'failed');
1300
- }
1301
- else {
1302
- appendEnnoEventInTransaction(database, input.runId, 'enno.replan_requested', 'enno-oduno', 'requested', {
1303
- fromContractRevision: current.revision, toContractRevision: current.revision + 1, reason,
1304
- });
1305
- }
1306
- }
1307
- const response = {
1308
- ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))),
1309
- verifierResults: results,
1310
- };
1311
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1312
- return response;
1313
- });
1314
- }
1315
- export async function finishEnno(database, rawInput, dependencies = {}) {
1316
- const parsedInput = parseFinishRequest(rawInput);
1317
- const initial = readEnnoSnapshot(database, identity(database, parsedInput));
1318
- const input = sanitizeFinishRequest(parsedInput, initial.repositoryRoot);
1319
- const operation = operationIdentity('finish', input.idempotencyKey, input);
1320
- const replay = readOperationReceipt(database, input.runId, operation);
1321
- if (replay !== undefined)
1322
- return replay;
1323
- const before = initial;
1324
- assertExpected(before, input.expectedRevision, ['enno_verifying']);
1325
- if (input.advisoryRoundDigest !== undefined) {
1326
- if (!before.finalEvidenceReady) {
1327
- throw ennoValidationError('finish', [{
1328
- path: ['advisoryRoundDigest'],
1329
- reasonCode: 'advisory_digest_stale',
1330
- }], 'refresh_state');
1331
- }
1332
- requireAdvisoryRound(database, before, 'final_review', before.mutationRevision, advisoryContextForSubmission(before, 'final_review'), input.advisoryRoundDigest);
1333
- }
1334
- const reviewSummary = sanitizedReviewSummary(input.review.summary, before.repositoryRoot);
1335
- // Acceptance settles the successful last attempt. Rejection still observes
1336
- // the limit below and cannot authorize another implementation cycle.
1337
- if (before.attempts > before.contract.maxAttempts) {
1338
- return withImmediateTransaction(database, () => blockedForAttemptLimit(database, readEnnoSnapshot(database, identity(database, input)), operation));
1339
- }
1340
- return withImmediateTransaction(database, () => {
1341
- const current = readEnnoSnapshot(database, identity(database, input));
1342
- assertExpected(current, input.expectedRevision, ['enno_verifying']);
1343
- const currentRepositoryDigest = captureRepositoryState(current.repositoryRoot).digest;
1344
- const results = readFreshFinalVerifierResults(database, {
1345
- runId: input.runId,
1346
- revision: current.revision,
1347
- mutationRevision: current.mutationRevision,
1348
- verifiers: current.contract.finalVerifiers,
1349
- repositoryDigest: currentRepositoryDigest,
1350
- });
1351
- if (results === undefined) {
1352
- throw new KiokukoError('CONFLICT', 'Final verification evidence is not prepared by the DSH host');
1353
- }
1354
- if (results.some((result) => result.repositoryStateDigest !== currentRepositoryDigest
1355
- || result.changedDuringVerification !== false)) {
1356
- throw new KiokukoError('CONFLICT', 'Final verification evidence is stale for the current repository state');
1357
- }
1358
- const advisoryRound = consumeAdvisoryRoundIfPresent(database, current, 'final_review', current.mutationRevision, input.advisoryRoundDigest === undefined ? undefined : advisoryContextForSubmission(current, 'final_review'), input.advisoryRoundDigest, input.advisoryDisposition);
1359
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
1360
- appendEnnoEventInTransaction(database, input.runId, 'enno.review_started', 'enno-oduno', 'started', {
1361
- contractRevision: current.revision,
1362
- mutationRevision: current.mutationRevision,
1363
- requestedDecision: input.review.decision,
1364
- });
1365
- appendEnnoEventInTransaction(database, input.runId, 'enno.verification_started', 'enno-oduno', 'reused', {
1366
- contractRevision: current.revision,
1367
- mutationRevision: current.mutationRevision,
1368
- verifierIds: current.contract.finalVerifiers.map((verifier) => verifier.id),
1369
- });
1370
- const passed = results.length > 0 && results.every((result) => result.status === 'passed');
1371
- if (passed && input.review.decision === 'accept'
1372
- && taskCompletionBlocksClose(saveTaskCompletionReceipt(database, input.runId))) {
1373
- throw new KiokukoError('CONFLICT', 'Approved acceptance criteria require fresh bound verification evidence');
1374
- }
1375
- const unsafe = results.some((result) => result.status === 'spawn_failed');
1376
- const attempts = current.attempts + 1;
1377
- const accepted = passed && input.review.decision === 'accept';
1378
- const mustBlock = unsafe || (!accepted && attempts >= current.contract.maxAttempts);
1379
- const reviewFeedback = accepted || mustBlock
1380
- ? null
1381
- : finalReviewFeedback(current.revision, reviewSummary, results);
1382
- const nextContract = reviewFeedback === null
1383
- ? current.contract
1384
- : { ...current.contract, revision: current.revision + 1 };
1385
- const blockedReason = unsafe
1386
- ? 'Final verifier could not be started safely'
1387
- : input.review.decision === 'replan' && passed
1388
- ? 'Enno review requested replanning at the attempt limit'
1389
- : 'Final verification reached the attempt limit';
1390
- updateContractInTransaction(database, current, {
1391
- contract: nextContract,
1392
- status: accepted ? 'oduno_meditation' : mustBlock ? 'blocked' : 'zenki_planning',
1393
- confirmationState: reviewFeedback === null ? current.confirmationState : 'revision_requested',
1394
- attempts,
1395
- blocker: mustBlock ? blockedReason : reviewFeedback,
1396
- });
1397
- appendEnnoEventInTransaction(database, input.runId, passed ? 'enno.verification_passed' : 'enno.verification_failed', 'enno-oduno', passed ? 'passed' : 'failed', {
1398
- contractRevision: current.revision,
1399
- mutationRevision: current.mutationRevision,
1400
- statuses: results.map((result) => ({ verifierId: result.verifier.id, status: result.status })),
1401
- });
1402
- let next = readEnnoSnapshot(database, identity(database, input));
1403
- if (accepted) {
1404
- appendEnnoEventInTransaction(database, input.runId, 'enno.review_accepted', 'enno-oduno', 'accepted', {
1405
- contractRevision: current.revision,
1406
- mutationRevision: current.mutationRevision,
1407
- summary: reviewSummary,
1408
- });
1409
- }
1410
- else if (mustBlock) {
1411
- appendEnnoEventInTransaction(database, input.runId, 'enno.blocked', 'enno-oduno', 'blocked', {
1412
- reason: unsafe ? 'spawn_failed' : 'attempt_limit',
1413
- });
1414
- terminalizeLedgerRunInTransaction(database, input.runId, 'failed');
1415
- }
1416
- else {
1417
- appendEnnoEventInTransaction(database, input.runId, 'enno.replan_requested', 'enno-oduno', 'requested', {
1418
- fromContractRevision: current.revision,
1419
- toContractRevision: next.revision,
1420
- reason: reviewFeedback,
1421
- });
1422
- next = readEnnoSnapshot(database, identity(database, input));
1423
- }
1424
- const response = {
1425
- ennoOduno: stateForSnapshot(next),
1426
- verifierResults: results,
1427
- ...(advisoryRound === undefined ? {} : { advisoryRound }),
1428
- };
1429
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1430
- return response;
1431
- });
1432
- }
1433
- export function submitOdunoMeditation(database, rawInput, options = {}) {
1434
- const parsedInput = parseMeditationSubmission(rawInput);
1435
- const before = readEnnoSnapshot(database, identity(database, parsedInput));
1436
- const input = sanitizeMeditationSubmission(parsedInput, before.repositoryRoot);
1437
- const operation = operationIdentity('meditation_submit', input.idempotencyKey, input);
1438
- const replay = readOperationReceipt(database, input.runId, operation);
1439
- if (replay !== undefined)
1440
- return replay;
1441
- assertExpected(before, input.expectedRevision, ['oduno_meditation']);
1442
- if (before.ideal === null)
1443
- throw new KiokukoError('INTEGRITY_ERROR', 'Oduno meditation requires a persisted ideal');
1444
- const meditation = input.meditation;
1445
- return withImmediateTransaction(database, () => {
1446
- const replayed = readOperationReceipt(database, input.runId, operation);
1447
- if (replayed !== undefined)
1448
- return replayed;
1449
- const current = readEnnoSnapshot(database, identity(database, input));
1450
- assertExpected(current, input.expectedRevision, ['oduno_meditation']);
1451
- if (current.ideal === null)
1452
- throw new KiokukoError('INTEGRITY_ERROR', 'Oduno meditation requires a persisted ideal');
1453
- const operationOwner = startOperationInTransaction(database, input.runId, operation);
1454
- const repositoryDigest = captureRepositoryState(current.repositoryRoot).digest;
1455
- const acceptedResults = readFreshFinalVerifierResults(database, {
1456
- runId: input.runId,
1457
- revision: current.revision,
1458
- mutationRevision: current.mutationRevision,
1459
- verifiers: current.contract.finalVerifiers,
1460
- repositoryDigest,
1461
- });
1462
- if (acceptedResults === undefined || acceptedResults.some(result => result.status !== 'passed')) {
1463
- updateContractInTransaction(database, current, {
1464
- contract: current.contract,
1465
- status: 'enno_verifying',
1466
- confirmationState: current.confirmationState,
1467
- blocker: 'Final verification evidence became stale after acceptance',
1468
- });
1469
- appendEnnoEventInTransaction(database, input.runId, 'enno.verification_failed', 'enno-oduno', 'stale', {
1470
- contractRevision: current.revision,
1471
- mutationRevision: current.mutationRevision,
1472
- reason: 'repository_changed_after_acceptance',
1473
- });
1474
- const response = { ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))) };
1475
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1476
- return response;
1477
- }
1478
- if (taskCompletionBlocksClose(saveTaskCompletionReceipt(database, input.runId))) {
1479
- throw new KiokukoError('CONFLICT', 'Accepted completion criteria became unresolved before the terminal transition');
1480
- }
1481
- updateContractInTransaction(database, current, {
1482
- contract: current.contract,
1483
- status: 'completed',
1484
- confirmationState: current.confirmationState,
1485
- meditation,
1486
- });
1487
- appendEnnoEventInTransaction(database, input.runId, 'oduno.meditation_completed', 'enno-oduno', 'completed', {
1488
- contractRevision: current.revision,
1489
- mutationRevision: current.mutationRevision,
1490
- inspectedPathCount: meditation.inspectedPaths.length,
1491
- deletionCandidateCount: meditation.deletionCandidates.length,
1492
- });
1493
- appendEnnoEventInTransaction(database, input.runId, 'enno.completed', 'enno-oduno', 'completed', {
1494
- contractRevision: current.revision,
1495
- mutationRevision: current.mutationRevision,
1496
- });
1497
- if (options.deferLedgerTerminalization !== true) {
1498
- terminalizeLedgerRunInTransaction(database, input.runId, 'completed');
1499
- }
1500
- const response = { ennoOduno: stateForSnapshot(readEnnoSnapshot(database, identity(database, input))) };
1501
- completeOperationInTransaction(database, input.runId, operation, operationOwner, response);
1502
- return response;
1503
- });
1504
- }
1505
- //# sourceMappingURL=service.js.map