@vellumai/assistant 0.10.0 → 0.10.1-staging.1

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 (824) 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 +6 -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__/trust-verdict-contract.test.ts +65 -0
  176. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
  177. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
  178. package/node_modules/@vellumai/gateway-client/src/index.ts +14 -0
  179. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +4 -2
  180. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +3 -2
  181. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +78 -0
  182. package/openapi.yaml +345 -18
  183. package/package.json +2 -1
  184. package/scripts/memory-inspect.ts +24 -14
  185. package/src/__tests__/access-request-seed-content-blocks.test.ts +83 -103
  186. package/src/__tests__/activation-early-marking.test.ts +1 -1
  187. package/src/__tests__/actor-token-service.test.ts +3 -3
  188. package/src/__tests__/agent-loop-callsite-precedence.test.ts +1 -40
  189. package/src/__tests__/agent-loop-compaction-events.test.ts +0 -1
  190. package/src/__tests__/agent-loop-compaction-strip.test.ts +0 -1
  191. package/src/__tests__/agent-loop-exit-reason.test.ts +0 -1
  192. package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
  193. package/src/__tests__/agent-loop-regrowth-guard.test.ts +0 -1
  194. package/src/__tests__/agent-loop.test.ts +3 -0
  195. package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
  196. package/src/__tests__/anthropic-provider.test.ts +143 -9
  197. package/src/__tests__/app-builder-skill-instructions.test.ts +47 -5
  198. package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -1
  199. package/src/__tests__/app-source-watcher.test.ts +30 -10
  200. package/src/__tests__/approval-cascade.test.ts +6 -0
  201. package/src/__tests__/approval-interception-trust-gates.test.ts +151 -0
  202. package/src/__tests__/approval-primitive.test.ts +1 -1
  203. package/src/__tests__/approval-routes-http.test.ts +1 -1
  204. package/src/__tests__/assistant-attachments.test.ts +155 -0
  205. package/src/__tests__/assistant-event-hub-machine-name.test.ts +2 -4
  206. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  207. package/src/__tests__/assistant-events-sse-shed.test.ts +1 -1
  208. package/src/__tests__/attachment-upload-trusted-source.test.ts +13 -8
  209. package/src/__tests__/attachments-store.test.ts +1 -1
  210. package/src/__tests__/audit-log-rotation.test.ts +50 -54
  211. package/src/__tests__/auth-fallback-events-store.test.ts +1 -1
  212. package/src/__tests__/auto-analysis-end-to-end.test.ts +9 -14
  213. package/src/__tests__/background-shell-bash.test.ts +4 -1
  214. package/src/__tests__/background-shell-host-bash.test.ts +17 -3
  215. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  216. package/src/__tests__/call-controller.test.ts +1 -1
  217. package/src/__tests__/call-conversation-messages.test.ts +1 -1
  218. package/src/__tests__/call-domain.test.ts +1 -1
  219. package/src/__tests__/call-pointer-messages.test.ts +3 -4
  220. package/src/__tests__/call-recovery.test.ts +1 -1
  221. package/src/__tests__/call-routes-http.test.ts +1 -1
  222. package/src/__tests__/call-store.test.ts +1 -1
  223. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  224. package/src/__tests__/canonical-guardian-store.test.ts +24 -1
  225. package/src/__tests__/channel-approval-routes.test.ts +73 -1119
  226. package/src/__tests__/channel-delivery-store.test.ts +1 -1
  227. package/src/__tests__/channel-guardian.test.ts +265 -641
  228. package/src/__tests__/channel-inbound-disk-pressure.test.ts +1 -2
  229. package/src/__tests__/channel-retry-sweep.test.ts +1 -1
  230. package/src/__tests__/compaction-events.test.ts +6 -0
  231. package/src/__tests__/compaction-trail-store.test.ts +6 -5
  232. package/src/__tests__/compaction.benchmark.test.ts +0 -1
  233. package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
  234. package/src/__tests__/config-loader-backfill.test.ts +183 -51
  235. package/src/__tests__/config-schema.test.ts +34 -0
  236. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -2
  237. package/src/__tests__/contact-store-user-file.test.ts +2 -2
  238. package/src/__tests__/contacts-relay-reads.test.ts +409 -0
  239. package/src/__tests__/contacts-tools.test.ts +4 -4
  240. package/src/__tests__/contacts-write.test.ts +1 -2
  241. package/src/__tests__/context-search-conversations-source.test.ts +1 -1
  242. package/src/__tests__/context-window-manager-compact-retry.test.ts +6 -2
  243. package/src/__tests__/context-window-manager-overflow-rung.test.ts +6 -2
  244. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  245. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
  246. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
  247. package/src/__tests__/conversation-agent-loop-overflow.test.ts +3 -0
  248. package/src/__tests__/conversation-agent-loop.test.ts +3 -0
  249. package/src/__tests__/conversation-attachments.test.ts +2 -5
  250. package/src/__tests__/conversation-attention-store.test.ts +1 -1
  251. package/src/__tests__/conversation-attention-telegram.test.ts +1 -2
  252. package/src/__tests__/conversation-clear-safety.test.ts +1 -1
  253. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
  254. package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -1
  255. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +12 -19
  256. package/src/__tests__/conversation-disk-view-integration.test.ts +1 -1
  257. package/src/__tests__/conversation-disk-view.test.ts +1 -1
  258. package/src/__tests__/conversation-fork-crud.test.ts +10 -8
  259. package/src/__tests__/conversation-fork-retrospective.test.ts +250 -0
  260. package/src/__tests__/conversation-fork-route.test.ts +1 -1
  261. package/src/__tests__/conversation-inference-profile-list.test.ts +1 -1
  262. package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
  263. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  264. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
  265. package/src/__tests__/conversation-lifecycle.test.ts +117 -0
  266. package/src/__tests__/conversation-list-source.test.ts +3 -3
  267. package/src/__tests__/conversation-process-callsite.test.ts +6 -14
  268. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  269. package/src/__tests__/conversation-queue.test.ts +6 -0
  270. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
  271. package/src/__tests__/conversation-runtime-assembly.test.ts +115 -12
  272. package/src/__tests__/conversation-slash-queue.test.ts +6 -0
  273. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  274. package/src/__tests__/conversation-speed-override.test.ts +6 -0
  275. package/src/__tests__/conversation-starter-routes.test.ts +5 -5
  276. package/src/__tests__/conversation-store.test.ts +1 -1
  277. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -1
  278. package/src/__tests__/conversation-sync-tags.test.ts +1 -1
  279. package/src/__tests__/conversation-usage.test.ts +1 -1
  280. package/src/__tests__/conversation-wipe.test.ts +9 -8
  281. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
  282. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  283. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  284. package/src/__tests__/conversations-import-system-filter.test.ts +1 -1
  285. package/src/__tests__/copy-composer-tc-templates.test.ts +17 -0
  286. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  287. package/src/__tests__/db-acp-history.test.ts +2 -2
  288. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +5 -7
  289. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -7
  290. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +5 -10
  291. package/src/__tests__/db-migration-rollback.test.ts +129 -39
  292. package/src/__tests__/db-proxy-transaction.test.ts +1 -1
  293. package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -11
  294. package/src/__tests__/db-test-helpers.ts +36 -19
  295. package/src/__tests__/delete-propagation.test.ts +1 -1
  296. package/src/__tests__/deterministic-verification-control-plane.test.ts +26 -8
  297. package/src/__tests__/disk-pressure-tools.test.ts +41 -1
  298. package/src/__tests__/dm-backfill.test.ts +1 -1
  299. package/src/__tests__/drop-capability-card-state-migration.test.ts +0 -8
  300. package/src/__tests__/edit-propagation.test.ts +1 -1
  301. package/src/__tests__/emit-signal-routing-intent.test.ts +83 -0
  302. package/src/__tests__/empty-response-hook.test.ts +42 -0
  303. package/src/__tests__/events-client-registration.test.ts +1 -1
  304. package/src/__tests__/followup-tools.test.ts +1 -1
  305. package/src/__tests__/gemini-count-tokens.test.ts +70 -0
  306. package/src/__tests__/guardian-action-sweep.test.ts +9 -2
  307. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  308. package/src/__tests__/guardian-card-withdrawal.test.ts +1 -1
  309. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -1
  310. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  311. package/src/__tests__/guardian-outbound-http.test.ts +7 -12
  312. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -1
  313. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  314. package/src/__tests__/guardian-routing-state.test.ts +1 -2
  315. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  316. package/src/__tests__/headless-browser-mode.test.ts +2 -2
  317. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  318. package/src/__tests__/heartbeat-service.test.ts +6 -0
  319. package/src/__tests__/helpers/channel-test-adapter.ts +98 -0
  320. package/src/__tests__/http-conversation-lineage.test.ts +1 -1
  321. package/src/__tests__/image-recovery-hook.test.ts +1 -1
  322. package/src/__tests__/inbound-invite-redemption.test.ts +1 -2
  323. package/src/__tests__/inbound-trust-verdict.test.ts +254 -0
  324. package/src/__tests__/inference-profile-reaper.test.ts +1 -1
  325. package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
  326. package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
  327. package/src/__tests__/injector-chain.test.ts +1 -1
  328. package/src/__tests__/injector-disk-pressure.test.ts +11 -6
  329. package/src/__tests__/internal-telemetry-routes.test.ts +1 -1
  330. package/src/__tests__/invite-redemption-service.test.ts +244 -43
  331. package/src/__tests__/invite-routes-http.test.ts +35 -186
  332. package/src/__tests__/invite-service-ipc.test.ts +287 -0
  333. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +5 -5
  334. package/src/__tests__/jobs-store-upsert-debounced.test.ts +9 -12
  335. package/src/__tests__/list-messages-attachments.test.ts +42 -1
  336. package/src/__tests__/list-messages-client-message-id.test.ts +1 -1
  337. package/src/__tests__/list-messages-hidden-metadata.test.ts +1 -1
  338. package/src/__tests__/list-messages-page-latest.test.ts +1 -1
  339. package/src/__tests__/list-messages-tool-merge.test.ts +1 -1
  340. package/src/__tests__/llm-context-route-provider.test.ts +69 -4
  341. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -5
  342. package/src/__tests__/llm-request-log-call-site.test.ts +6 -6
  343. package/src/__tests__/llm-request-log-turn-query.test.ts +27 -13
  344. package/src/__tests__/llm-usage-store.test.ts +40 -1
  345. package/src/__tests__/log-export-routes.test.ts +1 -1
  346. package/src/__tests__/log-export-workspace.test.ts +3 -3
  347. package/src/__tests__/memory-jobs-worker-lanes.test.ts +5 -5
  348. package/src/__tests__/memory-recall-log-store.test.ts +1 -1
  349. package/src/__tests__/memory-upsert-concurrency.test.ts +3 -4
  350. package/src/__tests__/messages-after-tiebreaker.test.ts +1 -1
  351. package/src/__tests__/migration-import-from-url.test.ts +2 -2
  352. package/src/__tests__/mtime-cache.test.ts +375 -0
  353. package/src/__tests__/non-member-access-request.test.ts +1 -2
  354. package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
  355. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  356. package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
  357. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  358. package/src/__tests__/oauth-provider-visibility.test.ts +1 -1
  359. package/src/__tests__/oauth-store.test.ts +1 -1
  360. package/src/__tests__/persist-unsendable-image-downscale.test.ts +1 -1
  361. package/src/__tests__/persist-unsendable-image.test.ts +1 -1
  362. package/src/__tests__/persona-resolver.test.ts +39 -1
  363. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
  364. package/src/__tests__/playbook-execution.test.ts +1 -1
  365. package/src/__tests__/playbook-tools.test.ts +1 -1
  366. package/src/__tests__/plugin-api-model-profiles.test.ts +74 -21
  367. package/src/__tests__/plugin-bootstrap.test.ts +78 -0
  368. package/src/__tests__/provider-platform-proxy-integration.test.ts +25 -5
  369. package/src/__tests__/provider-usage-tracking.test.ts +1 -1
  370. package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
  371. package/src/__tests__/reaction-persistence.test.ts +1 -1
  372. package/src/__tests__/relay-server.test.ts +357 -56
  373. package/src/__tests__/runtime-attachment-metadata.test.ts +10 -1
  374. package/src/__tests__/runtime-events-sse-bilingual.test.ts +7 -9
  375. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  376. package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
  377. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  378. package/src/__tests__/schedule-retry.test.ts +1 -1
  379. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -1
  380. package/src/__tests__/schedule-routes.test.ts +1 -1
  381. package/src/__tests__/schedule-store.test.ts +1 -1
  382. package/src/__tests__/schedule-tools.test.ts +1 -1
  383. package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
  384. package/src/__tests__/scheduler-recurrence.test.ts +1 -1
  385. package/src/__tests__/scheduler-reuse-conversation.test.ts +1 -1
  386. package/src/__tests__/scheduler-wake.test.ts +2 -1
  387. package/src/__tests__/scoped-approval-grants.test.ts +1 -1
  388. package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -5
  389. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +0 -8
  390. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
  391. package/src/__tests__/send-endpoint-busy.test.ts +1 -1
  392. package/src/__tests__/sequence-store.test.ts +1 -1
  393. package/src/__tests__/server-history-render.test.ts +40 -1
  394. package/src/__tests__/settings-routes.test.ts +11 -10
  395. package/src/__tests__/skill-load-tool.test.ts +72 -0
  396. package/src/__tests__/slack-inbound-verification.test.ts +1 -3
  397. package/src/__tests__/slack-messaging-token-resolution.test.ts +13 -2
  398. package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -1
  399. package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -73
  400. package/src/__tests__/subagent-tools.test.ts +1 -31
  401. package/src/__tests__/system-prompt.test.ts +1 -1
  402. package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
  403. package/src/__tests__/task-compiler.test.ts +1 -1
  404. package/src/__tests__/task-management-tools.test.ts +1 -1
  405. package/src/__tests__/task-memory-cleanup.test.ts +9 -6
  406. package/src/__tests__/task-scheduler.test.ts +1 -1
  407. package/src/__tests__/thread-backfill.test.ts +1 -1
  408. package/src/__tests__/tool-approval-handler.test.ts +1 -1
  409. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +2 -0
  410. package/src/__tests__/tool-executor.test.ts +32 -1
  411. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -2
  412. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +73 -1
  413. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +34 -34
  414. package/src/__tests__/trusted-contact-multichannel.test.ts +1 -2
  415. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  416. package/src/__tests__/turn-boundary-resolution.test.ts +3 -3
  417. package/src/__tests__/turn-events-store.test.ts +1 -1
  418. package/src/__tests__/twilio-routes.test.ts +2 -3
  419. package/src/__tests__/usage-cache-backfill-migration.test.ts +20 -10
  420. package/src/__tests__/usage-routes.test.ts +1 -1
  421. package/src/__tests__/user-plugin-loader.test.ts +34 -29
  422. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  423. package/src/__tests__/voice-invite-redemption.test.ts +134 -36
  424. package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
  425. package/src/__tests__/voice-session-bridge.test.ts +1 -1
  426. package/src/__tests__/workspace-git-service.test.ts +114 -1
  427. package/src/__tests__/workspace-heartbeat-service.test.ts +45 -0
  428. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -1
  429. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
  430. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +88 -18
  431. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +6 -6
  432. package/src/__tests__/workspace-migration-109-swap-quality-profile-to-glm-5p2.test.ts +281 -0
  433. package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +167 -0
  434. package/src/__tests__/workspace-migrations-runner.test.ts +55 -0
  435. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -1
  436. package/src/a2a/__tests__/task-store.test.ts +1 -1
  437. package/src/acp/__tests__/session-manager-persistence.test.ts +1 -1
  438. package/src/acp/__tests__/session-manager-resume.test.ts +22 -11
  439. package/src/acp/__tests__/session-manager-startup.test.ts +1 -1
  440. package/src/acp/__tests__/session-manager.test.ts +72 -1
  441. package/src/acp/index.ts +10 -0
  442. package/src/acp/session-manager.ts +35 -0
  443. package/src/agent/loop.ts +45 -27
  444. package/src/api/index.ts +0 -6
  445. package/src/approvals/AGENTS.md +1 -2
  446. package/src/approvals/guardian-decision-primitive.ts +13 -210
  447. package/src/approvals/guardian-request-resolvers.ts +104 -58
  448. package/src/background-wake/wake-intent-hooks.test.ts +1 -1
  449. package/src/calls/__tests__/inbound-trust-reader.test.ts +110 -0
  450. package/src/calls/__tests__/relay-setup-router.test.ts +88 -62
  451. package/src/calls/inbound-trust-reader.ts +40 -0
  452. package/src/calls/relay-server.ts +65 -23
  453. package/src/calls/relay-setup-router.ts +20 -6
  454. package/src/calls/relay-verification.ts +7 -7
  455. package/src/cli/commands/contacts.ts +6 -24
  456. package/src/cli/commands/db/__tests__/repair.test.ts +15 -6
  457. package/src/cli/commands/db/__tests__/status.test.ts +7 -3
  458. package/src/cli/commands/db/status.ts +212 -33
  459. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +6 -1
  460. package/src/cli/commands/memory/index.ts +2 -0
  461. package/src/cli/commands/memory/memory-retrospective.ts +129 -0
  462. package/src/cli/commands/memory/memory-v3.ts +176 -4
  463. package/src/cli/commands/plugins.ts +268 -11
  464. package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
  465. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
  466. package/src/cli/lib/__tests__/toggle-plugin.test.ts +158 -0
  467. package/src/cli/lib/install-from-github.ts +47 -6
  468. package/src/cli/lib/plugin-marketplace.ts +11 -0
  469. package/src/cli/lib/plugin-pin-history.ts +257 -0
  470. package/src/cli/lib/toggle-plugin.ts +146 -0
  471. package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
  472. package/src/config/bundled-skills/app-builder/SKILL.md +15 -33
  473. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +3 -8
  474. package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +64 -37
  475. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +1 -1
  476. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +14 -72
  477. package/src/config/bundled-skills/app-builder/references/examples/README.md +1 -2
  478. package/src/config/bundled-skills/contacts/SKILL.md +7 -12
  479. package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
  480. package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
  481. package/src/config/bundled-skills/workflows/SKILL.md +4 -3
  482. package/src/config/call-site-defaults.ts +11 -2
  483. package/src/config/feature-flag-registry.json +0 -8
  484. package/src/config/profile-dispatchability.ts +11 -0
  485. package/src/config/schemas/call-site-catalog.ts +7 -0
  486. package/src/config/schemas/llm.ts +2 -0
  487. package/src/config/schemas/memory-lifecycle.ts +5 -3
  488. package/src/config/schemas/timeouts.ts +24 -0
  489. package/src/config/seed-inference-profiles.ts +133 -45
  490. package/src/config/sync-gated-profiles.ts +13 -1
  491. package/src/contacts/contact-store.ts +21 -0
  492. package/src/contacts/member-status.ts +9 -0
  493. package/src/credential-health/credential-health-service.ts +1 -5
  494. package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
  495. package/src/daemon/app-source-watcher.ts +31 -18
  496. package/src/daemon/assistant-attachments.ts +94 -4
  497. package/src/daemon/conversation-agent-loop-handlers.ts +3 -0
  498. package/src/daemon/conversation-agent-loop.ts +9 -36
  499. package/src/daemon/conversation-runtime-assembly.ts +91 -66
  500. package/src/daemon/conversation-tool-setup.ts +20 -63
  501. package/src/daemon/conversation.ts +144 -52
  502. package/src/daemon/event-loop-watchdog.test.ts +85 -0
  503. package/src/daemon/event-loop-watchdog.ts +133 -0
  504. package/src/daemon/external-plugins-bootstrap.ts +26 -80
  505. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  506. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -1
  507. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -1
  508. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -1
  509. package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -1
  510. package/src/daemon/handlers/config-channels.ts +32 -18
  511. package/src/daemon/handlers/conversations.ts +7 -0
  512. package/src/daemon/handlers/shared.ts +7 -0
  513. package/src/daemon/lifecycle.ts +16 -3
  514. package/src/daemon/message-types/inbox.ts +0 -6
  515. package/src/daemon/message-types/messages.ts +0 -4
  516. package/src/daemon/message-types/surfaces.ts +18 -8
  517. package/src/daemon/server.ts +0 -4
  518. package/src/daemon/tool-setup-types.ts +0 -7
  519. package/src/daemon/trust-context.ts +6 -0
  520. package/src/daemon/wake-conversation-ops.ts +70 -0
  521. package/src/daemon/workspace-tools-watcher.ts +7 -3
  522. package/src/documents/document-comments-store.test.ts +1 -1
  523. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +1 -1
  524. package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
  525. package/src/heartbeat/heartbeat-service.ts +3 -4
  526. package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
  527. package/src/ipc/__tests__/browser-ipc.test.ts +73 -2
  528. package/src/ipc/__tests__/watcher-ipc.test.ts +59 -39
  529. package/src/ipc/assistant-server.ts +8 -0
  530. package/src/ipc/gateway-client.ts +2 -1
  531. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +58 -0
  532. package/src/ipc/routes/invite-ipc-routes.ts +66 -0
  533. package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
  534. package/src/memory/__tests__/activation-session-store.test.ts +1 -1
  535. package/src/memory/__tests__/auto-analysis-guard.test.ts +1 -1
  536. package/src/memory/__tests__/conversation-group-migration.test.ts +1 -1
  537. package/src/memory/__tests__/conversation-queries.test.ts +1 -1
  538. package/src/memory/__tests__/db-async-query.test.ts +1 -1
  539. package/src/memory/__tests__/db-logs-attach.test.ts +110 -0
  540. package/src/memory/__tests__/db-maintenance.test.ts +28 -36
  541. package/src/memory/__tests__/db-memory-attach.test.ts +113 -0
  542. package/src/memory/__tests__/find-analysis-conversation.test.ts +1 -1
  543. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -1
  544. package/src/memory/__tests__/fork-message-copy.test.ts +232 -0
  545. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +3 -0
  546. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +5 -5
  547. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +8 -6
  548. package/src/memory/__tests__/memory-retrospective-job.test.ts +30 -37
  549. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +69 -66
  550. package/src/memory/__tests__/memory-retrospective-state.test.ts +1 -1
  551. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  552. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +1 -1
  553. package/src/memory/__tests__/onboarding-events-store.test.ts +1 -1
  554. package/src/memory/__tests__/table-relocation.test.ts +129 -0
  555. package/src/memory/conversation-crud.ts +461 -152
  556. package/src/memory/db-async-query.ts +89 -5
  557. package/src/memory/db-connection.ts +101 -18
  558. package/src/memory/db-init.ts +409 -234
  559. package/src/memory/db-maintenance.ts +43 -38
  560. package/src/memory/db-singleton.ts +45 -19
  561. package/src/memory/fork-message-copy.ts +170 -0
  562. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +92 -0
  563. package/src/memory/graph/bootstrap.test.ts +6 -3
  564. package/src/memory/graph/retriever.test.ts +12 -12
  565. package/src/memory/graph/store.test.ts +15 -25
  566. package/src/memory/graph/store.ts +23 -14
  567. package/src/memory/graph/tool-handlers.ts +34 -5
  568. package/src/memory/graph/tools.ts +5 -2
  569. package/src/memory/indexer.ts +21 -9
  570. package/src/memory/job-handlers/cleanup.ts +10 -3
  571. package/src/memory/job-handlers/embedding.test.ts +4 -4
  572. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +4 -4
  573. package/src/memory/jobs/embed-pkb-file.test.ts +7 -7
  574. package/src/memory/jobs-store.ts +36 -24
  575. package/src/memory/llm-request-log-store.ts +51 -19
  576. package/src/memory/llm-usage-store.ts +31 -1
  577. package/src/memory/memory-retrospective-job.ts +27 -19
  578. package/src/memory/memory-retrospective-startup-cleanup.ts +10 -2
  579. package/src/memory/migrations/{100-core-tables.ts → 000-core-tables.ts} +6 -10
  580. package/src/memory/migrations/104-core-indexes.ts +1 -1
  581. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +189 -196
  582. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +98 -105
  583. package/src/memory/migrations/134-contacts-notes-column.ts +66 -69
  584. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +19 -22
  585. package/src/memory/migrations/136-drop-assistant-id-columns.ts +227 -230
  586. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +204 -209
  587. package/src/memory/migrations/141-rename-verification-table.ts +45 -48
  588. package/src/memory/migrations/142-rename-verification-session-id-column.ts +16 -23
  589. package/src/memory/migrations/143-rename-guardian-verification-values.ts +23 -30
  590. package/src/memory/migrations/144-rename-voice-to-phone.ts +133 -136
  591. package/src/memory/migrations/145-drop-accounts-table.ts +4 -7
  592. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +79 -82
  593. package/src/memory/migrations/148-drop-reminders-table.ts +3 -6
  594. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +71 -78
  595. package/src/memory/migrations/157-invite-contact-id.ts +73 -76
  596. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +44 -58
  597. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +36 -43
  598. package/src/memory/migrations/174-rename-thread-starters-table.ts +30 -37
  599. package/src/memory/migrations/176-drop-capability-card-state.ts +17 -22
  600. package/src/memory/migrations/177-create-trace-events-table.ts +23 -28
  601. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +36 -43
  602. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +14 -21
  603. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +17 -24
  604. package/src/memory/migrations/192-contacts-user-file-column.ts +6 -9
  605. package/src/memory/migrations/193-add-source-type-columns.ts +33 -36
  606. package/src/memory/migrations/194-memory-recall-logs.ts +34 -39
  607. package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +59 -66
  608. package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +41 -48
  609. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +11 -18
  610. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +76 -83
  611. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +50 -57
  612. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +6 -11
  613. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +4 -9
  614. package/src/memory/migrations/217-conversation-host-access.ts +13 -18
  615. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +86 -93
  616. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +41 -48
  617. package/src/memory/migrations/230-acp-session-history.ts +23 -28
  618. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +58 -62
  619. package/src/memory/migrations/232-activation-state.ts +11 -16
  620. package/src/memory/migrations/233-document-conversations.ts +20 -25
  621. package/src/memory/migrations/234-memory-v2-activation-logs.ts +26 -31
  622. package/src/memory/migrations/235-slack-compaction-watermark.ts +5 -10
  623. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +6 -11
  624. package/src/memory/migrations/237-heartbeat-runs.ts +22 -27
  625. package/src/memory/migrations/239-trace-events-created-at-index.ts +4 -9
  626. package/src/memory/migrations/242-message-bookmarks.ts +17 -22
  627. package/src/memory/migrations/245-memory-retrospective-state.ts +8 -13
  628. package/src/memory/migrations/249-normalize-slack-external-content.ts +37 -41
  629. package/src/memory/migrations/251-a2a-tasks.ts +27 -32
  630. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +12 -17
  631. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +10 -15
  632. package/src/memory/migrations/256-memory-v2-injection-events.ts +70 -74
  633. package/src/memory/migrations/259-conversation-cleaned-at.ts +4 -9
  634. package/src/memory/migrations/260-rename-cleaned-at.ts +11 -16
  635. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +3 -8
  636. package/src/memory/migrations/262-memory-v3-coactivation.ts +21 -26
  637. package/src/memory/migrations/263-memory-v3-auto-edges.ts +14 -19
  638. package/src/memory/migrations/270-schedule-description.ts +7 -12
  639. package/src/memory/migrations/272-acp-session-history-cwd.ts +8 -13
  640. package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +8 -13
  641. package/src/memory/migrations/297-move-llm-request-logs-to-logs-db.ts +111 -0
  642. package/src/memory/migrations/298-move-memory-jobs-to-memory-db.ts +128 -0
  643. package/src/memory/migrations/299-canonical-guardian-deliveries-conversation-index.ts +19 -0
  644. package/src/memory/migrations/__tests__/297-move-llm-request-logs.test.ts +180 -0
  645. package/src/memory/migrations/__tests__/run-migrations.test.ts +333 -7
  646. package/src/memory/migrations/helpers/relocation.ts +227 -0
  647. package/src/memory/migrations/registry.ts +63 -0
  648. package/src/memory/migrations/run-migrations.ts +187 -16
  649. package/src/memory/migrations/validate-migration-state.ts +50 -145
  650. package/src/memory/raw-query.ts +47 -2
  651. package/src/memory/skill-loaded-events-store.test.ts +1 -1
  652. package/src/memory/task-memory-cleanup.ts +62 -41
  653. package/src/memory/tool-executed-events-store.test.ts +1 -1
  654. package/src/memory/turn-trace-store.test.ts +1 -1
  655. package/src/memory/v2/__tests__/backfill-jobs.test.ts +16 -15
  656. package/src/memory/v2/__tests__/harness-compare.test.ts +1 -1
  657. package/src/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  658. package/src/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  659. package/src/memory/v2/__tests__/sweep-job.test.ts +2 -2
  660. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +38 -0
  661. package/src/memory/v3-eval/__tests__/eval-tally.test.ts +139 -0
  662. package/src/memory/v3-eval/eval-packets.ts +197 -12
  663. package/src/memory/v3-eval/eval-tally.ts +234 -0
  664. package/src/messaging/provider.ts +10 -0
  665. package/src/messaging/providers/gmail/adapter.ts +1 -0
  666. package/src/messaging/providers/gmail/client.ts +14 -0
  667. package/src/messaging/providers/index.ts +1 -1
  668. package/src/messaging/providers/slack/send.test.ts +87 -39
  669. package/src/messaging/providers/slack/send.ts +84 -105
  670. package/src/notifications/README.md +9 -5
  671. package/src/notifications/__tests__/deterministic-checks.test.ts +43 -1
  672. package/src/notifications/adapters/slack.ts +12 -10
  673. package/src/notifications/approval-card-builder.ts +81 -20
  674. package/src/notifications/approval-card-data.ts +8 -5
  675. package/src/notifications/canonical-delivery-recorder.ts +7 -5
  676. package/src/notifications/conversation-candidates.ts +24 -59
  677. package/src/notifications/copy-composer.ts +48 -68
  678. package/src/notifications/deterministic-checks.ts +19 -16
  679. package/src/notifications/emit-signal.ts +29 -1
  680. package/src/notifications/trusted-contact-payloads.ts +70 -0
  681. package/src/oauth/byo-connection.test.ts +9 -0
  682. package/src/oauth/connection-resolver.test.ts +146 -6
  683. package/src/oauth/connection-resolver.ts +132 -5
  684. package/src/oauth/oauth-store.ts +16 -3
  685. package/src/oauth/scope-utils.ts +21 -0
  686. package/src/plugin-api/index.ts +9 -4
  687. package/src/plugin-api/model-profiles.test.ts +123 -0
  688. package/src/plugin-api/model-profiles.ts +5 -1
  689. package/src/plugin-api/vision-support.test.ts +149 -0
  690. package/src/plugin-api/vision-support.ts +78 -0
  691. package/src/plugins/defaults/compaction/window-manager.ts +45 -64
  692. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +13 -4
  693. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +302 -0
  694. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +103 -0
  695. package/src/plugins/defaults/image-fallback/package.json +14 -0
  696. package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
  697. package/src/plugins/defaults/image-fallback/src/image-persist.ts +59 -0
  698. package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
  699. package/src/plugins/defaults/index.ts +23 -0
  700. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +14 -1
  701. package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
  702. package/src/plugins/external-plugin-loader.ts +47 -6
  703. package/src/plugins/mtime-cache.ts +772 -0
  704. package/src/plugins/pipeline.ts +7 -2
  705. package/src/plugins/registry.ts +16 -5
  706. package/src/plugins/user-loader.ts +22 -76
  707. package/src/prompts/persona-resolver.ts +29 -11
  708. package/src/prompts/system-prompt.ts +1 -1
  709. package/src/prompts/templates/system-sections.ts +4 -4
  710. package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
  711. package/src/providers/anthropic/client.ts +254 -185
  712. package/src/providers/call-site-routing.ts +10 -0
  713. package/src/providers/gemini/client.ts +43 -0
  714. package/src/providers/inference/adapter-factory.ts +6 -0
  715. package/src/providers/inference/connections.ts +6 -1
  716. package/src/providers/model-catalog.ts +37 -0
  717. package/src/providers/platform-proxy/constants.ts +5 -0
  718. package/src/providers/ratelimit.ts +9 -0
  719. package/src/providers/retry.ts +10 -0
  720. package/src/providers/together/client.ts +35 -0
  721. package/src/providers/types.ts +16 -0
  722. package/src/providers/usage-tracking.ts +7 -0
  723. package/src/runtime/AGENTS.md +9 -1
  724. package/src/runtime/__tests__/agent-wake.test.ts +259 -4
  725. package/src/runtime/__tests__/slack-block-formatting.test.ts +39 -10
  726. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +417 -0
  727. package/src/runtime/actor-trust-resolver.ts +8 -16
  728. package/src/runtime/agent-wake.ts +183 -60
  729. package/src/runtime/channel-reply-delivery.ts +6 -3
  730. package/src/runtime/guardian-decision-types.ts +3 -22
  731. package/src/runtime/http-server.ts +1 -15
  732. package/src/runtime/invite-redemption-service.ts +155 -6
  733. package/src/runtime/invite-service.ts +113 -62
  734. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
  735. package/src/runtime/routes/__tests__/acp-routes.test.ts +1 -1
  736. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -1
  737. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +277 -0
  738. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +140 -0
  739. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +26 -7
  740. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +14 -10
  741. package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +164 -0
  742. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  743. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +1 -1
  744. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +8 -8
  745. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +1 -1
  746. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +1 -3
  747. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +240 -0
  748. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +4 -0
  749. package/src/runtime/routes/__tests__/plugins-routes.test.ts +143 -0
  750. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -1
  751. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +1 -1
  752. package/src/runtime/routes/acp-routes-list.test.ts +4 -0
  753. package/src/runtime/routes/acp-routes.test.ts +5 -6
  754. package/src/runtime/routes/attachment-routes.ts +21 -17
  755. package/src/runtime/routes/browser-routes.ts +19 -1
  756. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -9
  757. package/src/runtime/routes/channel-verification-routes.ts +12 -1
  758. package/src/runtime/routes/contact-routes.ts +275 -164
  759. package/src/runtime/routes/conversation-query-routes.ts +15 -5
  760. package/src/runtime/routes/conversation-routes.ts +24 -3
  761. package/src/runtime/routes/conversation-starter-routes.ts +7 -8
  762. package/src/runtime/routes/guardian-approval-interception.ts +13 -274
  763. package/src/runtime/routes/inbound-message-handler.ts +20 -15
  764. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +285 -0
  765. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +45 -34
  766. package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
  767. package/src/runtime/routes/log-export-routes.ts +2 -2
  768. package/src/runtime/routes/memory-eval-routes.ts +92 -0
  769. package/src/runtime/routes/memory-item-routes.test.ts +12 -11
  770. package/src/runtime/routes/migration-routes.ts +51 -40
  771. package/src/runtime/routes/plugins-routes.ts +164 -8
  772. package/src/runtime/routes/schedule-routes.ts +1 -0
  773. package/src/runtime/routes/usage-routes.ts +3 -0
  774. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  775. package/src/runtime/slack-block-formatting.ts +46 -48
  776. package/src/runtime/trust-verdict-consumer.ts +172 -0
  777. package/src/schedule/scheduler.ts +6 -9
  778. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  779. package/src/tools/ask-question/ask-question-tool.test.ts +60 -52
  780. package/src/tools/ask-question/ask-question-tool.ts +14 -73
  781. package/src/tools/browser/__tests__/browser-status.test.ts +20 -0
  782. package/src/tools/browser/browser-execution.ts +16 -4
  783. package/src/tools/document/document-comment-tool.test.ts +1 -1
  784. package/src/tools/executor.ts +15 -3
  785. package/src/tools/host-terminal/host-shell.ts +28 -9
  786. package/src/tools/memory/register.test.ts +32 -0
  787. package/src/tools/skills/load.ts +43 -2
  788. package/src/tools/subagent/spawn.ts +4 -10
  789. package/src/tools/terminal/shell.ts +16 -5
  790. package/src/tools/types.ts +1 -0
  791. package/src/util/fs-watcher-error.ts +36 -0
  792. package/src/util/logs-db-path.ts +22 -0
  793. package/src/util/memory-db-path.ts +23 -0
  794. package/src/watcher/providers/gmail.ts +7 -2
  795. package/src/workflows/engine-integration.test.ts +1 -1
  796. package/src/workflows/engine.test.ts +1 -1
  797. package/src/workflows/engine.ts +22 -0
  798. package/src/workflows/fanout-load.test.ts +1 -1
  799. package/src/workflows/journal-store.test.ts +1 -1
  800. package/src/workflows/leaf-runner.test.ts +40 -1
  801. package/src/workflows/leaf-runner.ts +26 -1
  802. package/src/workspace/git-service.ts +144 -29
  803. package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +121 -0
  804. package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +82 -0
  805. package/src/workspace/migrations/registry.ts +4 -0
  806. package/src/workspace/migrations/runner.ts +32 -2
  807. package/src/__tests__/access-request-decision.test.ts +0 -375
  808. package/src/__tests__/guardian-grant-minting.test.ts +0 -607
  809. package/src/__tests__/plugin-source-watcher.test.ts +0 -302
  810. package/src/api/events/turn-profile-auto-routed.ts +0 -28
  811. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +0 -107
  812. package/src/daemon/plugin-source-watcher.ts +0 -278
  813. package/src/daemon/switch-inference-profile-tool.ts +0 -62
  814. package/src/memory/guardian-approvals.ts +0 -361
  815. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +0 -66
  816. package/src/memory/migrations/038-actor-token-records.ts +0 -45
  817. package/src/memory/migrations/039-actor-refresh-token-records.ts +0 -57
  818. package/src/memory/migrations/103-complex-migrations.ts +0 -23
  819. package/src/memory/migrations/113-late-migrations.ts +0 -30
  820. package/src/memory/migrations/index.ts +0 -301
  821. package/src/runtime/routes/access-request-decision.ts +0 -297
  822. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -963
  823. package/src/runtime/routes/channel-guardian-routes.ts +0 -19
  824. package/src/runtime/routes/guardian-expiry-sweep.ts +0 -132
@@ -63,6 +63,26 @@ 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
+
66
86
  import { handleChannelVerificationSession } from "../daemon/handlers/config-channels.js";
67
87
  import type {
68
88
  ChannelVerificationSessionRequest,
@@ -84,12 +104,6 @@ import {
84
104
  import { getDb } from "../memory/db-connection.js";
85
105
  import { initializeDb } from "../memory/db-init.js";
86
106
  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
107
  import {
94
108
  getRateLimit,
95
109
  recordInvalidAttempt,
@@ -133,7 +147,6 @@ afterAll(() => {
133
147
  function resetTables(): void {
134
148
  const db = getDb();
135
149
  db.run("DELETE FROM channel_verification_sessions");
136
- db.run("DELETE FROM channel_guardian_approval_requests");
137
150
  db.run("DELETE FROM channel_guardian_rate_limits");
138
151
  db.run("DELETE FROM contact_channels");
139
152
  db.run("DELETE FROM contacts");
@@ -564,251 +577,6 @@ describe("guardian identity check", () => {
564
577
  // 5. Approval Request CRUD (Store)
565
578
  // ═══════════════════════════════════════════════════════════════════════════
566
579
 
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
580
  // ═══════════════════════════════════════════════════════════════════════════
813
581
  // 6. Verification Rate Limiting (Store)
814
582
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1204,64 +972,6 @@ describe("channel-scoped guardian resolution", () => {
1204
972
  // 9. Assistant-scoped approval request lookups
1205
973
  // ═══════════════════════════════════════════════════════════════════════════
1206
974
 
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
975
  // ═══════════════════════════════════════════════════════════════════════════
1266
976
  // 10. HTTP handler — channel-aware guardian status response
1267
977
  // ═══════════════════════════════════════════════════════════════════════════
@@ -2588,24 +2298,20 @@ describe("outbound voice verification", () => {
2588
2298
  test("resend_outbound before cooldown is rejected", async () => {
2589
2299
  // Start an outbound session first
2590
2300
  broadcastedMessages.length = 0;
2591
- await handleChannelVerificationSession(
2592
- {
2593
- type: "channel_verification_session",
2594
- action: "create_session",
2595
- channel: "phone",
2596
- destination: "+15551234567",
2597
- },
2598
- );
2301
+ await handleChannelVerificationSession({
2302
+ type: "channel_verification_session",
2303
+ action: "create_session",
2304
+ channel: "phone",
2305
+ destination: "+15551234567",
2306
+ });
2599
2307
 
2600
2308
  // Immediately try to resend (before cooldown)
2601
2309
  const { lastResponse } = createResponseReader();
2602
- await handleChannelVerificationSession(
2603
- {
2604
- type: "channel_verification_session",
2605
- action: "resend_session",
2606
- channel: "phone",
2607
- },
2608
- );
2310
+ await handleChannelVerificationSession({
2311
+ type: "channel_verification_session",
2312
+ action: "resend_session",
2313
+ channel: "phone",
2314
+ });
2609
2315
 
2610
2316
  const resp = lastResponse();
2611
2317
  expect(resp).not.toBeNull();
@@ -2616,14 +2322,12 @@ describe("outbound voice verification", () => {
2616
2322
  test("resend_outbound after cooldown succeeds and increments sendCount", async () => {
2617
2323
  // Start an outbound session
2618
2324
  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
- );
2325
+ await handleChannelVerificationSession({
2326
+ type: "channel_verification_session",
2327
+ action: "create_session",
2328
+ channel: "phone",
2329
+ destination: "+15551234567",
2330
+ });
2627
2331
 
2628
2332
  const startResponse = startResp();
2629
2333
  expect(startResponse!.success).toBe(true);
@@ -2640,13 +2344,11 @@ describe("outbound voice verification", () => {
2640
2344
 
2641
2345
  // Now resend should succeed
2642
2346
  const { lastResponse } = createResponseReader();
2643
- await handleChannelVerificationSession(
2644
- {
2645
- type: "channel_verification_session",
2646
- action: "resend_session",
2647
- channel: "phone",
2648
- },
2649
- );
2347
+ await handleChannelVerificationSession({
2348
+ type: "channel_verification_session",
2349
+ action: "resend_session",
2350
+ channel: "phone",
2351
+ });
2650
2352
 
2651
2353
  const resp = lastResponse();
2652
2354
  expect(resp).not.toBeNull();
@@ -2658,14 +2360,12 @@ describe("outbound voice verification", () => {
2658
2360
  test("resend_outbound exceeding max sends is rejected", async () => {
2659
2361
  // Start an outbound session
2660
2362
  broadcastedMessages.length = 0;
2661
- await handleChannelVerificationSession(
2662
- {
2663
- type: "channel_verification_session",
2664
- action: "create_session",
2665
- channel: "phone",
2666
- destination: "+15551234567",
2667
- },
2668
- );
2363
+ await handleChannelVerificationSession({
2364
+ type: "channel_verification_session",
2365
+ action: "create_session",
2366
+ channel: "phone",
2367
+ destination: "+15551234567",
2368
+ });
2669
2369
 
2670
2370
  // Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
2671
2371
  const session = serviceFindActiveSession("phone");
@@ -2679,13 +2379,11 @@ describe("outbound voice verification", () => {
2679
2379
 
2680
2380
  // Resend should be rejected due to max sends
2681
2381
  const { lastResponse } = createResponseReader();
2682
- await handleChannelVerificationSession(
2683
- {
2684
- type: "channel_verification_session",
2685
- action: "resend_session",
2686
- channel: "phone",
2687
- },
2688
- );
2382
+ await handleChannelVerificationSession({
2383
+ type: "channel_verification_session",
2384
+ action: "resend_session",
2385
+ channel: "phone",
2386
+ });
2689
2387
 
2690
2388
  const resp = lastResponse();
2691
2389
  expect(resp).not.toBeNull();
@@ -2696,14 +2394,12 @@ describe("outbound voice verification", () => {
2696
2394
  test("cancel_outbound revokes active session", async () => {
2697
2395
  // Start an outbound session
2698
2396
  broadcastedMessages.length = 0;
2699
- await handleChannelVerificationSession(
2700
- {
2701
- type: "channel_verification_session",
2702
- action: "create_session",
2703
- channel: "phone",
2704
- destination: "+15551234567",
2705
- },
2706
- );
2397
+ await handleChannelVerificationSession({
2398
+ type: "channel_verification_session",
2399
+ action: "create_session",
2400
+ channel: "phone",
2401
+ destination: "+15551234567",
2402
+ });
2707
2403
 
2708
2404
  // Verify session exists
2709
2405
  const sessionBefore = serviceFindActiveSession("phone");
@@ -2711,13 +2407,11 @@ describe("outbound voice verification", () => {
2711
2407
 
2712
2408
  // Cancel it
2713
2409
  const { lastResponse } = createResponseReader();
2714
- await handleChannelVerificationSession(
2715
- {
2716
- type: "channel_verification_session",
2717
- action: "cancel_session",
2718
- channel: "phone",
2719
- },
2720
- );
2410
+ await handleChannelVerificationSession({
2411
+ type: "channel_verification_session",
2412
+ action: "cancel_session",
2413
+ channel: "phone",
2414
+ });
2721
2415
 
2722
2416
  const resp = lastResponse();
2723
2417
  expect(resp).not.toBeNull();
@@ -2780,14 +2474,12 @@ describe("outbound voice verification", () => {
2780
2474
 
2781
2475
  test("start_outbound succeeds for email channel", async () => {
2782
2476
  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
- );
2477
+ await handleChannelVerificationSession({
2478
+ type: "channel_verification_session",
2479
+ action: "create_session",
2480
+ channel: "email",
2481
+ destination: "user@example.com",
2482
+ });
2791
2483
 
2792
2484
  const resp = lastResponse();
2793
2485
  expect(resp).not.toBeNull();
@@ -2797,14 +2489,12 @@ describe("outbound voice verification", () => {
2797
2489
 
2798
2490
  test("create_session without destination falls through to inbound challenge", async () => {
2799
2491
  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
- );
2492
+ await handleChannelVerificationSession({
2493
+ type: "channel_verification_session",
2494
+ action: "create_session",
2495
+ channel: "phone",
2496
+ // no destination — unified create_session creates an inbound challenge
2497
+ });
2808
2498
 
2809
2499
  const resp = lastResponse();
2810
2500
  expect(resp).not.toBeNull();
@@ -2814,14 +2504,12 @@ describe("outbound voice verification", () => {
2814
2504
 
2815
2505
  test("start_outbound rejects unparseable phone number", async () => {
2816
2506
  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
- );
2507
+ await handleChannelVerificationSession({
2508
+ type: "channel_verification_session",
2509
+ action: "create_session",
2510
+ channel: "phone",
2511
+ destination: "not-a-phone",
2512
+ });
2825
2513
 
2826
2514
  const resp = lastResponse();
2827
2515
  expect(resp).not.toBeNull();
@@ -2831,14 +2519,12 @@ describe("outbound voice verification", () => {
2831
2519
 
2832
2520
  test("start_outbound normalizes formatted phone number for voice", async () => {
2833
2521
  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
- );
2522
+ await handleChannelVerificationSession({
2523
+ type: "channel_verification_session",
2524
+ action: "create_session",
2525
+ channel: "phone",
2526
+ destination: "(555) 123-4567",
2527
+ });
2842
2528
 
2843
2529
  const resp = lastResponse();
2844
2530
  expect(resp).not.toBeNull();
@@ -2863,13 +2549,11 @@ describe("outbound voice verification", () => {
2863
2549
 
2864
2550
  test("cancel_session succeeds even when no active session (idempotent)", async () => {
2865
2551
  const { lastResponse } = createResponseReader();
2866
- await handleChannelVerificationSession(
2867
- {
2868
- type: "channel_verification_session",
2869
- action: "cancel_session",
2870
- channel: "phone",
2871
- },
2872
- );
2552
+ await handleChannelVerificationSession({
2553
+ type: "channel_verification_session",
2554
+ action: "cancel_session",
2555
+ channel: "phone",
2556
+ });
2873
2557
 
2874
2558
  const resp = lastResponse();
2875
2559
  expect(resp).not.toBeNull();
@@ -2888,14 +2572,12 @@ describe("outbound Telegram verification", () => {
2888
2572
 
2889
2573
  test("start_outbound for telegram with handle returns deep link URL, no outbound message", async () => {
2890
2574
  const { lastResponse } = createResponseReader();
2891
- await handleChannelVerificationSession(
2892
- {
2893
- type: "channel_verification_session",
2894
- action: "create_session",
2895
- channel: "telegram",
2896
- destination: "@someuser",
2897
- },
2898
- );
2575
+ await handleChannelVerificationSession({
2576
+ type: "channel_verification_session",
2577
+ action: "create_session",
2578
+ channel: "telegram",
2579
+ destination: "@someuser",
2580
+ });
2899
2581
 
2900
2582
  const resp = lastResponse();
2901
2583
  expect(resp).not.toBeNull();
@@ -2921,14 +2603,12 @@ describe("outbound Telegram verification", () => {
2921
2603
 
2922
2604
  test("start_outbound for telegram with handle (no @ prefix) returns deep link", async () => {
2923
2605
  const { lastResponse } = createResponseReader();
2924
- await handleChannelVerificationSession(
2925
- {
2926
- type: "channel_verification_session",
2927
- action: "create_session",
2928
- channel: "telegram",
2929
- destination: "someuser",
2930
- },
2931
- );
2606
+ await handleChannelVerificationSession({
2607
+ type: "channel_verification_session",
2608
+ action: "create_session",
2609
+ channel: "telegram",
2610
+ destination: "someuser",
2611
+ });
2932
2612
 
2933
2613
  const resp = lastResponse();
2934
2614
  expect(resp).not.toBeNull();
@@ -2941,14 +2621,12 @@ describe("outbound Telegram verification", () => {
2941
2621
 
2942
2622
  test("start_outbound for telegram with known chat ID sends message, no deep link", async () => {
2943
2623
  const { lastResponse } = createResponseReader();
2944
- await handleChannelVerificationSession(
2945
- {
2946
- type: "channel_verification_session",
2947
- action: "create_session",
2948
- channel: "telegram",
2949
- destination: "123456789",
2950
- },
2951
- );
2624
+ await handleChannelVerificationSession({
2625
+ type: "channel_verification_session",
2626
+ action: "create_session",
2627
+ channel: "telegram",
2628
+ destination: "123456789",
2629
+ });
2952
2630
 
2953
2631
  const resp = lastResponse();
2954
2632
  expect(resp).not.toBeNull();
@@ -2980,14 +2658,12 @@ describe("outbound Telegram verification", () => {
2980
2658
  mockBotUsername = undefined;
2981
2659
 
2982
2660
  const { lastResponse } = createResponseReader();
2983
- await handleChannelVerificationSession(
2984
- {
2985
- type: "channel_verification_session",
2986
- action: "create_session",
2987
- channel: "telegram",
2988
- destination: "@someuser",
2989
- },
2990
- );
2661
+ await handleChannelVerificationSession({
2662
+ type: "channel_verification_session",
2663
+ action: "create_session",
2664
+ channel: "telegram",
2665
+ destination: "@someuser",
2666
+ });
2991
2667
 
2992
2668
  const resp = lastResponse();
2993
2669
  expect(resp).not.toBeNull();
@@ -3004,15 +2680,13 @@ describe("outbound Telegram verification", () => {
3004
2680
  });
3005
2681
 
3006
2682
  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
- );
2683
+ await handleChannelVerificationSession({
2684
+ type: "channel_verification_session",
2685
+ action: "create_session",
2686
+ channel: "telegram",
2687
+ destination: "@newuser",
2688
+ rebind: false,
2689
+ });
3016
2690
 
3017
2691
  const resp = lastResponse();
3018
2692
  expect(resp).not.toBeNull();
@@ -3166,14 +2840,12 @@ describe("outbound Telegram verification", () => {
3166
2840
  test("resend_outbound for telegram works with known chat ID", async () => {
3167
2841
  // Start an outbound session with a known chat ID
3168
2842
  broadcastedMessages.length = 0;
3169
- await handleChannelVerificationSession(
3170
- {
3171
- type: "channel_verification_session",
3172
- action: "create_session",
3173
- channel: "telegram",
3174
- destination: "123456789",
3175
- },
3176
- );
2843
+ await handleChannelVerificationSession({
2844
+ type: "channel_verification_session",
2845
+ action: "create_session",
2846
+ channel: "telegram",
2847
+ destination: "123456789",
2848
+ });
3177
2849
 
3178
2850
  // Fast-forward the cooldown
3179
2851
  const session = serviceFindActiveSession("telegram");
@@ -3186,13 +2858,11 @@ describe("outbound Telegram verification", () => {
3186
2858
  );
3187
2859
 
3188
2860
  const { lastResponse } = createResponseReader();
3189
- await handleChannelVerificationSession(
3190
- {
3191
- type: "channel_verification_session",
3192
- action: "resend_session",
3193
- channel: "telegram",
3194
- },
3195
- );
2861
+ await handleChannelVerificationSession({
2862
+ type: "channel_verification_session",
2863
+ action: "resend_session",
2864
+ channel: "telegram",
2865
+ });
3196
2866
 
3197
2867
  const resp = lastResponse();
3198
2868
  expect(resp).not.toBeNull();
@@ -3208,23 +2878,19 @@ describe("outbound Telegram verification", () => {
3208
2878
  test("resend_outbound for pending_bootstrap session is rejected", async () => {
3209
2879
  // Start an outbound session with a handle (pending_bootstrap)
3210
2880
  broadcastedMessages.length = 0;
3211
- await handleChannelVerificationSession(
3212
- {
3213
- type: "channel_verification_session",
3214
- action: "create_session",
3215
- channel: "telegram",
3216
- destination: "@someuser",
3217
- },
3218
- );
2881
+ await handleChannelVerificationSession({
2882
+ type: "channel_verification_session",
2883
+ action: "create_session",
2884
+ channel: "telegram",
2885
+ destination: "@someuser",
2886
+ });
3219
2887
 
3220
2888
  const { lastResponse } = createResponseReader();
3221
- await handleChannelVerificationSession(
3222
- {
3223
- type: "channel_verification_session",
3224
- action: "resend_session",
3225
- channel: "telegram",
3226
- },
3227
- );
2889
+ await handleChannelVerificationSession({
2890
+ type: "channel_verification_session",
2891
+ action: "resend_session",
2892
+ channel: "telegram",
2893
+ });
3228
2894
 
3229
2895
  const resp = lastResponse();
3230
2896
  expect(resp).not.toBeNull();
@@ -3235,26 +2901,22 @@ describe("outbound Telegram verification", () => {
3235
2901
  test("cancel_outbound for telegram revokes session", async () => {
3236
2902
  // Start an outbound session
3237
2903
  broadcastedMessages.length = 0;
3238
- await handleChannelVerificationSession(
3239
- {
3240
- type: "channel_verification_session",
3241
- action: "create_session",
3242
- channel: "telegram",
3243
- destination: "123456789",
3244
- },
3245
- );
2904
+ await handleChannelVerificationSession({
2905
+ type: "channel_verification_session",
2906
+ action: "create_session",
2907
+ channel: "telegram",
2908
+ destination: "123456789",
2909
+ });
3246
2910
 
3247
2911
  const session = serviceFindActiveSession("telegram");
3248
2912
  expect(session).not.toBeNull();
3249
2913
 
3250
2914
  const { lastResponse } = createResponseReader();
3251
- await handleChannelVerificationSession(
3252
- {
3253
- type: "channel_verification_session",
3254
- action: "cancel_session",
3255
- channel: "telegram",
3256
- },
3257
- );
2915
+ await handleChannelVerificationSession({
2916
+ type: "channel_verification_session",
2917
+ action: "cancel_session",
2918
+ channel: "telegram",
2919
+ });
3258
2920
 
3259
2921
  const resp = lastResponse();
3260
2922
  expect(resp).not.toBeNull();
@@ -3295,13 +2957,11 @@ describe("outbound Telegram verification", () => {
3295
2957
 
3296
2958
  test("create_session for telegram without destination falls through to inbound challenge", async () => {
3297
2959
  const { lastResponse } = createResponseReader();
3298
- await handleChannelVerificationSession(
3299
- {
3300
- type: "channel_verification_session",
3301
- action: "create_session",
3302
- channel: "telegram",
3303
- },
3304
- );
2960
+ await handleChannelVerificationSession({
2961
+ type: "channel_verification_session",
2962
+ action: "create_session",
2963
+ channel: "telegram",
2964
+ });
3305
2965
 
3306
2966
  const resp = lastResponse();
3307
2967
  expect(resp).not.toBeNull();
@@ -3312,14 +2972,12 @@ describe("outbound Telegram verification", () => {
3312
2972
  test("rate limits apply to telegram outbound (per-session send cap)", async () => {
3313
2973
  // Start an outbound session with a known chat ID
3314
2974
  broadcastedMessages.length = 0;
3315
- await handleChannelVerificationSession(
3316
- {
3317
- type: "channel_verification_session",
3318
- action: "create_session",
3319
- channel: "telegram",
3320
- destination: "123456789",
3321
- },
3322
- );
2975
+ await handleChannelVerificationSession({
2976
+ type: "channel_verification_session",
2977
+ action: "create_session",
2978
+ channel: "telegram",
2979
+ destination: "123456789",
2980
+ });
3323
2981
 
3324
2982
  // Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
3325
2983
  const session = serviceFindActiveSession("telegram");
@@ -3333,13 +2991,11 @@ describe("outbound Telegram verification", () => {
3333
2991
 
3334
2992
  // Resend should be rejected due to max sends
3335
2993
  const { lastResponse } = createResponseReader();
3336
- await handleChannelVerificationSession(
3337
- {
3338
- type: "channel_verification_session",
3339
- action: "resend_session",
3340
- channel: "telegram",
3341
- },
3342
- );
2994
+ await handleChannelVerificationSession({
2995
+ type: "channel_verification_session",
2996
+ action: "resend_session",
2997
+ channel: "telegram",
2998
+ });
3343
2999
 
3344
3000
  const resp = lastResponse();
3345
3001
  expect(resp).not.toBeNull();
@@ -3350,24 +3006,20 @@ describe("outbound Telegram verification", () => {
3350
3006
  test("rate limits apply to telegram outbound (cooldown)", async () => {
3351
3007
  // Start an outbound session with a known chat ID
3352
3008
  broadcastedMessages.length = 0;
3353
- await handleChannelVerificationSession(
3354
- {
3355
- type: "channel_verification_session",
3356
- action: "create_session",
3357
- channel: "telegram",
3358
- destination: "123456789",
3359
- },
3360
- );
3009
+ await handleChannelVerificationSession({
3010
+ type: "channel_verification_session",
3011
+ action: "create_session",
3012
+ channel: "telegram",
3013
+ destination: "123456789",
3014
+ });
3361
3015
 
3362
3016
  // Immediately try to resend (before cooldown)
3363
3017
  const { lastResponse } = createResponseReader();
3364
- await handleChannelVerificationSession(
3365
- {
3366
- type: "channel_verification_session",
3367
- action: "resend_session",
3368
- channel: "telegram",
3369
- },
3370
- );
3018
+ await handleChannelVerificationSession({
3019
+ type: "channel_verification_session",
3020
+ action: "resend_session",
3021
+ channel: "telegram",
3022
+ });
3371
3023
 
3372
3024
  const resp = lastResponse();
3373
3025
  expect(resp).not.toBeNull();
@@ -3387,14 +3039,12 @@ describe("outbound voice verification", () => {
3387
3039
 
3388
3040
  test("start_outbound for voice creates session with 6-digit code and initiates call", async () => {
3389
3041
  const { lastResponse } = createResponseReader();
3390
- await handleChannelVerificationSession(
3391
- {
3392
- type: "channel_verification_session",
3393
- action: "create_session",
3394
- channel: "phone",
3395
- destination: "+15551234567",
3396
- },
3397
- );
3042
+ await handleChannelVerificationSession({
3043
+ type: "channel_verification_session",
3044
+ action: "create_session",
3045
+ channel: "phone",
3046
+ destination: "+15551234567",
3047
+ });
3398
3048
 
3399
3049
  const resp = lastResponse();
3400
3050
  expect(resp).not.toBeNull();
@@ -3427,14 +3077,12 @@ describe("outbound voice verification", () => {
3427
3077
 
3428
3078
  test("start_outbound for voice rejects unparseable phone number", async () => {
3429
3079
  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
- );
3080
+ await handleChannelVerificationSession({
3081
+ type: "channel_verification_session",
3082
+ action: "create_session",
3083
+ channel: "phone",
3084
+ destination: "not-a-phone",
3085
+ });
3438
3086
 
3439
3087
  const resp = lastResponse();
3440
3088
  expect(resp).not.toBeNull();
@@ -3444,14 +3092,12 @@ describe("outbound voice verification", () => {
3444
3092
 
3445
3093
  test("start_outbound for voice normalizes formatted phone number", async () => {
3446
3094
  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
- );
3095
+ await handleChannelVerificationSession({
3096
+ type: "channel_verification_session",
3097
+ action: "create_session",
3098
+ channel: "phone",
3099
+ destination: "555-123-4567",
3100
+ });
3455
3101
 
3456
3102
  const resp = lastResponse();
3457
3103
  expect(resp).not.toBeNull();
@@ -3485,15 +3131,13 @@ describe("outbound voice verification", () => {
3485
3131
  });
3486
3132
 
3487
3133
  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
- );
3134
+ await handleChannelVerificationSession({
3135
+ type: "channel_verification_session",
3136
+ action: "create_session",
3137
+ channel: "phone",
3138
+ destination: "+15559876543",
3139
+ rebind: false,
3140
+ });
3497
3141
 
3498
3142
  const resp = lastResponse();
3499
3143
  expect(resp).not.toBeNull();
@@ -3504,24 +3148,20 @@ describe("outbound voice verification", () => {
3504
3148
  test("resend_outbound for voice initiates a new call with cooldown check", async () => {
3505
3149
  // Start an outbound session first
3506
3150
  broadcastedMessages.length = 0;
3507
- await handleChannelVerificationSession(
3508
- {
3509
- type: "channel_verification_session",
3510
- action: "create_session",
3511
- channel: "phone",
3512
- destination: "+15551234567",
3513
- },
3514
- );
3151
+ await handleChannelVerificationSession({
3152
+ type: "channel_verification_session",
3153
+ action: "create_session",
3154
+ channel: "phone",
3155
+ destination: "+15551234567",
3156
+ });
3515
3157
 
3516
3158
  // Immediately try to resend (before cooldown)
3517
3159
  const { lastResponse } = createResponseReader();
3518
- await handleChannelVerificationSession(
3519
- {
3520
- type: "channel_verification_session",
3521
- action: "resend_session",
3522
- channel: "phone",
3523
- },
3524
- );
3160
+ await handleChannelVerificationSession({
3161
+ type: "channel_verification_session",
3162
+ action: "resend_session",
3163
+ channel: "phone",
3164
+ });
3525
3165
 
3526
3166
  const resp = lastResponse();
3527
3167
  expect(resp).not.toBeNull();
@@ -3532,24 +3172,20 @@ describe("outbound voice verification", () => {
3532
3172
  test("cancel_outbound for voice cancels session", async () => {
3533
3173
  // Start an outbound session first
3534
3174
  broadcastedMessages.length = 0;
3535
- await handleChannelVerificationSession(
3536
- {
3537
- type: "channel_verification_session",
3538
- action: "create_session",
3539
- channel: "phone",
3540
- destination: "+15551234567",
3541
- },
3542
- );
3175
+ await handleChannelVerificationSession({
3176
+ type: "channel_verification_session",
3177
+ action: "create_session",
3178
+ channel: "phone",
3179
+ destination: "+15551234567",
3180
+ });
3543
3181
 
3544
3182
  // Cancel the session
3545
3183
  const { lastResponse } = createResponseReader();
3546
- await handleChannelVerificationSession(
3547
- {
3548
- type: "channel_verification_session",
3549
- action: "cancel_session",
3550
- channel: "phone",
3551
- },
3552
- );
3184
+ await handleChannelVerificationSession({
3185
+ type: "channel_verification_session",
3186
+ action: "cancel_session",
3187
+ channel: "phone",
3188
+ });
3553
3189
 
3554
3190
  const resp = lastResponse();
3555
3191
  expect(resp).not.toBeNull();
@@ -3583,14 +3219,12 @@ describe("outbound voice verification", () => {
3583
3219
  }
3584
3220
 
3585
3221
  const { lastResponse } = createResponseReader();
3586
- await handleChannelVerificationSession(
3587
- {
3588
- type: "channel_verification_session",
3589
- action: "create_session",
3590
- channel: "phone",
3591
- destination: "+15551234567",
3592
- },
3593
- );
3222
+ await handleChannelVerificationSession({
3223
+ type: "channel_verification_session",
3224
+ action: "create_session",
3225
+ channel: "phone",
3226
+ destination: "+15551234567",
3227
+ });
3594
3228
 
3595
3229
  const resp = lastResponse();
3596
3230
  expect(resp).not.toBeNull();
@@ -3600,13 +3234,11 @@ describe("outbound voice verification", () => {
3600
3234
 
3601
3235
  test("create_session for voice without destination falls through to inbound challenge", async () => {
3602
3236
  const { lastResponse } = createResponseReader();
3603
- await handleChannelVerificationSession(
3604
- {
3605
- type: "channel_verification_session",
3606
- action: "create_session",
3607
- channel: "phone",
3608
- },
3609
- );
3237
+ await handleChannelVerificationSession({
3238
+ type: "channel_verification_session",
3239
+ action: "create_session",
3240
+ channel: "phone",
3241
+ });
3610
3242
 
3611
3243
  const resp = lastResponse();
3612
3244
  expect(resp).not.toBeNull();
@@ -3634,14 +3266,12 @@ describe("M1–M4 hardening coverage", () => {
3634
3266
 
3635
3267
  test("start_outbound for voice response includes secret", async () => {
3636
3268
  const { lastResponse } = createResponseReader();
3637
- await handleChannelVerificationSession(
3638
- {
3639
- type: "channel_verification_session",
3640
- action: "create_session",
3641
- channel: "phone",
3642
- destination: "+15551234567",
3643
- },
3644
- );
3269
+ await handleChannelVerificationSession({
3270
+ type: "channel_verification_session",
3271
+ action: "create_session",
3272
+ channel: "phone",
3273
+ destination: "+15551234567",
3274
+ });
3645
3275
 
3646
3276
  const resp = lastResponse();
3647
3277
  expect(resp).not.toBeNull();
@@ -3656,14 +3286,12 @@ describe("M1–M4 hardening coverage", () => {
3656
3286
  test("resend_outbound for voice response includes secret", async () => {
3657
3287
  // Start a session first
3658
3288
  broadcastedMessages.length = 0;
3659
- await handleChannelVerificationSession(
3660
- {
3661
- type: "channel_verification_session",
3662
- action: "create_session",
3663
- channel: "phone",
3664
- destination: "+15551234567",
3665
- },
3666
- );
3289
+ await handleChannelVerificationSession({
3290
+ type: "channel_verification_session",
3291
+ action: "create_session",
3292
+ channel: "phone",
3293
+ destination: "+15551234567",
3294
+ });
3667
3295
 
3668
3296
  // Move past cooldown
3669
3297
  const session = serviceFindActiveSession("phone");
@@ -3677,13 +3305,11 @@ describe("M1–M4 hardening coverage", () => {
3677
3305
 
3678
3306
  // Resend
3679
3307
  const { lastResponse } = createResponseReader();
3680
- await handleChannelVerificationSession(
3681
- {
3682
- type: "channel_verification_session",
3683
- action: "resend_session",
3684
- channel: "phone",
3685
- },
3686
- );
3308
+ await handleChannelVerificationSession({
3309
+ type: "channel_verification_session",
3310
+ action: "resend_session",
3311
+ channel: "phone",
3312
+ });
3687
3313
 
3688
3314
  const resp = lastResponse();
3689
3315
  expect(resp).not.toBeNull();
@@ -3697,14 +3323,12 @@ describe("M1–M4 hardening coverage", () => {
3697
3323
 
3698
3324
  test("start_outbound for Telegram bootstrap (handle) does NOT return secret", async () => {
3699
3325
  const { lastResponse } = createResponseReader();
3700
- await handleChannelVerificationSession(
3701
- {
3702
- type: "channel_verification_session",
3703
- action: "create_session",
3704
- channel: "telegram",
3705
- destination: "@someuser",
3706
- },
3707
- );
3326
+ await handleChannelVerificationSession({
3327
+ type: "channel_verification_session",
3328
+ action: "create_session",
3329
+ channel: "telegram",
3330
+ destination: "@someuser",
3331
+ });
3708
3332
 
3709
3333
  const resp = lastResponse();
3710
3334
  expect(resp).not.toBeNull();