@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,136 +1,18 @@
1
- import { existsSync, readdirSync, rmSync } from 'node:fs';
2
- import { basename } from 'node:path';
3
- import { emitEvent } from '../../core/events/emit.js';
4
- import { reviewPath } from '../../core/human/convention.js';
5
- import { ticketDir } from '../../core/human/root.js';
6
- import { submitReview } from '../../core/human/tickets.js';
7
- import { reviewsRoot } from '../../core/canvas/paths.js';
8
- import { getNode } from '../../core/canvas/index.js';
9
- import { loadProfileManifest } from '../../core/profiles/manifest.js';
1
+ import { requireVisibleReview } from '../../core/review/store.js';
10
2
  import { projectReviewResult } from '../../core/review/project.js';
11
3
  import { realizeReview } from '../../core/review/realize.js';
12
- import { listBindingReviews, listReviews, markProjected, markProjectionError, } from '../../core/review/store.js';
13
- import { ReviewOperationError } from '../../core/review/types.js';
14
- function errorText(error) {
15
- return error instanceof Error ? error.message : String(error);
16
- }
17
- function isMissingPath(error) {
18
- return error?.code === 'ENOENT';
19
- }
20
- /** Republish the ticket projection only after its canonical review is already open. */
21
- function republishTicketReview(review) {
22
- if (review.bridge_node_id === null)
23
- throw new Error(`ticket review has no bridge node: ${review.review_id}`);
24
- if (review.subtitle === null)
25
- throw new Error(`ticket review has no subtitle: ${review.review_id}`);
26
- const dir = ticketDir(review.bridge_node_id);
27
- if (existsSync(reviewPath(dir)))
28
- return;
29
- const origin = getNode(review.origin_node_id);
30
- if (origin === null)
31
- throw new Error(`ticket review origin is missing: ${review.origin_node_id}`);
32
- const profileName = origin.profile_id == null
33
- ? undefined
34
- : loadProfileManifest(origin.profile_id).manifest.name;
35
- submitReview({
36
- dir,
37
- review: {
38
- file: review.file,
39
- ...(review.output_path === null ? {} : { output: review.output_path }),
40
- title: basename(review.file),
41
- subtitle: review.subtitle,
42
- source: {
43
- nodeId: review.origin_node_id,
44
- ...(profileName === undefined ? {} : { profileName }),
45
- },
46
- blockedSince: review.created,
4
+ import { retireCompanion } from '../companion-retire.js';
5
+ import { sweepHumanRequests } from '../human/sweep.js';
6
+ /** Compatibility entry point for daemon boot. All recovery is driven by human_requests. */
7
+ export async function sweepReviews() {
8
+ return sweepHumanRequests({
9
+ realizeReview,
10
+ projectReview: (request) => {
11
+ const review = requireVisibleReview(request.request_id);
12
+ if (review.result_json === null)
13
+ throw new Error(`approved review lacks its immutable result: ${review.review_id}`);
14
+ projectReviewResult(review, JSON.parse(review.result_json));
47
15
  },
16
+ retireCompanion: async (nodeId, outcome) => { await retireCompanion(nodeId, outcome); },
48
17
  });
49
18
  }
50
- /** Reproject only an immutable, already-approved canonical result. */
51
- function reprojectApprovedReview(review) {
52
- if (review.result_json === null)
53
- throw new Error(`approved review lacks its immutable result: ${review.review_id}`);
54
- projectReviewResult(review, JSON.parse(review.result_json));
55
- markProjected(review.review_id, new Date().toISOString());
56
- }
57
- /** Remove only direct review directories that are no longer referenced by a row. */
58
- function collectOrphanReviewDirectories(reviewIds) {
59
- let entries;
60
- try {
61
- entries = readdirSync(reviewsRoot(), { withFileTypes: true });
62
- }
63
- catch (error) {
64
- if (isMissingPath(error))
65
- return 0;
66
- throw error;
67
- }
68
- let collected = 0;
69
- for (const entry of entries) {
70
- if (!entry.isDirectory() || reviewIds.has(entry.name))
71
- continue;
72
- rmSync(`${reviewsRoot()}/${entry.name}`, { recursive: true, force: true });
73
- collected += 1;
74
- }
75
- return collected;
76
- }
77
- /**
78
- * Recover only pre-exposure review work at daemon startup. Terminal delivery and
79
- * retirement are intentionally outside this pass and require an explicit repeat.
80
- */
81
- export async function sweepReviews() {
82
- let realized = 0;
83
- let collected = 0;
84
- let reprojected = 0;
85
- let failed = 0;
86
- const bindings = listBindingReviews();
87
- for (const review of bindings) {
88
- try {
89
- await realizeReview(review.review_id);
90
- realized += 1;
91
- }
92
- catch (error) {
93
- // A missing immutable branch is an expected recovery outcome: realization
94
- // cancels the binding and never captures a replacement branch.
95
- if (!(error instanceof ReviewOperationError && error.code === 'branch_lost')) {
96
- emitEvent({ level: 'warn', event: 'daemon.review_sweep.realize_failed', fields: { review_id: review.review_id, error: errorText(error) } });
97
- failed += 1;
98
- }
99
- }
100
- }
101
- try {
102
- const reviewIds = new Set([
103
- ...listBindingReviews().map((review) => review.review_id),
104
- ...listReviews({}).map((review) => review.review_id),
105
- ]);
106
- collected = collectOrphanReviewDirectories(reviewIds);
107
- }
108
- catch (error) {
109
- emitEvent({ level: 'warn', event: 'daemon.review_sweep.collect_orphans_failed', fields: { error: errorText(error) } });
110
- failed += 1;
111
- }
112
- for (const review of listReviews({ state: 'approved' })) {
113
- if (review.projected_at !== null)
114
- continue;
115
- try {
116
- reprojectApprovedReview(review);
117
- reprojected += 1;
118
- }
119
- catch (error) {
120
- markProjectionError(review.review_id, errorText(error));
121
- failed += 1;
122
- }
123
- }
124
- for (const review of listReviews({ state: 'open' })) {
125
- if (review.origin_kind !== 'ticket')
126
- continue;
127
- try {
128
- republishTicketReview(review);
129
- }
130
- catch (error) {
131
- emitEvent({ level: 'warn', event: 'daemon.review_sweep.republish_failed', fields: { review_id: review.review_id, error: errorText(error) } });
132
- failed += 1;
133
- }
134
- }
135
- return { realized, collected, reprojected, failed };
136
- }
@@ -1,6 +1 @@
1
1
  export declare const DAEMON_STARTUP_WINDOW_MS: number;
2
- /** Exit code a daemon uses when startup hit a STANDING condition that retrying
3
- * cannot clear (today: a blocked on-disk migration). Distinct from a generic
4
- * failure so the spawner can stop retrying and surface the repair instead of
5
- * respawning into the same wall. 78 is sysexits' EX_CONFIG. */
6
- export declare const DAEMON_EXIT_STARTUP_BLOCKED = 78;
@@ -1,6 +1 @@
1
1
  export const DAEMON_STARTUP_WINDOW_MS = 5 * 60 * 1_000;
2
- /** Exit code a daemon uses when startup hit a STANDING condition that retrying
3
- * cannot clear (today: a blocked on-disk migration). Distinct from a generic
4
- * failure so the spawner can stop retrying and surface the repair instead of
5
- * respawning into the same wall. 78 is sysexits' EX_CONFIG. */
6
- export const DAEMON_EXIT_STARTUP_BLOCKED = 78;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@ export { reviveNode } from './core/runtime/revive.js';
2
2
  export type { ReviveResult } from './core/runtime/revive.js';
3
3
  export { closeNode } from './core/runtime/close.js';
4
4
  export type { CloseNodeResult } from './core/runtime/close.js';
5
- export { appendInbox } from './core/feed/inbox.js';
5
+ export { enqueueNodeMail } from './core/feed/messages.js';
6
+ export type { NodeMailInput } from './core/feed/messages.js';
6
7
  export type { InboxEntry, InboxTier, InboxKind } from './core/feed/inbox.js';
7
8
  export { appendSituationalContext } from './core/runtime/situational-context.js';
8
9
  export { isTurnInternal } from './core/runtime/turn-visibility.js';
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@
16
16
  // other caller (D-9), because an unbound launch throws by design (D-2).
17
17
  export { reviveNode } from './core/runtime/revive.js';
18
18
  export { closeNode } from './core/runtime/close.js';
19
- export { appendInbox } from './core/feed/inbox.js';
19
+ export { enqueueNodeMail } from './core/feed/messages.js';
20
20
  // Hidden ambient "current situation" sidecar (see runtime/situational-context.ts) —
21
21
  // upsert-only, narrow surface so an external composer (e.g. Hearth) never needs to
22
22
  // learn the storage file itself.
@@ -36,6 +36,7 @@ function childActivation(home, release) {
36
36
  const { activateOnDiskMigrations } = await import(${JSON.stringify(moduleUrl)});
37
37
  await activateOnDiskMigrations({
38
38
  timeoutMs: 5000,
39
+ nodes: [],
39
40
  runner: async () => {
40
41
  writeFileSync(join(${JSON.stringify(home)}, 'entered.' + process.pid), '');
41
42
  while (!existsSync(${JSON.stringify(release)})) await new Promise((resolve) => setTimeout(resolve, 5));
@@ -107,9 +108,9 @@ test('activation and a forced migration serialize, and forced still runs after t
107
108
  }
108
109
  };
109
110
  try {
110
- const activation = activateOnDiskMigrations({ timeoutMs: 1_000, runner });
111
+ const activation = activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner });
111
112
  await entered.promise;
112
- const forced = runForcedOnDiskMigrations({ timeoutMs: 1_000, runner });
113
+ const forced = runForcedOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner });
113
114
  await delay(30);
114
115
  assert.equal(calls, 1);
115
116
  gate.resolve();
@@ -37,13 +37,13 @@ test('activation skips only an exact current marker', async () => {
37
37
  let runs = 0;
38
38
  const runner = async () => { runs += 1; return result(); };
39
39
  writeFileSync(onDiskMigrationMarkerPath(), JSON.stringify(onDiskMigrationIdentity()));
40
- assert.equal(await activateOnDiskMigrations({ timeoutMs: 1_000, runner }), null);
40
+ assert.equal(await activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner }), null);
41
41
  assert.equal(runs, 0);
42
42
  for (const invalid of [undefined, '{broken', JSON.stringify(onDiskMigrationIdentity().slice(0, -1))]) {
43
43
  rmSync(onDiskMigrationMarkerPath(), { force: true });
44
44
  if (invalid !== undefined)
45
45
  writeFileSync(onDiskMigrationMarkerPath(), invalid);
46
- assert.notEqual(await activateOnDiskMigrations({ timeoutMs: 1_000, runner }), null);
46
+ assert.notEqual(await activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner }), null);
47
47
  }
48
48
  assert.equal(runs, 3);
49
49
  assert.deepEqual(marker(), onDiskMigrationIdentity());
@@ -63,7 +63,7 @@ test('a superseded 003 identity reruns the corpus lane and the repository-root i
63
63
  { id: '002-profile-project-memory', lane: 'profile-manifest' },
64
64
  { id: '003-workspace-qualified-memory-identity', lane: 'corpus' },
65
65
  ]));
66
- assert.notEqual(await activateOnDiskMigrations({ timeoutMs: 1_000, runner }), null, 'the superseded 003 identity must not satisfy activation');
66
+ assert.notEqual(await activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner }), null, 'the superseded 003 identity must not satisfy activation');
67
67
  assert.equal(runs, 1);
68
68
  const repositoryRootIdentity = [
69
69
  { id: '001-surfaces-frontmatter', lane: 'convergent' },
@@ -72,7 +72,7 @@ test('a superseded 003 identity reruns the corpus lane and the repository-root i
72
72
  ];
73
73
  assert.deepEqual(marker(), repositoryRootIdentity, 'the rerun records the repository-root identity in order');
74
74
  writeFileSync(onDiskMigrationMarkerPath(), JSON.stringify(repositoryRootIdentity));
75
- assert.equal(await activateOnDiskMigrations({ timeoutMs: 1_000, runner }), null);
75
+ assert.equal(await activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner }), null);
76
76
  assert.equal(runs, 1, 'the repository-root marker skips the run');
77
77
  });
78
78
  });
@@ -94,6 +94,7 @@ test('forced runs ignore current markers while dry runs leave marker bytes untou
94
94
  let runs = 0;
95
95
  await runForcedOnDiskMigrations({
96
96
  timeoutMs: 1_000,
97
+ nodes: [],
97
98
  runner: async () => { runs += 1; return result(); },
98
99
  });
99
100
  assert.equal(runs, 1);
@@ -101,6 +102,7 @@ test('forced runs ignore current markers while dry runs leave marker bytes untou
101
102
  writeFileSync(onDiskMigrationMarkerPath(), '{malformed but preserved');
102
103
  await runForcedOnDiskMigrations({
103
104
  timeoutMs: 1_000,
105
+ nodes: [],
104
106
  dryRun: true,
105
107
  runner: async () => { runs += 1; return result({ verified: false }); },
106
108
  });
@@ -110,9 +112,9 @@ test('forced runs ignore current markers while dry runs leave marker bytes untou
110
112
  });
111
113
  test('failure leaves the marker absent and a later activation converges', async () => {
112
114
  await inHome(async () => {
113
- await assert.rejects(activateOnDiskMigrations({ timeoutMs: 1_000, runner: async () => { throw new Error('interrupted'); } }), /interrupted/);
115
+ await assert.rejects(activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner: async () => { throw new Error('interrupted'); } }), /interrupted/);
114
116
  assert.equal(existsSync(onDiskMigrationMarkerPath()), false);
115
- await activateOnDiskMigrations({ timeoutMs: 1_000, runner: async () => result() });
117
+ await activateOnDiskMigrations({ timeoutMs: 1_000, nodes: [], runner: async () => result() });
116
118
  assert.deepEqual(marker(), onDiskMigrationIdentity());
117
119
  });
118
120
  });
@@ -124,6 +126,7 @@ test('an unreadable profile blocker aborts startup effects with its path and rep
124
126
  const startup = async () => {
125
127
  await activateOnDiskMigrations({
126
128
  timeoutMs: 1_000,
129
+ nodes: [],
127
130
  runner: async () => result({
128
131
  verified: false,
129
132
  writes: [writtenPath],
@@ -1,8 +1,10 @@
1
+ import type { NodeMemoryTarget } from '../core/canvas/types.js';
1
2
  import { runOnDiskMigrations, type OnDiskMigrationRunResult } from './runner.js';
2
3
  export type OnDiskMigrationRunner = typeof runOnDiskMigrations;
3
4
  interface CoordinationOptions {
4
5
  timeoutMs?: number;
5
6
  runner?: OnDiskMigrationRunner;
7
+ nodes: readonly NodeMemoryTarget[];
6
8
  }
7
9
  export interface ForcedMigrationOptions extends CoordinationOptions {
8
10
  dryRun?: boolean;
@@ -18,8 +20,7 @@ export declare class MigrationBlockedError extends Error {
18
20
  constructor(message: string, blockerPaths: readonly string[]);
19
21
  }
20
22
  /** Run startup migration only when this home lacks the current completion marker. */
21
- export declare function activateOnDiskMigrations(options?: CoordinationOptions): Promise<OnDiskMigrationRunResult | null>;
22
- export declare function ensureOnDiskMigrations(): Promise<void>;
23
+ export declare function activateOnDiskMigrations(options: CoordinationOptions): Promise<OnDiskMigrationRunResult | null>;
23
24
  /** Run migrations regardless of the marker; dry runs leave marker state untouched. */
24
25
  export declare function runForcedOnDiskMigrations(options: ForcedMigrationOptions): Promise<OnDiskMigrationRunResult>;
25
26
  export {};
@@ -64,6 +64,7 @@ async function coordinate(mode, options) {
64
64
  const result = await (options.runner ?? runOnDiskMigrations)({
65
65
  dryRun,
66
66
  explicitDirs: options.explicitDirs,
67
+ nodes: options.nodes,
67
68
  });
68
69
  if (!dryRun && result.finalVerificationSucceeded)
69
70
  writeCurrentMarker();
@@ -76,12 +77,9 @@ async function coordinate(mode, options) {
76
77
  });
77
78
  }
78
79
  /** Run startup migration only when this home lacks the current completion marker. */
79
- export async function activateOnDiskMigrations(options = {}) {
80
+ export async function activateOnDiskMigrations(options) {
80
81
  return coordinate('activation', options);
81
82
  }
82
- export async function ensureOnDiskMigrations() {
83
- await activateOnDiskMigrations();
84
- }
85
83
  /** Run migrations regardless of the marker; dry runs leave marker state untouched. */
86
84
  export async function runForcedOnDiskMigrations(options) {
87
85
  const result = await coordinate('forced', options);
@@ -1,3 +1,4 @@
1
+ import type { NodeMemoryTarget } from '../core/canvas/types.js';
1
2
  import type { CorpusBlocker, CorpusDiscoveryRoot, CorpusIdentityRename, CorpusReferenceRewrite, CorpusRepositoryDecision, CorpusSnapshot, CorpusStore, CorpusStorePrefix, CorpusTarget, ProfileManifestSnapshot, StateMigration, StoreSnapshot } from './types.js';
2
3
  /** A store before its documents are read. */
3
4
  export type DiscoveredStore = Omit<CorpusStore, 'snapshot'>;
@@ -10,11 +11,6 @@ export interface CorpusDiscovery {
10
11
  targets: CorpusTarget[];
11
12
  /** Roots and targets discovery could not read. */
12
13
  blockers: CorpusBlocker[];
13
- nodeMetadata: {
14
- available: boolean;
15
- nodes: number;
16
- error?: string;
17
- };
18
14
  }
19
15
  export interface CorpusSkippedDoc {
20
16
  storeRoot: string;
@@ -52,6 +48,7 @@ export declare function discoverCorpus(opts: {
52
48
  cwd?: string;
53
49
  profiles: readonly ProfileManifestSnapshot[];
54
50
  explicitDirs?: readonly string[];
51
+ nodes: readonly NodeMemoryTarget[];
55
52
  }): Promise<CorpusDiscovery>;
56
53
  /** Read every discovered store's documents. `preloaded` supplies the per-store
57
54
  * convergent lane's FOLDED snapshots so the corpus plans against the bytes a
@@ -12,16 +12,12 @@
12
12
  // the ENTIRE corpus. A store whose identity changed must not be readable at its
13
13
  // new address before every pointer to the old one has moved.
14
14
  //
15
- // Discovery is filesystem-only and never opens canvas.db. A migration runs
16
- // BEFORE the daemon on a cold home (Northlight's entrypoint does exactly that),
17
- // so node target metadata comes from each node's durable meta.json — the source
18
- // of truth the database index is rebuilt from — through its existing read-only
19
- // helper. Missing or corrupt metadata remains a global blocker.
15
+ // Discovery is filesystem-only and never opens canvas.db. The daemon supplies
16
+ // node target coordinates as plain values from its already-owned SQL roster.
20
17
  import { envProfileId } from '../shared/env.js';
21
18
  import { readdirSync } from 'node:fs';
22
19
  import { dirname, join } from 'node:path';
23
- import { readMetaObject } from '../core/canvas/meta-file.js';
24
- import { nodeMetaPath, nodesRoot } from '../core/canvas/paths.js';
20
+ import { nodesRoot } from '../core/canvas/paths.js';
25
21
  import { atomicWriteText, listDirs, pathExists, realpathOrSelf, removePath, walkFiles } from '../core/fs-utils.js';
26
22
  import { memoryStoresInPrecedence, } from '../core/memory-resolver.js';
27
23
  import { descendantStoreRootsExhaustive } from '../core/nested-stores.js';
@@ -224,26 +220,20 @@ export async function discoverCorpus(opts) {
224
220
  const nodeStores = nodeStoresWithDocs();
225
221
  if (pathExists(nodesRoot()))
226
222
  addRoot({ reason: 'node', root: nodesRoot(), boundary: 'nodes' });
227
- const nodeMetadata = { available: true, nodes: 0 };
223
+ const nodesById = new Map(opts.nodes.map((node) => [node.nodeId, node]));
228
224
  for (const { nodeId, storeRoot } of nodeStores) {
229
- const metaPath = nodeMetaPath(nodeId);
230
- const meta = readMetaObject(metaPath);
231
- if (meta === null) {
232
- nodeMetadata.available = false;
233
- nodeMetadata.error ??= `unreadable metadata: ${metaPath}`;
225
+ const node = nodesById.get(nodeId);
226
+ if (node === undefined || node.cwd === '') {
227
+ const reason = node === undefined ? 'no row' : 'empty cwd';
234
228
  blockers.push({
235
229
  kind: 'inaccessible-target',
236
- message: `node ${nodeId} holds memory documents but its durable metadata is unreadable at ${metaPath} — restore or repair that file, then re-run`,
230
+ message: `node ${nodeId} holds memory documents but canvas.db has no usable row for it (${reason}) — the corpus cannot resolve its project or profile`,
237
231
  storeRoot: realpathOrSelf(storeRoot),
238
- path: metaPath,
239
232
  });
240
233
  register(nodeStoreDescriptor(storeRoot), { reason: 'node', root: storeRoot });
241
234
  continue;
242
235
  }
243
- nodeMetadata.nodes += 1;
244
- const nodeCwd = typeof meta['cwd'] === 'string' && meta['cwd'] !== '' ? meta['cwd'] : cwd;
245
- const profileId = typeof meta['profile_id'] === 'string' && meta['profile_id'] !== '' ? meta['profile_id'] : null;
246
- addTarget('node', nodeId, { cwd: nodeCwd, profileId, nodeId });
236
+ addTarget('node', nodeId, { cwd: node.cwd, profileId: node.profileId, nodeId });
247
237
  }
248
238
  // Runtime default `includeDescendants: false`: this is the store stack a link
249
239
  // or route actually resolves through. A descendant store is reached by its
@@ -334,7 +324,6 @@ export async function discoverCorpus(opts) {
334
324
  storeKeys: record.storeKeys,
335
325
  })),
336
326
  blockers,
337
- nodeMetadata,
338
327
  };
339
328
  }
340
329
  // Snapshots
@@ -1,3 +1,4 @@
1
+ import type { NodeMemoryTarget } from '../core/canvas/types.js';
1
2
  import { type CorpusDiscovery } from './corpus.js';
2
3
  import type { CorpusBlocker, CorpusIdentityRename, CorpusRepositoryDecision, CorpusStorePrefix, CorpusReferenceRewrite, OnDiskMigrationLane, StoreSnapshot } from './types.js';
3
4
  export type OnDiskMigrationPhase = 'not-started' | 'planned' | 'written';
@@ -35,7 +36,8 @@ export interface OnDiskMigrationRunResult {
35
36
  finalVerificationSucceeded: boolean;
36
37
  dryRun: boolean;
37
38
  }
38
- export declare function runOnDiskMigrations(opts?: {
39
+ export declare function runOnDiskMigrations(opts: {
39
40
  dryRun?: boolean;
40
41
  explicitDirs?: readonly string[];
42
+ nodes: readonly NodeMemoryTarget[];
41
43
  }): Promise<OnDiskMigrationRunResult>;
@@ -1,8 +1,9 @@
1
1
  import { profilesRoot, withProfileManifestLock } from '../core/profiles/manifest.js';
2
+ import { resetScopeCache } from '../core/scope.js';
2
3
  import { buildCorpusSnapshot, discoverCorpus, loadCorpusSnapshots, parseFailureBlockers, runCorpusMigrations, } from './corpus.js';
3
4
  import { runConvergentMigrations } from './convergent.js';
4
5
  import { runProfileManifestMigrations } from './profile-manifests.js';
5
- export async function runOnDiskMigrations(opts = {}) {
6
+ export async function runOnDiskMigrations(opts) {
6
7
  const dryRun = opts.dryRun === true;
7
8
  const applied = [];
8
9
  const skipped = [];
@@ -22,7 +23,10 @@ export async function runOnDiskMigrations(opts = {}) {
22
23
  path: row.path,
23
24
  });
24
25
  }
25
- const discovery = await discoverCorpus({ profiles: profileRun.snapshots, explicitDirs: opts.explicitDirs });
26
+ // Corpus discovery must observe stores a preceding repair (or an external
27
+ // writer) created after this daemon last resolved a target's scope stack.
28
+ resetScopeCache();
29
+ const discovery = await discoverCorpus({ profiles: profileRun.snapshots, explicitDirs: opts.explicitDirs, nodes: opts.nodes });
26
30
  const parseFailures = [];
27
31
  const folded = new Map();
28
32
  for (const store of discovery.stores) {