@vellumai/assistant 0.10.0 → 0.10.1-dev.202606240317.ea25efe

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 (972) hide show
  1. package/ARCHITECTURE.md +36 -37
  2. package/bun.lock +3 -0
  3. package/docs/workflows.md +12 -7
  4. package/eslint-rules/cli-no-daemon-internals.js +12 -0
  5. package/node_modules/@slack/types/LICENSE +23 -0
  6. package/node_modules/@slack/types/README.md +32 -0
  7. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +953 -0
  8. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -0
  9. package/node_modules/@slack/types/dist/block-kit/block-elements.js +4 -0
  10. package/node_modules/@slack/types/dist/block-kit/block-elements.js.map +1 -0
  11. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +474 -0
  12. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -0
  13. package/node_modules/@slack/types/dist/block-kit/blocks.js +3 -0
  14. package/node_modules/@slack/types/dist/block-kit/blocks.js.map +1 -0
  15. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +237 -0
  16. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -0
  17. package/node_modules/@slack/types/dist/block-kit/composition-objects.js +4 -0
  18. package/node_modules/@slack/types/dist/block-kit/composition-objects.js.map +1 -0
  19. package/node_modules/@slack/types/dist/block-kit/extensions.d.ts +88 -0
  20. package/node_modules/@slack/types/dist/block-kit/extensions.d.ts.map +1 -0
  21. package/node_modules/@slack/types/dist/block-kit/extensions.js +3 -0
  22. package/node_modules/@slack/types/dist/block-kit/extensions.js.map +1 -0
  23. package/node_modules/@slack/types/dist/calls.d.ts +26 -0
  24. package/node_modules/@slack/types/dist/calls.d.ts.map +1 -0
  25. package/node_modules/@slack/types/dist/calls.js +6 -0
  26. package/node_modules/@slack/types/dist/calls.js.map +1 -0
  27. package/node_modules/@slack/types/dist/chunk.d.ts +52 -0
  28. package/node_modules/@slack/types/dist/chunk.d.ts.map +1 -0
  29. package/node_modules/@slack/types/dist/chunk.js +3 -0
  30. package/node_modules/@slack/types/dist/chunk.js.map +1 -0
  31. package/node_modules/@slack/types/dist/common/bot-profile.d.ts +12 -0
  32. package/node_modules/@slack/types/dist/common/bot-profile.d.ts.map +1 -0
  33. package/node_modules/@slack/types/dist/common/bot-profile.js +3 -0
  34. package/node_modules/@slack/types/dist/common/bot-profile.js.map +1 -0
  35. package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts +6 -0
  36. package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts.map +1 -0
  37. package/node_modules/@slack/types/dist/common/status-emoji-display-info.js +3 -0
  38. package/node_modules/@slack/types/dist/common/status-emoji-display-info.js.map +1 -0
  39. package/node_modules/@slack/types/dist/dialog.d.ts +36 -0
  40. package/node_modules/@slack/types/dist/dialog.d.ts.map +1 -0
  41. package/node_modules/@slack/types/dist/dialog.js +3 -0
  42. package/node_modules/@slack/types/dist/dialog.js.map +1 -0
  43. package/node_modules/@slack/types/dist/events/app.d.ts +204 -0
  44. package/node_modules/@slack/types/dist/events/app.d.ts.map +1 -0
  45. package/node_modules/@slack/types/dist/events/app.js +3 -0
  46. package/node_modules/@slack/types/dist/events/app.js.map +1 -0
  47. package/node_modules/@slack/types/dist/events/assistant.d.ts +29 -0
  48. package/node_modules/@slack/types/dist/events/assistant.d.ts.map +1 -0
  49. package/node_modules/@slack/types/dist/events/assistant.js +3 -0
  50. package/node_modules/@slack/types/dist/events/assistant.js.map +1 -0
  51. package/node_modules/@slack/types/dist/events/call.d.ts +8 -0
  52. package/node_modules/@slack/types/dist/events/call.d.ts.map +1 -0
  53. package/node_modules/@slack/types/dist/events/call.js +3 -0
  54. package/node_modules/@slack/types/dist/events/call.js.map +1 -0
  55. package/node_modules/@slack/types/dist/events/channel.d.ts +85 -0
  56. package/node_modules/@slack/types/dist/events/channel.d.ts.map +1 -0
  57. package/node_modules/@slack/types/dist/events/channel.js +3 -0
  58. package/node_modules/@slack/types/dist/events/channel.js.map +1 -0
  59. package/node_modules/@slack/types/dist/events/dnd.d.ts +24 -0
  60. package/node_modules/@slack/types/dist/events/dnd.d.ts.map +1 -0
  61. package/node_modules/@slack/types/dist/events/dnd.js +3 -0
  62. package/node_modules/@slack/types/dist/events/dnd.js.map +1 -0
  63. package/node_modules/@slack/types/dist/events/email.d.ts +6 -0
  64. package/node_modules/@slack/types/dist/events/email.d.ts.map +1 -0
  65. package/node_modules/@slack/types/dist/events/email.js +3 -0
  66. package/node_modules/@slack/types/dist/events/email.js.map +1 -0
  67. package/node_modules/@slack/types/dist/events/emoji.d.ts +11 -0
  68. package/node_modules/@slack/types/dist/events/emoji.d.ts.map +1 -0
  69. package/node_modules/@slack/types/dist/events/emoji.js +3 -0
  70. package/node_modules/@slack/types/dist/events/emoji.js.map +1 -0
  71. package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts +21 -0
  72. package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts.map +1 -0
  73. package/node_modules/@slack/types/dist/events/entity-details-requested.js +3 -0
  74. package/node_modules/@slack/types/dist/events/entity-details-requested.js.map +1 -0
  75. package/node_modules/@slack/types/dist/events/file.d.ts +60 -0
  76. package/node_modules/@slack/types/dist/events/file.d.ts.map +1 -0
  77. package/node_modules/@slack/types/dist/events/file.js +4 -0
  78. package/node_modules/@slack/types/dist/events/file.js.map +1 -0
  79. package/node_modules/@slack/types/dist/events/function.d.ts +33 -0
  80. package/node_modules/@slack/types/dist/events/function.d.ts.map +1 -0
  81. package/node_modules/@slack/types/dist/events/function.js +3 -0
  82. package/node_modules/@slack/types/dist/events/function.js.map +1 -0
  83. package/node_modules/@slack/types/dist/events/grid-migration.d.ts +9 -0
  84. package/node_modules/@slack/types/dist/events/grid-migration.d.ts.map +1 -0
  85. package/node_modules/@slack/types/dist/events/grid-migration.js +3 -0
  86. package/node_modules/@slack/types/dist/events/grid-migration.js.map +1 -0
  87. package/node_modules/@slack/types/dist/events/group.d.ts +55 -0
  88. package/node_modules/@slack/types/dist/events/group.d.ts.map +1 -0
  89. package/node_modules/@slack/types/dist/events/group.js +3 -0
  90. package/node_modules/@slack/types/dist/events/group.js.map +1 -0
  91. package/node_modules/@slack/types/dist/events/im.d.ts +26 -0
  92. package/node_modules/@slack/types/dist/events/im.d.ts.map +1 -0
  93. package/node_modules/@slack/types/dist/events/im.js +3 -0
  94. package/node_modules/@slack/types/dist/events/im.js.map +1 -0
  95. package/node_modules/@slack/types/dist/events/index.d.ts +60 -0
  96. package/node_modules/@slack/types/dist/events/index.d.ts.map +1 -0
  97. package/node_modules/@slack/types/dist/events/index.js +43 -0
  98. package/node_modules/@slack/types/dist/events/index.js.map +1 -0
  99. package/node_modules/@slack/types/dist/events/invite.d.ts +20 -0
  100. package/node_modules/@slack/types/dist/events/invite.d.ts.map +1 -0
  101. package/node_modules/@slack/types/dist/events/invite.js +3 -0
  102. package/node_modules/@slack/types/dist/events/invite.js.map +1 -0
  103. package/node_modules/@slack/types/dist/events/link-shared.d.ts +16 -0
  104. package/node_modules/@slack/types/dist/events/link-shared.d.ts.map +1 -0
  105. package/node_modules/@slack/types/dist/events/link-shared.js +3 -0
  106. package/node_modules/@slack/types/dist/events/link-shared.js.map +1 -0
  107. package/node_modules/@slack/types/dist/events/member.d.ts +19 -0
  108. package/node_modules/@slack/types/dist/events/member.d.ts.map +1 -0
  109. package/node_modules/@slack/types/dist/events/member.js +3 -0
  110. package/node_modules/@slack/types/dist/events/member.js.map +1 -0
  111. package/node_modules/@slack/types/dist/events/message-metadata.d.ts +38 -0
  112. package/node_modules/@slack/types/dist/events/message-metadata.d.ts.map +1 -0
  113. package/node_modules/@slack/types/dist/events/message-metadata.js +3 -0
  114. package/node_modules/@slack/types/dist/events/message-metadata.js.map +1 -0
  115. package/node_modules/@slack/types/dist/events/message.d.ts +306 -0
  116. package/node_modules/@slack/types/dist/events/message.d.ts.map +1 -0
  117. package/node_modules/@slack/types/dist/events/message.js +3 -0
  118. package/node_modules/@slack/types/dist/events/message.js.map +1 -0
  119. package/node_modules/@slack/types/dist/events/pin.d.ts +60 -0
  120. package/node_modules/@slack/types/dist/events/pin.d.ts.map +1 -0
  121. package/node_modules/@slack/types/dist/events/pin.js +3 -0
  122. package/node_modules/@slack/types/dist/events/pin.js.map +1 -0
  123. package/node_modules/@slack/types/dist/events/reaction.d.ts +23 -0
  124. package/node_modules/@slack/types/dist/events/reaction.d.ts.map +1 -0
  125. package/node_modules/@slack/types/dist/events/reaction.js +3 -0
  126. package/node_modules/@slack/types/dist/events/reaction.js.map +1 -0
  127. package/node_modules/@slack/types/dist/events/shared-channel.d.ts +134 -0
  128. package/node_modules/@slack/types/dist/events/shared-channel.d.ts.map +1 -0
  129. package/node_modules/@slack/types/dist/events/shared-channel.js +3 -0
  130. package/node_modules/@slack/types/dist/events/shared-channel.js.map +1 -0
  131. package/node_modules/@slack/types/dist/events/star.d.ts +13 -0
  132. package/node_modules/@slack/types/dist/events/star.d.ts.map +1 -0
  133. package/node_modules/@slack/types/dist/events/star.js +3 -0
  134. package/node_modules/@slack/types/dist/events/star.js.map +1 -0
  135. package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts +82 -0
  136. package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts.map +1 -0
  137. package/node_modules/@slack/types/dist/events/steps-from-apps.js +3 -0
  138. package/node_modules/@slack/types/dist/events/steps-from-apps.js.map +1 -0
  139. package/node_modules/@slack/types/dist/events/subteam.d.ts +66 -0
  140. package/node_modules/@slack/types/dist/events/subteam.d.ts.map +1 -0
  141. package/node_modules/@slack/types/dist/events/subteam.js +3 -0
  142. package/node_modules/@slack/types/dist/events/subteam.js.map +1 -0
  143. package/node_modules/@slack/types/dist/events/team.d.ts +99 -0
  144. package/node_modules/@slack/types/dist/events/team.d.ts.map +1 -0
  145. package/node_modules/@slack/types/dist/events/team.js +3 -0
  146. package/node_modules/@slack/types/dist/events/team.js.map +1 -0
  147. package/node_modules/@slack/types/dist/events/token.d.ts +8 -0
  148. package/node_modules/@slack/types/dist/events/token.d.ts.map +1 -0
  149. package/node_modules/@slack/types/dist/events/token.js +3 -0
  150. package/node_modules/@slack/types/dist/events/token.js.map +1 -0
  151. package/node_modules/@slack/types/dist/events/user.d.ts +313 -0
  152. package/node_modules/@slack/types/dist/events/user.d.ts.map +1 -0
  153. package/node_modules/@slack/types/dist/events/user.js +3 -0
  154. package/node_modules/@slack/types/dist/events/user.js.map +1 -0
  155. package/node_modules/@slack/types/dist/index.d.ts +12 -0
  156. package/node_modules/@slack/types/dist/index.d.ts.map +1 -0
  157. package/node_modules/@slack/types/dist/index.js +28 -0
  158. package/node_modules/@slack/types/dist/index.js.map +1 -0
  159. package/node_modules/@slack/types/dist/message-attachments.d.ts +171 -0
  160. package/node_modules/@slack/types/dist/message-attachments.d.ts.map +1 -0
  161. package/node_modules/@slack/types/dist/message-attachments.js +3 -0
  162. package/node_modules/@slack/types/dist/message-attachments.js.map +1 -0
  163. package/node_modules/@slack/types/dist/message-metadata.d.ts +281 -0
  164. package/node_modules/@slack/types/dist/message-metadata.d.ts.map +1 -0
  165. package/node_modules/@slack/types/dist/message-metadata.js +27 -0
  166. package/node_modules/@slack/types/dist/message-metadata.js.map +1 -0
  167. package/node_modules/@slack/types/dist/views.d.ts +71 -0
  168. package/node_modules/@slack/types/dist/views.d.ts.map +1 -0
  169. package/node_modules/@slack/types/dist/views.js +3 -0
  170. package/node_modules/@slack/types/dist/views.js.map +1 -0
  171. package/node_modules/@slack/types/package.json +47 -0
  172. package/node_modules/@vellumai/gateway-client/bun.lock +3 -0
  173. package/node_modules/@vellumai/gateway-client/package.json +1 -0
  174. package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +69 -0
  175. package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
  176. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +96 -0
  177. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
  178. package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
  179. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
  180. package/node_modules/@vellumai/gateway-client/src/index.ts +28 -0
  181. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +4 -2
  182. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +3 -2
  183. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +95 -0
  184. package/openapi.yaml +458 -18
  185. package/package.json +2 -1
  186. package/scripts/memory-inspect.ts +24 -14
  187. package/scripts/test.sh +36 -15
  188. package/src/__tests__/access-request-seed-content-blocks.test.ts +83 -103
  189. package/src/__tests__/activation-early-marking.test.ts +1 -1
  190. package/src/__tests__/actor-token-service.test.ts +39 -17
  191. package/src/__tests__/agent-loop-callsite-precedence.test.ts +1 -40
  192. package/src/__tests__/agent-loop-compaction-events.test.ts +0 -1
  193. package/src/__tests__/agent-loop-compaction-strip.test.ts +0 -1
  194. package/src/__tests__/agent-loop-exit-reason.test.ts +0 -1
  195. package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
  196. package/src/__tests__/agent-loop-regrowth-guard.test.ts +0 -1
  197. package/src/__tests__/agent-loop.test.ts +3 -0
  198. package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
  199. package/src/__tests__/anthropic-provider.test.ts +210 -9
  200. package/src/__tests__/app-builder-skill-instructions.test.ts +47 -5
  201. package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -1
  202. package/src/__tests__/app-source-watcher.test.ts +30 -10
  203. package/src/__tests__/approval-cascade.test.ts +6 -0
  204. package/src/__tests__/approval-interception-trust-gates.test.ts +151 -0
  205. package/src/__tests__/approval-primitive.test.ts +1 -1
  206. package/src/__tests__/approval-routes-http.test.ts +1 -1
  207. package/src/__tests__/assistant-attachments.test.ts +155 -0
  208. package/src/__tests__/assistant-event-hub-machine-name.test.ts +2 -4
  209. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  210. package/src/__tests__/assistant-events-sse-shed.test.ts +1 -1
  211. package/src/__tests__/attachment-upload-trusted-source.test.ts +13 -8
  212. package/src/__tests__/attachments-store.test.ts +1 -1
  213. package/src/__tests__/audit-log-rotation.test.ts +50 -54
  214. package/src/__tests__/auth-fallback-events-store.test.ts +1 -1
  215. package/src/__tests__/auto-analysis-end-to-end.test.ts +9 -14
  216. package/src/__tests__/background-shell-bash.test.ts +4 -1
  217. package/src/__tests__/background-shell-host-bash.test.ts +17 -3
  218. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  219. package/src/__tests__/call-controller.test.ts +20 -1
  220. package/src/__tests__/call-conversation-messages.test.ts +1 -1
  221. package/src/__tests__/call-domain.test.ts +1 -1
  222. package/src/__tests__/call-pointer-messages.test.ts +3 -4
  223. package/src/__tests__/call-recovery.test.ts +1 -1
  224. package/src/__tests__/call-routes-http.test.ts +1 -1
  225. package/src/__tests__/call-store.test.ts +1 -1
  226. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  227. package/src/__tests__/canonical-guardian-store.test.ts +24 -1
  228. package/src/__tests__/card-surface-data.test.ts +60 -0
  229. package/src/__tests__/channel-approval-routes.test.ts +73 -1119
  230. package/src/__tests__/channel-delivery-store.test.ts +1 -1
  231. package/src/__tests__/channel-guardian.test.ts +291 -641
  232. package/src/__tests__/channel-inbound-disk-pressure.test.ts +1 -2
  233. package/src/__tests__/channel-retry-sweep.test.ts +1 -1
  234. package/src/__tests__/compaction-events.test.ts +6 -0
  235. package/src/__tests__/compaction-trail-store.test.ts +6 -5
  236. package/src/__tests__/compaction.benchmark.test.ts +0 -1
  237. package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
  238. package/src/__tests__/config-loader-backfill.test.ts +188 -52
  239. package/src/__tests__/config-schema.test.ts +35 -0
  240. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -2
  241. package/src/__tests__/contact-store-user-file.test.ts +2 -2
  242. package/src/__tests__/contacts-relay-reads.test.ts +409 -0
  243. package/src/__tests__/contacts-tools.test.ts +4 -4
  244. package/src/__tests__/contacts-write.test.ts +1 -2
  245. package/src/__tests__/context-search-conversations-source.test.ts +1 -1
  246. package/src/__tests__/context-window-manager-compact-retry.test.ts +6 -2
  247. package/src/__tests__/context-window-manager-overflow-rung.test.ts +6 -2
  248. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  249. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
  250. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
  251. package/src/__tests__/conversation-agent-loop-overflow.test.ts +3 -0
  252. package/src/__tests__/conversation-agent-loop.test.ts +7 -0
  253. package/src/__tests__/conversation-attachments.test.ts +2 -5
  254. package/src/__tests__/conversation-attention-store.test.ts +1 -1
  255. package/src/__tests__/conversation-attention-telegram.test.ts +1 -2
  256. package/src/__tests__/conversation-clear-safety.test.ts +1 -1
  257. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
  258. package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -1
  259. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +12 -19
  260. package/src/__tests__/conversation-disk-view-integration.test.ts +1 -1
  261. package/src/__tests__/conversation-disk-view.test.ts +1 -1
  262. package/src/__tests__/conversation-fork-crud.test.ts +10 -8
  263. package/src/__tests__/conversation-fork-retrospective.test.ts +250 -0
  264. package/src/__tests__/conversation-fork-route.test.ts +1 -1
  265. package/src/__tests__/conversation-inference-profile-list.test.ts +1 -1
  266. package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
  267. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  268. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
  269. package/src/__tests__/conversation-lifecycle.test.ts +117 -0
  270. package/src/__tests__/conversation-list-source.test.ts +3 -3
  271. package/src/__tests__/conversation-process-callsite.test.ts +6 -14
  272. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  273. package/src/__tests__/conversation-queue.test.ts +95 -0
  274. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
  275. package/src/__tests__/conversation-routes-guardian-reply.test.ts +12 -0
  276. package/src/__tests__/conversation-routes-slash-commands.test.ts +12 -0
  277. package/src/__tests__/conversation-runtime-assembly.test.ts +115 -12
  278. package/src/__tests__/conversation-slash-queue.test.ts +6 -0
  279. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  280. package/src/__tests__/conversation-speed-override.test.ts +6 -0
  281. package/src/__tests__/conversation-starter-routes.test.ts +5 -5
  282. package/src/__tests__/conversation-store.test.ts +1 -1
  283. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +4 -4
  284. package/src/__tests__/conversation-surfaces-task-progress.test.ts +352 -0
  285. package/src/__tests__/conversation-sync-tags.test.ts +1 -1
  286. package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
  287. package/src/__tests__/conversation-usage.test.ts +1 -1
  288. package/src/__tests__/conversation-wipe.test.ts +9 -8
  289. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
  290. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  291. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  292. package/src/__tests__/conversations-import-system-filter.test.ts +1 -1
  293. package/src/__tests__/copy-composer-tc-templates.test.ts +17 -0
  294. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  295. package/src/__tests__/db-acp-history.test.ts +2 -2
  296. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +5 -7
  297. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -7
  298. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +5 -10
  299. package/src/__tests__/db-migration-rollback.test.ts +129 -39
  300. package/src/__tests__/db-proxy-transaction.test.ts +1 -1
  301. package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -11
  302. package/src/__tests__/db-test-helpers.ts +36 -19
  303. package/src/__tests__/delete-propagation.test.ts +1 -1
  304. package/src/__tests__/deterministic-verification-control-plane.test.ts +28 -8
  305. package/src/__tests__/disk-pressure-guard.test.ts +41 -0
  306. package/src/__tests__/disk-pressure-tools.test.ts +41 -1
  307. package/src/__tests__/dm-backfill.test.ts +1 -1
  308. package/src/__tests__/drop-capability-card-state-migration.test.ts +0 -8
  309. package/src/__tests__/dynamic-page-surface.test.ts +0 -94
  310. package/src/__tests__/edit-propagation.test.ts +1 -1
  311. package/src/__tests__/emit-signal-routing-intent.test.ts +93 -5
  312. package/src/__tests__/empty-response-hook.test.ts +42 -0
  313. package/src/__tests__/events-client-registration.test.ts +1 -1
  314. package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
  315. package/src/__tests__/followup-tools.test.ts +1 -1
  316. package/src/__tests__/gemini-count-tokens.test.ts +70 -0
  317. package/src/__tests__/guardian-action-sweep.test.ts +9 -2
  318. package/src/__tests__/guardian-binding-drift-heal.test.ts +76 -11
  319. package/src/__tests__/guardian-card-withdrawal.test.ts +1 -1
  320. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -1
  321. package/src/__tests__/guardian-dispatch.test.ts +96 -2
  322. package/src/__tests__/guardian-outbound-http.test.ts +20 -12
  323. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -1
  324. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  325. package/src/__tests__/guardian-routing-state.test.ts +1 -2
  326. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  327. package/src/__tests__/headless-browser-mode.test.ts +2 -2
  328. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  329. package/src/__tests__/heartbeat-service.test.ts +6 -0
  330. package/src/__tests__/helpers/channel-test-adapter.ts +92 -0
  331. package/src/__tests__/host-app-control-routes.test.ts +24 -30
  332. package/src/__tests__/host-bash-routes.test.ts +31 -41
  333. package/src/__tests__/host-browser-routes.test.ts +26 -32
  334. package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
  335. package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
  336. package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
  337. package/src/__tests__/http-conversation-lineage.test.ts +1 -1
  338. package/src/__tests__/http-user-message-parity.test.ts +165 -8
  339. package/src/__tests__/image-recovery-hook.test.ts +1 -1
  340. package/src/__tests__/inbound-invite-redemption.test.ts +1 -2
  341. package/src/__tests__/inbound-trust-verdict.test.ts +254 -0
  342. package/src/__tests__/inference-profile-reaper.test.ts +1 -1
  343. package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
  344. package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
  345. package/src/__tests__/injector-chain.test.ts +1 -1
  346. package/src/__tests__/injector-disk-pressure.test.ts +11 -6
  347. package/src/__tests__/internal-telemetry-routes.test.ts +1 -1
  348. package/src/__tests__/invite-redemption-service.test.ts +244 -43
  349. package/src/__tests__/invite-routes-http.test.ts +35 -186
  350. package/src/__tests__/invite-service-ipc.test.ts +287 -0
  351. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +5 -5
  352. package/src/__tests__/jobs-store-upsert-debounced.test.ts +9 -12
  353. package/src/__tests__/list-messages-attachments.test.ts +42 -1
  354. package/src/__tests__/list-messages-client-message-id.test.ts +1 -1
  355. package/src/__tests__/list-messages-hidden-metadata.test.ts +1 -1
  356. package/src/__tests__/list-messages-page-latest.test.ts +1 -1
  357. package/src/__tests__/list-messages-tool-merge.test.ts +1 -1
  358. package/src/__tests__/llm-context-normalization.test.ts +105 -0
  359. package/src/__tests__/llm-context-route-provider.test.ts +69 -4
  360. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -5
  361. package/src/__tests__/llm-request-log-call-site.test.ts +6 -6
  362. package/src/__tests__/llm-request-log-turn-query.test.ts +27 -13
  363. package/src/__tests__/llm-resolver.test.ts +205 -5
  364. package/src/__tests__/llm-usage-store.test.ts +65 -1
  365. package/src/__tests__/log-export-routes.test.ts +1 -1
  366. package/src/__tests__/log-export-workspace.test.ts +3 -3
  367. package/src/__tests__/media-stream-server-integration.test.ts +127 -0
  368. package/src/__tests__/memory-jobs-worker-lanes.test.ts +5 -5
  369. package/src/__tests__/memory-recall-log-store.test.ts +1 -1
  370. package/src/__tests__/memory-upsert-concurrency.test.ts +3 -4
  371. package/src/__tests__/messages-after-tiebreaker.test.ts +1 -1
  372. package/src/__tests__/migration-import-from-url.test.ts +2 -2
  373. package/src/__tests__/mtime-cache.test.ts +375 -0
  374. package/src/__tests__/non-member-access-request.test.ts +190 -19
  375. package/src/__tests__/notification-broadcaster.test.ts +4 -0
  376. package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
  377. package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
  378. package/src/__tests__/notification-deep-link.test.ts +4 -0
  379. package/src/__tests__/notification-guardian-path.test.ts +20 -1
  380. package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
  381. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  382. package/src/__tests__/oauth-provider-visibility.test.ts +1 -1
  383. package/src/__tests__/oauth-store.test.ts +1 -1
  384. package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
  385. package/src/__tests__/persist-unsendable-image-downscale.test.ts +1 -1
  386. package/src/__tests__/persist-unsendable-image.test.ts +1 -1
  387. package/src/__tests__/persona-resolver.test.ts +39 -1
  388. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
  389. package/src/__tests__/playbook-execution.test.ts +1 -1
  390. package/src/__tests__/playbook-tools.test.ts +1 -1
  391. package/src/__tests__/plugin-api-model-profiles.test.ts +74 -21
  392. package/src/__tests__/plugin-bootstrap.test.ts +78 -0
  393. package/src/__tests__/provider-platform-proxy-integration.test.ts +25 -5
  394. package/src/__tests__/provider-usage-tracking.test.ts +40 -1
  395. package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
  396. package/src/__tests__/reaction-persistence.test.ts +1 -1
  397. package/src/__tests__/registry.test.ts +3 -0
  398. package/src/__tests__/relay-server.test.ts +1026 -73
  399. package/src/__tests__/runtime-attachment-metadata.test.ts +9 -1
  400. package/src/__tests__/runtime-events-sse-bilingual.test.ts +7 -9
  401. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  402. package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
  403. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  404. package/src/__tests__/schedule-retry.test.ts +1 -1
  405. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -1
  406. package/src/__tests__/schedule-routes.test.ts +1 -1
  407. package/src/__tests__/schedule-store.test.ts +1 -1
  408. package/src/__tests__/schedule-tools.test.ts +1 -1
  409. package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
  410. package/src/__tests__/scheduler-recurrence.test.ts +1 -1
  411. package/src/__tests__/scheduler-reuse-conversation.test.ts +1 -1
  412. package/src/__tests__/scheduler-wake.test.ts +2 -1
  413. package/src/__tests__/scoped-approval-grants.test.ts +1 -1
  414. package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -5
  415. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +0 -8
  416. package/src/__tests__/secret-ingress-http.test.ts +12 -0
  417. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
  418. package/src/__tests__/send-endpoint-busy.test.ts +31 -9
  419. package/src/__tests__/sequence-store.test.ts +1 -1
  420. package/src/__tests__/server-history-render.test.ts +40 -1
  421. package/src/__tests__/settings-routes.test.ts +11 -10
  422. package/src/__tests__/skill-load-tool.test.ts +72 -0
  423. package/src/__tests__/skills.test.ts +44 -0
  424. package/src/__tests__/slack-inbound-verification.test.ts +48 -5
  425. package/src/__tests__/slack-messaging-token-resolution.test.ts +13 -2
  426. package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -1
  427. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +102 -0
  428. package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
  429. package/src/__tests__/stt-hints.test.ts +44 -13
  430. package/src/__tests__/subagent-detail.test.ts +27 -0
  431. package/src/__tests__/subagent-disposal.test.ts +65 -0
  432. package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -73
  433. package/src/__tests__/subagent-tools.test.ts +1 -31
  434. package/src/__tests__/system-prompt.test.ts +1 -1
  435. package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
  436. package/src/__tests__/task-compiler.test.ts +1 -1
  437. package/src/__tests__/task-management-tools.test.ts +1 -1
  438. package/src/__tests__/task-memory-cleanup.test.ts +9 -6
  439. package/src/__tests__/task-scheduler.test.ts +1 -1
  440. package/src/__tests__/thread-backfill.test.ts +1 -1
  441. package/src/__tests__/tool-approval-handler.test.ts +1 -1
  442. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +2 -0
  443. package/src/__tests__/tool-executor.test.ts +37 -1
  444. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -2
  445. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +73 -1
  446. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +34 -34
  447. package/src/__tests__/trusted-contact-multichannel.test.ts +1 -2
  448. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  449. package/src/__tests__/turn-boundary-resolution.test.ts +3 -3
  450. package/src/__tests__/turn-events-store.test.ts +1 -1
  451. package/src/__tests__/twilio-routes.test.ts +98 -3
  452. package/src/__tests__/usage-cache-backfill-migration.test.ts +20 -10
  453. package/src/__tests__/usage-routes.test.ts +1 -1
  454. package/src/__tests__/user-plugin-loader.test.ts +34 -29
  455. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  456. package/src/__tests__/voice-invite-redemption.test.ts +134 -36
  457. package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
  458. package/src/__tests__/voice-session-bridge.test.ts +1 -1
  459. package/src/__tests__/workspace-git-service.test.ts +114 -1
  460. package/src/__tests__/workspace-heartbeat-service.test.ts +45 -0
  461. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -1
  462. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
  463. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +88 -18
  464. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +6 -6
  465. package/src/__tests__/workspace-migration-109-swap-quality-profile-to-glm-5p2.test.ts +281 -0
  466. package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +167 -0
  467. package/src/__tests__/workspace-migrations-runner.test.ts +55 -0
  468. package/src/__tests__/workspace-tool-loader.test.ts +3 -0
  469. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -1
  470. package/src/a2a/__tests__/task-store.test.ts +1 -1
  471. package/src/acp/__tests__/session-manager-persistence.test.ts +1 -1
  472. package/src/acp/__tests__/session-manager-resume.test.ts +22 -11
  473. package/src/acp/__tests__/session-manager-startup.test.ts +1 -1
  474. package/src/acp/__tests__/session-manager.test.ts +72 -1
  475. package/src/acp/index.ts +10 -0
  476. package/src/acp/session-manager.ts +35 -0
  477. package/src/agent/loop-exclusive-tool.test.ts +150 -0
  478. package/src/agent/loop.ts +101 -27
  479. package/src/api/constants/sse-replay.ts +41 -0
  480. package/src/api/events/ui-surface-show.ts +8 -3
  481. package/src/api/index.ts +7 -6
  482. package/src/api/responses/conversation-message.ts +4 -0
  483. package/src/api/responses/llm-request-log-entry.ts +25 -0
  484. package/src/api/responses/subagent-detail.ts +17 -0
  485. package/src/api/surfaces.ts +33 -0
  486. package/src/approvals/AGENTS.md +1 -2
  487. package/src/approvals/guardian-decision-primitive.ts +13 -210
  488. package/src/approvals/guardian-request-resolvers.ts +104 -58
  489. package/src/background-wake/wake-intent-hooks.test.ts +1 -1
  490. package/src/calls/__tests__/inbound-trust-reader.test.ts +110 -0
  491. package/src/calls/__tests__/relay-setup-router.test.ts +349 -65
  492. package/src/calls/guardian-dispatch.ts +10 -8
  493. package/src/calls/inbound-trust-reader.ts +56 -0
  494. package/src/calls/media-stream-server.ts +21 -0
  495. package/src/calls/relay-server.ts +231 -72
  496. package/src/calls/relay-setup-router.ts +57 -13
  497. package/src/calls/relay-verification.ts +7 -7
  498. package/src/calls/stt-hints.ts +9 -12
  499. package/src/calls/twilio-routes.ts +13 -3
  500. package/src/cli/commands/__tests__/cache.test.ts +8 -1
  501. package/src/cli/commands/cache.ts +194 -181
  502. package/src/cli/commands/contacts.ts +6 -24
  503. package/src/cli/commands/db/__tests__/repair.test.ts +15 -6
  504. package/src/cli/commands/db/__tests__/status.test.ts +7 -3
  505. package/src/cli/commands/db/status.ts +212 -33
  506. package/src/cli/commands/mcp.ts +252 -218
  507. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +6 -1
  508. package/src/cli/commands/memory/__tests__/worker.test.ts +302 -0
  509. package/src/cli/commands/memory/index.ts +4 -0
  510. package/src/cli/commands/memory/memory-retrospective.ts +129 -0
  511. package/src/cli/commands/memory/memory-v3.ts +176 -4
  512. package/src/cli/commands/memory/worker.ts +175 -0
  513. package/src/cli/commands/plugins.ts +343 -14
  514. package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
  515. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
  516. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
  517. package/src/cli/lib/__tests__/toggle-plugin.test.ts +158 -0
  518. package/src/cli/lib/install-from-github.ts +47 -6
  519. package/src/cli/lib/list-installed-plugins.ts +179 -1
  520. package/src/cli/lib/plugin-marketplace.ts +11 -0
  521. package/src/cli/lib/plugin-pin-history.ts +257 -0
  522. package/src/cli/lib/toggle-plugin.ts +146 -0
  523. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
  524. package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
  525. package/src/config/bundled-skills/app-builder/SKILL.md +15 -33
  526. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +3 -8
  527. package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +64 -37
  528. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +1 -1
  529. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +14 -72
  530. package/src/config/bundled-skills/app-builder/references/examples/README.md +1 -2
  531. package/src/config/bundled-skills/contacts/SKILL.md +7 -12
  532. package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
  533. package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
  534. package/src/config/bundled-skills/workflows/SKILL.md +4 -3
  535. package/src/config/call-site-defaults.ts +11 -2
  536. package/src/config/feature-flag-registry.json +0 -8
  537. package/src/config/llm-resolver.ts +151 -14
  538. package/src/config/loader.ts +36 -5
  539. package/src/config/profile-dispatchability.ts +11 -0
  540. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  541. package/src/config/schemas/call-site-catalog.ts +7 -0
  542. package/src/config/schemas/llm.ts +2 -0
  543. package/src/config/schemas/memory-lifecycle.ts +17 -3
  544. package/src/config/schemas/memory-v3.ts +7 -0
  545. package/src/config/schemas/memory.ts +4 -0
  546. package/src/config/schemas/timeouts.ts +32 -0
  547. package/src/config/seed-inference-profiles.ts +147 -50
  548. package/src/config/skills.ts +27 -5
  549. package/src/config/sync-gated-profiles.ts +13 -1
  550. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
  551. package/src/contacts/contact-store.ts +21 -0
  552. package/src/contacts/contacts-write.ts +3 -0
  553. package/src/contacts/guardian-delivery-reader.ts +223 -0
  554. package/src/contacts/member-status.ts +9 -0
  555. package/src/credential-health/credential-health-service.ts +1 -5
  556. package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
  557. package/src/daemon/app-source-watcher.ts +31 -18
  558. package/src/daemon/assistant-attachments.ts +94 -4
  559. package/src/daemon/conversation-agent-loop-handlers.ts +3 -0
  560. package/src/daemon/conversation-agent-loop.ts +18 -36
  561. package/src/daemon/conversation-process.ts +35 -16
  562. package/src/daemon/conversation-runtime-assembly.ts +91 -66
  563. package/src/daemon/conversation-surfaces.ts +273 -18
  564. package/src/daemon/conversation-tool-setup.ts +24 -64
  565. package/src/daemon/conversation.ts +149 -53
  566. package/src/daemon/disk-pressure-guard.ts +12 -2
  567. package/src/daemon/event-loop-watchdog.test.ts +85 -0
  568. package/src/daemon/event-loop-watchdog.ts +133 -0
  569. package/src/daemon/external-plugins-bootstrap.ts +26 -80
  570. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  571. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -1
  572. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -1
  573. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -1
  574. package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -1
  575. package/src/daemon/handlers/config-channels.ts +41 -27
  576. package/src/daemon/handlers/conversations.ts +84 -0
  577. package/src/daemon/handlers/shared.ts +7 -0
  578. package/src/daemon/lifecycle.ts +44 -5
  579. package/src/daemon/memory-v2-startup.test.ts +72 -0
  580. package/src/daemon/memory-v2-startup.ts +87 -19
  581. package/src/daemon/message-types/inbox.ts +0 -6
  582. package/src/daemon/message-types/messages.ts +0 -4
  583. package/src/daemon/message-types/surfaces.ts +12 -11
  584. package/src/daemon/server.ts +0 -4
  585. package/src/daemon/shutdown-handlers.ts +20 -0
  586. package/src/daemon/tool-setup-types.ts +7 -5
  587. package/src/daemon/trust-context.ts +6 -0
  588. package/src/daemon/wake-conversation-ops.ts +70 -0
  589. package/src/daemon/workspace-tools-watcher.ts +7 -3
  590. package/src/documents/document-comments-store.test.ts +1 -1
  591. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +1 -1
  592. package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
  593. package/src/heartbeat/heartbeat-service.ts +3 -4
  594. package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
  595. package/src/ipc/__tests__/browser-ipc.test.ts +73 -2
  596. package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
  597. package/src/ipc/__tests__/watcher-ipc.test.ts +59 -39
  598. package/src/ipc/assistant-server.ts +10 -2
  599. package/src/ipc/gateway-client.ts +2 -1
  600. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +58 -0
  601. package/src/ipc/routes/invite-ipc-routes.ts +66 -0
  602. package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
  603. package/src/memory/__tests__/activation-session-store.test.ts +1 -1
  604. package/src/memory/__tests__/auto-analysis-guard.test.ts +1 -1
  605. package/src/memory/__tests__/conversation-group-migration.test.ts +1 -1
  606. package/src/memory/__tests__/conversation-queries.test.ts +1 -1
  607. package/src/memory/__tests__/db-async-query.test.ts +1 -1
  608. package/src/memory/__tests__/db-logs-attach.test.ts +110 -0
  609. package/src/memory/__tests__/db-maintenance.test.ts +28 -36
  610. package/src/memory/__tests__/db-memory-attach.test.ts +113 -0
  611. package/src/memory/__tests__/find-analysis-conversation.test.ts +1 -1
  612. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -1
  613. package/src/memory/__tests__/fork-message-copy.test.ts +232 -0
  614. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +3 -0
  615. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +5 -5
  616. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +8 -6
  617. package/src/memory/__tests__/memory-retrospective-job.test.ts +30 -37
  618. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +69 -66
  619. package/src/memory/__tests__/memory-retrospective-state.test.ts +1 -1
  620. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  621. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +1 -1
  622. package/src/memory/__tests__/onboarding-events-store.test.ts +1 -1
  623. package/src/memory/__tests__/prompt-override.test.ts +192 -0
  624. package/src/memory/__tests__/table-relocation.test.ts +129 -0
  625. package/src/memory/conversation-crud.ts +461 -152
  626. package/src/memory/db-async-query.ts +89 -5
  627. package/src/memory/db-connection.ts +101 -18
  628. package/src/memory/db-init.ts +409 -234
  629. package/src/memory/db-maintenance.ts +43 -38
  630. package/src/memory/db-singleton.ts +45 -19
  631. package/src/memory/embedding-gemini.test.ts +3 -1
  632. package/src/memory/embedding-gemini.ts +18 -2
  633. package/src/memory/fork-message-copy.ts +170 -0
  634. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +92 -0
  635. package/src/memory/graph/bootstrap.test.ts +6 -3
  636. package/src/memory/graph/retriever.test.ts +12 -12
  637. package/src/memory/graph/store.test.ts +15 -25
  638. package/src/memory/graph/store.ts +23 -14
  639. package/src/memory/graph/tool-handlers.ts +34 -5
  640. package/src/memory/graph/tools.ts +5 -2
  641. package/src/memory/indexer.ts +21 -9
  642. package/src/memory/job-handlers/cleanup.ts +10 -3
  643. package/src/memory/job-handlers/embedding.test.ts +4 -4
  644. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +4 -4
  645. package/src/memory/jobs/embed-pkb-file.test.ts +7 -7
  646. package/src/memory/jobs-store.ts +36 -24
  647. package/src/memory/llm-request-log-store.ts +51 -19
  648. package/src/memory/llm-usage-store.ts +79 -21
  649. package/src/memory/memory-retrospective-job.ts +27 -19
  650. package/src/memory/memory-retrospective-startup-cleanup.ts +10 -2
  651. package/src/memory/migrations/{100-core-tables.ts → 000-core-tables.ts} +6 -10
  652. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +13 -3
  653. package/src/memory/migrations/104-core-indexes.ts +1 -1
  654. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +189 -196
  655. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +98 -105
  656. package/src/memory/migrations/134-contacts-notes-column.ts +66 -69
  657. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +19 -22
  658. package/src/memory/migrations/136-drop-assistant-id-columns.ts +241 -219
  659. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +204 -209
  660. package/src/memory/migrations/141-rename-verification-table.ts +45 -48
  661. package/src/memory/migrations/142-rename-verification-session-id-column.ts +16 -23
  662. package/src/memory/migrations/143-rename-guardian-verification-values.ts +23 -30
  663. package/src/memory/migrations/144-rename-voice-to-phone.ts +133 -136
  664. package/src/memory/migrations/145-drop-accounts-table.ts +4 -7
  665. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +79 -82
  666. package/src/memory/migrations/148-drop-reminders-table.ts +3 -6
  667. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +71 -78
  668. package/src/memory/migrations/157-invite-contact-id.ts +73 -76
  669. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +44 -58
  670. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +36 -43
  671. package/src/memory/migrations/174-rename-thread-starters-table.ts +30 -37
  672. package/src/memory/migrations/176-drop-capability-card-state.ts +17 -22
  673. package/src/memory/migrations/177-create-trace-events-table.ts +23 -28
  674. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +36 -43
  675. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +14 -21
  676. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +17 -24
  677. package/src/memory/migrations/192-contacts-user-file-column.ts +6 -9
  678. package/src/memory/migrations/193-add-source-type-columns.ts +33 -36
  679. package/src/memory/migrations/194-memory-recall-logs.ts +34 -39
  680. package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +59 -66
  681. package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +41 -48
  682. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +11 -18
  683. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +76 -83
  684. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +135 -68
  685. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +6 -11
  686. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +4 -9
  687. package/src/memory/migrations/217-conversation-host-access.ts +13 -18
  688. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +86 -93
  689. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +41 -48
  690. package/src/memory/migrations/230-acp-session-history.ts +23 -28
  691. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +58 -62
  692. package/src/memory/migrations/232-activation-state.ts +11 -16
  693. package/src/memory/migrations/233-document-conversations.ts +20 -25
  694. package/src/memory/migrations/234-memory-v2-activation-logs.ts +26 -31
  695. package/src/memory/migrations/235-slack-compaction-watermark.ts +5 -10
  696. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +6 -11
  697. package/src/memory/migrations/237-heartbeat-runs.ts +22 -27
  698. package/src/memory/migrations/239-trace-events-created-at-index.ts +4 -9
  699. package/src/memory/migrations/242-message-bookmarks.ts +17 -22
  700. package/src/memory/migrations/245-memory-retrospective-state.ts +8 -13
  701. package/src/memory/migrations/249-normalize-slack-external-content.ts +37 -41
  702. package/src/memory/migrations/251-a2a-tasks.ts +27 -32
  703. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +12 -17
  704. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +10 -15
  705. package/src/memory/migrations/256-memory-v2-injection-events.ts +70 -74
  706. package/src/memory/migrations/259-conversation-cleaned-at.ts +4 -9
  707. package/src/memory/migrations/260-rename-cleaned-at.ts +11 -16
  708. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +3 -8
  709. package/src/memory/migrations/262-memory-v3-coactivation.ts +21 -26
  710. package/src/memory/migrations/263-memory-v3-auto-edges.ts +14 -19
  711. package/src/memory/migrations/270-schedule-description.ts +7 -12
  712. package/src/memory/migrations/272-acp-session-history-cwd.ts +8 -13
  713. package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +8 -13
  714. package/src/memory/migrations/297-move-llm-request-logs-to-logs-db.ts +111 -0
  715. package/src/memory/migrations/298-move-memory-jobs-to-memory-db.ts +128 -0
  716. package/src/memory/migrations/299-canonical-guardian-deliveries-conversation-index.ts +19 -0
  717. package/src/memory/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +108 -0
  718. package/src/memory/migrations/__tests__/136-drop-assistant-id-columns.test.ts +82 -0
  719. package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +224 -0
  720. package/src/memory/migrations/__tests__/297-move-llm-request-logs.test.ts +180 -0
  721. package/src/memory/migrations/__tests__/run-migrations.test.ts +333 -7
  722. package/src/memory/migrations/helpers/relocation.ts +227 -0
  723. package/src/memory/migrations/registry.ts +63 -0
  724. package/src/memory/migrations/run-migrations.ts +187 -16
  725. package/src/memory/migrations/schema-introspection.ts +14 -0
  726. package/src/memory/migrations/validate-migration-state.ts +50 -145
  727. package/src/memory/prompt-override.ts +129 -0
  728. package/src/memory/raw-query.ts +47 -2
  729. package/src/memory/skill-loaded-events-store.test.ts +1 -1
  730. package/src/memory/task-memory-cleanup.ts +62 -41
  731. package/src/memory/tool-executed-events-store.test.ts +1 -1
  732. package/src/memory/turn-trace-store.test.ts +1 -1
  733. package/src/memory/v2/__tests__/backfill-jobs.test.ts +16 -15
  734. package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
  735. package/src/memory/v2/__tests__/harness-compare.test.ts +1 -1
  736. package/src/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  737. package/src/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  738. package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
  739. package/src/memory/v2/__tests__/sweep-job.test.ts +2 -2
  740. package/src/memory/v2/cli-command-store.ts +75 -38
  741. package/src/memory/v2/prompts/consolidation.ts +13 -82
  742. package/src/memory/v2/prompts/router.ts +21 -93
  743. package/src/memory/v2/skill-store.ts +68 -31
  744. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +38 -0
  745. package/src/memory/v3-eval/__tests__/eval-tally.test.ts +139 -0
  746. package/src/memory/v3-eval/eval-packets.ts +197 -12
  747. package/src/memory/v3-eval/eval-tally.ts +234 -0
  748. package/src/memory/worker-control.ts +118 -0
  749. package/src/memory/worker-process.ts +72 -0
  750. package/src/messaging/provider.ts +10 -0
  751. package/src/messaging/providers/gmail/adapter.ts +1 -0
  752. package/src/messaging/providers/gmail/client.ts +13 -0
  753. package/src/messaging/providers/index.ts +1 -1
  754. package/src/messaging/providers/slack/send.test.ts +87 -39
  755. package/src/messaging/providers/slack/send.ts +84 -105
  756. package/src/notifications/README.md +9 -5
  757. package/src/notifications/__tests__/broadcaster.test.ts +16 -8
  758. package/src/notifications/__tests__/connected-channels.test.ts +114 -0
  759. package/src/notifications/__tests__/decision-engine.test.ts +78 -9
  760. package/src/notifications/__tests__/destination-resolver.test.ts +256 -0
  761. package/src/notifications/__tests__/deterministic-checks.test.ts +43 -1
  762. package/src/notifications/adapters/slack.ts +12 -10
  763. package/src/notifications/approval-card-builder.ts +81 -20
  764. package/src/notifications/approval-card-data.ts +8 -5
  765. package/src/notifications/broadcaster.ts +8 -1
  766. package/src/notifications/canonical-delivery-recorder.ts +7 -5
  767. package/src/notifications/conversation-candidates.ts +24 -59
  768. package/src/notifications/copy-composer.ts +48 -68
  769. package/src/notifications/decision-engine.ts +15 -7
  770. package/src/notifications/destination-resolver.ts +68 -24
  771. package/src/notifications/deterministic-checks.ts +19 -16
  772. package/src/notifications/emit-signal.ts +68 -15
  773. package/src/notifications/trusted-contact-payloads.ts +70 -0
  774. package/src/oauth/byo-connection.test.ts +9 -0
  775. package/src/oauth/connection-resolver.test.ts +174 -6
  776. package/src/oauth/connection-resolver.ts +132 -5
  777. package/src/oauth/oauth-store.ts +16 -3
  778. package/src/oauth/scope-utils.ts +39 -0
  779. package/src/permissions/question-prompter.test.ts +1 -1
  780. package/src/permissions/question-prompter.ts +7 -4
  781. package/src/plugin-api/index.ts +9 -4
  782. package/src/plugin-api/model-profiles.test.ts +123 -0
  783. package/src/plugin-api/model-profiles.ts +5 -1
  784. package/src/plugin-api/vision-support.test.ts +173 -0
  785. package/src/plugin-api/vision-support.ts +113 -0
  786. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +90 -0
  787. package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +106 -0
  788. package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +60 -0
  789. package/src/plugins/defaults/advisor/consult.ts +65 -6
  790. package/src/plugins/defaults/advisor/context-pack.ts +288 -0
  791. package/src/plugins/defaults/advisor/steering.ts +14 -2
  792. package/src/plugins/defaults/advisor/tools/advisor.ts +32 -5
  793. package/src/plugins/defaults/compaction/window-manager.ts +45 -64
  794. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +13 -4
  795. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +441 -0
  796. package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +57 -0
  797. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +61 -0
  798. package/src/plugins/defaults/image-fallback/package.json +14 -0
  799. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +108 -0
  800. package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
  801. package/src/plugins/defaults/image-fallback/src/image-persist.ts +56 -0
  802. package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
  803. package/src/plugins/defaults/index.ts +27 -0
  804. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +14 -1
  805. package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
  806. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +134 -5
  807. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
  808. package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
  809. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +246 -19
  810. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +8 -1
  811. package/src/plugins/external-plugin-loader.ts +47 -6
  812. package/src/plugins/mtime-cache.ts +772 -0
  813. package/src/plugins/pipeline.ts +7 -2
  814. package/src/plugins/registry.ts +16 -5
  815. package/src/plugins/user-loader.ts +22 -76
  816. package/src/prompts/persona-resolver.ts +29 -11
  817. package/src/prompts/system-prompt.ts +1 -1
  818. package/src/prompts/templates/system-sections.ts +4 -4
  819. package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
  820. package/src/providers/anthropic/client.ts +290 -185
  821. package/src/providers/call-site-routing.ts +14 -0
  822. package/src/providers/gemini/client.ts +43 -0
  823. package/src/providers/inference/adapter-factory.ts +6 -0
  824. package/src/providers/inference/connections.ts +6 -1
  825. package/src/providers/model-catalog.ts +53 -0
  826. package/src/providers/openai/responses-provider.ts +5 -0
  827. package/src/providers/openrouter/client.ts +5 -0
  828. package/src/providers/platform-proxy/constants.ts +5 -0
  829. package/src/providers/provider-send-message.ts +4 -0
  830. package/src/providers/ratelimit.ts +13 -0
  831. package/src/providers/retry.ts +14 -0
  832. package/src/providers/together/client.ts +35 -0
  833. package/src/providers/types.ts +25 -0
  834. package/src/providers/usage-tracking.ts +11 -0
  835. package/src/runtime/AGENTS.md +9 -1
  836. package/src/runtime/__tests__/agent-wake.test.ts +259 -4
  837. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +181 -0
  838. package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +64 -0
  839. package/src/runtime/__tests__/local-principal-trust.test.ts +164 -0
  840. package/src/runtime/__tests__/slack-block-formatting.test.ts +39 -10
  841. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +670 -0
  842. package/src/runtime/access-request-helper.ts +19 -39
  843. package/src/runtime/actor-trust-resolver.ts +8 -16
  844. package/src/runtime/agent-wake.ts +183 -60
  845. package/src/runtime/anchored-guardian.test.ts +156 -0
  846. package/src/runtime/anchored-guardian.ts +135 -0
  847. package/src/runtime/assistant-stream-state.ts +9 -2
  848. package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
  849. package/src/runtime/auth/require-bound-guardian.ts +21 -11
  850. package/src/runtime/channel-reply-delivery.ts +6 -3
  851. package/src/runtime/channel-verification-service.ts +24 -0
  852. package/src/runtime/guardian-decision-types.ts +3 -22
  853. package/src/runtime/guardian-vellum-migration.ts +66 -7
  854. package/src/runtime/http-server.ts +1 -15
  855. package/src/runtime/invite-redemption-service.ts +155 -6
  856. package/src/runtime/invite-service.ts +113 -62
  857. package/src/runtime/local-actor-identity.ts +76 -11
  858. package/src/runtime/local-principal-trust.ts +52 -0
  859. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
  860. package/src/runtime/pending-interactions.ts +11 -1
  861. package/src/runtime/routes/__tests__/acp-routes.test.ts +1 -1
  862. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -1
  863. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +277 -0
  864. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +140 -0
  865. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +26 -7
  866. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +14 -10
  867. package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +164 -0
  868. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  869. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +1 -1
  870. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +8 -8
  871. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +1 -1
  872. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +1 -3
  873. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +240 -0
  874. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +4 -0
  875. package/src/runtime/routes/__tests__/plugins-routes.test.ts +143 -0
  876. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -1
  877. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +1 -1
  878. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +163 -0
  879. package/src/runtime/routes/acp-routes-list.test.ts +4 -0
  880. package/src/runtime/routes/acp-routes.test.ts +5 -6
  881. package/src/runtime/routes/attachment-routes.ts +21 -17
  882. package/src/runtime/routes/browser-routes.ts +19 -1
  883. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -9
  884. package/src/runtime/routes/channel-verification-routes.ts +13 -2
  885. package/src/runtime/routes/contact-routes.ts +275 -164
  886. package/src/runtime/routes/conversation-query-routes.ts +15 -5
  887. package/src/runtime/routes/conversation-routes.ts +80 -66
  888. package/src/runtime/routes/conversation-starter-routes.ts +7 -8
  889. package/src/runtime/routes/events-routes.ts +2 -2
  890. package/src/runtime/routes/guardian-approval-interception.ts +13 -274
  891. package/src/runtime/routes/host-app-control-routes.ts +5 -4
  892. package/src/runtime/routes/host-bash-routes.ts +5 -4
  893. package/src/runtime/routes/host-browser-routes.ts +9 -11
  894. package/src/runtime/routes/host-cu-routes.ts +5 -4
  895. package/src/runtime/routes/host-file-routes.ts +5 -4
  896. package/src/runtime/routes/host-transfer-routes.ts +6 -6
  897. package/src/runtime/routes/http-adapter.ts +1 -1
  898. package/src/runtime/routes/inbound-message-handler.ts +21 -16
  899. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +376 -0
  900. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +86 -64
  901. package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
  902. package/src/runtime/routes/inbound-stages/background-dispatch.ts +16 -4
  903. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
  904. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
  905. package/src/runtime/routes/llm-context-normalization.ts +71 -0
  906. package/src/runtime/routes/log-export-routes.ts +2 -2
  907. package/src/runtime/routes/mcp-auth-routes.ts +38 -15
  908. package/src/runtime/routes/memory-eval-routes.ts +92 -0
  909. package/src/runtime/routes/memory-item-routes.test.ts +12 -11
  910. package/src/runtime/routes/migration-routes.ts +51 -40
  911. package/src/runtime/routes/plugins-routes.ts +164 -8
  912. package/src/runtime/routes/schedule-routes.ts +1 -0
  913. package/src/runtime/routes/subagents-routes.ts +5 -0
  914. package/src/runtime/routes/surface-action-routes.ts +39 -51
  915. package/src/runtime/routes/usage-routes.ts +3 -0
  916. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  917. package/src/runtime/slack-block-formatting.ts +46 -48
  918. package/src/runtime/trust-verdict-consumer.ts +210 -0
  919. package/src/schedule/scheduler.ts +6 -9
  920. package/src/signals/user-message.ts +16 -0
  921. package/src/subagent/manager.ts +9 -0
  922. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  923. package/src/tools/ask-question/ask-question-tool.test.ts +89 -52
  924. package/src/tools/ask-question/ask-question-tool.ts +27 -73
  925. package/src/tools/browser/__tests__/browser-status.test.ts +20 -0
  926. package/src/tools/browser/browser-execution.ts +16 -4
  927. package/src/tools/document/document-comment-tool.test.ts +1 -1
  928. package/src/tools/executor.ts +15 -3
  929. package/src/tools/host-terminal/host-shell.ts +28 -9
  930. package/src/tools/memory/register.test.ts +32 -0
  931. package/src/tools/skills/load.ts +43 -2
  932. package/src/tools/subagent/spawn.ts +4 -10
  933. package/src/tools/terminal/shell.ts +16 -5
  934. package/src/tools/tool-defaults.ts +2 -0
  935. package/src/tools/types.ts +18 -2
  936. package/src/tools/ui-surface/definitions.ts +0 -43
  937. package/src/util/fs-watcher-error.ts +36 -0
  938. package/src/util/log-redact.ts +2 -4
  939. package/src/util/logs-db-path.ts +22 -0
  940. package/src/util/memory-db-path.ts +23 -0
  941. package/src/util/platform.ts +5 -0
  942. package/src/watcher/providers/gmail.ts +7 -2
  943. package/src/workflows/engine-integration.test.ts +1 -1
  944. package/src/workflows/engine.test.ts +1 -1
  945. package/src/workflows/engine.ts +22 -0
  946. package/src/workflows/fanout-load.test.ts +1 -1
  947. package/src/workflows/journal-store.test.ts +1 -1
  948. package/src/workflows/leaf-runner.test.ts +40 -1
  949. package/src/workflows/leaf-runner.ts +26 -1
  950. package/src/workspace/git-service.ts +144 -29
  951. package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +121 -0
  952. package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +82 -0
  953. package/src/workspace/migrations/registry.ts +4 -0
  954. package/src/workspace/migrations/runner.ts +32 -2
  955. package/src/__tests__/access-request-decision.test.ts +0 -375
  956. package/src/__tests__/guardian-grant-minting.test.ts +0 -607
  957. package/src/__tests__/plugin-source-watcher.test.ts +0 -302
  958. package/src/api/events/turn-profile-auto-routed.ts +0 -28
  959. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +0 -107
  960. package/src/daemon/plugin-source-watcher.ts +0 -278
  961. package/src/daemon/switch-inference-profile-tool.ts +0 -62
  962. package/src/memory/guardian-approvals.ts +0 -361
  963. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +0 -66
  964. package/src/memory/migrations/038-actor-token-records.ts +0 -45
  965. package/src/memory/migrations/039-actor-refresh-token-records.ts +0 -57
  966. package/src/memory/migrations/103-complex-migrations.ts +0 -23
  967. package/src/memory/migrations/113-late-migrations.ts +0 -30
  968. package/src/memory/migrations/index.ts +0 -301
  969. package/src/runtime/routes/access-request-decision.ts +0 -297
  970. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -963
  971. package/src/runtime/routes/channel-guardian-routes.ts +0 -19
  972. package/src/runtime/routes/guardian-expiry-sweep.ts +0 -132
@@ -63,6 +63,52 @@ mock.module("../runtime/assistant-event-hub.js", () => ({
63
63
  },
64
64
  }));
65
65
 
66
+ // Gateway relay mock — the revoke path relays the ACL downgrade over IPC and
67
+ // validates the response; return a well-formed mark_channel_revoked result.
68
+ mock.module("../ipc/gateway-client.js", () => ({
69
+ ipcCallPersistent: async (
70
+ _method: string,
71
+ params?: Record<string, unknown>,
72
+ ) => ({
73
+ ok: true,
74
+ didWrite: true,
75
+ channel: {
76
+ id: (params?.contactChannelId as string) ?? "ch1",
77
+ contactId: "c1",
78
+ type: "phone",
79
+ address: "addr",
80
+ status: "revoked",
81
+ revokedReason: (params?.reason as string) ?? null,
82
+ },
83
+ }),
84
+ }));
85
+
86
+ // Guardian-delivery reader mock — the inbound challenge guard reads guardian
87
+ // existence from the gateway. Derive the list from the local binding state so
88
+ // the gateway-backed presence guard mirrors the DB the rest of the test sets up.
89
+ const resolveGuardianList = async (input?: { channelTypes?: string[] }) => {
90
+ const { findGuardianForChannel } = await import(
91
+ "../contacts/contact-store.js"
92
+ );
93
+ const channels = input?.channelTypes ?? [];
94
+ return channels
95
+ .map((channelType) => {
96
+ const found = findGuardianForChannel(channelType);
97
+ return found ? { channelType, status: "active" } : null;
98
+ })
99
+ .filter((g): g is { channelType: string; status: string } => g !== null);
100
+ };
101
+
102
+ mock.module("../contacts/guardian-delivery-reader.js", () => ({
103
+ getGuardianDelivery: resolveGuardianList,
104
+ getGuardianDeliveryFresh: resolveGuardianList,
105
+ guardianForChannel: (
106
+ list: Array<{ channelType: string; status: string }>,
107
+ channelType: string,
108
+ ) =>
109
+ list.find((g) => g.channelType === channelType && g.status === "active"),
110
+ }));
111
+
66
112
  import { handleChannelVerificationSession } from "../daemon/handlers/config-channels.js";
67
113
  import type {
68
114
  ChannelVerificationSessionRequest,
@@ -84,12 +130,6 @@ import {
84
130
  import { getDb } from "../memory/db-connection.js";
85
131
  import { initializeDb } from "../memory/db-init.js";
86
132
  import { upsertBinding as upsertExternalBinding } from "../memory/external-conversation-store.js";
87
- import {
88
- createApprovalRequest,
89
- getPendingApprovalByGuardianChat,
90
- getPendingApprovalForRequest,
91
- updateApprovalDecision,
92
- } from "../memory/guardian-approvals.js";
93
133
  import {
94
134
  getRateLimit,
95
135
  recordInvalidAttempt,
@@ -133,7 +173,6 @@ afterAll(() => {
133
173
  function resetTables(): void {
134
174
  const db = getDb();
135
175
  db.run("DELETE FROM channel_verification_sessions");
136
- db.run("DELETE FROM channel_guardian_approval_requests");
137
176
  db.run("DELETE FROM channel_guardian_rate_limits");
138
177
  db.run("DELETE FROM contact_channels");
139
178
  db.run("DELETE FROM contacts");
@@ -564,251 +603,6 @@ describe("guardian identity check", () => {
564
603
  // 5. Approval Request CRUD (Store)
565
604
  // ═══════════════════════════════════════════════════════════════════════════
566
605
 
567
- describe("guardian approval request CRUD", () => {
568
- beforeEach(() => {
569
- resetTables();
570
- });
571
-
572
- test("createApprovalRequest creates a pending request", () => {
573
- const request = createApprovalRequest({
574
- runId: "run-1",
575
- requestId: "req-1",
576
- conversationId: "conv-1",
577
- channel: "telegram",
578
- requesterExternalUserId: "user-99",
579
- requesterChatId: "chat-99",
580
- guardianExternalUserId: "user-42",
581
- guardianChatId: "chat-42",
582
- toolName: "shell",
583
- riskLevel: "high",
584
- reason: "Executing rm command",
585
- expiresAt: Date.now() + 300_000,
586
- });
587
-
588
- expect(request.id).toBeDefined();
589
- expect(request.runId).toBe("run-1");
590
- expect(request.requestId).toBe("req-1");
591
- expect(request.status).toBe("pending");
592
- expect(request.toolName).toBe("shell");
593
- expect(request.riskLevel).toBe("high");
594
- expect(request.reason).toBe("Executing rm command");
595
- expect(request.decidedByExternalUserId).toBeNull();
596
- });
597
-
598
- test("getPendingApprovalForRequest returns the pending request", () => {
599
- createApprovalRequest({
600
- runId: "run-1",
601
- requestId: "req-1",
602
- conversationId: "conv-1",
603
- channel: "telegram",
604
- requesterExternalUserId: "user-99",
605
- requesterChatId: "chat-99",
606
- guardianExternalUserId: "user-42",
607
- guardianChatId: "chat-42",
608
- toolName: "shell",
609
- expiresAt: Date.now() + 300_000,
610
- });
611
-
612
- const found = getPendingApprovalForRequest("req-1");
613
- expect(found).not.toBeNull();
614
- expect(found!.requestId).toBe("req-1");
615
- expect(found!.status).toBe("pending");
616
- });
617
-
618
- test("getPendingApprovalForRequest returns null when no pending request exists", () => {
619
- const found = getPendingApprovalForRequest("req-nonexistent");
620
- expect(found).toBeNull();
621
- });
622
-
623
- test("getPendingApprovalByGuardianChat returns pending request for guardian chat", () => {
624
- createApprovalRequest({
625
- runId: "run-1",
626
- requestId: "req-1",
627
- conversationId: "conv-1",
628
- channel: "telegram",
629
- requesterExternalUserId: "user-99",
630
- requesterChatId: "chat-99",
631
- guardianExternalUserId: "user-42",
632
- guardianChatId: "chat-42",
633
- toolName: "shell",
634
- expiresAt: Date.now() + 300_000,
635
- });
636
-
637
- const found = getPendingApprovalByGuardianChat("telegram", "chat-42");
638
- expect(found).not.toBeNull();
639
- expect(found!.guardianChatId).toBe("chat-42");
640
- });
641
-
642
- test("getPendingApprovalByGuardianChat returns null for wrong channel", () => {
643
- createApprovalRequest({
644
- runId: "run-1",
645
- requestId: "req-1",
646
- conversationId: "conv-1",
647
- channel: "telegram",
648
- requesterExternalUserId: "user-99",
649
- requesterChatId: "chat-99",
650
- guardianExternalUserId: "user-42",
651
- guardianChatId: "chat-42",
652
- toolName: "shell",
653
- expiresAt: Date.now() + 300_000,
654
- });
655
-
656
- const found = getPendingApprovalByGuardianChat("slack", "chat-42");
657
- expect(found).toBeNull();
658
- });
659
-
660
- test("updateApprovalDecision updates status to approved", () => {
661
- const request = createApprovalRequest({
662
- runId: "run-1",
663
- requestId: "req-1",
664
- conversationId: "conv-1",
665
- channel: "telegram",
666
- requesterExternalUserId: "user-99",
667
- requesterChatId: "chat-99",
668
- guardianExternalUserId: "user-42",
669
- guardianChatId: "chat-42",
670
- toolName: "shell",
671
- expiresAt: Date.now() + 300_000,
672
- });
673
-
674
- updateApprovalDecision(request.id, {
675
- status: "approved",
676
- decidedByExternalUserId: "user-42",
677
- });
678
-
679
- // After approval, getPendingApprovalForRequest should return null
680
- const found = getPendingApprovalForRequest("req-1");
681
- expect(found).toBeNull();
682
- });
683
-
684
- test("updateApprovalDecision updates status to denied", () => {
685
- const request = createApprovalRequest({
686
- runId: "run-1",
687
- requestId: "req-1",
688
- conversationId: "conv-1",
689
- channel: "telegram",
690
- requesterExternalUserId: "user-99",
691
- requesterChatId: "chat-99",
692
- guardianExternalUserId: "user-42",
693
- guardianChatId: "chat-42",
694
- toolName: "shell",
695
- expiresAt: Date.now() + 300_000,
696
- });
697
-
698
- updateApprovalDecision(request.id, {
699
- status: "denied",
700
- decidedByExternalUserId: "user-42",
701
- });
702
-
703
- const found = getPendingApprovalForRequest("req-1");
704
- expect(found).toBeNull();
705
- });
706
-
707
- test("multiple approval requests for different runs are independent", () => {
708
- createApprovalRequest({
709
- runId: "run-1",
710
- requestId: "req-1",
711
- conversationId: "conv-1",
712
- channel: "telegram",
713
- requesterExternalUserId: "user-99",
714
- requesterChatId: "chat-99",
715
- guardianExternalUserId: "user-42",
716
- guardianChatId: "chat-42",
717
- toolName: "shell",
718
- expiresAt: Date.now() + 300_000,
719
- });
720
-
721
- createApprovalRequest({
722
- runId: "run-2",
723
- requestId: "req-2",
724
- conversationId: "conv-2",
725
- channel: "telegram",
726
- requesterExternalUserId: "user-88",
727
- requesterChatId: "chat-88",
728
- guardianExternalUserId: "user-42",
729
- guardianChatId: "chat-42",
730
- toolName: "browser",
731
- expiresAt: Date.now() + 300_000,
732
- });
733
-
734
- const found1 = getPendingApprovalForRequest("req-1");
735
- const found2 = getPendingApprovalForRequest("req-2");
736
- expect(found1).not.toBeNull();
737
- expect(found2).not.toBeNull();
738
- expect(found1!.toolName).toBe("shell");
739
- expect(found2!.toolName).toBe("browser");
740
- });
741
-
742
- test("createApprovalRequest works for voice channel", () => {
743
- const request = createApprovalRequest({
744
- runId: "run-voice-1",
745
- requestId: "req-voice-1",
746
- conversationId: "conv-voice-1",
747
- channel: "phone",
748
- requesterExternalUserId: "phone-user-99",
749
- requesterChatId: "voice-chat-99",
750
- guardianExternalUserId: "phone-user-42",
751
- guardianChatId: "voice-chat-42",
752
- toolName: "shell",
753
- expiresAt: Date.now() + 300_000,
754
- });
755
-
756
- expect(request.id).toBeDefined();
757
- expect(request.runId).toBe("run-voice-1");
758
- expect(request.requestId).toBe("req-voice-1");
759
- expect(request.channel).toBe("phone");
760
- expect(request.status).toBe("pending");
761
-
762
- const found = getPendingApprovalForRequest("req-voice-1");
763
- expect(found).not.toBeNull();
764
- expect(found!.channel).toBe("phone");
765
- });
766
-
767
- test("getPendingApprovalByGuardianChat works for voice channel", () => {
768
- createApprovalRequest({
769
- runId: "run-voice-2",
770
- requestId: "req-voice-2",
771
- conversationId: "conv-voice-2",
772
- channel: "phone",
773
- requesterExternalUserId: "phone-user-99",
774
- requesterChatId: "voice-chat-99",
775
- guardianExternalUserId: "phone-user-42",
776
- guardianChatId: "voice-chat-42",
777
- toolName: "shell",
778
- expiresAt: Date.now() + 300_000,
779
- });
780
-
781
- const found = getPendingApprovalByGuardianChat("phone", "voice-chat-42");
782
- expect(found).not.toBeNull();
783
- expect(found!.channel).toBe("phone");
784
-
785
- // Should not find it under a different channel
786
- const notFound = getPendingApprovalByGuardianChat(
787
- "telegram",
788
- "voice-chat-42",
789
- );
790
- expect(notFound).toBeNull();
791
- });
792
-
793
- test("createApprovalRequest with optional fields omitted defaults to null", () => {
794
- const request = createApprovalRequest({
795
- runId: "run-1",
796
- requestId: "req-1",
797
- conversationId: "conv-1",
798
- channel: "telegram",
799
- requesterExternalUserId: "user-99",
800
- requesterChatId: "chat-99",
801
- guardianExternalUserId: "user-42",
802
- guardianChatId: "chat-42",
803
- toolName: "shell",
804
- expiresAt: Date.now() + 300_000,
805
- });
806
-
807
- expect(request.riskLevel).toBeNull();
808
- expect(request.reason).toBeNull();
809
- });
810
- });
811
-
812
606
  // ═══════════════════════════════════════════════════════════════════════════
813
607
  // 6. Verification Rate Limiting (Store)
814
608
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1204,64 +998,6 @@ describe("channel-scoped guardian resolution", () => {
1204
998
  // 9. Assistant-scoped approval request lookups
1205
999
  // ═══════════════════════════════════════════════════════════════════════════
1206
1000
 
1207
- describe("assistant-scoped approval request lookups", () => {
1208
- beforeEach(() => {
1209
- resetTables();
1210
- });
1211
-
1212
- test("createApprovalRequest no longer exposes assistantId on the returned interface", () => {
1213
- const req = createApprovalRequest({
1214
- runId: "run-1",
1215
- requestId: "req-1",
1216
- conversationId: "conv-1",
1217
- channel: "telegram",
1218
- requesterExternalUserId: "user-99",
1219
- requesterChatId: "chat-99",
1220
- guardianExternalUserId: "user-42",
1221
- guardianChatId: "chat-42",
1222
- toolName: "shell",
1223
- expiresAt: Date.now() + 300_000,
1224
- });
1225
- // assistantId is no longer on the public interface
1226
- expect(req.id).toBeDefined();
1227
- expect(req.toolName).toBe("shell");
1228
- });
1229
-
1230
- test("approval requests from different conversations are independent", () => {
1231
- createApprovalRequest({
1232
- runId: "run-A",
1233
- requestId: "req-A",
1234
- conversationId: "conv-A",
1235
- channel: "telegram",
1236
- requesterExternalUserId: "user-99",
1237
- requesterChatId: "chat-99",
1238
- guardianExternalUserId: "user-42",
1239
- guardianChatId: "chat-42",
1240
- toolName: "shell",
1241
- expiresAt: Date.now() + 300_000,
1242
- });
1243
- createApprovalRequest({
1244
- runId: "run-B",
1245
- requestId: "req-B",
1246
- conversationId: "conv-B",
1247
- channel: "telegram",
1248
- requesterExternalUserId: "user-88",
1249
- requesterChatId: "chat-88",
1250
- guardianExternalUserId: "user-42",
1251
- guardianChatId: "chat-42",
1252
- toolName: "browser",
1253
- expiresAt: Date.now() + 300_000,
1254
- });
1255
-
1256
- const foundA = getPendingApprovalForRequest("req-A");
1257
- const foundB = getPendingApprovalForRequest("req-B");
1258
- expect(foundA).not.toBeNull();
1259
- expect(foundB).not.toBeNull();
1260
- expect(foundA!.toolName).toBe("shell");
1261
- expect(foundB!.toolName).toBe("browser");
1262
- });
1263
- });
1264
-
1265
1001
  // ═══════════════════════════════════════════════════════════════════════════
1266
1002
  // 10. HTTP handler — channel-aware guardian status response
1267
1003
  // ═══════════════════════════════════════════════════════════════════════════
@@ -2588,24 +2324,20 @@ describe("outbound voice verification", () => {
2588
2324
  test("resend_outbound before cooldown is rejected", async () => {
2589
2325
  // Start an outbound session first
2590
2326
  broadcastedMessages.length = 0;
2591
- await handleChannelVerificationSession(
2592
- {
2593
- type: "channel_verification_session",
2594
- action: "create_session",
2595
- channel: "phone",
2596
- destination: "+15551234567",
2597
- },
2598
- );
2327
+ await handleChannelVerificationSession({
2328
+ type: "channel_verification_session",
2329
+ action: "create_session",
2330
+ channel: "phone",
2331
+ destination: "+15551234567",
2332
+ });
2599
2333
 
2600
2334
  // Immediately try to resend (before cooldown)
2601
2335
  const { lastResponse } = createResponseReader();
2602
- await handleChannelVerificationSession(
2603
- {
2604
- type: "channel_verification_session",
2605
- action: "resend_session",
2606
- channel: "phone",
2607
- },
2608
- );
2336
+ await handleChannelVerificationSession({
2337
+ type: "channel_verification_session",
2338
+ action: "resend_session",
2339
+ channel: "phone",
2340
+ });
2609
2341
 
2610
2342
  const resp = lastResponse();
2611
2343
  expect(resp).not.toBeNull();
@@ -2616,14 +2348,12 @@ describe("outbound voice verification", () => {
2616
2348
  test("resend_outbound after cooldown succeeds and increments sendCount", async () => {
2617
2349
  // Start an outbound session
2618
2350
  const { lastResponse: startResp } = createResponseReader();
2619
- await handleChannelVerificationSession(
2620
- {
2621
- type: "channel_verification_session",
2622
- action: "create_session",
2623
- channel: "phone",
2624
- destination: "+15551234567",
2625
- },
2626
- );
2351
+ await handleChannelVerificationSession({
2352
+ type: "channel_verification_session",
2353
+ action: "create_session",
2354
+ channel: "phone",
2355
+ destination: "+15551234567",
2356
+ });
2627
2357
 
2628
2358
  const startResponse = startResp();
2629
2359
  expect(startResponse!.success).toBe(true);
@@ -2640,13 +2370,11 @@ describe("outbound voice verification", () => {
2640
2370
 
2641
2371
  // Now resend should succeed
2642
2372
  const { lastResponse } = createResponseReader();
2643
- await handleChannelVerificationSession(
2644
- {
2645
- type: "channel_verification_session",
2646
- action: "resend_session",
2647
- channel: "phone",
2648
- },
2649
- );
2373
+ await handleChannelVerificationSession({
2374
+ type: "channel_verification_session",
2375
+ action: "resend_session",
2376
+ channel: "phone",
2377
+ });
2650
2378
 
2651
2379
  const resp = lastResponse();
2652
2380
  expect(resp).not.toBeNull();
@@ -2658,14 +2386,12 @@ describe("outbound voice verification", () => {
2658
2386
  test("resend_outbound exceeding max sends is rejected", async () => {
2659
2387
  // Start an outbound session
2660
2388
  broadcastedMessages.length = 0;
2661
- await handleChannelVerificationSession(
2662
- {
2663
- type: "channel_verification_session",
2664
- action: "create_session",
2665
- channel: "phone",
2666
- destination: "+15551234567",
2667
- },
2668
- );
2389
+ await handleChannelVerificationSession({
2390
+ type: "channel_verification_session",
2391
+ action: "create_session",
2392
+ channel: "phone",
2393
+ destination: "+15551234567",
2394
+ });
2669
2395
 
2670
2396
  // Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
2671
2397
  const session = serviceFindActiveSession("phone");
@@ -2679,13 +2405,11 @@ describe("outbound voice verification", () => {
2679
2405
 
2680
2406
  // Resend should be rejected due to max sends
2681
2407
  const { lastResponse } = createResponseReader();
2682
- await handleChannelVerificationSession(
2683
- {
2684
- type: "channel_verification_session",
2685
- action: "resend_session",
2686
- channel: "phone",
2687
- },
2688
- );
2408
+ await handleChannelVerificationSession({
2409
+ type: "channel_verification_session",
2410
+ action: "resend_session",
2411
+ channel: "phone",
2412
+ });
2689
2413
 
2690
2414
  const resp = lastResponse();
2691
2415
  expect(resp).not.toBeNull();
@@ -2696,14 +2420,12 @@ describe("outbound voice verification", () => {
2696
2420
  test("cancel_outbound revokes active session", async () => {
2697
2421
  // Start an outbound session
2698
2422
  broadcastedMessages.length = 0;
2699
- await handleChannelVerificationSession(
2700
- {
2701
- type: "channel_verification_session",
2702
- action: "create_session",
2703
- channel: "phone",
2704
- destination: "+15551234567",
2705
- },
2706
- );
2423
+ await handleChannelVerificationSession({
2424
+ type: "channel_verification_session",
2425
+ action: "create_session",
2426
+ channel: "phone",
2427
+ destination: "+15551234567",
2428
+ });
2707
2429
 
2708
2430
  // Verify session exists
2709
2431
  const sessionBefore = serviceFindActiveSession("phone");
@@ -2711,13 +2433,11 @@ describe("outbound voice verification", () => {
2711
2433
 
2712
2434
  // Cancel it
2713
2435
  const { lastResponse } = createResponseReader();
2714
- await handleChannelVerificationSession(
2715
- {
2716
- type: "channel_verification_session",
2717
- action: "cancel_session",
2718
- channel: "phone",
2719
- },
2720
- );
2436
+ await handleChannelVerificationSession({
2437
+ type: "channel_verification_session",
2438
+ action: "cancel_session",
2439
+ channel: "phone",
2440
+ });
2721
2441
 
2722
2442
  const resp = lastResponse();
2723
2443
  expect(resp).not.toBeNull();
@@ -2780,14 +2500,12 @@ describe("outbound voice verification", () => {
2780
2500
 
2781
2501
  test("start_outbound succeeds for email channel", async () => {
2782
2502
  const { lastResponse } = createResponseReader();
2783
- await handleChannelVerificationSession(
2784
- {
2785
- type: "channel_verification_session",
2786
- action: "create_session",
2787
- channel: "email",
2788
- destination: "user@example.com",
2789
- },
2790
- );
2503
+ await handleChannelVerificationSession({
2504
+ type: "channel_verification_session",
2505
+ action: "create_session",
2506
+ channel: "email",
2507
+ destination: "user@example.com",
2508
+ });
2791
2509
 
2792
2510
  const resp = lastResponse();
2793
2511
  expect(resp).not.toBeNull();
@@ -2797,14 +2515,12 @@ describe("outbound voice verification", () => {
2797
2515
 
2798
2516
  test("create_session without destination falls through to inbound challenge", async () => {
2799
2517
  const { lastResponse } = createResponseReader();
2800
- await handleChannelVerificationSession(
2801
- {
2802
- type: "channel_verification_session",
2803
- action: "create_session",
2804
- channel: "phone",
2805
- // no destination — unified create_session creates an inbound challenge
2806
- },
2807
- );
2518
+ await handleChannelVerificationSession({
2519
+ type: "channel_verification_session",
2520
+ action: "create_session",
2521
+ channel: "phone",
2522
+ // no destination — unified create_session creates an inbound challenge
2523
+ });
2808
2524
 
2809
2525
  const resp = lastResponse();
2810
2526
  expect(resp).not.toBeNull();
@@ -2814,14 +2530,12 @@ describe("outbound voice verification", () => {
2814
2530
 
2815
2531
  test("start_outbound rejects unparseable phone number", async () => {
2816
2532
  const { lastResponse } = createResponseReader();
2817
- await handleChannelVerificationSession(
2818
- {
2819
- type: "channel_verification_session",
2820
- action: "create_session",
2821
- channel: "phone",
2822
- destination: "not-a-phone",
2823
- },
2824
- );
2533
+ await handleChannelVerificationSession({
2534
+ type: "channel_verification_session",
2535
+ action: "create_session",
2536
+ channel: "phone",
2537
+ destination: "not-a-phone",
2538
+ });
2825
2539
 
2826
2540
  const resp = lastResponse();
2827
2541
  expect(resp).not.toBeNull();
@@ -2831,14 +2545,12 @@ describe("outbound voice verification", () => {
2831
2545
 
2832
2546
  test("start_outbound normalizes formatted phone number for voice", async () => {
2833
2547
  const { lastResponse } = createResponseReader();
2834
- await handleChannelVerificationSession(
2835
- {
2836
- type: "channel_verification_session",
2837
- action: "create_session",
2838
- channel: "phone",
2839
- destination: "(555) 123-4567",
2840
- },
2841
- );
2548
+ await handleChannelVerificationSession({
2549
+ type: "channel_verification_session",
2550
+ action: "create_session",
2551
+ channel: "phone",
2552
+ destination: "(555) 123-4567",
2553
+ });
2842
2554
 
2843
2555
  const resp = lastResponse();
2844
2556
  expect(resp).not.toBeNull();
@@ -2863,13 +2575,11 @@ describe("outbound voice verification", () => {
2863
2575
 
2864
2576
  test("cancel_session succeeds even when no active session (idempotent)", async () => {
2865
2577
  const { lastResponse } = createResponseReader();
2866
- await handleChannelVerificationSession(
2867
- {
2868
- type: "channel_verification_session",
2869
- action: "cancel_session",
2870
- channel: "phone",
2871
- },
2872
- );
2578
+ await handleChannelVerificationSession({
2579
+ type: "channel_verification_session",
2580
+ action: "cancel_session",
2581
+ channel: "phone",
2582
+ });
2873
2583
 
2874
2584
  const resp = lastResponse();
2875
2585
  expect(resp).not.toBeNull();
@@ -2888,14 +2598,12 @@ describe("outbound Telegram verification", () => {
2888
2598
 
2889
2599
  test("start_outbound for telegram with handle returns deep link URL, no outbound message", async () => {
2890
2600
  const { lastResponse } = createResponseReader();
2891
- await handleChannelVerificationSession(
2892
- {
2893
- type: "channel_verification_session",
2894
- action: "create_session",
2895
- channel: "telegram",
2896
- destination: "@someuser",
2897
- },
2898
- );
2601
+ await handleChannelVerificationSession({
2602
+ type: "channel_verification_session",
2603
+ action: "create_session",
2604
+ channel: "telegram",
2605
+ destination: "@someuser",
2606
+ });
2899
2607
 
2900
2608
  const resp = lastResponse();
2901
2609
  expect(resp).not.toBeNull();
@@ -2921,14 +2629,12 @@ describe("outbound Telegram verification", () => {
2921
2629
 
2922
2630
  test("start_outbound for telegram with handle (no @ prefix) returns deep link", async () => {
2923
2631
  const { lastResponse } = createResponseReader();
2924
- await handleChannelVerificationSession(
2925
- {
2926
- type: "channel_verification_session",
2927
- action: "create_session",
2928
- channel: "telegram",
2929
- destination: "someuser",
2930
- },
2931
- );
2632
+ await handleChannelVerificationSession({
2633
+ type: "channel_verification_session",
2634
+ action: "create_session",
2635
+ channel: "telegram",
2636
+ destination: "someuser",
2637
+ });
2932
2638
 
2933
2639
  const resp = lastResponse();
2934
2640
  expect(resp).not.toBeNull();
@@ -2941,14 +2647,12 @@ describe("outbound Telegram verification", () => {
2941
2647
 
2942
2648
  test("start_outbound for telegram with known chat ID sends message, no deep link", async () => {
2943
2649
  const { lastResponse } = createResponseReader();
2944
- await handleChannelVerificationSession(
2945
- {
2946
- type: "channel_verification_session",
2947
- action: "create_session",
2948
- channel: "telegram",
2949
- destination: "123456789",
2950
- },
2951
- );
2650
+ await handleChannelVerificationSession({
2651
+ type: "channel_verification_session",
2652
+ action: "create_session",
2653
+ channel: "telegram",
2654
+ destination: "123456789",
2655
+ });
2952
2656
 
2953
2657
  const resp = lastResponse();
2954
2658
  expect(resp).not.toBeNull();
@@ -2980,14 +2684,12 @@ describe("outbound Telegram verification", () => {
2980
2684
  mockBotUsername = undefined;
2981
2685
 
2982
2686
  const { lastResponse } = createResponseReader();
2983
- await handleChannelVerificationSession(
2984
- {
2985
- type: "channel_verification_session",
2986
- action: "create_session",
2987
- channel: "telegram",
2988
- destination: "@someuser",
2989
- },
2990
- );
2687
+ await handleChannelVerificationSession({
2688
+ type: "channel_verification_session",
2689
+ action: "create_session",
2690
+ channel: "telegram",
2691
+ destination: "@someuser",
2692
+ });
2991
2693
 
2992
2694
  const resp = lastResponse();
2993
2695
  expect(resp).not.toBeNull();
@@ -3004,15 +2706,13 @@ describe("outbound Telegram verification", () => {
3004
2706
  });
3005
2707
 
3006
2708
  const { lastResponse } = createResponseReader();
3007
- await handleChannelVerificationSession(
3008
- {
3009
- type: "channel_verification_session",
3010
- action: "create_session",
3011
- channel: "telegram",
3012
- destination: "@newuser",
3013
- rebind: false,
3014
- },
3015
- );
2709
+ await handleChannelVerificationSession({
2710
+ type: "channel_verification_session",
2711
+ action: "create_session",
2712
+ channel: "telegram",
2713
+ destination: "@newuser",
2714
+ rebind: false,
2715
+ });
3016
2716
 
3017
2717
  const resp = lastResponse();
3018
2718
  expect(resp).not.toBeNull();
@@ -3166,14 +2866,12 @@ describe("outbound Telegram verification", () => {
3166
2866
  test("resend_outbound for telegram works with known chat ID", async () => {
3167
2867
  // Start an outbound session with a known chat ID
3168
2868
  broadcastedMessages.length = 0;
3169
- await handleChannelVerificationSession(
3170
- {
3171
- type: "channel_verification_session",
3172
- action: "create_session",
3173
- channel: "telegram",
3174
- destination: "123456789",
3175
- },
3176
- );
2869
+ await handleChannelVerificationSession({
2870
+ type: "channel_verification_session",
2871
+ action: "create_session",
2872
+ channel: "telegram",
2873
+ destination: "123456789",
2874
+ });
3177
2875
 
3178
2876
  // Fast-forward the cooldown
3179
2877
  const session = serviceFindActiveSession("telegram");
@@ -3186,13 +2884,11 @@ describe("outbound Telegram verification", () => {
3186
2884
  );
3187
2885
 
3188
2886
  const { lastResponse } = createResponseReader();
3189
- await handleChannelVerificationSession(
3190
- {
3191
- type: "channel_verification_session",
3192
- action: "resend_session",
3193
- channel: "telegram",
3194
- },
3195
- );
2887
+ await handleChannelVerificationSession({
2888
+ type: "channel_verification_session",
2889
+ action: "resend_session",
2890
+ channel: "telegram",
2891
+ });
3196
2892
 
3197
2893
  const resp = lastResponse();
3198
2894
  expect(resp).not.toBeNull();
@@ -3208,23 +2904,19 @@ describe("outbound Telegram verification", () => {
3208
2904
  test("resend_outbound for pending_bootstrap session is rejected", async () => {
3209
2905
  // Start an outbound session with a handle (pending_bootstrap)
3210
2906
  broadcastedMessages.length = 0;
3211
- await handleChannelVerificationSession(
3212
- {
3213
- type: "channel_verification_session",
3214
- action: "create_session",
3215
- channel: "telegram",
3216
- destination: "@someuser",
3217
- },
3218
- );
2907
+ await handleChannelVerificationSession({
2908
+ type: "channel_verification_session",
2909
+ action: "create_session",
2910
+ channel: "telegram",
2911
+ destination: "@someuser",
2912
+ });
3219
2913
 
3220
2914
  const { lastResponse } = createResponseReader();
3221
- await handleChannelVerificationSession(
3222
- {
3223
- type: "channel_verification_session",
3224
- action: "resend_session",
3225
- channel: "telegram",
3226
- },
3227
- );
2915
+ await handleChannelVerificationSession({
2916
+ type: "channel_verification_session",
2917
+ action: "resend_session",
2918
+ channel: "telegram",
2919
+ });
3228
2920
 
3229
2921
  const resp = lastResponse();
3230
2922
  expect(resp).not.toBeNull();
@@ -3235,26 +2927,22 @@ describe("outbound Telegram verification", () => {
3235
2927
  test("cancel_outbound for telegram revokes session", async () => {
3236
2928
  // Start an outbound session
3237
2929
  broadcastedMessages.length = 0;
3238
- await handleChannelVerificationSession(
3239
- {
3240
- type: "channel_verification_session",
3241
- action: "create_session",
3242
- channel: "telegram",
3243
- destination: "123456789",
3244
- },
3245
- );
2930
+ await handleChannelVerificationSession({
2931
+ type: "channel_verification_session",
2932
+ action: "create_session",
2933
+ channel: "telegram",
2934
+ destination: "123456789",
2935
+ });
3246
2936
 
3247
2937
  const session = serviceFindActiveSession("telegram");
3248
2938
  expect(session).not.toBeNull();
3249
2939
 
3250
2940
  const { lastResponse } = createResponseReader();
3251
- await handleChannelVerificationSession(
3252
- {
3253
- type: "channel_verification_session",
3254
- action: "cancel_session",
3255
- channel: "telegram",
3256
- },
3257
- );
2941
+ await handleChannelVerificationSession({
2942
+ type: "channel_verification_session",
2943
+ action: "cancel_session",
2944
+ channel: "telegram",
2945
+ });
3258
2946
 
3259
2947
  const resp = lastResponse();
3260
2948
  expect(resp).not.toBeNull();
@@ -3295,13 +2983,11 @@ describe("outbound Telegram verification", () => {
3295
2983
 
3296
2984
  test("create_session for telegram without destination falls through to inbound challenge", async () => {
3297
2985
  const { lastResponse } = createResponseReader();
3298
- await handleChannelVerificationSession(
3299
- {
3300
- type: "channel_verification_session",
3301
- action: "create_session",
3302
- channel: "telegram",
3303
- },
3304
- );
2986
+ await handleChannelVerificationSession({
2987
+ type: "channel_verification_session",
2988
+ action: "create_session",
2989
+ channel: "telegram",
2990
+ });
3305
2991
 
3306
2992
  const resp = lastResponse();
3307
2993
  expect(resp).not.toBeNull();
@@ -3312,14 +2998,12 @@ describe("outbound Telegram verification", () => {
3312
2998
  test("rate limits apply to telegram outbound (per-session send cap)", async () => {
3313
2999
  // Start an outbound session with a known chat ID
3314
3000
  broadcastedMessages.length = 0;
3315
- await handleChannelVerificationSession(
3316
- {
3317
- type: "channel_verification_session",
3318
- action: "create_session",
3319
- channel: "telegram",
3320
- destination: "123456789",
3321
- },
3322
- );
3001
+ await handleChannelVerificationSession({
3002
+ type: "channel_verification_session",
3003
+ action: "create_session",
3004
+ channel: "telegram",
3005
+ destination: "123456789",
3006
+ });
3323
3007
 
3324
3008
  // Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
3325
3009
  const session = serviceFindActiveSession("telegram");
@@ -3333,13 +3017,11 @@ describe("outbound Telegram verification", () => {
3333
3017
 
3334
3018
  // Resend should be rejected due to max sends
3335
3019
  const { lastResponse } = createResponseReader();
3336
- await handleChannelVerificationSession(
3337
- {
3338
- type: "channel_verification_session",
3339
- action: "resend_session",
3340
- channel: "telegram",
3341
- },
3342
- );
3020
+ await handleChannelVerificationSession({
3021
+ type: "channel_verification_session",
3022
+ action: "resend_session",
3023
+ channel: "telegram",
3024
+ });
3343
3025
 
3344
3026
  const resp = lastResponse();
3345
3027
  expect(resp).not.toBeNull();
@@ -3350,24 +3032,20 @@ describe("outbound Telegram verification", () => {
3350
3032
  test("rate limits apply to telegram outbound (cooldown)", async () => {
3351
3033
  // Start an outbound session with a known chat ID
3352
3034
  broadcastedMessages.length = 0;
3353
- await handleChannelVerificationSession(
3354
- {
3355
- type: "channel_verification_session",
3356
- action: "create_session",
3357
- channel: "telegram",
3358
- destination: "123456789",
3359
- },
3360
- );
3035
+ await handleChannelVerificationSession({
3036
+ type: "channel_verification_session",
3037
+ action: "create_session",
3038
+ channel: "telegram",
3039
+ destination: "123456789",
3040
+ });
3361
3041
 
3362
3042
  // Immediately try to resend (before cooldown)
3363
3043
  const { lastResponse } = createResponseReader();
3364
- await handleChannelVerificationSession(
3365
- {
3366
- type: "channel_verification_session",
3367
- action: "resend_session",
3368
- channel: "telegram",
3369
- },
3370
- );
3044
+ await handleChannelVerificationSession({
3045
+ type: "channel_verification_session",
3046
+ action: "resend_session",
3047
+ channel: "telegram",
3048
+ });
3371
3049
 
3372
3050
  const resp = lastResponse();
3373
3051
  expect(resp).not.toBeNull();
@@ -3387,14 +3065,12 @@ describe("outbound voice verification", () => {
3387
3065
 
3388
3066
  test("start_outbound for voice creates session with 6-digit code and initiates call", async () => {
3389
3067
  const { lastResponse } = createResponseReader();
3390
- await handleChannelVerificationSession(
3391
- {
3392
- type: "channel_verification_session",
3393
- action: "create_session",
3394
- channel: "phone",
3395
- destination: "+15551234567",
3396
- },
3397
- );
3068
+ await handleChannelVerificationSession({
3069
+ type: "channel_verification_session",
3070
+ action: "create_session",
3071
+ channel: "phone",
3072
+ destination: "+15551234567",
3073
+ });
3398
3074
 
3399
3075
  const resp = lastResponse();
3400
3076
  expect(resp).not.toBeNull();
@@ -3427,14 +3103,12 @@ describe("outbound voice verification", () => {
3427
3103
 
3428
3104
  test("start_outbound for voice rejects unparseable phone number", async () => {
3429
3105
  const { lastResponse } = createResponseReader();
3430
- await handleChannelVerificationSession(
3431
- {
3432
- type: "channel_verification_session",
3433
- action: "create_session",
3434
- channel: "phone",
3435
- destination: "not-a-phone",
3436
- },
3437
- );
3106
+ await handleChannelVerificationSession({
3107
+ type: "channel_verification_session",
3108
+ action: "create_session",
3109
+ channel: "phone",
3110
+ destination: "not-a-phone",
3111
+ });
3438
3112
 
3439
3113
  const resp = lastResponse();
3440
3114
  expect(resp).not.toBeNull();
@@ -3444,14 +3118,12 @@ describe("outbound voice verification", () => {
3444
3118
 
3445
3119
  test("start_outbound for voice normalizes formatted phone number", async () => {
3446
3120
  const { lastResponse } = createResponseReader();
3447
- await handleChannelVerificationSession(
3448
- {
3449
- type: "channel_verification_session",
3450
- action: "create_session",
3451
- channel: "phone",
3452
- destination: "555-123-4567",
3453
- },
3454
- );
3121
+ await handleChannelVerificationSession({
3122
+ type: "channel_verification_session",
3123
+ action: "create_session",
3124
+ channel: "phone",
3125
+ destination: "555-123-4567",
3126
+ });
3455
3127
 
3456
3128
  const resp = lastResponse();
3457
3129
  expect(resp).not.toBeNull();
@@ -3485,15 +3157,13 @@ describe("outbound voice verification", () => {
3485
3157
  });
3486
3158
 
3487
3159
  const { lastResponse } = createResponseReader();
3488
- await handleChannelVerificationSession(
3489
- {
3490
- type: "channel_verification_session",
3491
- action: "create_session",
3492
- channel: "phone",
3493
- destination: "+15559876543",
3494
- rebind: false,
3495
- },
3496
- );
3160
+ await handleChannelVerificationSession({
3161
+ type: "channel_verification_session",
3162
+ action: "create_session",
3163
+ channel: "phone",
3164
+ destination: "+15559876543",
3165
+ rebind: false,
3166
+ });
3497
3167
 
3498
3168
  const resp = lastResponse();
3499
3169
  expect(resp).not.toBeNull();
@@ -3504,24 +3174,20 @@ describe("outbound voice verification", () => {
3504
3174
  test("resend_outbound for voice initiates a new call with cooldown check", async () => {
3505
3175
  // Start an outbound session first
3506
3176
  broadcastedMessages.length = 0;
3507
- await handleChannelVerificationSession(
3508
- {
3509
- type: "channel_verification_session",
3510
- action: "create_session",
3511
- channel: "phone",
3512
- destination: "+15551234567",
3513
- },
3514
- );
3177
+ await handleChannelVerificationSession({
3178
+ type: "channel_verification_session",
3179
+ action: "create_session",
3180
+ channel: "phone",
3181
+ destination: "+15551234567",
3182
+ });
3515
3183
 
3516
3184
  // Immediately try to resend (before cooldown)
3517
3185
  const { lastResponse } = createResponseReader();
3518
- await handleChannelVerificationSession(
3519
- {
3520
- type: "channel_verification_session",
3521
- action: "resend_session",
3522
- channel: "phone",
3523
- },
3524
- );
3186
+ await handleChannelVerificationSession({
3187
+ type: "channel_verification_session",
3188
+ action: "resend_session",
3189
+ channel: "phone",
3190
+ });
3525
3191
 
3526
3192
  const resp = lastResponse();
3527
3193
  expect(resp).not.toBeNull();
@@ -3532,24 +3198,20 @@ describe("outbound voice verification", () => {
3532
3198
  test("cancel_outbound for voice cancels session", async () => {
3533
3199
  // Start an outbound session first
3534
3200
  broadcastedMessages.length = 0;
3535
- await handleChannelVerificationSession(
3536
- {
3537
- type: "channel_verification_session",
3538
- action: "create_session",
3539
- channel: "phone",
3540
- destination: "+15551234567",
3541
- },
3542
- );
3201
+ await handleChannelVerificationSession({
3202
+ type: "channel_verification_session",
3203
+ action: "create_session",
3204
+ channel: "phone",
3205
+ destination: "+15551234567",
3206
+ });
3543
3207
 
3544
3208
  // Cancel the session
3545
3209
  const { lastResponse } = createResponseReader();
3546
- await handleChannelVerificationSession(
3547
- {
3548
- type: "channel_verification_session",
3549
- action: "cancel_session",
3550
- channel: "phone",
3551
- },
3552
- );
3210
+ await handleChannelVerificationSession({
3211
+ type: "channel_verification_session",
3212
+ action: "cancel_session",
3213
+ channel: "phone",
3214
+ });
3553
3215
 
3554
3216
  const resp = lastResponse();
3555
3217
  expect(resp).not.toBeNull();
@@ -3583,14 +3245,12 @@ describe("outbound voice verification", () => {
3583
3245
  }
3584
3246
 
3585
3247
  const { lastResponse } = createResponseReader();
3586
- await handleChannelVerificationSession(
3587
- {
3588
- type: "channel_verification_session",
3589
- action: "create_session",
3590
- channel: "phone",
3591
- destination: "+15551234567",
3592
- },
3593
- );
3248
+ await handleChannelVerificationSession({
3249
+ type: "channel_verification_session",
3250
+ action: "create_session",
3251
+ channel: "phone",
3252
+ destination: "+15551234567",
3253
+ });
3594
3254
 
3595
3255
  const resp = lastResponse();
3596
3256
  expect(resp).not.toBeNull();
@@ -3600,13 +3260,11 @@ describe("outbound voice verification", () => {
3600
3260
 
3601
3261
  test("create_session for voice without destination falls through to inbound challenge", async () => {
3602
3262
  const { lastResponse } = createResponseReader();
3603
- await handleChannelVerificationSession(
3604
- {
3605
- type: "channel_verification_session",
3606
- action: "create_session",
3607
- channel: "phone",
3608
- },
3609
- );
3263
+ await handleChannelVerificationSession({
3264
+ type: "channel_verification_session",
3265
+ action: "create_session",
3266
+ channel: "phone",
3267
+ });
3610
3268
 
3611
3269
  const resp = lastResponse();
3612
3270
  expect(resp).not.toBeNull();
@@ -3634,14 +3292,12 @@ describe("M1–M4 hardening coverage", () => {
3634
3292
 
3635
3293
  test("start_outbound for voice response includes secret", async () => {
3636
3294
  const { lastResponse } = createResponseReader();
3637
- await handleChannelVerificationSession(
3638
- {
3639
- type: "channel_verification_session",
3640
- action: "create_session",
3641
- channel: "phone",
3642
- destination: "+15551234567",
3643
- },
3644
- );
3295
+ await handleChannelVerificationSession({
3296
+ type: "channel_verification_session",
3297
+ action: "create_session",
3298
+ channel: "phone",
3299
+ destination: "+15551234567",
3300
+ });
3645
3301
 
3646
3302
  const resp = lastResponse();
3647
3303
  expect(resp).not.toBeNull();
@@ -3656,14 +3312,12 @@ describe("M1–M4 hardening coverage", () => {
3656
3312
  test("resend_outbound for voice response includes secret", async () => {
3657
3313
  // Start a session first
3658
3314
  broadcastedMessages.length = 0;
3659
- await handleChannelVerificationSession(
3660
- {
3661
- type: "channel_verification_session",
3662
- action: "create_session",
3663
- channel: "phone",
3664
- destination: "+15551234567",
3665
- },
3666
- );
3315
+ await handleChannelVerificationSession({
3316
+ type: "channel_verification_session",
3317
+ action: "create_session",
3318
+ channel: "phone",
3319
+ destination: "+15551234567",
3320
+ });
3667
3321
 
3668
3322
  // Move past cooldown
3669
3323
  const session = serviceFindActiveSession("phone");
@@ -3677,13 +3331,11 @@ describe("M1–M4 hardening coverage", () => {
3677
3331
 
3678
3332
  // Resend
3679
3333
  const { lastResponse } = createResponseReader();
3680
- await handleChannelVerificationSession(
3681
- {
3682
- type: "channel_verification_session",
3683
- action: "resend_session",
3684
- channel: "phone",
3685
- },
3686
- );
3334
+ await handleChannelVerificationSession({
3335
+ type: "channel_verification_session",
3336
+ action: "resend_session",
3337
+ channel: "phone",
3338
+ });
3687
3339
 
3688
3340
  const resp = lastResponse();
3689
3341
  expect(resp).not.toBeNull();
@@ -3697,14 +3349,12 @@ describe("M1–M4 hardening coverage", () => {
3697
3349
 
3698
3350
  test("start_outbound for Telegram bootstrap (handle) does NOT return secret", async () => {
3699
3351
  const { lastResponse } = createResponseReader();
3700
- await handleChannelVerificationSession(
3701
- {
3702
- type: "channel_verification_session",
3703
- action: "create_session",
3704
- channel: "telegram",
3705
- destination: "@someuser",
3706
- },
3707
- );
3352
+ await handleChannelVerificationSession({
3353
+ type: "channel_verification_session",
3354
+ action: "create_session",
3355
+ channel: "telegram",
3356
+ destination: "@someuser",
3357
+ });
3708
3358
 
3709
3359
  const resp = lastResponse();
3710
3360
  expect(resp).not.toBeNull();