@openrig/cli 0.6.14 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (778) hide show
  1. package/README.md +10 -9
  2. package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +1 -1
  3. package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +1 -1
  4. package/daemon/assets/plugins/openrig-core/README.md +11 -4
  5. package/daemon/assets/plugins/openrig-core/hooks/codex.json +6 -6
  6. package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +13 -1
  7. package/daemon/assets/plugins/openrig-core/hooks/scripts/codex-hook-trust.cjs +49 -0
  8. package/daemon/assets/plugins/openrig-core/hooks/scripts/refocus.cjs +26 -5
  9. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/SKILL.md +9 -2
  10. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +3 -2
  11. package/daemon/assets/plugins/openrig-core/skills/messaging-the-human/SKILL.md +24 -0
  12. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +2 -2
  13. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +28 -18
  14. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +10 -4
  15. package/daemon/assets/skills/rigs/SKILL.md +24 -5
  16. package/daemon/context-packs/help/manifest.yaml +1 -1
  17. package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
  18. package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +4 -6
  19. package/daemon/context-packs/reference/getting-started.md +87 -21
  20. package/daemon/context-packs/reference/manifest.yaml +1 -1
  21. package/daemon/context-packs/reference/rig-spec.md +1 -1
  22. package/daemon/context-packs/reference/whats-new.md +123 -68
  23. package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +1 -1
  24. package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
  26. package/daemon/context-packs/skills/claude-compaction-restore/SKILL.md +9 -2
  27. package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
  28. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  29. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  30. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  31. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/core/messaging-the-human/SKILL.md +24 -0
  33. package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
  34. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +2 -2
  38. package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/core/openrig-software-factory/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/core/openrig-upgrade/SKILL.md +11 -5
  41. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  46. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/forming-an-openrig-mental-model/SKILL.md +3 -2
  50. package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/openrig-user/SKILL.md +28 -18
  55. package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
  57. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  58. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  64. package/daemon/context-packs/skills/pods/development-team/SKILL.md +2 -0
  65. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +3 -1
  66. package/daemon/context-packs/skills/pods/development-team/references/refactoring.md +11 -0
  67. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  68. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  69. package/daemon/context-packs/skills/pods/review-team/SKILL.md +46 -96
  70. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  71. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  72. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  73. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  74. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  75. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  76. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  77. package/daemon/context-packs/skills/process/verification-before-completion/SKILL.md +17 -80
  78. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +5 -3
  79. package/daemon/context-packs/skills/process/verification-before-completion/references/performance-claims.md +12 -0
  80. package/daemon/context-packs/skills/queue-handoff/SKILL.md +10 -4
  81. package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
  82. package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
  83. package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
  84. package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
  85. package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
  86. package/daemon/context-packs/skills/software-for-agents/manifest.yaml +1 -1
  87. package/daemon/context-packs/world-example/manifest.yaml +1 -1
  88. package/daemon/context-packs/world-public/manifest.yaml +1 -1
  89. package/daemon/dist/adapters/claude-code-adapter.d.ts +6 -2
  90. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  91. package/daemon/dist/adapters/claude-code-adapter.js +33 -6
  92. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  93. package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
  94. package/daemon/dist/adapters/codex-resume.js +2 -7
  95. package/daemon/dist/adapters/codex-resume.js.map +1 -1
  96. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +68 -2
  97. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  98. package/daemon/dist/adapters/codex-runtime-adapter.js +371 -60
  99. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  100. package/daemon/dist/adapters/compose-services-adapter.d.ts +16 -0
  101. package/daemon/dist/adapters/compose-services-adapter.d.ts.map +1 -1
  102. package/daemon/dist/adapters/compose-services-adapter.js +52 -9
  103. package/daemon/dist/adapters/compose-services-adapter.js.map +1 -1
  104. package/daemon/dist/adapters/kernel-authority.d.ts.map +1 -1
  105. package/daemon/dist/adapters/kernel-authority.js +9 -5
  106. package/daemon/dist/adapters/kernel-authority.js.map +1 -1
  107. package/daemon/dist/adapters/pi-runner.d.ts +2 -0
  108. package/daemon/dist/adapters/pi-runner.d.ts.map +1 -1
  109. package/daemon/dist/adapters/pi-runner.js +5 -0
  110. package/daemon/dist/adapters/pi-runner.js.map +1 -1
  111. package/daemon/dist/adapters/runtime-probe-exec.d.ts +11 -0
  112. package/daemon/dist/adapters/runtime-probe-exec.d.ts.map +1 -0
  113. package/daemon/dist/adapters/runtime-probe-exec.js +25 -0
  114. package/daemon/dist/adapters/runtime-probe-exec.js.map +1 -0
  115. package/daemon/dist/adapters/stub-runner.d.ts.map +1 -1
  116. package/daemon/dist/adapters/stub-runner.js +2 -0
  117. package/daemon/dist/adapters/stub-runner.js.map +1 -1
  118. package/daemon/dist/adapters/tmux.d.ts +21 -1
  119. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  120. package/daemon/dist/adapters/tmux.js +100 -13
  121. package/daemon/dist/adapters/tmux.js.map +1 -1
  122. package/daemon/dist/build-info.js +3 -3
  123. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  124. package/daemon/dist/db/all-migrations.js +12 -0
  125. package/daemon/dist/db/all-migrations.js.map +1 -1
  126. package/daemon/dist/db/migrations/116_queue_item_wake_input_box.d.ts +3 -0
  127. package/daemon/dist/db/migrations/116_queue_item_wake_input_box.d.ts.map +1 -0
  128. package/daemon/dist/db/migrations/116_queue_item_wake_input_box.js +8 -0
  129. package/daemon/dist/db/migrations/116_queue_item_wake_input_box.js.map +1 -0
  130. package/daemon/dist/db/migrations/118_human_quiet_windows.d.ts +3 -0
  131. package/daemon/dist/db/migrations/118_human_quiet_windows.d.ts.map +1 -0
  132. package/daemon/dist/db/migrations/118_human_quiet_windows.js +30 -0
  133. package/daemon/dist/db/migrations/118_human_quiet_windows.js.map +1 -0
  134. package/daemon/dist/db/migrations/119_seat_identity_pane_pid.d.ts +3 -0
  135. package/daemon/dist/db/migrations/119_seat_identity_pane_pid.d.ts.map +1 -0
  136. package/daemon/dist/db/migrations/119_seat_identity_pane_pid.js +7 -0
  137. package/daemon/dist/db/migrations/119_seat_identity_pane_pid.js.map +1 -0
  138. package/daemon/dist/db/migrations/121_rig_startup_layers.d.ts +13 -0
  139. package/daemon/dist/db/migrations/121_rig_startup_layers.d.ts.map +1 -0
  140. package/daemon/dist/db/migrations/121_rig_startup_layers.js +17 -0
  141. package/daemon/dist/db/migrations/121_rig_startup_layers.js.map +1 -0
  142. package/daemon/dist/db/migrations/122_human_operating_modes.d.ts +3 -0
  143. package/daemon/dist/db/migrations/122_human_operating_modes.d.ts.map +1 -0
  144. package/daemon/dist/db/migrations/122_human_operating_modes.js +55 -0
  145. package/daemon/dist/db/migrations/122_human_operating_modes.js.map +1 -0
  146. package/daemon/dist/db/migrations/123_queue_delegated_decision.d.ts +3 -0
  147. package/daemon/dist/db/migrations/123_queue_delegated_decision.d.ts.map +1 -0
  148. package/daemon/dist/db/migrations/123_queue_delegated_decision.js +10 -0
  149. package/daemon/dist/db/migrations/123_queue_delegated_decision.js.map +1 -0
  150. package/daemon/dist/domain/active-occupant.d.ts +5 -3
  151. package/daemon/dist/domain/active-occupant.d.ts.map +1 -1
  152. package/daemon/dist/domain/active-occupant.js +2 -2
  153. package/daemon/dist/domain/active-occupant.js.map +1 -1
  154. package/daemon/dist/domain/activity-taxonomy.d.ts +16 -1
  155. package/daemon/dist/domain/activity-taxonomy.d.ts.map +1 -1
  156. package/daemon/dist/domain/activity-taxonomy.js +21 -0
  157. package/daemon/dist/domain/activity-taxonomy.js.map +1 -1
  158. package/daemon/dist/domain/agent-activity-store.d.ts +20 -0
  159. package/daemon/dist/domain/agent-activity-store.d.ts.map +1 -1
  160. package/daemon/dist/domain/agent-activity-store.js +41 -5
  161. package/daemon/dist/domain/agent-activity-store.js.map +1 -1
  162. package/daemon/dist/domain/agent-images/evidence-guard.js +3 -3
  163. package/daemon/dist/domain/agent-images/evidence-guard.js.map +1 -1
  164. package/daemon/dist/domain/agent-images/resume-token-discovery.d.ts.map +1 -1
  165. package/daemon/dist/domain/agent-images/resume-token-discovery.js +2 -10
  166. package/daemon/dist/domain/agent-images/resume-token-discovery.js.map +1 -1
  167. package/daemon/dist/domain/ask-service.d.ts +1 -0
  168. package/daemon/dist/domain/ask-service.d.ts.map +1 -1
  169. package/daemon/dist/domain/ask-service.js +7 -1
  170. package/daemon/dist/domain/ask-service.js.map +1 -1
  171. package/daemon/dist/domain/bootstrap-orchestrator.d.ts +2 -0
  172. package/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
  173. package/daemon/dist/domain/bootstrap-orchestrator.js +5 -6
  174. package/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
  175. package/daemon/dist/domain/claim-service.d.ts +1 -1
  176. package/daemon/dist/domain/claim-service.d.ts.map +1 -1
  177. package/daemon/dist/domain/claim-service.js +7 -0
  178. package/daemon/dist/domain/claim-service.js.map +1 -1
  179. package/daemon/dist/domain/classification-sources.d.ts.map +1 -1
  180. package/daemon/dist/domain/classification-sources.js +2 -0
  181. package/daemon/dist/domain/classification-sources.js.map +1 -1
  182. package/daemon/dist/domain/claude-compaction-enforcer.d.ts +17 -4
  183. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
  184. package/daemon/dist/domain/claude-compaction-enforcer.js +88 -24
  185. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
  186. package/daemon/dist/domain/claude-core-plugin-env.d.ts +11 -0
  187. package/daemon/dist/domain/claude-core-plugin-env.d.ts.map +1 -1
  188. package/daemon/dist/domain/claude-core-plugin-env.js +15 -0
  189. package/daemon/dist/domain/claude-core-plugin-env.js.map +1 -1
  190. package/daemon/dist/domain/codex-core-plugin-install.d.ts +41 -0
  191. package/daemon/dist/domain/codex-core-plugin-install.d.ts.map +1 -0
  192. package/daemon/dist/domain/codex-core-plugin-install.js +126 -0
  193. package/daemon/dist/domain/codex-core-plugin-install.js.map +1 -0
  194. package/daemon/dist/domain/codex-thread-id.d.ts +23 -1
  195. package/daemon/dist/domain/codex-thread-id.d.ts.map +1 -1
  196. package/daemon/dist/domain/codex-thread-id.js +58 -17
  197. package/daemon/dist/domain/codex-thread-id.js.map +1 -1
  198. package/daemon/dist/domain/context-monitor.d.ts +13 -5
  199. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  200. package/daemon/dist/domain/context-monitor.js +47 -13
  201. package/daemon/dist/domain/context-monitor.js.map +1 -1
  202. package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  203. package/daemon/dist/domain/context-usage-store.js +3 -0
  204. package/daemon/dist/domain/context-usage-store.js.map +1 -1
  205. package/daemon/dist/domain/current-work.d.ts +18 -0
  206. package/daemon/dist/domain/current-work.d.ts.map +1 -1
  207. package/daemon/dist/domain/current-work.js +17 -3
  208. package/daemon/dist/domain/current-work.js.map +1 -1
  209. package/daemon/dist/domain/draft-aware-delivery.d.ts +7 -7
  210. package/daemon/dist/domain/draft-aware-delivery.d.ts.map +1 -1
  211. package/daemon/dist/domain/draft-aware-delivery.js +61 -82
  212. package/daemon/dist/domain/draft-aware-delivery.js.map +1 -1
  213. package/daemon/dist/domain/execution-view.d.ts.map +1 -1
  214. package/daemon/dist/domain/execution-view.js +2 -1
  215. package/daemon/dist/domain/execution-view.js.map +1 -1
  216. package/daemon/dist/domain/existing-rig-restore.d.ts +110 -0
  217. package/daemon/dist/domain/existing-rig-restore.d.ts.map +1 -0
  218. package/daemon/dist/domain/existing-rig-restore.js +254 -0
  219. package/daemon/dist/domain/existing-rig-restore.js.map +1 -0
  220. package/daemon/dist/domain/fresh-occupant-relation.d.ts.map +1 -1
  221. package/daemon/dist/domain/fresh-occupant-relation.js +9 -2
  222. package/daemon/dist/domain/fresh-occupant-relation.js.map +1 -1
  223. package/daemon/dist/domain/gateway/channel-operations.d.ts +3 -4
  224. package/daemon/dist/domain/gateway/channel-operations.d.ts.map +1 -1
  225. package/daemon/dist/domain/gateway/channel-operations.js.map +1 -1
  226. package/daemon/dist/domain/gateway/connections-projection.d.ts +0 -5
  227. package/daemon/dist/domain/gateway/connections-projection.d.ts.map +1 -1
  228. package/daemon/dist/domain/gateway/connections-projection.js +3 -46
  229. package/daemon/dist/domain/gateway/connections-projection.js.map +1 -1
  230. package/daemon/dist/domain/gateway/delivery-rules-engine.d.ts +11 -1
  231. package/daemon/dist/domain/gateway/delivery-rules-engine.d.ts.map +1 -1
  232. package/daemon/dist/domain/gateway/delivery-rules-engine.js +12 -2
  233. package/daemon/dist/domain/gateway/delivery-rules-engine.js.map +1 -1
  234. package/daemon/dist/domain/gateway/dispatch-buffer.d.ts +4 -0
  235. package/daemon/dist/domain/gateway/dispatch-buffer.d.ts.map +1 -1
  236. package/daemon/dist/domain/gateway/dispatch-buffer.js +18 -0
  237. package/daemon/dist/domain/gateway/dispatch-buffer.js.map +1 -1
  238. package/daemon/dist/domain/gateway/human-mode-account.d.ts +61 -0
  239. package/daemon/dist/domain/gateway/human-mode-account.d.ts.map +1 -0
  240. package/daemon/dist/domain/gateway/human-mode-account.js +112 -0
  241. package/daemon/dist/domain/gateway/human-mode-account.js.map +1 -0
  242. package/daemon/dist/domain/gateway/human-operating-modes.d.ts +171 -0
  243. package/daemon/dist/domain/gateway/human-operating-modes.d.ts.map +1 -0
  244. package/daemon/dist/domain/gateway/human-operating-modes.js +422 -0
  245. package/daemon/dist/domain/gateway/human-operating-modes.js.map +1 -0
  246. package/daemon/dist/domain/gateway/human-quiet-windows.d.ts +121 -0
  247. package/daemon/dist/domain/gateway/human-quiet-windows.d.ts.map +1 -0
  248. package/daemon/dist/domain/gateway/human-quiet-windows.js +217 -0
  249. package/daemon/dist/domain/gateway/human-quiet-windows.js.map +1 -0
  250. package/daemon/dist/domain/gateway/human-registry.d.ts +23 -2
  251. package/daemon/dist/domain/gateway/human-registry.d.ts.map +1 -1
  252. package/daemon/dist/domain/gateway/human-registry.js +67 -5
  253. package/daemon/dist/domain/gateway/human-registry.js.map +1 -1
  254. package/daemon/dist/domain/gateway/operator-delivery-engine.d.ts.map +1 -1
  255. package/daemon/dist/domain/gateway/operator-delivery-engine.js +9 -0
  256. package/daemon/dist/domain/gateway/operator-delivery-engine.js.map +1 -1
  257. package/daemon/dist/domain/gateway/slack/inbound.d.ts +10 -2
  258. package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -1
  259. package/daemon/dist/domain/gateway/slack/inbound.js +24 -2
  260. package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -1
  261. package/daemon/dist/domain/gateway/slack/message.d.ts +1 -0
  262. package/daemon/dist/domain/gateway/slack/message.d.ts.map +1 -1
  263. package/daemon/dist/domain/gateway/slack/message.js +5 -1
  264. package/daemon/dist/domain/gateway/slack/message.js.map +1 -1
  265. package/daemon/dist/domain/gateway/slack/outbound-driver.d.ts +9 -3
  266. package/daemon/dist/domain/gateway/slack/outbound-driver.d.ts.map +1 -1
  267. package/daemon/dist/domain/gateway/slack/outbound-driver.js +40 -6
  268. package/daemon/dist/domain/gateway/slack/outbound-driver.js.map +1 -1
  269. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +19 -1
  270. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -1
  271. package/daemon/dist/domain/gateway/slack/slack-delivery.js +128 -41
  272. package/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -1
  273. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts +3 -2
  274. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -1
  275. package/daemon/dist/domain/gateway/slack/slack-subsystem.js +268 -50
  276. package/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -1
  277. package/daemon/dist/domain/health-passive-ceremony.d.ts +4 -0
  278. package/daemon/dist/domain/health-passive-ceremony.d.ts.map +1 -1
  279. package/daemon/dist/domain/health-passive-ceremony.js +34 -4
  280. package/daemon/dist/domain/health-passive-ceremony.js.map +1 -1
  281. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts +3 -1
  282. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -1
  283. package/daemon/dist/domain/hosts/hosts-registry-reader.js +9 -9
  284. package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -1
  285. package/daemon/dist/domain/hosts/learned-host-bindings.d.ts +28 -0
  286. package/daemon/dist/domain/hosts/learned-host-bindings.d.ts.map +1 -0
  287. package/daemon/dist/domain/hosts/learned-host-bindings.js +77 -0
  288. package/daemon/dist/domain/hosts/learned-host-bindings.js.map +1 -0
  289. package/daemon/dist/domain/hot-potato-enforcer.d.ts +7 -5
  290. package/daemon/dist/domain/hot-potato-enforcer.d.ts.map +1 -1
  291. package/daemon/dist/domain/hot-potato-enforcer.js +19 -10
  292. package/daemon/dist/domain/hot-potato-enforcer.js.map +1 -1
  293. package/daemon/dist/domain/human-questions.d.ts +8 -1
  294. package/daemon/dist/domain/human-questions.d.ts.map +1 -1
  295. package/daemon/dist/domain/human-questions.js.map +1 -1
  296. package/daemon/dist/domain/kernel-boot-tracker.d.ts +17 -1
  297. package/daemon/dist/domain/kernel-boot-tracker.d.ts.map +1 -1
  298. package/daemon/dist/domain/kernel-boot-tracker.js +44 -3
  299. package/daemon/dist/domain/kernel-boot-tracker.js.map +1 -1
  300. package/daemon/dist/domain/kernel-boot.d.ts +21 -0
  301. package/daemon/dist/domain/kernel-boot.d.ts.map +1 -1
  302. package/daemon/dist/domain/kernel-boot.js +57 -2
  303. package/daemon/dist/domain/kernel-boot.js.map +1 -1
  304. package/daemon/dist/domain/model-divergence/current-generation-record.d.ts +2 -1
  305. package/daemon/dist/domain/model-divergence/current-generation-record.d.ts.map +1 -1
  306. package/daemon/dist/domain/model-divergence/current-generation-record.js +8 -3
  307. package/daemon/dist/domain/model-divergence/current-generation-record.js.map +1 -1
  308. package/daemon/dist/domain/native-process-lineage.d.ts.map +1 -1
  309. package/daemon/dist/domain/native-process-lineage.js +43 -15
  310. package/daemon/dist/domain/native-process-lineage.js.map +1 -1
  311. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  312. package/daemon/dist/domain/node-inventory.js +26 -12
  313. package/daemon/dist/domain/node-inventory.js.map +1 -1
  314. package/daemon/dist/domain/node-launcher.d.ts +5 -3
  315. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  316. package/daemon/dist/domain/node-launcher.js +29 -25
  317. package/daemon/dist/domain/node-launcher.js.map +1 -1
  318. package/daemon/dist/domain/outbox-handler.d.ts +3 -5
  319. package/daemon/dist/domain/outbox-handler.d.ts.map +1 -1
  320. package/daemon/dist/domain/outbox-handler.js +9 -19
  321. package/daemon/dist/domain/outbox-handler.js.map +1 -1
  322. package/daemon/dist/domain/park-wake-text.d.ts +11 -0
  323. package/daemon/dist/domain/park-wake-text.d.ts.map +1 -0
  324. package/daemon/dist/domain/park-wake-text.js +26 -0
  325. package/daemon/dist/domain/park-wake-text.js.map +1 -0
  326. package/daemon/dist/domain/plugin-vendor-service.d.ts +4 -0
  327. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  328. package/daemon/dist/domain/plugin-vendor-service.js +29 -6
  329. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  330. package/daemon/dist/domain/policies/delivery-digest-flush.d.ts +1 -0
  331. package/daemon/dist/domain/policies/delivery-digest-flush.d.ts.map +1 -1
  332. package/daemon/dist/domain/policies/delivery-digest-flush.js +25 -4
  333. package/daemon/dist/domain/policies/delivery-digest-flush.js.map +1 -1
  334. package/daemon/dist/domain/policies/mode-scheduled-end.d.ts +37 -0
  335. package/daemon/dist/domain/policies/mode-scheduled-end.d.ts.map +1 -0
  336. package/daemon/dist/domain/policies/mode-scheduled-end.js +161 -0
  337. package/daemon/dist/domain/policies/mode-scheduled-end.js.map +1 -0
  338. package/daemon/dist/domain/policies/parked-owner-consumer.d.ts +11 -7
  339. package/daemon/dist/domain/policies/parked-owner-consumer.d.ts.map +1 -1
  340. package/daemon/dist/domain/policies/parked-owner-consumer.js +82 -113
  341. package/daemon/dist/domain/policies/parked-owner-consumer.js.map +1 -1
  342. package/daemon/dist/domain/policies/quiet-release.d.ts +109 -0
  343. package/daemon/dist/domain/policies/quiet-release.d.ts.map +1 -0
  344. package/daemon/dist/domain/policies/quiet-release.js +213 -0
  345. package/daemon/dist/domain/policies/quiet-release.js.map +1 -0
  346. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  347. package/daemon/dist/domain/profile-resolver.js +8 -3
  348. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  349. package/daemon/dist/domain/proof/source-watch.js +2 -2
  350. package/daemon/dist/domain/proof/source-watch.js.map +1 -1
  351. package/daemon/dist/domain/queue-destination-check.d.ts +6 -0
  352. package/daemon/dist/domain/queue-destination-check.d.ts.map +1 -0
  353. package/daemon/dist/domain/queue-destination-check.js +35 -0
  354. package/daemon/dist/domain/queue-destination-check.js.map +1 -0
  355. package/daemon/dist/domain/queue-owner.d.ts.map +1 -1
  356. package/daemon/dist/domain/queue-owner.js +2 -1
  357. package/daemon/dist/domain/queue-owner.js.map +1 -1
  358. package/daemon/dist/domain/queue-recovery.d.ts +1 -1
  359. package/daemon/dist/domain/queue-recovery.d.ts.map +1 -1
  360. package/daemon/dist/domain/queue-recovery.js +3 -2
  361. package/daemon/dist/domain/queue-recovery.js.map +1 -1
  362. package/daemon/dist/domain/queue-repository.d.ts +108 -67
  363. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  364. package/daemon/dist/domain/queue-repository.js +316 -140
  365. package/daemon/dist/domain/queue-repository.js.map +1 -1
  366. package/daemon/dist/domain/queue-stuck-sweep.d.ts +13 -1
  367. package/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -1
  368. package/daemon/dist/domain/queue-stuck-sweep.js +95 -13
  369. package/daemon/dist/domain/queue-stuck-sweep.js.map +1 -1
  370. package/daemon/dist/domain/queue-transition-log.d.ts +5 -0
  371. package/daemon/dist/domain/queue-transition-log.d.ts.map +1 -1
  372. package/daemon/dist/domain/queue-transition-log.js +25 -8
  373. package/daemon/dist/domain/queue-transition-log.js.map +1 -1
  374. package/daemon/dist/domain/queue-wake-ladder.d.ts +2 -0
  375. package/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -1
  376. package/daemon/dist/domain/queue-wake-ladder.js +94 -11
  377. package/daemon/dist/domain/queue-wake-ladder.js.map +1 -1
  378. package/daemon/dist/domain/quiet-hold-custody.d.ts +24 -0
  379. package/daemon/dist/domain/quiet-hold-custody.d.ts.map +1 -0
  380. package/daemon/dist/domain/quiet-hold-custody.js +85 -0
  381. package/daemon/dist/domain/quiet-hold-custody.js.map +1 -0
  382. package/daemon/dist/domain/rehydrate-eligibility.d.ts +12 -1
  383. package/daemon/dist/domain/rehydrate-eligibility.d.ts.map +1 -1
  384. package/daemon/dist/domain/rehydrate-eligibility.js +47 -9
  385. package/daemon/dist/domain/rehydrate-eligibility.js.map +1 -1
  386. package/daemon/dist/domain/restore-orchestrator.d.ts +11 -0
  387. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  388. package/daemon/dist/domain/restore-orchestrator.js +144 -15
  389. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  390. package/daemon/dist/domain/restore-plan-preview.d.ts +3 -1
  391. package/daemon/dist/domain/restore-plan-preview.d.ts.map +1 -1
  392. package/daemon/dist/domain/restore-plan-preview.js +30 -13
  393. package/daemon/dist/domain/restore-plan-preview.js.map +1 -1
  394. package/daemon/dist/domain/review/gather.d.ts.map +1 -1
  395. package/daemon/dist/domain/review/gather.js +8 -5
  396. package/daemon/dist/domain/review/gather.js.map +1 -1
  397. package/daemon/dist/domain/rig-mode/operating-posture.d.ts.map +1 -1
  398. package/daemon/dist/domain/rig-mode/operating-posture.js +3 -1
  399. package/daemon/dist/domain/rig-mode/operating-posture.js.map +1 -1
  400. package/daemon/dist/domain/rig-repository.d.ts +11 -1
  401. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  402. package/daemon/dist/domain/rig-repository.js +27 -3
  403. package/daemon/dist/domain/rig-repository.js.map +1 -1
  404. package/daemon/dist/domain/rig-teardown.d.ts.map +1 -1
  405. package/daemon/dist/domain/rig-teardown.js +31 -4
  406. package/daemon/dist/domain/rig-teardown.js.map +1 -1
  407. package/daemon/dist/domain/rigspec-instantiator.d.ts +9 -0
  408. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  409. package/daemon/dist/domain/rigspec-instantiator.js +59 -28
  410. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  411. package/daemon/dist/domain/rigspec-schema.d.ts +5 -0
  412. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  413. package/daemon/dist/domain/rigspec-schema.js +30 -0
  414. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  415. package/daemon/dist/domain/runtime-adapter.d.ts +27 -2
  416. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  417. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  418. package/daemon/dist/domain/seat-activity-service.d.ts +18 -3
  419. package/daemon/dist/domain/seat-activity-service.d.ts.map +1 -1
  420. package/daemon/dist/domain/seat-activity-service.js +124 -57
  421. package/daemon/dist/domain/seat-activity-service.js.map +1 -1
  422. package/daemon/dist/domain/seat-attention-reconciler.d.ts +8 -1
  423. package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  424. package/daemon/dist/domain/seat-attention-reconciler.js +3 -1
  425. package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  426. package/daemon/dist/domain/seat-delivery-guard.d.ts.map +1 -1
  427. package/daemon/dist/domain/seat-delivery-guard.js +21 -5
  428. package/daemon/dist/domain/seat-delivery-guard.js.map +1 -1
  429. package/daemon/dist/domain/seat-handover-service.d.ts +2 -2
  430. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  431. package/daemon/dist/domain/seat-handover-service.js +28 -2
  432. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  433. package/daemon/dist/domain/seat-identity-reconciler.js +1 -1
  434. package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
  435. package/daemon/dist/domain/seat-identity-store.d.ts.map +1 -1
  436. package/daemon/dist/domain/seat-identity-store.js +5 -2
  437. package/daemon/dist/domain/seat-identity-store.js.map +1 -1
  438. package/daemon/dist/domain/seat-launch-environment.d.ts.map +1 -1
  439. package/daemon/dist/domain/seat-launch-environment.js +17 -1
  440. package/daemon/dist/domain/seat-launch-environment.js.map +1 -1
  441. package/daemon/dist/domain/seat-lifecycle-service.d.ts +4 -0
  442. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  443. package/daemon/dist/domain/seat-restart-in-place.d.ts +33 -14
  444. package/daemon/dist/domain/seat-restart-in-place.d.ts.map +1 -1
  445. package/daemon/dist/domain/seat-restart-in-place.js +102 -30
  446. package/daemon/dist/domain/seat-restart-in-place.js.map +1 -1
  447. package/daemon/dist/domain/self-attach-service.d.ts +3 -2
  448. package/daemon/dist/domain/self-attach-service.d.ts.map +1 -1
  449. package/daemon/dist/domain/self-attach-service.js +18 -1
  450. package/daemon/dist/domain/self-attach-service.js.map +1 -1
  451. package/daemon/dist/domain/services-readiness.d.ts.map +1 -1
  452. package/daemon/dist/domain/services-readiness.js +14 -3
  453. package/daemon/dist/domain/services-readiness.js.map +1 -1
  454. package/daemon/dist/domain/session-registry.d.ts +45 -0
  455. package/daemon/dist/domain/session-registry.d.ts.map +1 -1
  456. package/daemon/dist/domain/session-registry.js +124 -0
  457. package/daemon/dist/domain/session-registry.js.map +1 -1
  458. package/daemon/dist/domain/session-transport.d.ts +24 -6
  459. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  460. package/daemon/dist/domain/session-transport.js +58 -41
  461. package/daemon/dist/domain/session-transport.js.map +1 -1
  462. package/daemon/dist/domain/skill-discovery.d.ts +7 -1
  463. package/daemon/dist/domain/skill-discovery.d.ts.map +1 -1
  464. package/daemon/dist/domain/skill-discovery.js +41 -7
  465. package/daemon/dist/domain/skill-discovery.js.map +1 -1
  466. package/daemon/dist/domain/snapshot-repository.d.ts +1 -0
  467. package/daemon/dist/domain/snapshot-repository.d.ts.map +1 -1
  468. package/daemon/dist/domain/snapshot-repository.js +23 -10
  469. package/daemon/dist/domain/snapshot-repository.js.map +1 -1
  470. package/daemon/dist/domain/startup-orchestrator.d.ts +21 -3
  471. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  472. package/daemon/dist/domain/startup-orchestrator.js +66 -16
  473. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  474. package/daemon/dist/domain/startup-submission-evidence.d.ts +4 -11
  475. package/daemon/dist/domain/startup-submission-evidence.d.ts.map +1 -1
  476. package/daemon/dist/domain/startup-submission-evidence.js +11 -17
  477. package/daemon/dist/domain/startup-submission-evidence.js.map +1 -1
  478. package/daemon/dist/domain/successor-session-launcher.d.ts +2 -1
  479. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  480. package/daemon/dist/domain/successor-session-launcher.js +3 -1
  481. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  482. package/daemon/dist/domain/terminal/herdr-adapter.d.ts +1 -1
  483. package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -1
  484. package/daemon/dist/domain/terminal/herdr-adapter.js +22 -4
  485. package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -1
  486. package/daemon/dist/domain/types.d.ts +15 -4
  487. package/daemon/dist/domain/types.d.ts.map +1 -1
  488. package/daemon/dist/domain/types.js.map +1 -1
  489. package/daemon/dist/domain/user-settings/settings-browser.d.ts.map +1 -1
  490. package/daemon/dist/domain/user-settings/settings-browser.js +2 -0
  491. package/daemon/dist/domain/user-settings/settings-browser.js.map +1 -1
  492. package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  493. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  494. package/daemon/dist/domain/user-settings/settings-store.js +33 -7
  495. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  496. package/daemon/dist/domain/watchdog-delivery.d.ts +3 -23
  497. package/daemon/dist/domain/watchdog-delivery.d.ts.map +1 -1
  498. package/daemon/dist/domain/watchdog-delivery.js +12 -89
  499. package/daemon/dist/domain/watchdog-delivery.js.map +1 -1
  500. package/daemon/dist/domain/watchdog-history-log.d.ts +5 -2
  501. package/daemon/dist/domain/watchdog-history-log.d.ts.map +1 -1
  502. package/daemon/dist/domain/watchdog-history-log.js.map +1 -1
  503. package/daemon/dist/domain/watchdog-jobs-repository.d.ts +2 -2
  504. package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -1
  505. package/daemon/dist/domain/watchdog-jobs-repository.js +4 -0
  506. package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -1
  507. package/daemon/dist/domain/watchdog-policy-engine.d.ts +16 -24
  508. package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  509. package/daemon/dist/domain/watchdog-policy-engine.js +44 -43
  510. package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  511. package/daemon/dist/domain/whoami-service.d.ts +2 -0
  512. package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
  513. package/daemon/dist/domain/whoami-service.js +23 -6
  514. package/daemon/dist/domain/whoami-service.js.map +1 -1
  515. package/daemon/dist/domain/workflow-boot-sweep.d.ts +2 -1
  516. package/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -1
  517. package/daemon/dist/domain/workflow-boot-sweep.js +11 -5
  518. package/daemon/dist/domain/workflow-boot-sweep.js.map +1 -1
  519. package/daemon/dist/domain/workflow-exception-escalation.d.ts.map +1 -1
  520. package/daemon/dist/domain/workflow-exception-escalation.js +2 -1
  521. package/daemon/dist/domain/workflow-exception-escalation.js.map +1 -1
  522. package/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
  523. package/daemon/dist/domain/workflow-projector.js +5 -2
  524. package/daemon/dist/domain/workflow-projector.js.map +1 -1
  525. package/daemon/dist/domain/workflow-role-context.js +2 -2
  526. package/daemon/dist/domain/workflow-role-context.js.map +1 -1
  527. package/daemon/dist/domain/workflow-runtime.d.ts +1 -1
  528. package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  529. package/daemon/dist/domain/workflow-runtime.js +2 -0
  530. package/daemon/dist/domain/workflow-runtime.js.map +1 -1
  531. package/daemon/dist/routes/activity.d.ts +13 -1
  532. package/daemon/dist/routes/activity.d.ts.map +1 -1
  533. package/daemon/dist/routes/activity.js +67 -2
  534. package/daemon/dist/routes/activity.js.map +1 -1
  535. package/daemon/dist/routes/agent-images.d.ts.map +1 -1
  536. package/daemon/dist/routes/agent-images.js +2 -0
  537. package/daemon/dist/routes/agent-images.js.map +1 -1
  538. package/daemon/dist/routes/compaction.d.ts.map +1 -1
  539. package/daemon/dist/routes/compaction.js +7 -2
  540. package/daemon/dist/routes/compaction.js.map +1 -1
  541. package/daemon/dist/routes/discovery.js +3 -0
  542. package/daemon/dist/routes/discovery.js.map +1 -1
  543. package/daemon/dist/routes/down.js +9 -1
  544. package/daemon/dist/routes/down.js.map +1 -1
  545. package/daemon/dist/routes/gateway.d.ts +2 -0
  546. package/daemon/dist/routes/gateway.d.ts.map +1 -1
  547. package/daemon/dist/routes/gateway.js +181 -1
  548. package/daemon/dist/routes/gateway.js.map +1 -1
  549. package/daemon/dist/routes/kernel-status.js +6 -1
  550. package/daemon/dist/routes/kernel-status.js.map +1 -1
  551. package/daemon/dist/routes/provider.d.ts.map +1 -1
  552. package/daemon/dist/routes/provider.js +0 -73
  553. package/daemon/dist/routes/provider.js.map +1 -1
  554. package/daemon/dist/routes/queue.d.ts.map +1 -1
  555. package/daemon/dist/routes/queue.js +73 -13
  556. package/daemon/dist/routes/queue.js.map +1 -1
  557. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  558. package/daemon/dist/routes/rigs.js +29 -10
  559. package/daemon/dist/routes/rigs.js.map +1 -1
  560. package/daemon/dist/routes/rigspec.js +2 -3
  561. package/daemon/dist/routes/rigspec.js.map +1 -1
  562. package/daemon/dist/routes/seat.js +2 -2
  563. package/daemon/dist/routes/seat.js.map +1 -1
  564. package/daemon/dist/routes/skills.js +2 -2
  565. package/daemon/dist/routes/skills.js.map +1 -1
  566. package/daemon/dist/routes/transcripts.d.ts.map +1 -1
  567. package/daemon/dist/routes/transcripts.js +7 -3
  568. package/daemon/dist/routes/transcripts.js.map +1 -1
  569. package/daemon/dist/routes/transport.js +1 -1
  570. package/daemon/dist/routes/transport.js.map +1 -1
  571. package/daemon/dist/routes/up.js +36 -52
  572. package/daemon/dist/routes/up.js.map +1 -1
  573. package/daemon/dist/startup.d.ts.map +1 -1
  574. package/daemon/dist/startup.js +102 -60
  575. package/daemon/dist/startup.js.map +1 -1
  576. package/daemon/docs/reference/agent-state-taxonomy.md +17 -2
  577. package/daemon/docs/reference/getting-started.md +87 -21
  578. package/daemon/docs/reference/quickstart.md +33 -20
  579. package/daemon/docs/reference/refocus-channel.md +9 -3
  580. package/daemon/docs/reference/rig-spec.md +1 -1
  581. package/daemon/docs/reference/seat-delivery.md +57 -18
  582. package/daemon/docs/reference/slack-app-setup.md +49 -2
  583. package/daemon/docs/reference/whats-new.md +123 -68
  584. package/daemon/specs/agents/shared/skills/core/messaging-the-human/SKILL.md +24 -0
  585. package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +2 -2
  586. package/daemon/specs/agents/shared/skills/core/openrig-upgrade/SKILL.md +11 -5
  587. package/daemon/specs/agents/shared/skills/pods/development-team/SKILL.md +2 -0
  588. package/daemon/specs/agents/shared/skills/pods/development-team/references/refactoring.md +11 -0
  589. package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +46 -96
  590. package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +17 -80
  591. package/daemon/specs/agents/shared/skills/process/verification-before-completion/references/performance-claims.md +12 -0
  592. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +93 -14
  593. package/dist/build-info.js +3 -3
  594. package/dist/cli-error.d.ts +4 -0
  595. package/dist/cli-error.d.ts.map +1 -1
  596. package/dist/cli-error.js +6 -0
  597. package/dist/cli-error.js.map +1 -1
  598. package/dist/commands/agent-image.d.ts.map +1 -1
  599. package/dist/commands/agent-image.js +15 -7
  600. package/dist/commands/agent-image.js.map +1 -1
  601. package/dist/commands/archive.d.ts.map +1 -1
  602. package/dist/commands/archive.js +17 -3
  603. package/dist/commands/archive.js.map +1 -1
  604. package/dist/commands/attach.d.ts.map +1 -1
  605. package/dist/commands/attach.js +6 -4
  606. package/dist/commands/attach.js.map +1 -1
  607. package/dist/commands/broadcast.js +2 -0
  608. package/dist/commands/broadcast.js.map +1 -1
  609. package/dist/commands/community-harness.d.ts.map +1 -1
  610. package/dist/commands/community-harness.js +2 -1
  611. package/dist/commands/community-harness.js.map +1 -1
  612. package/dist/commands/compact-plan.d.ts.map +1 -1
  613. package/dist/commands/compact-plan.js +2 -1
  614. package/dist/commands/compact-plan.js.map +1 -1
  615. package/dist/commands/compact.d.ts.map +1 -1
  616. package/dist/commands/compact.js +10 -3
  617. package/dist/commands/compact.js.map +1 -1
  618. package/dist/commands/config.d.ts.map +1 -1
  619. package/dist/commands/config.js +10 -2
  620. package/dist/commands/config.js.map +1 -1
  621. package/dist/commands/context.d.ts.map +1 -1
  622. package/dist/commands/context.js +16 -9
  623. package/dist/commands/context.js.map +1 -1
  624. package/dist/commands/expand.d.ts.map +1 -1
  625. package/dist/commands/expand.js +16 -2
  626. package/dist/commands/expand.js.map +1 -1
  627. package/dist/commands/export.d.ts.map +1 -1
  628. package/dist/commands/export.js +9 -2
  629. package/dist/commands/export.js.map +1 -1
  630. package/dist/commands/fork.d.ts.map +1 -1
  631. package/dist/commands/fork.js +3 -1
  632. package/dist/commands/fork.js.map +1 -1
  633. package/dist/commands/gateway.d.ts +39 -0
  634. package/dist/commands/gateway.d.ts.map +1 -1
  635. package/dist/commands/gateway.js +310 -3
  636. package/dist/commands/gateway.js.map +1 -1
  637. package/dist/commands/health.js +3 -2
  638. package/dist/commands/health.js.map +1 -1
  639. package/dist/commands/host.d.ts +1 -1
  640. package/dist/commands/host.d.ts.map +1 -1
  641. package/dist/commands/host.js +2 -2
  642. package/dist/commands/host.js.map +1 -1
  643. package/dist/commands/launch.d.ts.map +1 -1
  644. package/dist/commands/launch.js +9 -2
  645. package/dist/commands/launch.js.map +1 -1
  646. package/dist/commands/plugin.d.ts.map +1 -1
  647. package/dist/commands/plugin.js +2 -1
  648. package/dist/commands/plugin.js.map +1 -1
  649. package/dist/commands/provider.d.ts.map +1 -1
  650. package/dist/commands/provider.js +0 -73
  651. package/dist/commands/provider.js.map +1 -1
  652. package/dist/commands/ps.d.ts +4 -0
  653. package/dist/commands/ps.d.ts.map +1 -1
  654. package/dist/commands/ps.js +95 -5
  655. package/dist/commands/ps.js.map +1 -1
  656. package/dist/commands/queue.d.ts +4 -0
  657. package/dist/commands/queue.d.ts.map +1 -1
  658. package/dist/commands/queue.js +78 -3
  659. package/dist/commands/queue.js.map +1 -1
  660. package/dist/commands/release.d.ts.map +1 -1
  661. package/dist/commands/release.js +16 -2
  662. package/dist/commands/release.js.map +1 -1
  663. package/dist/commands/restore-check.d.ts.map +1 -1
  664. package/dist/commands/restore-check.js +2 -1
  665. package/dist/commands/restore-check.js.map +1 -1
  666. package/dist/commands/restore-packet.d.ts.map +1 -1
  667. package/dist/commands/restore-packet.js +2 -1
  668. package/dist/commands/restore-packet.js.map +1 -1
  669. package/dist/commands/restore.d.ts.map +1 -1
  670. package/dist/commands/restore.js +23 -6
  671. package/dist/commands/restore.js.map +1 -1
  672. package/dist/commands/scope.d.ts.map +1 -1
  673. package/dist/commands/scope.js +5 -2
  674. package/dist/commands/scope.js.map +1 -1
  675. package/dist/commands/seat.js +0 -4
  676. package/dist/commands/seat.js.map +1 -1
  677. package/dist/commands/send.d.ts.map +1 -1
  678. package/dist/commands/send.js +27 -3
  679. package/dist/commands/send.js.map +1 -1
  680. package/dist/commands/setup.d.ts +3 -0
  681. package/dist/commands/setup.d.ts.map +1 -1
  682. package/dist/commands/setup.js +29 -9
  683. package/dist/commands/setup.js.map +1 -1
  684. package/dist/commands/shrink.d.ts.map +1 -1
  685. package/dist/commands/shrink.js +16 -2
  686. package/dist/commands/shrink.js.map +1 -1
  687. package/dist/commands/slack.d.ts.map +1 -1
  688. package/dist/commands/slack.js +11 -24
  689. package/dist/commands/slack.js.map +1 -1
  690. package/dist/commands/snapshot.d.ts.map +1 -1
  691. package/dist/commands/snapshot.js +36 -10
  692. package/dist/commands/snapshot.js.map +1 -1
  693. package/dist/commands/specs.d.ts.map +1 -1
  694. package/dist/commands/specs.js +11 -5
  695. package/dist/commands/specs.js.map +1 -1
  696. package/dist/commands/start.d.ts.map +1 -1
  697. package/dist/commands/start.js +36 -10
  698. package/dist/commands/start.js.map +1 -1
  699. package/dist/commands/status.d.ts.map +1 -1
  700. package/dist/commands/status.js +4 -1
  701. package/dist/commands/status.js.map +1 -1
  702. package/dist/commands/transcript.d.ts.map +1 -1
  703. package/dist/commands/transcript.js +12 -7
  704. package/dist/commands/transcript.js.map +1 -1
  705. package/dist/commands/unarchive.d.ts.map +1 -1
  706. package/dist/commands/unarchive.js +16 -2
  707. package/dist/commands/unarchive.js.map +1 -1
  708. package/dist/commands/up.d.ts.map +1 -1
  709. package/dist/commands/up.js +33 -7
  710. package/dist/commands/up.js.map +1 -1
  711. package/dist/commands/walk.d.ts.map +1 -1
  712. package/dist/commands/walk.js +2 -1
  713. package/dist/commands/walk.js.map +1 -1
  714. package/dist/commands/whoami.d.ts.map +1 -1
  715. package/dist/commands/whoami.js +3 -0
  716. package/dist/commands/whoami.js.map +1 -1
  717. package/dist/config-store.d.ts +4 -2
  718. package/dist/config-store.d.ts.map +1 -1
  719. package/dist/config-store.js +34 -7
  720. package/dist/config-store.js.map +1 -1
  721. package/dist/daemon-lifecycle.d.ts +9 -4
  722. package/dist/daemon-lifecycle.d.ts.map +1 -1
  723. package/dist/daemon-lifecycle.js +27 -9
  724. package/dist/daemon-lifecycle.js.map +1 -1
  725. package/dist/daemon-reachability.d.ts +13 -0
  726. package/dist/daemon-reachability.d.ts.map +1 -1
  727. package/dist/daemon-reachability.js +28 -0
  728. package/dist/daemon-reachability.js.map +1 -1
  729. package/dist/fetch-with-timeout.d.ts.map +1 -1
  730. package/dist/fetch-with-timeout.js +19 -16
  731. package/dist/fetch-with-timeout.js.map +1 -1
  732. package/dist/host-bindings.d.ts +6 -0
  733. package/dist/host-bindings.d.ts.map +1 -1
  734. package/dist/host-bindings.js +7 -4
  735. package/dist/host-bindings.js.map +1 -1
  736. package/dist/lib/bundle-check.d.ts.map +1 -1
  737. package/dist/lib/bundle-check.js +13 -5
  738. package/dist/lib/bundle-check.js.map +1 -1
  739. package/dist/mcp-server.d.ts.map +1 -1
  740. package/dist/mcp-server.js +57 -14
  741. package/dist/mcp-server.js.map +1 -1
  742. package/dist/rig-handle.d.ts +18 -1
  743. package/dist/rig-handle.d.ts.map +1 -1
  744. package/dist/rig-handle.js +19 -2
  745. package/dist/rig-handle.js.map +1 -1
  746. package/package.json +1 -1
  747. package/tui/dist/config/config-model.js +1 -1
  748. package/tui/dist/config/config-model.js.map +1 -1
  749. package/tui/dist/connections/connections-model.d.ts +0 -5
  750. package/tui/dist/connections/connections-model.d.ts.map +1 -1
  751. package/tui/dist/connections/connections-model.js +1 -1
  752. package/tui/dist/connections/connections-model.js.map +1 -1
  753. package/tui/dist/daemon-client.d.ts +2 -0
  754. package/tui/dist/daemon-client.d.ts.map +1 -1
  755. package/tui/dist/daemon-client.js +23 -0
  756. package/tui/dist/daemon-client.js.map +1 -1
  757. package/tui/dist/hydrate.d.ts.map +1 -1
  758. package/tui/dist/hydrate.js +13 -1
  759. package/tui/dist/hydrate.js.map +1 -1
  760. package/tui/dist/live.d.ts +10 -1
  761. package/tui/dist/live.d.ts.map +1 -1
  762. package/tui/dist/live.js +56 -7
  763. package/tui/dist/live.js.map +1 -1
  764. package/tui/dist/main.js +35 -2
  765. package/tui/dist/main.js.map +1 -1
  766. package/tui/dist/render.d.ts.map +1 -1
  767. package/tui/dist/render.js +111 -7
  768. package/tui/dist/render.js.map +1 -1
  769. package/tui/dist/types.d.ts +53 -0
  770. package/tui/dist/types.d.ts.map +1 -1
  771. package/tui/dist/version-skew.d.ts +24 -0
  772. package/tui/dist/version-skew.d.ts.map +1 -0
  773. package/tui/dist/version-skew.js +37 -0
  774. package/tui/dist/version-skew.js.map +1 -0
  775. package/daemon/dist/domain/provider/subscription-moves.d.ts +0 -77
  776. package/daemon/dist/domain/provider/subscription-moves.d.ts.map +0 -1
  777. package/daemon/dist/domain/provider/subscription-moves.js +0 -140
  778. package/daemon/dist/domain/provider/subscription-moves.js.map +0 -1
@@ -1,4 +1,5 @@
1
- import { readWakeLadderBackstop } from "./queue-wake-ladder.js";
1
+ import { PROMPT_ALERT_TAG, readWakeLadderBackstop } from "./queue-wake-ladder.js";
2
+ import { quietCustodyBackstop, quietHoldCustody } from "./quiet-hold-custody.js";
2
3
  import { createHash } from "node:crypto";
3
4
  import { loadHumanRegistry, resolveRegisteredHumanAddress } from "./gateway/human-registry.js";
4
5
  import { resolveExternal } from "./gateway/external-admission.js";
@@ -12,6 +13,7 @@ import { getSelfHostId } from "./hosts/fanout-contract.js";
12
13
  import { parseSessionName, isHumanSeatSessionRef } from "./session-name.js";
13
14
  import { parseReplyToChoice, formatReplyToChoice, describeReplyToFallback, REPLY_TO_CHOICE_ACTOR } from "./reply-to-choice.js";
14
15
  import { classifyDestination } from "./gateway/destination-resolver.js";
16
+ import { effectiveGateRoles } from "./gate-predicate.js";
15
17
  import { computeClosureRequiredAt, validateClosure, } from "./hot-potato-enforcer.js";
16
18
  import { isHumanSeatSession, validateHumanPark, validateHumanRoute } from "./human-route-enforcer.js";
17
19
  import { QueueWakeRepository, USAGE_LIMIT_BLOCKER_TAG, } from "./queue-wake-repository.js";
@@ -123,6 +125,35 @@ export function classifyNudgeFailure(lastNudgeResult) {
123
125
  return "unknown";
124
126
  }
125
127
  export const QUEUE_PRIORITIES = ["routine", "urgent", "critical"];
128
+ /** #1278: reject incomplete or invalid readings and keep only the four diagnostic fields. */
129
+ function inputBoxReading(inputBox) {
130
+ if (!inputBox || typeof inputBox !== "object")
131
+ return undefined;
132
+ const { seat, before, after, sameProcess } = inputBox;
133
+ if (!["idle", "not-idle", "unknown", "unchecked"].includes(seat) || typeof sameProcess !== "boolean")
134
+ return undefined;
135
+ const readings = ["exact", "ambiguous", "empty", "queued", "hidden", "other", "unrecognized", "unavailable", "unchecked"];
136
+ if (!readings.includes(before) || !readings.includes(after))
137
+ return undefined;
138
+ return { seat, before, after, sameProcess };
139
+ }
140
+ /** #1278: read a stored reading back; an absent or unreadable value reads unknown (null). The
141
+ * reading carries its attempt's timestamp (`at`), and reads unknown unless that is still the row's
142
+ * latest attempt: an older daemon records an attempt without touching this column, so a reading
143
+ * left behind by an earlier attempt must not read as the latest one's. */
144
+ function parseNudgeInputBox(stored, lastAttempt) {
145
+ if (!stored || !lastAttempt)
146
+ return null;
147
+ try {
148
+ const parsed = JSON.parse(stored);
149
+ if (parsed?.at !== lastAttempt)
150
+ return null;
151
+ return inputBoxReading(parsed) ?? null;
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ }
126
157
  /** The message a `--wake-after` park timer carries when its owner gives none. */
127
158
  export function defaultParkWakeMessage(qitemId) {
128
159
  return `Wake timer fired for parked qitem ${qitemId}. Resume the recorded continuation and update the row.`;
@@ -260,7 +291,8 @@ function detectTable(db, tableName) {
260
291
  // the compact projection is one thing: present text is shown, and what isn't selected is left out
261
292
  // and named in fieldsElided, never backfilled as empty.
262
293
  const COMPACT_ELIDED_FIELDS = [
263
- "body", "evidenceRef", "humanDetail", "waiting", "chainOfRecord", "replyTo", "humanQuestions", "humanAnswers",
294
+ "body", "evidenceRef", "humanDetail", "waiting", "chainOfRecord", "replyTo", "humanQuestions", "humanAnswers", "delegatedDecision",
295
+ "lastNudgeInputBox",
264
296
  ];
265
297
  function compactRow(item) {
266
298
  const row = { ...item, fieldsElided: [...COMPACT_ELIDED_FIELDS] };
@@ -406,6 +438,7 @@ export class QueueRepository {
406
438
  * fallback real code rather than a promise in a comment). */
407
439
  outbox;
408
440
  resolveOccupantGeneration;
441
+ resolveSessionAddresses;
409
442
  wakeRepo;
410
443
  watchdogJobsRepo;
411
444
  /** PL-007 Workspace Primitive — true when migration 038 has applied the
@@ -418,7 +451,10 @@ export class QueueRepository {
418
451
  hasHumanIntentColumn;
419
452
  hasReplyToColumn;
420
453
  hasHumanQuestionsColumn;
454
+ hasDelegatedDecisionColumn;
421
455
  hasEvidenceRefColumn;
456
+ /** #1278 — migration 116; older fixtures without it record no reading. */
457
+ hasNudgeInputBoxColumn;
422
458
  hasMintingGenColumn;
423
459
  hasClaimedGenColumn;
424
460
  hasQueueTransitionsTable;
@@ -439,13 +475,16 @@ export class QueueRepository {
439
475
  this.attachTransport(opts.transport);
440
476
  this.workflowFrontierPredicate = opts?.workflowFrontierPredicate;
441
477
  this.resolveOccupantGeneration = opts?.resolveOccupantGeneration;
478
+ this.resolveSessionAddresses = opts?.resolveSessionAddresses ?? ((name) => [name]);
442
479
  this.loadHumanRegistryFn = opts?.loadHumanRegistry ?? (() => loadHumanRegistry());
443
480
  this.hasTargetRepoColumn = detectQueueColumn(db, "target_repo");
444
481
  this.hasSummaryColumn = detectQueueColumn(db, "summary");
445
482
  this.hasHumanIntentColumn = detectQueueColumn(db, "human_intent");
446
483
  this.hasReplyToColumn = detectQueueColumn(db, "reply_to");
447
484
  this.hasHumanQuestionsColumn = detectQueueColumn(db, "human_questions");
485
+ this.hasDelegatedDecisionColumn = detectQueueColumn(db, "delegated_decision");
448
486
  this.hasEvidenceRefColumn = detectQueueColumn(db, "evidence_ref");
487
+ this.hasNudgeInputBoxColumn = detectQueueColumn(db, "last_nudge_input_box");
449
488
  this.hasQueueTransitionsTable = detectTable(db, "queue_transitions");
450
489
  const transitionColumns = this.hasQueueTransitionsTable
451
490
  ? new Set(db.prepare("PRAGMA table_info(queue_transitions)").all().map((column) => column.name))
@@ -508,8 +547,8 @@ export class QueueRepository {
508
547
  }));
509
548
  }
510
549
  currentWakeIntent(entry) {
511
- const row = entry.auditPointer ? this.db.prepare("SELECT state FROM queue_items WHERE qitem_id=?").get(entry.auditPointer) : undefined;
512
- if (row?.state !== "pending")
550
+ const row = entry.auditPointer ? this.db.prepare("SELECT state, destination_session FROM queue_items WHERE qitem_id=?").get(entry.auditPointer) : undefined;
551
+ if (row?.state !== "pending" || row.destination_session !== entry.destinationSession)
513
552
  return false;
514
553
  const prefix = `${WAKE_INTENT_PREFIX}blocker-`;
515
554
  if (!entry.outboxId.startsWith(prefix))
@@ -523,16 +562,22 @@ export class QueueRepository {
523
562
  return expected === latest?.transition_id;
524
563
  }
525
564
  classifyWakeResult(res) {
565
+ // #1278: the reading rides along unchanged; it never alters the classification.
566
+ const inputBox = inputBoxReading(res.inputBox);
567
+ const reading = inputBox ? { inputBox } : {};
526
568
  if (res.outcome === "retained")
527
569
  return { classified: "retained", nudgeResult: res.reason?.startsWith("draft_")
528
- ? "retained:draft_aware" : "retained:typing_guard" };
570
+ ? "retained:draft_aware" : "retained:typing_guard", ...reading };
529
571
  if (res.ok)
530
- return res.verified ? { classified: "verified", nudgeResult: "verified" } : { classified: "indeterminate", nudgeResult: "delivered-ack-pending" };
572
+ return res.verified ? { classified: "verified", nudgeResult: "verified", ...reading } : { classified: "indeterminate", nudgeResult: "delivered-ack-pending", ...reading };
531
573
  const detail = res.error ?? res.reason ?? "unknown";
532
- if (res.delivery?.state === "indeterminate" || res.delivery?.state === "sending" || isWakeTimeoutSignal(res.reason) || isWakeTimeoutSignal(res.error)) {
533
- return { classified: "indeterminate", nudgeResult: `indeterminate:${detail}` };
574
+ // Input evidence survives receipt removal: an issued paste or uncertain Enter is never an unsent failure.
575
+ const inputUncertain = res.sent === true || res.inputPhase === "attempted" || res.inputPhase === "written"
576
+ || (res.sent !== false && res.inputPhase !== "not_reached" && (res.reason === "delivery_indeterminate" || res.reason === "submit_failed"));
577
+ if (inputUncertain || isWakeTimeoutSignal(res.reason) || isWakeTimeoutSignal(res.error)) {
578
+ return { classified: "indeterminate", nudgeResult: `indeterminate:${detail}`, ...reading };
534
579
  }
535
- return { classified: "failed", nudgeResult: `failed:${detail}` };
580
+ return { classified: "failed", nudgeResult: `failed:${detail}`, ...reading };
536
581
  }
537
582
  /**
538
583
  * W1 (transactional closure): attach the durable wake-intent store AFTER
@@ -690,34 +735,31 @@ export class QueueRepository {
690
735
  }
691
736
  }
692
737
  /**
693
- * W1-b: deliver ONE committed wake intent. MF3: CLAIM (pending→sending) before
694
- * the external send, then finalize (sending→outcome) after — so overlapping
695
- * drains send the wake exactly ONCE (the effect, not just the state), and a
696
- * second drain of an already-claimed/resolved intent skips. Returns what
697
- * happened for the drain's tally.
698
- *
699
- * verified → delivered
700
- * ok, unverified → indeterminate (ambiguous; never silently delivered/failed)
701
- * timeout (MF6) → indeterminate (may have landed — not a hard failure)
702
- * other not-ok/throw→ failed (visible terminal state)
738
+ * Attempt a current committed notification. A live claim, known success or manual
739
+ * hold is left alone; failed/uncertain history permits another attempt. A recovery
740
+ * pass tracks its coalesced members only in memory so each is attempted once per pass.
703
741
  */
704
- async deliverWakeIntent(outboxId) {
742
+ async deliverWakeIntent(outboxId, attempted) {
705
743
  if (!this.outbox)
706
744
  return "skipped";
707
745
  if (!this.transport)
708
746
  return "skipped"; // no transport → stays pending for a later drain
747
+ if (attempted?.has(outboxId))
748
+ return "skipped";
709
749
  const alreadyHeld = this.outbox.getById(outboxId);
710
750
  if (alreadyHeld?.deliveryState === "retained" || alreadyHeld?.deliveryState === "retired") {
711
751
  if (alreadyHeld.auditPointer)
712
752
  this.recordNudgeAttempt(alreadyHeld.auditPointer, "retained:typing_guard");
713
753
  return "retained";
714
754
  }
715
- // MF3: CLAIM (pending→sending) BEFORE the external send so overlapping drains
716
- // cannot both send. A losing claim — the row is no longer `pending` (already
717
- // resolved, in-flight under another drainer, or claimed) — simply skips: no
718
- // send, no tally. This makes the external effect once, not merely the state.
719
- // Claim the exact return's arrival + dependent resumes atomically. Each
720
- // original frozen intent and audit pointer survives; only transport coalesces.
755
+ let recovering = false;
756
+ const claim = (entry) => {
757
+ if (attempted?.has(entry.outboxId) || !this.outbox.claimForDelivery(entry.outboxId))
758
+ return false;
759
+ attempted?.add(entry.outboxId);
760
+ recovering ||= entry.deliveryState !== "pending";
761
+ return true;
762
+ };
721
763
  let superseded = false;
722
764
  const actionable = (entry) => {
723
765
  const current = this.currentWakeIntent(entry);
@@ -733,21 +775,23 @@ export class QueueRepository {
733
775
  };
734
776
  const group = this.db.transaction(() => {
735
777
  const candidate = this.outbox.getById(outboxId);
736
- if (!candidate || candidate.deliveryState !== "pending" || !actionable(candidate))
778
+ if (!candidate || !["pending", "failed", "indeterminate"].includes(candidate.deliveryState) || !actionable(candidate))
737
779
  return [];
738
- if (!this.outbox.claimForDelivery(outboxId))
780
+ if (!claim(candidate))
739
781
  return [];
740
- const first = this.outbox.getById(outboxId);
782
+ const first = candidate; // Keep each member's pre-claim uncertainty.
741
783
  const intents = [first];
742
784
  const correlation = first.tags?.find(tag => tag.startsWith("queue:return:"));
743
785
  if (correlation) {
744
786
  const peers = this.db.prepare(`SELECT outbox_id FROM outbox_entries
745
- WHERE delivery_state = 'pending' AND destination_session = ? AND substr(outbox_id, 1, ?) = ?
787
+ WHERE delivery_state IN ('pending','failed','indeterminate') AND destination_session = ? AND substr(outbox_id, 1, ?) = ?
746
788
  AND EXISTS (SELECT 1 FROM json_each(outbox_entries.tags) WHERE value = ?)
747
789
  ORDER BY outbox_id`).all(first.destinationSession, WAKE_INTENT_PREFIX.length, WAKE_INTENT_PREFIX, correlation);
748
- for (const peer of peers)
749
- if (actionable(this.outbox.getById(peer.outbox_id)) && this.outbox.claimForDelivery(peer.outbox_id))
750
- intents.push(this.outbox.getById(peer.outbox_id));
790
+ for (const peer of peers) {
791
+ const entry = this.outbox.getById(peer.outbox_id);
792
+ if (actionable(entry) && claim(entry))
793
+ intents.push(entry);
794
+ }
751
795
  }
752
796
  return intents;
753
797
  })();
@@ -763,11 +807,17 @@ export class QueueRepository {
763
807
  return "failed";
764
808
  }
765
809
  const qitemId = intent.auditPointer ?? outboxId;
766
- // MF4: send the FROZEN envelope stored on the intent verbatim (no re-resolution).
767
- const outcome = await this.performWakeSend(qitemId, intent.destinationSession, intent.senderSession, undefined, group.map(entry => entry.body).join("\n"), group.map(entry => entry.outboxId));
768
- const finalState = outcome.classified === "verified" ? "delivered" : outcome.classified;
769
- for (const member of group) {
770
- const intent = member;
810
+ // Preserve the original envelope/source generation; add context without rewriting its stored bytes.
811
+ const recoveryNotice = recovering ? "Recovered queue notification: delivery may repeat after an earlier unconfirmed attempt.\n" : "";
812
+ const outcome = await this.performWakeSend(qitemId, intent.destinationSession, intent.senderSession, undefined, recoveryNotice + group.map(entry => entry.body).join("\n"), group.map(entry => entry.outboxId));
813
+ let reportedState = outcome.classified === "verified" ? "delivered" : outcome.classified;
814
+ for (const intent of group) {
815
+ // A no-write retry cannot settle whether an earlier attempt landed.
816
+ const earlierUnknown = intent.deliveryState === "indeterminate" && outcome.classified === "failed";
817
+ const finalState = earlierUnknown ? "indeterminate" : outcome.classified === "verified" ? "delivered" : outcome.classified;
818
+ const nudgeResult = earlierUnknown ? `indeterminate:earlier delivery unconfirmed; retry ${outcome.nudgeResult}` : outcome.nudgeResult;
819
+ if (earlierUnknown)
820
+ reportedState = "indeterminate";
771
821
  const qitemId = intent.auditPointer;
772
822
  const blockerRef = intent.tags?.includes(AUTO_UNPARK_WAKE_TAG)
773
823
  ? intent.tags
@@ -775,7 +825,8 @@ export class QueueRepository {
775
825
  ?.slice(AUTO_UNPARK_BLOCKER_TAG_PREFIX.length)
776
826
  : undefined;
777
827
  const wakeEvent = this.db.transaction(() => {
778
- this.recordNudgeAttempt(qitemId, outcome.nudgeResult);
828
+ // #1278: a coalesced wake is one send, so every row it woke gets that send's reading.
829
+ this.recordNudgeAttempt(qitemId, nudgeResult, outcome.inputBox);
779
830
  this.outbox.finalizeDelivery(intent.outboxId, finalState);
780
831
  if (!blockerRef)
781
832
  return null;
@@ -784,7 +835,7 @@ export class QueueRepository {
784
835
  qitemId,
785
836
  state: item.state,
786
837
  actorSession: "queue@system",
787
- transitionNote: `blocker ${blockerRef} wake attempted; delivery=${outcome.nudgeResult}`,
838
+ transitionNote: `blocker ${blockerRef} wake attempted; delivery=${nudgeResult}`,
788
839
  });
789
840
  this.wakeRepo.record({
790
841
  transitionId: transition.transitionId,
@@ -792,7 +843,7 @@ export class QueueRepository {
792
843
  phase: "fired",
793
844
  kind: "blocker",
794
845
  ref: blockerRef,
795
- deliveryStatus: outcome.nudgeResult,
846
+ deliveryStatus: nudgeResult,
796
847
  });
797
848
  return this.eventBus.persistWithinTransaction({
798
849
  type: "queue.updated",
@@ -808,32 +859,10 @@ export class QueueRepository {
808
859
  if (wakeEvent)
809
860
  this.eventBus.notifySubscribers(wakeEvent);
810
861
  }
811
- return finalState;
862
+ return reportedState;
812
863
  }
813
- /**
814
- * W1-b: the post-commit delivery for a successor's wake, and the ONE shared
815
- * staged-intent delivery path. When the durable intent store is present
816
- * (production), deliver the just-committed intent — which CLAIMS and FINALIZES
817
- * the row, so a later recovery sweep cannot send it a second time. When it is
818
- * absent (test/bootstrap), fall back to the pre-W1 best-effort nudge so behavior
819
- * is unchanged where there is no intent to make durable. Called AFTER the
820
- * terminal transaction commits (reversed-never: a pane write must not join the
821
- * db transaction).
822
- *
823
- * PUBLIC as of P34: every terminal-closing writer that stages an intent must
824
- * deliver through THIS path rather than {@link maybeNudge}. `maybeNudge` sends
825
- * WITHOUT claiming or finalizing, so a staged intent would remain `pending` and
826
- * the startup recovery sweep would deliver the same wake AGAIN. One staged
827
- * intent, one delivery, one finalized row.
828
- *
829
- * P34 correction: the no-outbox fallback above was documented here but never
830
- * implemented — `deliverWakeIntent` simply returns "skipped" with no outbox
831
- * attached, so the nudge vanished SILENTLY (a skip is not an error, so nothing
832
- * surfaced it). The pre-W1 callers reached this path only after the MF2 guard
833
- * had already proven an outbox was attached, which is why it never showed. P34
834
- * routes writers here whose harnesses attach no outbox, so the fallback is now
835
- * real code rather than a promise in a comment.
836
- */
864
+ /** Deliver after the queue transaction commits, never from inside it. The shared
865
+ * intent path owns claims and outcomes; without an intent store use the legacy nudge. */
837
866
  async deliverWakeForSuccessor(successorQitemId, destinationSession, nudge, sourceSession) {
838
867
  if (nudge === false)
839
868
  return;
@@ -846,69 +875,45 @@ export class QueueRepository {
846
875
  }
847
876
  await this.deliverWakeIntent(`${WAKE_INTENT_PREFIX}${successorQitemId}`);
848
877
  }
849
- /**
850
- * W1-b: the startup-recovery sweep. Delivers wake intents a crash left
851
- * committed-but-undelivered (the terminal txn committed, the process died
852
- * before the post-commit deliver). Pages in bounded batches and TERMINATES on
853
- * a served short batch or on a no-progress round (a flapping transport marks
854
- * rows failed = visible, so it still progresses) — never a silent cap, never a
855
- * spin.
856
- *
857
- * MF6 (honest retry policy): the sweep retries ONLY `pending` rows — i.e. wake
858
- * intents a crash left committed-but-undelivered. Terminal `failed` and
859
- * `indeterminate` rows are NOT re-driven: a failed row would risk resurrecting
860
- * a dead wake and an indeterminate one may already have landed (double-send).
861
- * Both are left in a VISIBLE terminal state for out-of-band reconciliation. No
862
- * periodic timer (out of scope, ruled); a bounded retry of failed rows is the
863
- * NAMED residue, not a silent guarantee.
864
- */
865
- /**
866
- * BLOCKING 1 (guard re-seal): the recovery-boundary reconciliation, called ONCE
867
- * at startup (NOT inside the drain, which can be invoked concurrently). Moves any
868
- * abandoned `sending` wake intents — a prior crashed process's claims — to
869
- * `indeterminate`, WITHOUT re-sending: a claim left `sending` is ambiguous (the
870
- * send may or may not have landed). Kept SEPARATE from drainPendingWakeIntents so
871
- * an overlapping drain can never reconcile another drain's in-flight claim.
872
- * Returns the count reconciled.
873
- */
878
+ /** Once at startup, mark abandoned live claims unknown before recovery makes a
879
+ * new attempt. Never run inside a drain: another drain may still own a live send. */
874
880
  reconcileAbandonedWakeIntents() {
875
881
  if (!this.outbox)
876
882
  return 0;
877
883
  return this.outbox.reconcileAbandonedSending(WAKE_INTENT_PREFIX);
878
884
  }
885
+ /** Recover current notifications once per pass. A snapshot horizon and seek cursor
886
+ * prevent new arrivals or persistent failures from making this pass unbounded. */
879
887
  async drainPendingWakeIntents() {
880
888
  const tally = { delivered: 0, indeterminate: 0, failed: 0, retained: 0 };
881
889
  if (!this.outbox || !this.transport)
882
890
  return tally;
883
891
  const BATCH = 200;
892
+ const horizon = this.db.prepare("SELECT COALESCE(MAX(rowid),0) AS id FROM outbox_entries").get().id;
893
+ // Retire never-attempted obsolete notifications without materializing historical intents.
894
+ tally.failed += this.db.prepare(`UPDATE outbox_entries AS o SET delivery_state = 'failed',
895
+ tags = json_insert(COALESCE(tags, '[]'), '$[#]', 'queue:wake-superseded')
896
+ WHERE delivery_state = 'pending' AND rowid <= ? AND substr(outbox_id, 1, ?) = ?
897
+ AND NOT EXISTS (SELECT 1 FROM queue_items q WHERE q.qitem_id = o.audit_pointer
898
+ AND q.state = 'pending' AND q.destination_session = o.destination_session)`)
899
+ .run(horizon, WAKE_INTENT_PREFIX.length, WAKE_INTENT_PREFIX).changes;
900
+ const attempted = new Set();
901
+ let cursor = 0;
884
902
  for (;;) {
885
- const pending = this.outbox.listPending(WAKE_INTENT_PREFIX, BATCH);
903
+ const pending = this.db.prepare(`SELECT o.rowid AS id, o.outbox_id FROM outbox_entries o
904
+ JOIN queue_items q ON q.qitem_id = o.audit_pointer AND q.state = 'pending'
905
+ AND q.destination_session = o.destination_session
906
+ WHERE o.rowid > ? AND o.rowid <= ? AND substr(o.outbox_id, 1, ?) = ?
907
+ AND o.delivery_state IN ('pending','failed','indeterminate') ORDER BY o.rowid LIMIT ?`)
908
+ .all(cursor, horizon, WAKE_INTENT_PREFIX.length, WAKE_INTENT_PREFIX, BATCH);
886
909
  if (pending.length === 0)
887
910
  break;
888
- let progressed = 0;
889
911
  for (const intent of pending) {
890
- const outcome = await this.deliverWakeIntent(intent.outboxId);
891
- if (outcome === "delivered") {
892
- tally.delivered++;
893
- progressed++;
894
- }
895
- else if (outcome === "indeterminate") {
896
- tally.indeterminate++;
897
- progressed++;
898
- }
899
- else if (outcome === "failed") {
900
- tally.failed++;
901
- progressed++;
902
- }
903
- else if (outcome === "retained") {
904
- tally.retained++;
905
- progressed++;
906
- }
912
+ cursor = intent.id;
913
+ const outcome = await this.deliverWakeIntent(intent.outbox_id, attempted);
914
+ if (outcome !== "skipped")
915
+ tally[outcome]++;
907
916
  }
908
- // Nothing left pending changed state this round (e.g. transport gone
909
- // mid-sweep) — stop rather than spin; the next daemon start retries.
910
- if (progressed === 0)
911
- break;
912
917
  if (pending.length < BATCH)
913
918
  break; // served short batch ⇒ drained
914
919
  }
@@ -942,7 +947,15 @@ export class QueueRepository {
942
947
  if (!this.transport)
943
948
  return;
944
949
  const outcome = await this.performWakeSend(qitemId, destinationSession, sourceSession, bodyOverride);
945
- this.recordNudgeAttempt(qitemId, outcome.nudgeResult);
950
+ this.recordNudgeAttempt(qitemId, outcome.nudgeResult, outcome.inputBox);
951
+ }
952
+ /** The following startup intent drain owns durable pending wakes. Legacy packets
953
+ * and overdue claimed work (not eligible for that drain) still use the nudge path. */
954
+ async recoverLostNudge(qitemId, destinationSession, sourceSession) {
955
+ const outboxId = `${WAKE_INTENT_PREFIX}${qitemId}`;
956
+ if (this.outbox?.getById(outboxId) && this.getById(qitemId)?.state === "pending")
957
+ return;
958
+ await this.maybeNudge(qitemId, destinationSession, undefined, sourceSession);
946
959
  }
947
960
  /**
948
961
  * W1 (transactional closure): the shared wake-send CORE. Builds the pane
@@ -1679,23 +1692,25 @@ export class QueueRepository {
1679
1692
  * Per PL-004 Phase A § Routes: GET /api/queue/whoami.
1680
1693
  */
1681
1694
  whoami(session, opts) {
1695
+ const addresses = this.resolveSessionAddresses(session);
1696
+ const slots = addresses.map(() => "?").join(",");
1682
1697
  const limit = Math.max(1, Math.min(opts?.recentLimit ?? 25, 200));
1683
1698
  const countByState = (state) => {
1684
1699
  const row = this.db
1685
- .prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE destination_session = ? AND state = ?`)
1686
- .get(session, state);
1700
+ .prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE destination_session IN (${slots}) AND state = ?`)
1701
+ .get(...addresses, state);
1687
1702
  return row.n;
1688
1703
  };
1689
1704
  const recent = this.db
1690
1705
  .prepare(`SELECT * FROM queue_items
1691
- WHERE destination_session = ?
1706
+ WHERE destination_session IN (${slots})
1692
1707
  AND state IN ('pending','in-progress','blocked')
1693
1708
  ORDER BY ts_updated DESC
1694
1709
  LIMIT ?`)
1695
- .all(session, limit);
1710
+ .all(...addresses, limit);
1696
1711
  const sourceTotalRow = this.db
1697
- .prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE source_session = ?`)
1698
- .get(session);
1712
+ .prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE source_session IN (${slots})`)
1713
+ .get(...addresses);
1699
1714
  return {
1700
1715
  session,
1701
1716
  asDestination: {
@@ -1717,9 +1732,11 @@ export class QueueRepository {
1717
1732
  * silently degrades into a confident answer. This is that authoritative input.
1718
1733
  */
1719
1734
  listInProgressForDestination(session) {
1735
+ const addresses = this.resolveSessionAddresses(session);
1736
+ const slots = addresses.map(() => "?").join(",");
1720
1737
  const rows = this.db
1721
- .prepare(`SELECT * FROM queue_items WHERE destination_session = ? AND state = 'in-progress'`)
1722
- .all(session);
1738
+ .prepare(`SELECT * FROM queue_items WHERE destination_session IN (${slots}) AND state = 'in-progress'`)
1739
+ .all(...addresses);
1723
1740
  return rows.map((r) => this.rowToItem(r));
1724
1741
  }
1725
1742
  /**
@@ -1730,7 +1747,7 @@ export class QueueRepository {
1730
1747
  if (!qitem) {
1731
1748
  throw new QueueRepositoryError("qitem_not_found", `qitem ${input.qitemId} not found`);
1732
1749
  }
1733
- if (qitem.destinationSession !== input.destinationSession) {
1750
+ if (!this.resolveSessionAddresses(input.destinationSession).includes(qitem.destinationSession)) {
1734
1751
  throw new QueueRepositoryError("claim_destination_mismatch", `qitem ${input.qitemId} destination is ${qitem.destinationSession}, not ${input.destinationSession}`);
1735
1752
  }
1736
1753
  if (qitem.state !== "pending" && qitem.state !== "blocked") {
@@ -1874,6 +1891,11 @@ export class QueueRepository {
1874
1891
  const result = this.updateInTransactionalContext(input);
1875
1892
  return { qitemId: input.qitemId, ...result };
1876
1893
  }
1894
+ /** Notify subscribers of events persisted inside a caller's own transaction (updateWithinTransaction), after it commits. */
1895
+ notifyCommitted(events) {
1896
+ for (const event of events)
1897
+ this.eventBus.notifySubscribers(event);
1898
+ }
1877
1899
  /** Internal read-only audit pointer for non-state receipts. Never search past a state write. */
1878
1900
  retainedClaimBlocker(qitemId) {
1879
1901
  const latest = this.transitionLog.listForQitem(qitemId).at(-1);
@@ -1916,6 +1938,19 @@ export class QueueRepository {
1916
1938
  || (input.state !== undefined && input.summary != null)
1917
1939
  || (input.summary != null && !hasValidSummary);
1918
1940
  if (disallowed) {
1941
+ // Keep the terminal-park correction visible even when the row is already done.
1942
+ if (input.state === "done" && input.closureReason === "blocked_on") {
1943
+ const validation = validateClosure({
1944
+ state: input.state,
1945
+ closureReason: input.closureReason,
1946
+ closureTarget: input.closureTarget,
1947
+ });
1948
+ if (!validation.ok) {
1949
+ throw new QueueRepositoryError(validation.code, validation.message, {
1950
+ validReasons: validation.validReasons,
1951
+ });
1952
+ }
1953
+ }
1919
1954
  throw new QueueRepositoryError("note_append_fields_not_admitted", "a state-preserving note append accepts only --note (and an optional same --state); state-write fields were supplied, so nothing was written");
1920
1955
  }
1921
1956
  if (hasValidSummary) {
@@ -2459,7 +2494,8 @@ export class QueueRepository {
2459
2494
  /** The parked row an ordinary due park timer reminds about, when its reminder may share one message with other
2460
2495
  * reminders due for the same seat in the same scheduler pass: a one-shot `--wake-after` timer serving exactly one
2461
2496
  * live parked row, carrying its default message. Null keeps the reminder's own send: a custom message, a shared
2462
- * or attached watchdog, a repeating wait and a provider-limit timer each deliver as before. */
2497
+ * or attached watchdog, a repeating wait and a provider-limit timer each deliver as before. The entry carries the
2498
+ * current park's recorded continuation, or null, for the wake's preview. */
2463
2499
  parkReminderDigestEntry(jobId, message) {
2464
2500
  const generated = this.wakeRepo.findCurrentQitemsByGeneratedTimer(jobId);
2465
2501
  const bound = this.wakeRepo.findBlockedQitemsByWatchdog(jobId, true);
@@ -2473,7 +2509,7 @@ export class QueueRepository {
2473
2509
  return null;
2474
2510
  if (message !== defaultParkWakeMessage(row.qitemId))
2475
2511
  return null;
2476
- return { qitemId: row.qitemId, summary: row.summary ?? null };
2512
+ return { qitemId: row.qitemId, summary: row.summary ?? null, continuation: this.currentParkContinuation(row.qitemId) };
2477
2513
  }
2478
2514
  /** Called by the watchdog engine after the delivery attempt is durably
2479
2515
  * audited. The queue transition records that attempt independently of
@@ -2617,7 +2653,11 @@ export class QueueRepository {
2617
2653
  if (item.state !== "pending") {
2618
2654
  // Slack can redeliver the click that closed it. Only to the asked human, say whether this answer is on record.
2619
2655
  const onRecord = item.destinationSession === input.actorSession && item.humanAnswers?.[input.questionId] === input.optionId;
2620
- return { status: "not-applicable", reason: `state-${item.state}`, ...(onRecord ? { answerOnRecord: true } : {}) };
2656
+ const delegated = item.destinationSession === input.actorSession ? item.delegatedDecision : null;
2657
+ const decidedForThem = delegated ? { decidedBy: delegated.decidedBy, modeName: delegated.modeName, reversible: delegated.reversible,
2658
+ chose: delegated.choices.map((c) => c.options.find((o) => o.id === c.chosen)?.label ?? c.chosen).join(", ") } : null;
2659
+ return { status: "not-applicable", reason: `state-${item.state}`, ...(onRecord ? { answerOnRecord: true } : {}),
2660
+ ...(decidedForThem ? { decidedForThem } : {}) };
2621
2661
  }
2622
2662
  if (item.destinationSession !== input.actorSession)
2623
2663
  return { status: "not-applicable", reason: "not-the-asked-human" };
@@ -2634,6 +2674,101 @@ export class QueueRepository {
2634
2674
  return { status: "recorded", answers, complete, questions: item.humanQuestions };
2635
2675
  })();
2636
2676
  }
2677
+ /**
2678
+ * Record a decision made on the person's behalf, inside their mode's decision room, on the ask's own row. Only the
2679
+ * agent that asked may record it, only on a pending decision to that person, and only while their mode has a stated
2680
+ * decision room, read in the same transaction. A permission prompt or approval gate is never decided this way. It never writes humanAnswers or a
2681
+ * human-decision-resolved notice: the person didn't answer. The ask is closed (done, no follow-on) so it isn't posted
2682
+ * or re-offered, and the asking agent carries on with its choice.
2683
+ */
2684
+ recordDelegatedDecision(input) {
2685
+ const refuse = (reason, message) => ({ status: "refused", reason, message });
2686
+ if (!this.hasDelegatedDecisionColumn)
2687
+ return refuse("schema", "this daemon's queue schema has no place for a delegated decision");
2688
+ const result = this.db.transaction(() => {
2689
+ const item = this.getById(input.qitemId);
2690
+ if (!item)
2691
+ return refuse("not-found", `qitem ${input.qitemId} not found`);
2692
+ if (item.state !== "pending")
2693
+ return refuse("not-pending", `${input.qitemId} is ${item.state}; only a pending ask can be decided`);
2694
+ const person = parseSessionName(item.destinationSession);
2695
+ if (person.kind !== "external" || item.humanIntent === "update")
2696
+ return refuse("not-a-decision", `${input.qitemId} isn't a decision asked of a person`);
2697
+ // A permission prompt (the wake ladder's prompt alert) or an approval gate (gate work for the human role) is never delegated.
2698
+ if (item.tags?.includes(PROMPT_ALERT_TAG) || effectiveGateRoles({ tags: item.tags, tier: item.tier }).includes("human")) {
2699
+ return refuse("permission-prompt", "a permission prompt or approval gate is never decided on the person's behalf");
2700
+ }
2701
+ // A click keeps a multi-question ask pending until every question is answered: once the person has started, it's theirs.
2702
+ if (item.humanAnswers && Object.keys(item.humanAnswers).length > 0) {
2703
+ return refuse("person-answering", "they've started answering; their answer stands");
2704
+ }
2705
+ if (item.sourceSession !== input.actorSession) {
2706
+ return refuse("not-the-asking-agent", `only the agent that asked (${item.sourceSession}) can record a decision on this ask`);
2707
+ }
2708
+ const app = input.currentApplication(person.local);
2709
+ if (!app)
2710
+ return refuse("no-active-mode", `${person.local} has no mode on, so nothing can be decided for them`);
2711
+ if (app.entityId !== person.local)
2712
+ return refuse("not-the-persons-mode", `that mode is ${app.entityId}'s, not ${person.local}'s`);
2713
+ if (!app.decisionRoom)
2714
+ return refuse("no-decision-room", `${person.local}'s ${app.modeName} has no decision room, so nothing can be decided for them`);
2715
+ if (app.applicationId !== input.expectedApplicationId) {
2716
+ return refuse("mode-changed", "their mode changed since you read the room; read it again");
2717
+ }
2718
+ if (!input.reason.trim())
2719
+ return refuse("invalid-choice", "say why this choice was made");
2720
+ let choices;
2721
+ const questions = item.humanQuestions ?? [];
2722
+ if (questions.length > 0) {
2723
+ const picked = new Map(input.choices.map((c) => [c.questionId ?? "", c.chosen]));
2724
+ if (picked.size !== input.choices.length || questions.some((q) => !picked.has(q.id)) || [...picked.keys()].some((id) => !questions.some((q) => q.id === id))) {
2725
+ return refuse("invalid-choice", `choose one option for each question: ${questions.map((q) => q.id).join(", ")}`);
2726
+ }
2727
+ choices = [];
2728
+ for (const q of questions) {
2729
+ const chosen = picked.get(q.id);
2730
+ if (!q.options.some((o) => o.id === chosen))
2731
+ return refuse("invalid-choice", `"${chosen}" isn't an option of ${q.id}`);
2732
+ choices.push({ questionId: q.id, question: q.question, options: q.options.map((o) => ({ id: o.id, label: o.label })), chosen });
2733
+ }
2734
+ }
2735
+ else {
2736
+ const chosen = input.choices.length === 1 && !input.choices[0].questionId ? input.choices[0].chosen.trim() : "";
2737
+ if (!chosen)
2738
+ return refuse("invalid-choice", "this ask has no structured questions: give one choice, in words");
2739
+ choices = [{ questionId: null, question: item.summary ?? item.body.slice(0, 200), options: [], chosen }];
2740
+ }
2741
+ const record = {
2742
+ applicationId: app.applicationId, modeName: app.modeName, decisionRoom: app.decisionRoom, decidedBy: input.actorSession,
2743
+ decidedAt: (input.now ?? new Date()).toISOString(), choices, reason: input.reason.trim(), reversible: input.reversible,
2744
+ };
2745
+ this.db.prepare("UPDATE queue_items SET delegated_decision = ? WHERE qitem_id = ?").run(JSON.stringify(record), input.qitemId);
2746
+ const chose = choices.map((c) => `${c.questionId ?? "choice"}=${c.chosen}`).join(", ");
2747
+ const closed = this.updateInTransactionalContext({
2748
+ qitemId: input.qitemId,
2749
+ actorSession: input.actorSession,
2750
+ state: "done",
2751
+ closureReason: "no-follow-on",
2752
+ transitionNote: `delegated-decision application=${app.applicationId} mode=${app.modeName} reversible=${input.reversible} `
2753
+ + `chose ${chose}: decided on ${person.local}'s behalf by ${input.actorSession}, not answered by them`,
2754
+ });
2755
+ return { status: "closed", events: closed.persistedEvents };
2756
+ })();
2757
+ if (result.status === "refused")
2758
+ return result;
2759
+ for (const event of result.events)
2760
+ this.eventBus.notifySubscribers(event);
2761
+ return { status: "recorded", item: this.getById(input.qitemId) };
2762
+ }
2763
+ /** The decisions made on a person's behalf under one mode application, oldest first: for the account when they're back. */
2764
+ delegatedDecisionsFor(applicationId) {
2765
+ if (!this.hasDelegatedDecisionColumn)
2766
+ return [];
2767
+ const rows = this.db.prepare(`SELECT * FROM queue_items WHERE delegated_decision IS NOT NULL
2768
+ AND json_extract(delegated_decision, '$.applicationId') = ?
2769
+ ORDER BY json_extract(delegated_decision, '$.decidedAt'), qitem_id`).all(applicationId);
2770
+ return rows.map((row) => this.rowToItem(row));
2771
+ }
2637
2772
  getById(qitemId) {
2638
2773
  const row = this.db
2639
2774
  .prepare("SELECT * FROM queue_items WHERE qitem_id = ?")
@@ -2702,9 +2837,11 @@ export class QueueRepository {
2702
2837
  /** The parked query's obligation face: open rows to one destination, newest first, without the per-row
2703
2838
  * projections list() derives (pickup, waiting view, delivery ledger), which this read never uses. */
2704
2839
  listOpenObligations(destinationSession, limit) {
2840
+ const addresses = this.resolveSessionAddresses(destinationSession);
2841
+ const slots = addresses.map(() => "?").join(",");
2705
2842
  const rows = this.db.prepare(`SELECT qitem_id, state${this.hasSummaryColumn ? ", summary" : ""} FROM queue_items
2706
- WHERE destination_session = ? AND state IN ('pending', 'in-progress', 'blocked')
2707
- ORDER BY ts_created DESC LIMIT ?`).all(destinationSession, limit);
2843
+ WHERE destination_session IN (${slots}) AND state IN ('pending', 'in-progress', 'blocked')
2844
+ ORDER BY ts_created DESC LIMIT ?`).all(...addresses, limit);
2708
2845
  return rows.map((r) => ({ qitemId: r.qitem_id, state: r.state, summary: r.summary ?? null }));
2709
2846
  }
2710
2847
  list(opts) {
@@ -2721,19 +2858,23 @@ export class QueueRepository {
2721
2858
  params.push(`%@${escaped}`, `%@${escaped}`);
2722
2859
  }
2723
2860
  if (opts?.asSession) {
2724
- conditions.push("(destination_session = ? OR source_session = ?)");
2725
- params.push(opts.asSession, opts.asSession);
2861
+ const addresses = this.resolveSessionAddresses(opts.asSession);
2862
+ const slots = addresses.map(() => "?").join(",");
2863
+ conditions.push(`(destination_session IN (${slots}) OR source_session IN (${slots}))`);
2864
+ params.push(...addresses, ...addresses);
2726
2865
  }
2727
2866
  if (opts?.activeOnly && !opts?.state) {
2728
2867
  conditions.push("state IN ('pending', 'in-progress', 'blocked')");
2729
2868
  }
2730
2869
  if (opts?.destinationSession) {
2731
- conditions.push("destination_session = ?");
2732
- params.push(opts.destinationSession);
2870
+ const addresses = this.resolveSessionAddresses(opts.destinationSession);
2871
+ conditions.push(`destination_session IN (${addresses.map(() => "?").join(",")})`);
2872
+ params.push(...addresses);
2733
2873
  }
2734
2874
  if (opts?.sourceSession) {
2735
- conditions.push("source_session = ?");
2736
- params.push(opts.sourceSession);
2875
+ const addresses = this.resolveSessionAddresses(opts.sourceSession);
2876
+ conditions.push(`source_session IN (${addresses.map(() => "?").join(",")})`);
2877
+ params.push(...addresses);
2737
2878
  }
2738
2879
  if (opts?.state) {
2739
2880
  const states = Array.isArray(opts.state) ? opts.state : [opts.state];
@@ -2862,12 +3003,14 @@ export class QueueRepository {
2862
3003
  conditions.push("COALESCE(human_intent, 'decision') <> 'update'");
2863
3004
  const params = [...states];
2864
3005
  if (opts?.destinationSession) {
2865
- conditions.push("destination_session = ?");
2866
- params.push(opts.destinationSession);
3006
+ const addresses = this.resolveSessionAddresses(opts.destinationSession);
3007
+ conditions.push(`destination_session IN (${addresses.map(() => "?").join(",")})`);
3008
+ params.push(...addresses);
2867
3009
  }
2868
3010
  if (opts?.sourceSession) {
2869
- conditions.push("source_session = ?");
2870
- params.push(opts.sourceSession);
3011
+ const addresses = this.resolveSessionAddresses(opts.sourceSession);
3012
+ conditions.push(`source_session IN (${addresses.map(() => "?").join(",")})`);
3013
+ params.push(...addresses);
2871
3014
  }
2872
3015
  if (opts?.targetRepo && this.hasTargetRepoColumn) {
2873
3016
  conditions.push("target_repo = ?");
@@ -3240,8 +3383,22 @@ export class QueueRepository {
3240
3383
  /** The grace window before a receiptless gateway-routed row honestly reads
3241
3384
  * never-posted (the connector sweep cadence bounds normal posting latency). */
3242
3385
  static NEVER_POSTED_WINDOW_MS = 120_000;
3243
- recordNudgeAttempt(qitemId, result) {
3386
+ /**
3387
+ * Record one wake attempt. #1278: `inputBox` is that attempt's input-box reading, when the
3388
+ * transport returned one. It is written with the attempt every time, so an attempt without a
3389
+ * reading clears an earlier attempt's reading rather than leaving it to read as current.
3390
+ */
3391
+ recordNudgeAttempt(qitemId, result, inputBox) {
3244
3392
  const ts = new Date().toISOString();
3393
+ if (this.hasNudgeInputBoxColumn) {
3394
+ const reading = inputBoxReading(inputBox);
3395
+ this.db
3396
+ .prepare(`UPDATE queue_items
3397
+ SET last_nudge_attempt = ?, last_nudge_result = ?, last_nudge_input_box = ?
3398
+ WHERE qitem_id = ?`)
3399
+ .run(ts, result, reading ? JSON.stringify({ ...reading, at: ts }) : null, qitemId);
3400
+ return;
3401
+ }
3245
3402
  this.db
3246
3403
  .prepare(`UPDATE queue_items
3247
3404
  SET last_nudge_attempt = ?, last_nudge_result = ?
@@ -3465,6 +3622,12 @@ export class QueueRepository {
3465
3622
  if (awaitingHuman) {
3466
3623
  view.nextBackstop = { owner: view.owner, mechanism: "none (posted to the human; awaiting their decision)", dueAt: null, intervalSeconds: null };
3467
3624
  }
3625
+ // Quiet hours: a held ask is owned by its window's release job until it posts.
3626
+ const quiet = awaitingHuman ? null : quietCustodyBackstop(view.owner, quietHoldCustody(this.db, qitemId));
3627
+ if (quiet) {
3628
+ view.nextBackstop = quiet;
3629
+ return view;
3630
+ }
3468
3631
  const recovery = readWakeLadderBackstop(this.db, qitemId);
3469
3632
  if (recovery) {
3470
3633
  if (!awaitingHuman)
@@ -3472,6 +3635,16 @@ export class QueueRepository {
3472
3635
  view.nextBackstop = recovery;
3473
3636
  }
3474
3637
  }
3638
+ if (view?.state === "blocked") {
3639
+ // A row parked on a person carries that person's notification, which quiet hours can hold. Its quiet custody is the
3640
+ // next step; the row's blocker is unchanged, and its own timer or wait notice stays as the later backstop.
3641
+ const quiet = quietCustodyBackstop(view.owner, quietHoldCustody(this.db, qitemId));
3642
+ if (quiet) {
3643
+ if (/^(watchdog:|unconsumed wait notice)/.test(view.nextBackstop.mechanism))
3644
+ view.laterBackstop = view.nextBackstop;
3645
+ view.nextBackstop = quiet;
3646
+ }
3647
+ }
3475
3648
  return view;
3476
3649
  }
3477
3650
  handoffAdvisory(row) {
@@ -3546,6 +3719,7 @@ export class QueueRepository {
3546
3719
  replyTo: row.reply_to ?? null,
3547
3720
  humanQuestions: row.human_questions ? JSON.parse(row.human_questions) : null,
3548
3721
  humanAnswers: row.human_answers ? JSON.parse(row.human_answers) : null,
3722
+ delegatedDecision: row.delegated_decision ? JSON.parse(row.delegated_decision) : null,
3549
3723
  closureReason: row.closure_reason,
3550
3724
  closureTarget: row.closure_target,
3551
3725
  closureRequiredAt: row.closure_required_at,
@@ -3553,6 +3727,8 @@ export class QueueRepository {
3553
3727
  lastNudgeAttempt: row.last_nudge_attempt,
3554
3728
  lastNudgeResult: presentedNudgeResult(row.last_nudge_result, row.claimed_at),
3555
3729
  lastNudgeWireResult: row.last_nudge_result,
3730
+ // #1278: absent before migration 116 and on compact rows (elided there), so null.
3731
+ lastNudgeInputBox: parseNudgeInputBox(row.last_nudge_input_box, row.last_nudge_attempt),
3556
3732
  lastHeartbeat: row.last_heartbeat,
3557
3733
  resolution: row.resolution,
3558
3734
  // PL-007: target_repo present only when migration 038 has applied;