@north-light/crouter 0.3.312 → 0.3.313

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 (495) hide show
  1. package/dist/api/client.d.ts +27 -30
  2. package/dist/api/client.js +80 -67
  3. package/dist/api/dto/broker-ops.d.ts +10 -20
  4. package/dist/api/dto/canvas.d.ts +1 -10
  5. package/dist/api/dto/health.d.ts +113 -0
  6. package/dist/api/dto/human-requests.d.ts +14 -3
  7. package/dist/api/dto/human.d.ts +2 -48
  8. package/dist/api/dto/human.js +3 -2
  9. package/dist/api/dto/inbox.d.ts +14 -0
  10. package/dist/api/dto/mail.d.ts +43 -0
  11. package/dist/api/dto/nodes.d.ts +11 -8
  12. package/dist/api/dto/recovery.d.ts +96 -0
  13. package/dist/api/dto/reviews.d.ts +2 -2
  14. package/dist/api/routes.d.ts +9 -6
  15. package/dist/api/routes.js +11 -11
  16. package/dist/build-root.d.ts +4 -0
  17. package/dist/build-root.js +11 -1
  18. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
  19. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
  20. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
  22. package/dist/cli.js +10 -1
  23. package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
  24. package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
  25. package/dist/clients/attach/chrome/canvas-panels.js +1 -1
  26. package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
  27. package/dist/clients/attach/chrome/inbox-strip.js +17 -9
  28. package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
  29. package/dist/clients/attach/chrome/ticket-panel.js +77 -46
  30. package/dist/clients/attach/overlays/graph.js +6 -9
  31. package/dist/clients/attach/render/chat-view.d.ts +5 -4
  32. package/dist/clients/attach/render/chat-view.js +22 -13
  33. package/dist/clients/attach/render/page-block.d.ts +11 -7
  34. package/dist/clients/attach/render/page-block.js +64 -55
  35. package/dist/clients/attach/viewer.js +746 -735
  36. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
  37. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
  38. package/dist/clients/inbox/controller.d.ts +42 -14
  39. package/dist/clients/inbox/controller.js +240 -124
  40. package/dist/clients/inbox/dto-adapt.d.ts +28 -0
  41. package/dist/clients/inbox/dto-adapt.js +93 -0
  42. package/dist/clients/inbox/page-adapter.d.ts +5 -4
  43. package/dist/clients/inbox/page-adapter.js +12 -12
  44. package/dist/clients/inbox/resolve.d.ts +10 -5
  45. package/dist/clients/inbox/resolve.js +13 -12
  46. package/dist/clients/inbox/review/review-client.d.ts +0 -1
  47. package/dist/clients/inbox/review/review-client.js +0 -4
  48. package/dist/clients/inbox/review-adapter.d.ts +2 -1
  49. package/dist/clients/inbox/review-adapter.js +3 -5
  50. package/dist/clients/inbox/surface.d.ts +2 -2
  51. package/dist/clients/inbox/surface.js +19 -8
  52. package/dist/clients/inbox/tui.d.ts +3 -3
  53. package/dist/commands/__tests__/human.test.js +31 -15
  54. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
  55. package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
  56. package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
  57. package/dist/commands/api-client.d.ts +5 -4
  58. package/dist/commands/api-client.js +13 -7
  59. package/dist/commands/canvas-history/shared.js +1 -1
  60. package/dist/commands/canvas-history.js +1 -1
  61. package/dist/commands/canvas-roster.js +1 -1
  62. package/dist/commands/canvas.js +1 -2
  63. package/dist/commands/human/feedback.js +20 -17
  64. package/dist/commands/human/prompts.js +45 -36
  65. package/dist/commands/human/queue.js +73 -123
  66. package/dist/commands/human/review.js +6 -16
  67. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
  68. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
  69. package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
  70. package/dist/commands/node-inspect-artifacts.js +1 -1
  71. package/dist/commands/node-lifecycle-revive.d.ts +2 -2
  72. package/dist/commands/node-lifecycle-revive.js +9 -19
  73. package/dist/commands/pkg/plugin-manage.js +0 -1
  74. package/dist/commands/profile/show.js +4 -12
  75. package/dist/commands/surface-tmux-spread.js +1 -5
  76. package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
  77. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
  78. package/dist/commands/sys/branch.d.ts +2 -0
  79. package/dist/commands/sys/branch.js +19 -0
  80. package/dist/commands/sys/config.js +106 -33
  81. package/dist/commands/sys/daemon.d.ts +2 -0
  82. package/dist/commands/sys/daemon.js +130 -7
  83. package/dist/commands/sys/doctor.js +5 -15
  84. package/dist/commands/sys/migrate.js +21 -92
  85. package/dist/commands/sys/setup-settings-runner.js +4 -2
  86. package/dist/commands/sys.js +2 -15
  87. package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
  88. package/dist/core/__tests__/boot.test.js +32 -25
  89. package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
  90. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
  91. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
  92. package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
  93. package/dist/core/__tests__/canvas.test.js +18 -47
  94. package/dist/core/__tests__/child-death-wake.test.js +29 -7
  95. package/dist/core/__tests__/cli-help-contract.test.js +2 -0
  96. package/dist/core/__tests__/close.test.js +29 -10
  97. package/dist/core/__tests__/collectible.test.js +2 -1
  98. package/dist/core/__tests__/config-change-delta.test.js +2 -0
  99. package/dist/core/__tests__/context-intro.test.js +13 -1
  100. package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
  101. package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
  102. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
  103. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
  104. package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
  105. package/dist/core/__tests__/daemon-boot.test.js +51 -14
  106. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  107. package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
  108. package/dist/core/__tests__/focuses.test.js +10 -5
  109. package/dist/core/__tests__/helpers/harness.js +50 -18
  110. package/dist/core/__tests__/history-inbox.test.js +12 -16
  111. package/dist/core/__tests__/human-action-delivery.test.js +48 -28
  112. package/dist/core/__tests__/human-actions.test.js +7 -3
  113. package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
  114. package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
  115. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
  116. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
  117. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
  118. package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
  119. package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
  120. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
  121. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +16 -3
  122. package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
  123. package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
  124. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
  125. package/dist/core/__tests__/integration/revive.test.js +67 -21
  126. package/dist/core/__tests__/integration/spawn-root.test.js +51 -8
  127. package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
  128. package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
  129. package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
  130. package/dist/core/__tests__/kickoff.test.js +36 -39
  131. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
  132. package/dist/core/__tests__/lifecycle.test.js +2 -1
  133. package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
  134. package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
  135. package/dist/core/__tests__/migration.test.js +145 -31
  136. package/dist/core/__tests__/model-pin-durability.test.js +4 -1
  137. package/dist/core/__tests__/model-routes-config.test.js +13 -5
  138. package/dist/core/__tests__/node-outcome.test.js +93 -26
  139. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
  140. package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
  141. package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
  142. package/dist/core/__tests__/passive-subscription.test.js +50 -157
  143. package/dist/core/__tests__/plugin-kinds.test.js +6 -4
  144. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
  145. package/dist/core/__tests__/plugin-page-components.test.js +6 -4
  146. package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
  147. package/dist/core/__tests__/profile-project-memory-delivery.test.js +4 -1
  148. package/dist/core/__tests__/prune.test.js +11 -5
  149. package/dist/core/__tests__/push-final-guard.test.js +14 -7
  150. package/dist/core/__tests__/relaunch-root.test.js +30 -2
  151. package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
  152. package/dist/core/__tests__/repository-root-identity.test.js +4 -0
  153. package/dist/core/__tests__/review-model-floor.test.js +6 -3
  154. package/dist/core/__tests__/revive-all.test.js +13 -3
  155. package/dist/core/__tests__/revive-capacity.test.js +26 -4
  156. package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
  157. package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
  158. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
  159. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
  160. package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
  161. package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
  162. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
  163. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
  164. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
  165. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +2 -1
  166. package/dist/core/__tests__/stop-guard.test.js +2 -1
  167. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
  168. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +18 -4
  169. package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
  170. package/dist/core/bootstrap.js +2 -0
  171. package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
  172. package/dist/core/broker-client/transport-socket.d.ts +1 -0
  173. package/dist/core/broker-client/transport-socket.js +13 -5
  174. package/dist/core/canvas/__tests__/attention.test.js +29 -35
  175. package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
  176. package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
  177. package/dist/core/canvas/attention.d.ts +2 -5
  178. package/dist/core/canvas/attention.js +15 -64
  179. package/dist/core/canvas/boot.d.ts +6 -7
  180. package/dist/core/canvas/boot.js +5 -9
  181. package/dist/core/canvas/canvas.d.ts +13 -109
  182. package/dist/core/canvas/canvas.js +140 -401
  183. package/dist/core/canvas/crons.d.ts +2 -0
  184. package/dist/core/canvas/crons.js +16 -15
  185. package/dist/core/canvas/daemon-owner.js +10 -0
  186. package/dist/core/canvas/db.d.ts +2 -2
  187. package/dist/core/canvas/db.js +2 -18
  188. package/dist/core/canvas/deliveries.d.ts +104 -0
  189. package/dist/core/canvas/deliveries.js +354 -0
  190. package/dist/core/canvas/executions.d.ts +29 -0
  191. package/dist/core/canvas/executions.js +68 -0
  192. package/dist/core/canvas/history.js +35 -35
  193. package/dist/core/canvas/index.d.ts +3 -1
  194. package/dist/core/canvas/index.js +3 -1
  195. package/dist/core/canvas/migrations.js +20 -12
  196. package/dist/core/canvas/nav-model.js +1 -3
  197. package/dist/core/canvas/nav-render.d.ts +4 -4
  198. package/dist/core/canvas/nav-render.js +11 -21
  199. package/dist/core/canvas/node-sql-migration.d.ts +3 -0
  200. package/dist/core/canvas/node-sql-migration.js +261 -0
  201. package/dist/core/canvas/paths.d.ts +2 -16
  202. package/dist/core/canvas/paths.js +2 -31
  203. package/dist/core/canvas/recovery.d.ts +76 -0
  204. package/dist/core/canvas/recovery.js +588 -0
  205. package/dist/core/canvas/remote-canvas-source.js +4 -0
  206. package/dist/core/canvas/render-source.d.ts +16 -27
  207. package/dist/core/canvas/render-source.js +16 -45
  208. package/dist/core/canvas/sessions.d.ts +33 -0
  209. package/dist/core/canvas/sessions.js +78 -0
  210. package/dist/core/canvas/types.d.ts +33 -33
  211. package/dist/core/canvas/types.js +2 -5
  212. package/dist/core/canvas/waits.d.ts +18 -0
  213. package/dist/core/canvas/waits.js +70 -0
  214. package/dist/core/canvas/worktrees.d.ts +40 -0
  215. package/dist/core/canvas/worktrees.js +93 -0
  216. package/dist/core/config.d.ts +17 -12
  217. package/dist/core/config.js +106 -155
  218. package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
  219. package/dist/core/feed/feed.d.ts +0 -6
  220. package/dist/core/feed/feed.js +68 -56
  221. package/dist/core/feed/inbox.d.ts +7 -81
  222. package/dist/core/feed/inbox.js +46 -378
  223. package/dist/core/feed/messages.d.ts +58 -0
  224. package/dist/core/feed/messages.js +217 -0
  225. package/dist/core/fs-utils.d.ts +4 -0
  226. package/dist/core/fs-utils.js +21 -1
  227. package/dist/core/human/answer.d.ts +1 -1
  228. package/dist/core/human/answer.js +1 -1
  229. package/dist/core/human/claim.d.ts +1 -1
  230. package/dist/core/human/claim.js +2 -4
  231. package/dist/core/human/component-docs.js +1 -1
  232. package/dist/core/human/feedback-companion.js +3 -2
  233. package/dist/core/human/feedback.d.ts +5 -8
  234. package/dist/core/human/feedback.js +57 -85
  235. package/dist/core/human/page-authoring.d.ts +30 -0
  236. package/dist/core/human/page-authoring.js +19 -0
  237. package/dist/core/human/requests.d.ts +136 -0
  238. package/dist/core/human/requests.js +515 -0
  239. package/dist/core/human/root.d.ts +0 -7
  240. package/dist/core/human/root.js +0 -17
  241. package/dist/core/human/scan.d.ts +2 -7
  242. package/dist/core/human/scan.js +48 -132
  243. package/dist/core/human/summary.d.ts +1 -1
  244. package/dist/core/human/summary.js +1 -1
  245. package/dist/core/human/tickets.d.ts +23 -83
  246. package/dist/core/human/tickets.js +92 -243
  247. package/dist/core/human/types.d.ts +5 -1
  248. package/dist/core/installed-plugins.js +8 -3
  249. package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
  250. package/dist/core/locked-file.d.ts +6 -3
  251. package/dist/core/locked-file.js +36 -9
  252. package/dist/core/memory/extensions.js +2 -0
  253. package/dist/core/preview-registry.js +0 -1
  254. package/dist/core/profiles/__tests__/env-store.test.js +2 -0
  255. package/dist/core/profiles/default-binding.d.ts +0 -4
  256. package/dist/core/profiles/default-binding.js +12 -58
  257. package/dist/core/profiles/env-store.js +8 -3
  258. package/dist/core/profiles/manifest.d.ts +2 -37
  259. package/dist/core/profiles/manifest.js +35 -161
  260. package/dist/core/profiles/select.js +3 -0
  261. package/dist/core/review/__tests__/capture-origin.test.js +13 -2
  262. package/dist/core/review/__tests__/comments.test.js +28 -10
  263. package/dist/core/review/__tests__/remap.test.js +28 -10
  264. package/dist/core/review/__tests__/stage-identity.test.js +17 -7
  265. package/dist/core/review/birth.d.ts +1 -1
  266. package/dist/core/review/birth.js +34 -5
  267. package/dist/core/review/comments.js +1 -1
  268. package/dist/core/review/document.js +1 -1
  269. package/dist/core/review/project.d.ts +5 -1
  270. package/dist/core/review/project.js +14 -36
  271. package/dist/core/review/realize.d.ts +3 -6
  272. package/dist/core/review/realize.js +51 -168
  273. package/dist/core/review/remap.js +1 -1
  274. package/dist/core/review/stage.d.ts +3 -2
  275. package/dist/core/review/stage.js +2 -3
  276. package/dist/core/review/store.d.ts +3 -21
  277. package/dist/core/review/store.js +140 -186
  278. package/dist/core/review/types.d.ts +0 -1
  279. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
  280. package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
  281. package/dist/core/runtime/broker/auth-reload.js +9 -10
  282. package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
  283. package/dist/core/runtime/broker/daemon-ops.js +42 -9
  284. package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
  285. package/dist/core/runtime/broker/extension-abort.js +11 -0
  286. package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
  287. package/dist/core/runtime/broker/fault-retry.js +142 -95
  288. package/dist/core/runtime/broker/inbox.d.ts +4 -32
  289. package/dist/core/runtime/broker/inbox.js +4 -92
  290. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  291. package/dist/core/runtime/broker/rebind.js +21 -12
  292. package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
  293. package/dist/core/runtime/broker-persona-guidance.js +2 -13
  294. package/dist/core/runtime/broker.js +28 -22
  295. package/dist/core/runtime/close.d.ts +3 -9
  296. package/dist/core/runtime/close.js +16 -27
  297. package/dist/core/runtime/fault.d.ts +3 -93
  298. package/dist/core/runtime/fault.js +9 -419
  299. package/dist/core/runtime/kickoff.d.ts +3 -6
  300. package/dist/core/runtime/kickoff.js +12 -18
  301. package/dist/core/runtime/launch.js +1 -1
  302. package/dist/core/runtime/lifecycle.js +40 -7
  303. package/dist/core/runtime/placement.js +2 -2
  304. package/dist/core/runtime/recycle.js +8 -2
  305. package/dist/core/runtime/reset.js +22 -6
  306. package/dist/core/runtime/revive.js +226 -218
  307. package/dist/core/runtime/spawn.js +14 -3
  308. package/dist/core/scoped-state/db.d.ts +7 -0
  309. package/dist/core/scoped-state/db.js +92 -0
  310. package/dist/core/scoped-state/migrate.d.ts +11 -0
  311. package/dist/core/scoped-state/migrate.js +198 -0
  312. package/dist/core/scoped-state/paths.d.ts +9 -0
  313. package/dist/core/scoped-state/paths.js +27 -0
  314. package/dist/core/scoped-state/profiles.d.ts +12 -0
  315. package/dist/core/scoped-state/profiles.js +62 -0
  316. package/dist/core/scoped-state/providers.d.ts +16 -0
  317. package/dist/core/scoped-state/providers.js +8 -0
  318. package/dist/core/scoped-state/schema.d.ts +3 -0
  319. package/dist/core/scoped-state/schema.js +26 -0
  320. package/dist/core/scoped-state/settings.d.ts +28 -0
  321. package/dist/core/scoped-state/settings.js +82 -0
  322. package/dist/core/subscription-state.d.ts +29 -48
  323. package/dist/core/subscription-state.js +176 -712
  324. package/dist/core/worktree-close.js +4 -4
  325. package/dist/core/worktree-mutation-async.js +2 -2
  326. package/dist/core/worktree-sweep.js +11 -16
  327. package/dist/core/worktree.js +6 -12
  328. package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
  329. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
  330. package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
  331. package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
  332. package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
  333. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +39 -15
  334. package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
  335. package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
  336. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
  337. package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
  338. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
  339. package/dist/daemon/api/__tests__/model-config.test.js +8 -8
  340. package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
  341. package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
  342. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
  343. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +4 -1
  344. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
  345. package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
  346. package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
  347. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
  348. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
  349. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +27 -41
  350. package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
  351. package/dist/daemon/api/bridge.js +1 -1
  352. package/dist/daemon/api/handlers/bash-jobs.js +6 -7
  353. package/dist/daemon/api/handlers/broker-ops.js +47 -84
  354. package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
  355. package/dist/daemon/api/handlers/broker-recovery.js +251 -0
  356. package/dist/daemon/api/handlers/canvas.js +2 -44
  357. package/dist/daemon/api/handlers/daemon.js +41 -0
  358. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  359. package/dist/daemon/api/handlers/health.js +10 -5
  360. package/dist/daemon/api/handlers/human-requests.js +168 -188
  361. package/dist/daemon/api/handlers/human.js +3 -151
  362. package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
  363. package/dist/daemon/api/handlers/inbox-page.js +89 -0
  364. package/dist/daemon/api/handlers/inbox.js +21 -120
  365. package/dist/daemon/api/handlers/messages.d.ts +1 -0
  366. package/dist/daemon/api/handlers/messages.js +73 -15
  367. package/dist/daemon/api/handlers/node-outcomes.js +58 -13
  368. package/dist/daemon/api/handlers/nodes.js +7 -13
  369. package/dist/daemon/api/handlers/reviews.js +4 -29
  370. package/dist/daemon/api/map.d.ts +25 -3
  371. package/dist/daemon/api/map.js +84 -14
  372. package/dist/daemon/api/server.js +68 -9
  373. package/dist/daemon/control.d.ts +18 -0
  374. package/dist/daemon/cron/disposition.d.ts +2 -0
  375. package/dist/daemon/cron/disposition.js +8 -5
  376. package/dist/daemon/cron/settle.js +37 -13
  377. package/dist/daemon/cron/sinks.d.ts +18 -1
  378. package/dist/daemon/cron/sinks.js +47 -93
  379. package/dist/daemon/crtrd-cli.js +4 -19
  380. package/dist/daemon/crtrd.d.ts +2 -0
  381. package/dist/daemon/crtrd.js +206 -81
  382. package/dist/daemon/fleet.js +5 -6
  383. package/dist/daemon/human/finish.d.ts +12 -24
  384. package/dist/daemon/human/finish.js +88 -285
  385. package/dist/daemon/human/settle.d.ts +40 -0
  386. package/dist/daemon/human/settle.js +89 -0
  387. package/dist/daemon/human/sweep.d.ts +20 -5
  388. package/dist/daemon/human/sweep.js +56 -60
  389. package/dist/daemon/manage.d.ts +21 -16
  390. package/dist/daemon/manage.js +85 -51
  391. package/dist/daemon/messaging/node-message.d.ts +1 -1
  392. package/dist/daemon/messaging/node-message.js +9 -12
  393. package/dist/daemon/park-activity.js +3 -3
  394. package/dist/daemon/reconcilers/bash-deadline.js +6 -7
  395. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  396. package/dist/daemon/reconcilers/broker-supervision.js +41 -19
  397. package/dist/daemon/reconcilers/controller-death.js +6 -18
  398. package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
  399. package/dist/daemon/reconcilers/delivery-lane.js +130 -0
  400. package/dist/daemon/reconcilers/live-obligation.js +3 -3
  401. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  402. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
  403. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
  404. package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
  405. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  406. package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
  407. package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
  408. package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
  409. package/dist/daemon/review/companion.js +5 -11
  410. package/dist/daemon/review/deliver.d.ts +1 -5
  411. package/dist/daemon/review/deliver.js +3 -52
  412. package/dist/daemon/review/finish.d.ts +2 -27
  413. package/dist/daemon/review/finish.js +79 -263
  414. package/dist/daemon/review/sweep.d.ts +3 -10
  415. package/dist/daemon/review/sweep.js +13 -131
  416. package/dist/daemon/startup-policy.d.ts +0 -5
  417. package/dist/daemon/startup-policy.js +0 -5
  418. package/dist/index.d.ts +2 -1
  419. package/dist/index.js +1 -1
  420. package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
  421. package/dist/migrations/__tests__/activation.test.js +9 -6
  422. package/dist/migrations/activation.d.ts +3 -2
  423. package/dist/migrations/activation.js +2 -4
  424. package/dist/migrations/corpus.d.ts +2 -5
  425. package/dist/migrations/corpus.js +9 -20
  426. package/dist/migrations/runner.d.ts +3 -1
  427. package/dist/migrations/runner.js +6 -2
  428. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
  429. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
  430. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
  431. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
  432. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
  433. package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
  434. package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
  435. package/dist/pi-extensions/canvas-passive-context.js +85 -37
  436. package/dist/pi-extensions/canvas-stophook.js +47 -31
  437. package/dist/shared/env.d.ts +1 -0
  438. package/dist/shared/env.js +3 -0
  439. package/package.json +1 -1
  440. package/runtime.lock.json +5 -5
  441. package/dist/clients/attach/__tests__/page-block.test.js +0 -54
  442. package/dist/clients/inbox/review-visibility.d.ts +0 -5
  443. package/dist/clients/inbox/review-visibility.js +0 -19
  444. package/dist/commands/canvas-rebuild-index.d.ts +0 -2
  445. package/dist/commands/canvas-rebuild-index.js +0 -46
  446. package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
  447. package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
  448. package/dist/core/__tests__/human-deliver.test.js +0 -256
  449. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
  450. package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
  451. package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
  452. package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
  453. package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
  454. package/dist/core/__tests__/phase4-review-store.test.js +0 -144
  455. package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
  456. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
  457. package/dist/core/canvas/human-deliveries.d.ts +0 -39
  458. package/dist/core/canvas/human-deliveries.js +0 -75
  459. package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
  460. package/dist/core/canvas/node-outcome-deliveries.js +0 -159
  461. package/dist/core/feed/passive.d.ts +0 -3
  462. package/dist/core/feed/passive.js +0 -53
  463. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
  464. package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
  465. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
  466. package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
  467. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
  468. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
  469. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
  470. package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
  471. package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
  472. package/dist/core/human/__tests__/page-tickets.test.js +0 -161
  473. package/dist/core/review/ticket-filter.d.ts +0 -17
  474. package/dist/core/review/ticket-filter.js +0 -21
  475. package/dist/core/runtime/broker/passive.d.ts +0 -17
  476. package/dist/core/runtime/broker/passive.js +0 -44
  477. package/dist/core/runtime/busy.d.ts +0 -46
  478. package/dist/core/runtime/busy.js +0 -150
  479. package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
  480. package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
  481. package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
  482. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
  483. package/dist/daemon/human/deliver-action.d.ts +0 -3
  484. package/dist/daemon/human/deliver-action.js +0 -9
  485. package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
  486. package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
  487. package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
  488. package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
  489. package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
  490. package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
  491. package/dist/daemon/startup-block-marker.d.ts +0 -25
  492. package/dist/daemon/startup-block-marker.js +0 -99
  493. /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
  494. /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
  495. /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
@@ -1,7 +1,3 @@
1
1
  import type { ReviewRecord } from '../../core/review/types.js';
2
- /** Render the immutable approval fact without replaying comment text. */
2
+ /** Render the immutable approval fact for the direct outbox notification. */
3
3
  export declare function renderApprovalMessage(review: ReviewRecord, resultPath: string): string;
4
- /** Deliver an approval through its origin-specific canonical route. */
5
- export declare function deliverApproval(review: ReviewRecord, resultPath: string): Promise<{
6
- receipt: string | null;
7
- }>;
@@ -1,57 +1,8 @@
1
- import { FinalizationError, pushFinal, redeliverFinalReport } from '../../core/feed/feed.js';
2
1
  import { formatCard } from '../../shared/generated-context.js';
3
- import { deliverNodeMessage } from '../messaging/node-message.js';
4
- function approvalBody(review, resultPath) {
2
+ /** Render the immutable approval fact for the direct outbox notification. */
3
+ export function renderApprovalMessage(review, resultPath) {
5
4
  const summary = review.changed
6
5
  ? `The user reviewed and approved \`${review.file}\`. The document changed during review; re-read it before continuing. Review conversation: node \`${review.companion_node_id}\`.`
7
6
  : `The user reviewed and approved \`${review.file}\`. The document was not modified.`;
8
- return `${summary}\n\nDurable review result: ${resultPath}`;
9
- }
10
- /** Render the immutable approval fact without replaying comment text. */
11
- export function renderApprovalMessage(review, resultPath) {
12
- return formatCard('review-approval', {}, approvalBody(review, resultPath));
13
- }
14
- function recordedFailedFanout(review, reportBasename) {
15
- const error = review.delivery_error;
16
- if (error === null || !error.includes(reportBasename))
17
- return false;
18
- const failed = /delivery failed for (.+)$/.exec(error)?.[1]?.split(', ') ?? [];
19
- return failed.includes(review.origin_node_id);
20
- }
21
- /** Deliver an approval through its origin-specific canonical route. */
22
- export async function deliverApproval(review, resultPath) {
23
- const body = renderApprovalMessage(review, resultPath);
24
- if (review.origin_kind === 'inline') {
25
- const delivery = await deliverNodeMessage({
26
- node_id: review.origin_node_id,
27
- body,
28
- label: 'review approved by the user',
29
- from: 'crtrd',
30
- mode: 'interactive',
31
- data: { review_id: review.review_id, result_path: resultPath },
32
- });
33
- return { receipt: delivery.entry_id };
34
- }
35
- if (review.bridge_node_id === null) {
36
- throw new Error(`ticket review ${review.review_id} has no bridge node`);
37
- }
38
- try {
39
- const result = await pushFinal(review.bridge_node_id, body);
40
- return { receipt: result.reportPath.split('/').at(-1) ?? null };
41
- }
42
- catch (error) {
43
- if (!(error instanceof FinalizationError) || error.code !== 'already_finalized')
44
- throw error;
45
- const reportBasename = error.reportPath;
46
- if (reportBasename === undefined)
47
- throw error;
48
- // A committed final with no failed-delivery ledger is the crash window
49
- // after a successful fanout and before the review ledger was marked.
50
- if (review.delivery_error === null)
51
- return { receipt: reportBasename };
52
- if (!recordedFailedFanout(review, reportBasename))
53
- throw error;
54
- const result = redeliverFinalReport(review.bridge_node_id, review.origin_node_id, reportBasename, body);
55
- return { receipt: result.reportPath.split('/').at(-1) ?? null };
56
- }
7
+ return formatCard('review-approval', {}, `${summary}\n\nDurable review result: ${resultPath}`);
57
8
  }
@@ -1,12 +1,9 @@
1
- import type { TicketResult } from '../../core/human/types.js';
2
1
  import { type ReviewRecord, type ReviewResult } from '../../core/review/types.js';
3
2
  export interface ReviewApprovalFinishOutcome {
4
3
  outcome: 'settled' | 'already_settled';
5
4
  record: ReviewRecord;
6
5
  result: ReviewResult;
7
6
  }
8
- /** The human submitted while the companion was still working. The review stays
9
- * open and the daemon completes the approval once the companion goes quiet. */
10
7
  export interface ReviewSubmitDeferredOutcome {
11
8
  outcome: 'awaiting_companion';
12
9
  record: ReviewRecord;
@@ -15,38 +12,16 @@ export type ReviewSubmitOutcome = ReviewApprovalFinishOutcome | ReviewSubmitDefe
15
12
  export interface ReviewCancellationFinishOutcome {
16
13
  outcome: 'settled' | 'already_settled';
17
14
  record: ReviewRecord;
18
- ticket_result?: TicketResult;
19
15
  }
20
16
  export type ReviewFinishOutcome = ReviewApprovalFinishOutcome | ReviewCancellationFinishOutcome;
21
- /** Approve on the human's behalf, waiting first when the companion is still
22
- * working. Waiting is the only new outcome: an idle companion approves in the
23
- * same pass it always did, and the wait never freezes the review — comments
24
- * added during it are in the snapshot, because the snapshot happens at
25
- * completion and the review is still open. */
26
17
  export declare function submitReviewApproval(reviewId: string): Promise<ReviewSubmitOutcome>;
27
- /** Complete a submit the human already pressed, once its companion is quiet.
28
- * Returns null when there is nothing to complete — no pending intent, the
29
- * review moved on, or the companion is still working. Idempotent: concurrent
30
- * callers race on the same conditional `state = 'open'` approval write, so
31
- * only one can win and the loser reports what the winner committed.
32
- *
33
- * `atCompanionTurnEnd` marks the one caller that IS the companion's turn end.
34
- * There the mid-turn marker may not be cleared yet, so it is not consulted;
35
- * queued work still defers, because an inbox entry means another turn is
36
- * coming and the wait should outlast it. */
37
18
  export declare function completeRequestedSubmit(reviewId: string, opts: {
38
19
  atCompanionTurnEnd: boolean;
39
20
  }): Promise<ReviewApprovalFinishOutcome | null>;
40
- /** The companion's turn ended: complete any submit the human left waiting on
41
- * it. Never throws — a settlement directive must not depend on delivery. */
42
- export declare function completeCompanionRequestedSubmit(companionNodeId: string): Promise<void>;
43
- /** `disposition` rides through to the ticket result: the recipient closing a
44
- * review in their inbox is a dismissal, while the requester withdrawing it
45
- * stays a cancellation. */
21
+ export declare function completeCompanionRequestedSubmit(companionNodeId: string): Promise<ReviewApprovalFinishOutcome | null>;
46
22
  export interface ReviewCancellationArgs {
47
23
  reason?: string;
48
24
  actor?: string;
49
25
  disposition?: 'canceled' | 'dismissed';
50
26
  }
51
- /** Cancel an open review once; ticket cancellation remains owned by the retained human-ticket finisher. */
52
- export declare function cancelReview(reviewId: string, args: ReviewCancellationArgs): Promise<ReviewCancellationFinishOutcome>;
27
+ export declare function cancelReview(reviewId: string, args?: ReviewCancellationArgs): Promise<ReviewCancellationFinishOutcome>;
@@ -1,265 +1,86 @@
1
1
  import { withCanvasWrite } from '../../core/canvas/db.js';
2
- import { responsePath } from '../../core/human/convention.js';
3
- import { ticketDir } from '../../core/human/root.js';
4
- import { readTicketResult } from '../../core/human/tickets.js';
5
- import { projectReviewResult, buildReviewResult } from '../../core/review/project.js';
6
- import { reviewResultPath } from '../../core/canvas/paths.js';
7
2
  import { snapshotCommentsLocked } from '../../core/review/comments.js';
8
3
  import { readReviewSource } from '../../core/review/document.js';
4
+ import { projectReviewCancellation, projectReviewResult, buildReviewResult } from '../../core/review/project.js';
9
5
  import { signalReviewActivity } from '../../core/review/signal.js';
10
- import { approveReviewLocked, cancelReviewRow, getReview, getReviewByCompanion, markDelivered, markDeliveryError, markProjected, markProjectionError, requestReviewSubmit, requireVisibleReview, } from '../../core/review/store.js';
6
+ import { getReview, getReviewByCompanion, requestReviewSubmit, requireVisibleReview } from '../../core/review/store.js';
11
7
  import { ReviewOperationError } from '../../core/review/types.js';
12
- import { cancelPendingEntries } from '../../core/feed/inbox.js';
13
- import { emitEvent } from '../../core/events/emit.js';
8
+ import { settleHumanRequest } from '../human/settle.js';
14
9
  import { retireCompanion } from '../companion-retire.js';
15
- import { deliverNodeMessage } from '../messaging/node-message.js';
16
- import { cancelHumanTicket, deliverTerminalResult } from '../human/finish.js';
17
10
  import { companionHasQueuedWork, companionMidTurn, companionStillWorking } from './companion.js';
18
- import { deliverApproval } from './deliver.js';
19
- /** One daemon serializes terminal side effects for each immutable review row. */
20
- const finishChains = new Map();
21
- function now() {
22
- return new Date().toISOString();
23
- }
24
- function errorText(error) {
25
- return error instanceof Error ? error.message : String(error);
26
- }
11
+ import { renderApprovalMessage } from './deliver.js';
12
+ function now() { return new Date().toISOString(); }
27
13
  function terminalConflict(review, requested) {
28
- throw new ReviewOperationError('review_terminal', 'review already has a terminal outcome', {
29
- state: review.state,
30
- requested,
31
- review,
32
- });
14
+ throw new ReviewOperationError('review_terminal', 'review already has a terminal outcome', { state: review.state, requested, review });
33
15
  }
34
16
  function approvedResult(review) {
35
17
  if (review.result_json === null)
36
18
  throw new Error(`approved review lacks its immutable result: ${review.review_id}`);
37
19
  return JSON.parse(review.result_json);
38
20
  }
39
- function resultPath(review) {
40
- if (review.origin_kind === 'inline')
41
- return reviewResultPath(review.review_id);
42
- if (review.bridge_node_id === null)
43
- throw new Error(`ticket review lacks its bridge node: ${review.review_id}`);
44
- return responsePath(ticketDir(review.bridge_node_id));
45
- }
46
- function ticketResult(review) {
47
- return review.origin_kind === 'ticket' && review.bridge_node_id !== null
48
- ? readTicketResult(ticketDir(review.bridge_node_id)) ?? undefined
49
- : undefined;
50
- }
51
- function isPostReplayAlreadyResolved(error) {
52
- return error instanceof Error
53
- && 'status' in error
54
- && error.status === 409
55
- && 'code' in error
56
- && error.code === 'ticket_already_resolved';
57
- }
58
- async function serializedFinish(reviewId, work) {
59
- const prior = finishChains.get(reviewId) ?? Promise.resolve();
60
- const run = prior.catch(() => { }).then(work);
61
- const tail = run.then(() => { }, () => { });
62
- finishChains.set(reviewId, tail);
63
- try {
64
- return await run;
65
- }
66
- finally {
67
- if (finishChains.get(reviewId) === tail)
68
- finishChains.delete(reviewId);
69
- }
70
- }
71
- async function finishApproved(review, result) {
72
- retractSubmitQueuedNote(review);
73
- let current = requireVisibleReview(review.review_id);
74
- if (current.projected_at === null) {
75
- try {
76
- projectReviewResult(current, result);
77
- markProjected(current.review_id, now());
78
- }
79
- catch (error) {
80
- markProjectionError(current.review_id, errorText(error));
81
- }
82
- }
83
- current = requireVisibleReview(review.review_id);
84
- if (current.delivered_at === null) {
85
- try {
86
- const delivery = await deliverApproval(current, resultPath(current));
87
- markDelivered(current.review_id, delivery.receipt, now());
88
- }
89
- catch (error) {
90
- markDeliveryError(current.review_id, errorText(error));
91
- }
92
- }
93
- current = requireVisibleReview(review.review_id);
94
- await retireCompanion(current.companion_node_id, 'approved');
95
- return requireVisibleReview(review.review_id);
96
- }
97
- async function finishCanceled(review, winningWrite, args) {
98
- retractSubmitQueuedNote(review);
99
- let current = requireVisibleReview(review.review_id);
100
- let canceledTicket;
101
- if (current.origin_kind === 'inline') {
102
- if (current.projected_at === null)
103
- markProjected(current.review_id, now());
104
- current = requireVisibleReview(review.review_id);
105
- if (current.delivered_at === null)
106
- markDelivered(current.review_id, null, now());
107
- }
108
- else if (current.bridge_node_id === null) {
109
- markProjectionError(current.review_id, `ticket review lacks its bridge node: ${current.review_id}`);
110
- markDeliveryError(current.review_id, `ticket review lacks its bridge node: ${current.review_id}`);
111
- }
112
- else if (current.delivered_at === null) {
113
- try {
114
- if (winningWrite) {
115
- canceledTicket = await cancelHumanTicket(current.bridge_node_id, args);
116
- }
117
- else {
118
- const delivered = await deliverTerminalResult(current.bridge_node_id);
119
- if (!delivered)
120
- throw new Error(`ticket cancellation is not available for delivery: ${current.bridge_node_id}`);
121
- canceledTicket = ticketResult(current);
122
- }
123
- if (canceledTicket === undefined)
124
- throw new Error(`ticket cancellation result is missing: ${current.bridge_node_id}`);
125
- markProjected(current.review_id, now());
126
- markDelivered(current.review_id, null, now());
127
- }
128
- catch (error) {
129
- if (winningWrite && isPostReplayAlreadyResolved(error)) {
130
- try {
131
- const delivered = await deliverTerminalResult(current.bridge_node_id);
132
- if (!delivered)
133
- throw new Error(`ticket cancellation is not available for delivery: ${current.bridge_node_id}`);
134
- canceledTicket = ticketResult(current);
135
- if (canceledTicket === undefined)
136
- throw new Error(`ticket cancellation result is missing: ${current.bridge_node_id}`);
137
- markProjected(current.review_id, now());
138
- markDelivered(current.review_id, null, now());
139
- }
140
- catch (replayError) {
141
- markDeliveryError(current.review_id, errorText(replayError));
142
- }
143
- }
144
- else {
145
- // cancelHumanTicket publishes response.json before fanout. Preserve that
146
- // publication ledger even when the retained delivery path reports a failure.
147
- if (ticketResult(current) !== undefined)
148
- markProjected(current.review_id, now());
149
- markDeliveryError(current.review_id, errorText(error));
150
- }
151
- }
152
- }
153
- current = requireVisibleReview(review.review_id);
154
- if (canceledTicket === undefined)
155
- canceledTicket = ticketResult(current);
156
- await retireCompanion(current.companion_node_id, 'canceled');
157
- return { record: requireVisibleReview(review.review_id), ...(canceledTicket === undefined ? {} : { ticket_result: canceledTicket }) };
158
- }
159
- const SUBMIT_QUEUED_NOTE = 'review-submit-queued';
160
- /** Retract an undelivered queued-submit note once the review is settling. The
161
- * note rides the deferred tier and so does not wake the origin, while the
162
- * terminal result goes live — without this the origin reads "result to
163
- * follow" only after it already acted on that result. */
164
- function retractSubmitQueuedNote(review) {
165
- try {
166
- cancelPendingEntries(review.origin_node_id, (entry) => entry.kind === 'message'
167
- && entry.data?.['note'] === SUBMIT_QUEUED_NOTE
168
- && entry.data?.['review_id'] === review.review_id);
169
- }
170
- catch (error) {
171
- emitEvent({ level: 'warn', event: 'review.submit_queued_note.retract_failed', error });
172
- }
21
+ function resultPath(review) { return `${review.review_dir}/result.json`; }
22
+ function effects(result) {
23
+ return {
24
+ project: (request) => { projectReviewResult(requireVisibleReview(request.request_id), result); },
25
+ retire: async (nodeId, outcome) => { await retireCompanion(nodeId, outcome); },
26
+ };
173
27
  }
174
- /** Tell the origin its review was submitted but is finishing behind the
175
- * companion. Deliberately deferred: the origin is told nothing is needed of
176
- * it, so waking it to say so would be noise. The approval itself wakes it. */
177
- async function noteSubmitQueued(review) {
178
- try {
179
- await deliverNodeMessage({
180
- node_id: review.origin_node_id,
181
- from: 'crtrd',
182
- mode: 'quiet',
183
- label: 'human review submitted — result to follow',
184
- data: { review_id: review.review_id, note: SUBMIT_QUEUED_NOTE },
185
- runtime: { kind: 'review-queued', facts: {} },
186
- body: `The human submitted their review of \`${review.file}\`; the document is still being edited. `
187
- + "You'll be notified with the result once the review completes. Nothing is needed from you now.",
188
- });
189
- }
190
- catch (error) {
191
- emitEvent({ level: 'warn', event: 'review.submit_queued_note.failed', error });
192
- }
28
+ function approvalNotification(review) {
29
+ return {
30
+ label: 'review approved by the user',
31
+ disposition: 'human-answer',
32
+ body_json: { review_id: review.review_id, result_path: resultPath(review), body: renderApprovalMessage(review, resultPath(review)) },
33
+ };
193
34
  }
194
- /** Approve on the human's behalf, waiting first when the companion is still
195
- * working. Waiting is the only new outcome: an idle companion approves in the
196
- * same pass it always did, and the wait never freezes the review — comments
197
- * added during it are in the snapshot, because the snapshot happens at
198
- * completion and the review is still open. */
199
- export async function submitReviewApproval(reviewId) {
200
- const initial = requireVisibleReview(reviewId);
201
- if (initial.state === 'canceled')
202
- return terminalConflict(initial, 'submit');
203
- if (initial.state === 'open' && companionStillWorking(initial.companion_node_id)) {
204
- if (requestReviewSubmit(reviewId, now())) {
205
- signalReviewActivity();
206
- await noteSubmitQueued(initial);
207
- }
208
- return { outcome: 'awaiting_companion', record: requireVisibleReview(reviewId) };
209
- }
210
- return await approveReview(initial);
35
+ function cancellationNotification(review, reason, disposition) {
36
+ const dismissed = disposition === 'dismissed';
37
+ return {
38
+ label: dismissed ? 'review dismissed' : 'review canceled',
39
+ disposition: 'human-canceled',
40
+ body_json: { review_id: review.review_id, disposition, body: dismissed ? `The review of \`${review.file}\` was dismissed without approval.` : `The review of \`${review.file}\` was canceled${reason === '' ? '' : ` — ${reason}`}.` },
41
+ };
211
42
  }
212
- /** Commit approval once, then independently finish its projection, delivery, and companion retirement ledgers. */
213
43
  async function approveReview(initial) {
214
- const reviewId = initial.review_id;
215
44
  if (initial.state === 'canceled')
216
45
  return terminalConflict(initial, 'submit');
217
- if (initial.state === 'approved') {
218
- const result = approvedResult(initial);
219
- const record = await serializedFinish(reviewId, () => finishApproved(initial, result));
220
- return { outcome: 'already_settled', record, result };
221
- }
46
+ if (initial.state === 'approved')
47
+ return { outcome: 'already_settled', record: initial, result: approvedResult(initial) };
222
48
  const source = readReviewSource(initial.file, 'submit');
223
- const committed = withCanvasWrite((db) => {
224
- const review = requireVisibleReview(reviewId);
49
+ const { result, resultJson } = withCanvasWrite((db) => {
50
+ const review = requireVisibleReview(initial.review_id);
225
51
  if (review.state === 'canceled')
226
52
  return terminalConflict(review, 'submit');
227
53
  if (review.state === 'approved')
228
- return { outcome: 'already_settled', review, result: approvedResult(review) };
229
- const snapshot = snapshotCommentsLocked(db, reviewId);
230
- const at = now();
231
- const result = buildReviewResult(review, snapshot, source.sha256, at);
232
- if (!approveReviewLocked(db, {
233
- review_id: reviewId,
234
- approved_at: at,
235
- approved_sha256: source.sha256,
236
- changed: result.changed,
237
- comments_total: snapshot.total,
238
- comments_unresolved: snapshot.unresolved,
239
- result_json: JSON.stringify(result),
240
- })) {
241
- const winner = requireVisibleReview(reviewId);
242
- if (winner.state === 'approved')
243
- return { outcome: 'already_settled', review: winner, result: approvedResult(winner) };
244
- return terminalConflict(winner, 'submit');
245
- }
246
- return { outcome: 'settled', review: requireVisibleReview(reviewId), result };
54
+ return { result: approvedResult(review), resultJson: review.result_json };
55
+ const snapshot = snapshotCommentsLocked(db, review.review_id);
56
+ const result = buildReviewResult(review, snapshot, source.sha256, now());
57
+ return { result, resultJson: JSON.stringify(result) };
58
+ });
59
+ const settled = await settleHumanRequest({
60
+ request_id: initial.review_id,
61
+ outcome: 'approved',
62
+ result_json: resultJson,
63
+ notification: approvalNotification({ ...initial, changed: result.changed }),
64
+ post_commit: effects(result),
247
65
  });
248
- if (committed.outcome === 'settled')
66
+ if (settled.outcome === 'settled')
249
67
  signalReviewActivity();
250
- const record = await serializedFinish(reviewId, () => finishApproved(committed.review, committed.result));
251
- return { outcome: committed.outcome, record, result: committed.result };
68
+ const record = requireVisibleReview(initial.review_id);
69
+ if (settled.outcome === 'already_settled' && record.state !== 'approved')
70
+ return terminalConflict(record, 'submit');
71
+ return { outcome: settled.outcome, record, result: settled.outcome === 'settled' ? result : approvedResult(record) };
72
+ }
73
+ export async function submitReviewApproval(reviewId) {
74
+ const review = requireVisibleReview(reviewId);
75
+ if (review.state === 'canceled')
76
+ return terminalConflict(review, 'submit');
77
+ if (review.state === 'open' && companionStillWorking(review.companion_node_id)) {
78
+ if (requestReviewSubmit(reviewId, now()))
79
+ signalReviewActivity();
80
+ return { outcome: 'awaiting_companion', record: requireVisibleReview(reviewId) };
81
+ }
82
+ return approveReview(review);
252
83
  }
253
- /** Complete a submit the human already pressed, once its companion is quiet.
254
- * Returns null when there is nothing to complete — no pending intent, the
255
- * review moved on, or the companion is still working. Idempotent: concurrent
256
- * callers race on the same conditional `state = 'open'` approval write, so
257
- * only one can win and the loser reports what the winner committed.
258
- *
259
- * `atCompanionTurnEnd` marks the one caller that IS the companion's turn end.
260
- * There the mid-turn marker may not be cleared yet, so it is not consulted;
261
- * queued work still defers, because an inbox entry means another turn is
262
- * coming and the wait should outlast it. */
263
84
  export async function completeRequestedSubmit(reviewId, opts) {
264
85
  const review = getReview(reviewId);
265
86
  if (review === null || review.state !== 'open' || review.submit_requested_at === null)
@@ -268,39 +89,34 @@ export async function completeRequestedSubmit(reviewId, opts) {
268
89
  return null;
269
90
  if (!opts.atCompanionTurnEnd && companionMidTurn(review.companion_node_id))
270
91
  return null;
271
- return await approveReview(review);
92
+ return approveReview(review);
272
93
  }
273
- /** The companion's turn ended: complete any submit the human left waiting on
274
- * it. Never throws — a settlement directive must not depend on delivery. */
275
94
  export async function completeCompanionRequestedSubmit(companionNodeId) {
276
- try {
277
- const review = getReviewByCompanion(companionNodeId);
278
- if (review === null || review.state !== 'open' || review.submit_requested_at === null)
279
- return;
280
- await completeRequestedSubmit(review.review_id, { atCompanionTurnEnd: true });
281
- }
282
- catch (error) {
283
- emitEvent({ level: 'error', event: 'review.deferred_submit.failed', error });
284
- }
95
+ const review = getReviewByCompanion(companionNodeId);
96
+ return review === null ? null : completeRequestedSubmit(review.review_id, { atCompanionTurnEnd: true });
285
97
  }
286
- /** Cancel an open review once; ticket cancellation remains owned by the retained human-ticket finisher. */
287
- export async function cancelReview(reviewId, args) {
288
- const initial = requireVisibleReview(reviewId);
289
- if (initial.state === 'approved')
290
- return terminalConflict(initial, 'cancel');
291
- const winningWrite = initial.state === 'open'
292
- && cancelReviewRow(reviewId, { at: now(), reason: args.reason ?? '', actor: args.actor ?? null });
98
+ export async function cancelReview(reviewId, args = {}) {
293
99
  const review = requireVisibleReview(reviewId);
294
100
  if (review.state === 'approved')
295
101
  return terminalConflict(review, 'cancel');
296
- if (review.state !== 'canceled')
297
- throw new Error(`review ${reviewId} did not reach its canceled state`);
298
- if (winningWrite)
102
+ const at = now();
103
+ const reason = args.reason ?? '';
104
+ const disposition = args.disposition ?? 'canceled';
105
+ const resultJson = JSON.stringify({ schema: 'humanloop.cancel/v1', kind: 'canceled', canceledAt: at, ...(reason === '' ? {} : { reason }), ...(args.actor === undefined ? {} : { actor: args.actor }), ...(disposition === 'dismissed' ? { disposition } : {}) });
106
+ const settled = await settleHumanRequest({
107
+ request_id: reviewId,
108
+ outcome: disposition === 'dismissed' ? 'dismissed' : 'canceled',
109
+ result_json: resultJson,
110
+ notification: cancellationNotification(review, reason, disposition),
111
+ post_commit: {
112
+ project: (request) => { projectReviewCancellation(requireVisibleReview(request.request_id), JSON.parse(resultJson)); },
113
+ retire: async (nodeId, outcome) => { await retireCompanion(nodeId, outcome); },
114
+ },
115
+ });
116
+ if (settled.outcome === 'settled')
299
117
  signalReviewActivity();
300
- const finished = await serializedFinish(reviewId, () => finishCanceled(review, winningWrite, args));
301
- return {
302
- outcome: winningWrite ? 'settled' : 'already_settled',
303
- record: finished.record,
304
- ...(finished.ticket_result === undefined ? {} : { ticket_result: finished.ticket_result }),
305
- };
118
+ const record = requireVisibleReview(reviewId);
119
+ if (settled.outcome === 'already_settled' && record.state === 'approved')
120
+ return terminalConflict(record, 'cancel');
121
+ return { outcome: settled.outcome, record };
306
122
  }
@@ -1,11 +1,4 @@
1
- export interface ReviewSweepResult {
2
- realized: number;
3
- collected: number;
4
- reprojected: number;
5
- failed: number;
6
- }
7
- /**
8
- * Recover only pre-exposure review work at daemon startup. Terminal delivery and
9
- * retirement are intentionally outside this pass and require an explicit repeat.
10
- */
1
+ import { type HumanRequestSweepResult } from '../human/sweep.js';
2
+ export type ReviewSweepResult = HumanRequestSweepResult;
3
+ /** Compatibility entry point for daemon boot. All recovery is driven by human_requests. */
11
4
  export declare function sweepReviews(): Promise<ReviewSweepResult>;