@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.2

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 (430) hide show
  1. package/bun.lock +0 -20
  2. package/docs/workspace-tools.md +33 -42
  3. package/eslint-rules/cli-no-daemon-internals.js +0 -6
  4. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
  5. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
  6. package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
  7. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
  8. package/node_modules/@vellumai/service-contracts/package.json +0 -1
  9. package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
  10. package/openapi.yaml +0 -155
  11. package/package.json +1 -4
  12. package/scripts/test.sh +15 -36
  13. package/src/__tests__/actor-token-service.test.ts +14 -36
  14. package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
  15. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
  16. package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
  17. package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
  18. package/src/__tests__/annotate-risk-options.test.ts +0 -2
  19. package/src/__tests__/approval-cascade.test.ts +0 -2
  20. package/src/__tests__/assistant-attachments.test.ts +0 -42
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
  22. package/src/__tests__/btw-routes.test.ts +0 -2
  23. package/src/__tests__/build-persisted-content.test.ts +0 -2
  24. package/src/__tests__/call-controller.test.ts +0 -19
  25. package/src/__tests__/channel-guardian.test.ts +58 -94
  26. package/src/__tests__/channel-reply-delivery.test.ts +0 -2
  27. package/src/__tests__/compaction-events.test.ts +0 -2
  28. package/src/__tests__/compaction.benchmark.test.ts +0 -2
  29. package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
  30. package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
  31. package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
  32. package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
  33. package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
  34. package/src/__tests__/config-loader-backfill.test.ts +10 -123
  35. package/src/__tests__/config-schema.test.ts +0 -1
  36. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
  37. package/src/__tests__/contacts-relay-reads.test.ts +15 -13
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
  39. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
  40. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
  41. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  42. package/src/__tests__/conversation-agent-loop.test.ts +0 -134
  43. package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
  44. package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
  45. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
  46. package/src/__tests__/conversation-history-web-search.test.ts +0 -2
  47. package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
  48. package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
  49. package/src/__tests__/conversation-pairing.test.ts +0 -2
  50. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +0 -2
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
  53. package/src/__tests__/conversation-queue.test.ts +0 -91
  54. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
  56. package/src/__tests__/conversation-slash-queue.test.ts +0 -2
  57. package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
  58. package/src/__tests__/conversation-speed-override.test.ts +0 -2
  59. package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
  60. package/src/__tests__/conversation-title-service.test.ts +0 -2
  61. package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
  62. package/src/__tests__/conversation-usage.test.ts +0 -2
  63. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
  64. package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
  65. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
  66. package/src/__tests__/credential-security-invariants.test.ts +1 -1
  67. package/src/__tests__/db-migration-rollback.test.ts +171 -205
  68. package/src/__tests__/db-test-helpers.ts +4 -5
  69. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
  70. package/src/__tests__/disk-pressure-guard.test.ts +0 -41
  71. package/src/__tests__/dm-persistence.test.ts +0 -2
  72. package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
  73. package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
  74. package/src/__tests__/exploration-drift-hook.test.ts +2 -3
  75. package/src/__tests__/filing-service.test.ts +0 -2
  76. package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
  77. package/src/__tests__/guardian-dispatch.test.ts +1 -95
  78. package/src/__tests__/guardian-outbound-http.test.ts +0 -13
  79. package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
  80. package/src/__tests__/heartbeat-service.test.ts +0 -2
  81. package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
  82. package/src/__tests__/host-app-control-routes.test.ts +30 -24
  83. package/src/__tests__/host-bash-routes.test.ts +41 -31
  84. package/src/__tests__/host-browser-routes.test.ts +32 -26
  85. package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
  86. package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
  87. package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
  88. package/src/__tests__/http-user-message-parity.test.ts +8 -290
  89. package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
  90. package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
  91. package/src/__tests__/invite-redemption-service.test.ts +0 -198
  92. package/src/__tests__/llm-context-normalization.test.ts +0 -105
  93. package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
  94. package/src/__tests__/llm-usage-store.test.ts +0 -25
  95. package/src/__tests__/mcp-health-check.test.ts +1 -2
  96. package/src/__tests__/media-stream-server-integration.test.ts +0 -127
  97. package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
  98. package/src/__tests__/messaging-send-tool.test.ts +0 -2
  99. package/src/__tests__/migration-import-from-url.test.ts +2 -2
  100. package/src/__tests__/mtime-cache.test.ts +5 -146
  101. package/src/__tests__/native-web-search.test.ts +0 -2
  102. package/src/__tests__/non-member-access-request.test.ts +17 -189
  103. package/src/__tests__/notification-broadcaster.test.ts +0 -4
  104. package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
  105. package/src/__tests__/notification-deep-link.test.ts +0 -6
  106. package/src/__tests__/notification-guardian-path.test.ts +0 -19
  107. package/src/__tests__/openai-provider.test.ts +12 -22
  108. package/src/__tests__/openai-responses-provider.test.ts +2 -12
  109. package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
  110. package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
  111. package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
  112. package/src/__tests__/plugin-bootstrap.test.ts +73 -3
  113. package/src/__tests__/plugin-route-contribution.test.ts +17 -4
  114. package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
  115. package/src/__tests__/plugin-types.test.ts +2 -0
  116. package/src/__tests__/process-message-background-slack.test.ts +0 -2
  117. package/src/__tests__/process-message-display-content.test.ts +0 -2
  118. package/src/__tests__/provider-error-scenarios.test.ts +4 -5
  119. package/src/__tests__/provider-usage-tracking.test.ts +0 -39
  120. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
  121. package/src/__tests__/registry.test.ts +1 -4
  122. package/src/__tests__/relay-server.test.ts +25 -694
  123. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
  124. package/src/__tests__/secret-ingress-http.test.ts +0 -14
  125. package/src/__tests__/send-endpoint-busy.test.ts +8 -30
  126. package/src/__tests__/skills.test.ts +0 -44
  127. package/src/__tests__/slack-inbound-verification.test.ts +2 -47
  128. package/src/__tests__/stt-hints.test.ts +13 -44
  129. package/src/__tests__/subagent-detail.test.ts +0 -27
  130. package/src/__tests__/subagent-disposal.test.ts +0 -65
  131. package/src/__tests__/subagent-notify-parent.test.ts +0 -2
  132. package/src/__tests__/subagent-role-registry.test.ts +2 -7
  133. package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
  134. package/src/__tests__/subagent-tools.test.ts +0 -2
  135. package/src/__tests__/suggestion-routes.test.ts +0 -2
  136. package/src/__tests__/title-generate-hook.test.ts +0 -2
  137. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
  138. package/src/__tests__/tool-executor.test.ts +11 -16
  139. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
  140. package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
  141. package/src/__tests__/tool-start-timestamp.test.ts +0 -2
  142. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
  143. package/src/__tests__/twilio-routes.test.ts +0 -96
  144. package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
  145. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  146. package/src/__tests__/voice-invite-redemption.test.ts +0 -33
  147. package/src/__tests__/web-search-backend-failure.test.ts +0 -2
  148. package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
  149. package/src/__tests__/workspace-tool-loader.test.ts +2 -195
  150. package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
  151. package/src/agent/loop.ts +0 -56
  152. package/src/api/index.ts +1 -19
  153. package/src/api/responses/llm-request-log-entry.ts +0 -29
  154. package/src/api/responses/subagent-detail.ts +0 -17
  155. package/src/api/surfaces.ts +3 -39
  156. package/src/approvals/guardian-request-resolvers.ts +11 -1
  157. package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
  158. package/src/calls/call-domain.ts +3 -3
  159. package/src/calls/guardian-dispatch.ts +8 -10
  160. package/src/calls/inbound-trust-reader.ts +1 -17
  161. package/src/calls/media-stream-server.ts +0 -21
  162. package/src/calls/relay-server.ts +50 -167
  163. package/src/calls/relay-setup-router.ts +7 -37
  164. package/src/calls/relay-verification.ts +4 -4
  165. package/src/calls/stt-hints.ts +12 -9
  166. package/src/calls/twilio-routes.ts +4 -14
  167. package/src/channels/types.ts +20 -10
  168. package/src/cli/commands/__tests__/cache.test.ts +1 -8
  169. package/src/cli/commands/cache.ts +181 -194
  170. package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
  171. package/src/cli/commands/db/status.ts +1 -37
  172. package/src/cli/commands/mcp.ts +218 -252
  173. package/src/cli/commands/memory/index.ts +0 -2
  174. package/src/cli/commands/plugins.ts +3 -75
  175. package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
  176. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
  177. package/src/cli/lib/list-installed-plugins.ts +1 -179
  178. package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
  179. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
  180. package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
  181. package/src/config/bundled-skills/subagent/SKILL.md +1 -1
  182. package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
  183. package/src/config/feature-flag-registry.json +13 -5
  184. package/src/config/loader.ts +5 -38
  185. package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
  186. package/src/config/schemas/memory-lifecycle.ts +0 -12
  187. package/src/config/schemas/memory-v3.ts +0 -7
  188. package/src/config/schemas/memory.ts +0 -4
  189. package/src/config/schemas/timeouts.ts +0 -8
  190. package/src/config/seed-inference-profiles.ts +11 -21
  191. package/src/config/skills.ts +5 -27
  192. package/src/config/sync-gated-profiles.ts +13 -12
  193. package/src/contacts/contacts-write.ts +0 -3
  194. package/src/daemon/assistant-attachments.ts +4 -27
  195. package/src/daemon/conversation-agent-loop.ts +0 -28
  196. package/src/daemon/conversation-process.ts +16 -35
  197. package/src/daemon/conversation-surfaces.ts +38 -111
  198. package/src/daemon/conversation-tool-setup.ts +16 -50
  199. package/src/daemon/conversation.ts +1 -13
  200. package/src/daemon/disk-pressure-guard.ts +2 -12
  201. package/src/daemon/event-loop-watchdog.ts +1 -28
  202. package/src/daemon/external-plugins-bootstrap.ts +34 -4
  203. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
  204. package/src/daemon/handlers/config-a2a.ts +14 -6
  205. package/src/daemon/handlers/config-channels.ts +22 -78
  206. package/src/daemon/handlers/conversations.ts +0 -77
  207. package/src/daemon/lifecycle.ts +0 -4
  208. package/src/daemon/mcp-reload-service.ts +0 -10
  209. package/src/daemon/memory-v2-startup.test.ts +0 -72
  210. package/src/daemon/memory-v2-startup.ts +19 -87
  211. package/src/daemon/message-types/conversations.ts +0 -2
  212. package/src/daemon/message-types/surfaces.ts +12 -12
  213. package/src/daemon/server.ts +4 -0
  214. package/src/daemon/shutdown-handlers.ts +0 -20
  215. package/src/daemon/tool-setup-types.ts +0 -9
  216. package/src/daemon/workspace-tools-watcher.ts +328 -0
  217. package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
  218. package/src/ipc/assistant-server.ts +2 -2
  219. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  220. package/src/mcp/client.ts +1 -15
  221. package/src/mcp/mcp-auth-orchestrator.ts +1 -6
  222. package/src/mcp/mcp-oauth-provider.ts +8 -19
  223. package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
  224. package/src/memory/conversation-crud.ts +0 -38
  225. package/src/memory/db-connection.ts +3 -22
  226. package/src/memory/db-init.ts +502 -36
  227. package/src/memory/db-singleton.ts +4 -6
  228. package/src/memory/jobs-worker.ts +0 -58
  229. package/src/memory/llm-request-log-store.ts +1 -26
  230. package/src/memory/llm-usage-store.ts +20 -48
  231. package/src/memory/memory-retrospective-job.ts +8 -9
  232. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
  233. package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
  234. package/src/memory/migrations/registry.ts +573 -0
  235. package/src/memory/migrations/run-migrations.ts +6 -90
  236. package/src/memory/migrations/validate-migration-state.ts +66 -101
  237. package/src/memory/schema/conversations.ts +0 -9
  238. package/src/memory/schema/infrastructure.ts +0 -20
  239. package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
  240. package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
  241. package/src/memory/v2/cli-command-store.ts +38 -75
  242. package/src/memory/v2/prompts/consolidation.ts +82 -13
  243. package/src/memory/v2/prompts/router.ts +93 -21
  244. package/src/memory/v2/skill-store.ts +31 -68
  245. package/src/notifications/__tests__/broadcaster.test.ts +8 -16
  246. package/src/notifications/__tests__/decision-engine.test.ts +9 -78
  247. package/src/notifications/broadcaster.ts +1 -8
  248. package/src/notifications/decision-engine.ts +7 -15
  249. package/src/notifications/destination-resolver.ts +24 -68
  250. package/src/notifications/emit-signal.ts +14 -39
  251. package/src/permissions/question-prompter.test.ts +1 -1
  252. package/src/permissions/question-prompter.ts +4 -7
  253. package/src/plugin-api/index.ts +6 -6
  254. package/src/plugin-api/types.ts +5 -3
  255. package/src/plugin-api/vision-support.test.ts +4 -28
  256. package/src/plugin-api/vision-support.ts +31 -66
  257. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
  258. package/src/plugins/defaults/advisor/consult.ts +6 -110
  259. package/src/plugins/defaults/advisor/steering.ts +2 -14
  260. package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
  261. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
  262. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
  263. package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
  264. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
  265. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
  266. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
  267. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
  268. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
  269. package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
  270. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
  271. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
  272. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
  273. package/src/plugins/mtime-cache.ts +291 -76
  274. package/src/plugins/pipeline.ts +13 -111
  275. package/src/plugins/types.ts +2 -0
  276. package/src/providers/anthropic/client.ts +0 -5
  277. package/src/providers/call-site-routing.ts +0 -4
  278. package/src/providers/model-catalog.ts +0 -16
  279. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  280. package/src/providers/openai/chat-completions-provider.ts +83 -37
  281. package/src/providers/openai/responses-provider.ts +46 -50
  282. package/src/providers/openrouter/client.ts +0 -5
  283. package/src/providers/provider-send-message.ts +0 -4
  284. package/src/providers/ratelimit.ts +0 -4
  285. package/src/providers/retry.ts +0 -4
  286. package/src/providers/types.ts +0 -9
  287. package/src/providers/usage-tracking.ts +0 -4
  288. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
  289. package/src/runtime/access-request-helper.ts +39 -19
  290. package/src/runtime/actor-trust-resolver.ts +2 -2
  291. package/src/runtime/assistant-event-hub.ts +1 -1
  292. package/src/runtime/assistant-stream-state.ts +2 -9
  293. package/src/runtime/auth/require-bound-guardian.ts +11 -21
  294. package/src/runtime/channel-verification-service.ts +31 -56
  295. package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
  296. package/src/runtime/guardian-vellum-migration.ts +7 -66
  297. package/src/runtime/invite-redemption-service.ts +187 -198
  298. package/src/runtime/local-actor-identity.ts +11 -76
  299. package/src/runtime/pending-interactions.ts +1 -11
  300. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
  301. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
  302. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
  303. package/src/runtime/routes/browser-routes.ts +1 -1
  304. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
  305. package/src/runtime/routes/channel-verification-routes.ts +3 -3
  306. package/src/runtime/routes/contact-routes.ts +32 -8
  307. package/src/runtime/routes/conversation-cli-routes.ts +5 -4
  308. package/src/runtime/routes/conversation-list-routes.ts +7 -4
  309. package/src/runtime/routes/conversation-query-routes.ts +0 -72
  310. package/src/runtime/routes/conversation-routes.ts +85 -84
  311. package/src/runtime/routes/events-routes.ts +2 -2
  312. package/src/runtime/routes/global-search-routes.ts +1 -3
  313. package/src/runtime/routes/guardian-action-routes.ts +5 -4
  314. package/src/runtime/routes/host-app-control-routes.ts +4 -5
  315. package/src/runtime/routes/host-bash-routes.ts +4 -5
  316. package/src/runtime/routes/host-browser-routes.ts +11 -9
  317. package/src/runtime/routes/host-cu-routes.ts +4 -5
  318. package/src/runtime/routes/host-file-routes.ts +4 -5
  319. package/src/runtime/routes/host-transfer-routes.ts +6 -6
  320. package/src/runtime/routes/http-adapter.ts +1 -1
  321. package/src/runtime/routes/identity-routes.ts +2 -3
  322. package/src/runtime/routes/inbound-message-handler.ts +5 -5
  323. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
  324. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
  325. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
  326. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
  327. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
  328. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
  329. package/src/runtime/routes/index.ts +0 -2
  330. package/src/runtime/routes/llm-context-normalization.ts +0 -83
  331. package/src/runtime/routes/mcp-auth-routes.ts +19 -171
  332. package/src/runtime/routes/migration-rollback-routes.ts +3 -4
  333. package/src/runtime/routes/migration-routes.ts +1 -4
  334. package/src/runtime/routes/subagents-routes.ts +0 -5
  335. package/src/runtime/routes/surface-action-routes.ts +56 -42
  336. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
  337. package/src/runtime/services/conversation-serializer.ts +9 -7
  338. package/src/runtime/tool-grant-request-helper.ts +3 -3
  339. package/src/runtime/trust-verdict-consumer.ts +9 -85
  340. package/src/runtime/verification-outbound-actions.ts +18 -18
  341. package/src/signals/user-message.ts +0 -16
  342. package/src/subagent/manager.ts +0 -9
  343. package/src/subagent/types.ts +3 -3
  344. package/src/telemetry/types.ts +1 -34
  345. package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
  346. package/src/telemetry/usage-telemetry-reporter.ts +3 -87
  347. package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
  348. package/src/tools/ask-question/ask-question-tool.ts +0 -13
  349. package/src/tools/executor.ts +4 -4
  350. package/src/tools/registry.ts +0 -18
  351. package/src/tools/shared/filesystem/path-policy.ts +5 -12
  352. package/src/tools/tool-approval-handler.ts +1 -1
  353. package/src/tools/tool-defaults.ts +2 -9
  354. package/src/tools/tool-manifest.ts +0 -3
  355. package/src/tools/types.ts +2 -17
  356. package/src/tools/workspace-tools/loader.ts +244 -348
  357. package/src/util/errors.ts +1 -26
  358. package/src/util/platform.ts +0 -5
  359. package/src/workflows/library.test.ts +0 -140
  360. package/src/workflows/library.ts +28 -82
  361. package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
  362. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
  363. package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
  364. package/src/workspace/migrations/registry.ts +0 -2
  365. package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
  366. package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
  367. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
  368. package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
  369. package/src/__tests__/code-search-tool.test.ts +0 -585
  370. package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
  371. package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
  372. package/src/__tests__/plugin-pipeline.test.ts +0 -96
  373. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
  374. package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
  375. package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
  376. package/src/agent/loop-exclusive-tool.test.ts +0 -150
  377. package/src/api/constants/sse-replay.ts +0 -41
  378. package/src/api/events/conversation-notice.ts +0 -26
  379. package/src/approvals/guardian-channel-delivery.ts +0 -30
  380. package/src/approvals/guardian-expiry-notifier.ts +0 -148
  381. package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
  382. package/src/cli/commands/memory/worker.ts +0 -175
  383. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
  384. package/src/config/prune-seeded-callsite-defaults.ts +0 -110
  385. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
  386. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
  387. package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
  388. package/src/contacts/guardian-delivery-reader.ts +0 -223
  389. package/src/contacts/member-write-relay.ts +0 -189
  390. package/src/daemon/conversation-notices.ts +0 -60
  391. package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
  392. package/src/hooks/hook-loader.ts +0 -341
  393. package/src/mcp/mcp-header-store.ts +0 -134
  394. package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
  395. package/src/memory/__tests__/prompt-override.test.ts +0 -192
  396. package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
  397. package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
  398. package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
  399. package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
  400. package/src/memory/prompt-override.ts +0 -129
  401. package/src/memory/steps.ts +0 -573
  402. package/src/memory/watchdog-events-store.ts +0 -87
  403. package/src/memory/worker-control.ts +0 -118
  404. package/src/memory/worker-process.ts +0 -72
  405. package/src/notifications/__tests__/connected-channels.test.ts +0 -114
  406. package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
  407. package/src/onboarding/checkin-event.test.ts +0 -222
  408. package/src/onboarding/checkin-event.ts +0 -321
  409. package/src/onboarding/schedule-checkin.ts +0 -190
  410. package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
  411. package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
  412. package/src/plugins/defaults/advisor/context-pack.ts +0 -288
  413. package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
  414. package/src/plugins/surface-import.ts +0 -121
  415. package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
  416. package/src/providers/openai/api-error-normalization.ts +0 -270
  417. package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
  418. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
  419. package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
  420. package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
  421. package/src/runtime/anchored-guardian.test.ts +0 -156
  422. package/src/runtime/anchored-guardian.ts +0 -135
  423. package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
  424. package/src/runtime/local-principal-trust.ts +0 -52
  425. package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
  426. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
  427. package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
  428. package/src/tools/filesystem/search.ts +0 -543
  429. package/src/util/telemetry-db-path.ts +0 -24
  430. package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
@@ -8,16 +8,15 @@
8
8
 
9
9
  import { randomInt } from "node:crypto";
10
10
 
11
- import type { AdmissionPolicy, TrustVerdict } from "@vellumai/gateway-client";
11
+ import type { AdmissionPolicy } from "@vellumai/gateway-client";
12
12
  import type { ServerWebSocket } from "bun";
13
13
 
14
14
  import {
15
- getGuardianDelivery,
16
- voiceGuardianDisplayName,
17
- } from "../contacts/guardian-delivery-reader.js";
15
+ findGuardianForChannel,
16
+ listGuardianChannels,
17
+ } from "../contacts/contact-store.js";
18
18
  import { getAssistantName } from "../daemon/identity-helpers.js";
19
19
  import type { ServerMessage } from "../daemon/message-protocol.js";
20
- import type { TrustContext } from "../daemon/trust-context.js";
21
20
  import { getCanonicalGuardianRequest } from "../memory/canonical-guardian-store.js";
22
21
  import { addMessage } from "../memory/conversation-crud.js";
23
22
  import { revokeScopedApprovalGrantsForContext } from "../memory/scoped-approval-grants.js";
@@ -27,11 +26,6 @@ import {
27
26
  resolveActorTrust,
28
27
  toTrustContext,
29
28
  } from "../runtime/actor-trust-resolver.js";
30
- import {
31
- trustContextFromVerdict,
32
- verdictHasMemberIdentity,
33
- verdictMemberUnresolvable,
34
- } from "../runtime/trust-verdict-consumer.js";
35
29
  import {
36
30
  composeVerificationVoice,
37
31
  GUARDIAN_VERIFY_TEMPLATE_KEYS,
@@ -56,10 +50,6 @@ import {
56
50
  import { ConversationRelayTransport } from "./call-transport.js";
57
51
  import { getChannelAdmissionPolicy } from "./channel-admission-reader.js";
58
52
  import { finalizeCall } from "./finalize-call.js";
59
- import {
60
- getInboundTrustVerdict,
61
- getPhoneCallerVerdict,
62
- } from "./inbound-trust-reader.js";
63
53
  import {
64
54
  classifyWaitUtterance,
65
55
  emitAccessRequestCallbackHandoff,
@@ -262,10 +252,6 @@ export class RelayConnection {
262
252
  private accessRequestWaitStartedAt: number = 0;
263
253
  private heartbeatSequence = 0;
264
254
 
265
- // Guardian displayName primed from the gateway binding at setup, read
266
- // synchronously by the heartbeat-driven wait-label path.
267
- private primedGuardianDisplayName: string | undefined;
268
-
269
255
  // In-wait prompt handling state
270
256
  private lastInWaitReplyAt = 0;
271
257
  private static readonly IN_WAIT_REPLY_COOLDOWN_MS = 3000;
@@ -275,12 +261,6 @@ export class RelayConnection {
275
261
  private callbackOptIn = false;
276
262
  private callbackHandoffNotified = false;
277
263
 
278
- // True while mid-call trust is being re-resolved (async). handlePrompt defers
279
- // prompts to trustReResolvePending so a verified caller can't start a turn
280
- // under the stale pre-verification trust context during the await window.
281
- private trustReResolving = false;
282
- private trustReResolvePending: RelayPromptMessage[] = [];
283
-
284
264
  constructor(ws: ServerWebSocket<RelayWebSocketData>, callSessionId: string) {
285
265
  this.ws = ws;
286
266
  this.callSessionId = callSessionId;
@@ -601,21 +581,12 @@ export class RelayConnection {
601
581
  const session = getCallSession(this.callSessionId);
602
582
  this.recordSetupBookkeeping(session, msg);
603
583
 
604
- await this.primeGuardianDisplayName();
605
-
606
584
  // Resolve the phone channel's inbound admission floor. The reader fails
607
585
  // open to `null` by contract, so a transport hiccup admits the caller.
608
586
  const admissionPolicy = await getChannelAdmissionPolicy("phone");
609
587
 
610
- // Verdict-first caller trust. routeSetup uses it when present and not
611
- // resolutionFailed, else falls back to local resolution. The reader
612
- // returns null on failure, so a gateway blip keeps the local path.
613
- const isInbound = session?.initiatedFromConversationId == null;
614
- const otherPartyNumber = isInbound ? msg.from : msg.to;
615
- const verdict = await getPhoneCallerVerdict(otherPartyNumber);
616
-
617
588
  try {
618
- await this.routeSetupOutcome(msg, session, admissionPolicy, verdict);
589
+ await this.routeSetupOutcome(msg, session, admissionPolicy);
619
590
  } catch (err) {
620
591
  // Never leave the connection stranded in "setting_up": a setup that
621
592
  // throws before reaching a terminal outcome would otherwise drop every
@@ -644,7 +615,6 @@ export class RelayConnection {
644
615
  msg: RelaySetupMessage,
645
616
  session: ReturnType<typeof getCallSession>,
646
617
  admissionPolicy: AdmissionPolicy | null,
647
- verdict: TrustVerdict | null,
648
618
  ): Promise<void> {
649
619
  const { outcome, resolved } = routeSetup({
650
620
  callSessionId: this.callSessionId,
@@ -653,7 +623,6 @@ export class RelayConnection {
653
623
  to: msg.to,
654
624
  customParameters: msg.customParameters,
655
625
  admissionPolicy,
656
- verdict,
657
626
  });
658
627
 
659
628
  const initialTrustContext = toTrustContext(
@@ -902,95 +871,6 @@ export class RelayConnection {
902
871
  );
903
872
  }
904
873
 
905
- /**
906
- * Re-resolve caller trust after a mid-call verification/activation. Prefers
907
- * the gateway verdict (authoritative right after the gateway updated the
908
- * binding); falls back to local resolution on a missing/failed/unusable
909
- * verdict so a blip never drops the call. Mirrors the setup path's
910
- * verdict-first-with-fallback condition.
911
- */
912
- private async resolveMidCallTrustContext(
913
- assistantId: string,
914
- fromNumber: string,
915
- ): Promise<TrustContext> {
916
- const verdict = await getInboundTrustVerdict({
917
- channelType: "phone",
918
- actorExternalId: fromNumber,
919
- });
920
-
921
- // Only a MEMBERLESS unknown verdict is treated as a stale gateway view and
922
- // falls back to local: the caller was just activated, and invite redemption
923
- // writes the channel assistant-side, so the gateway may not see the member
924
- // yet — local resolution has it. A MEMBERFUL unknown verdict (blocked/revoked
925
- // member, carrying contactId/channelId) is honored so its deny ACL is
926
- // enforced; falling back could lose the gateway's member status if local
927
- // state is stale.
928
- const memberlessUnknown =
929
- verdict?.trustClass === "unknown" && !verdictHasMemberIdentity(verdict);
930
- const usable =
931
- verdict &&
932
- !verdict.resolutionFailed &&
933
- !verdictMemberUnresolvable(verdict) &&
934
- !memberlessUnknown;
935
-
936
- if (usable) {
937
- return trustContextFromVerdict(verdict, {
938
- sourceChannel: "phone",
939
- conversationExternalId: fromNumber,
940
- });
941
- }
942
-
943
- return toTrustContext(
944
- resolveActorTrust({
945
- assistantId,
946
- sourceChannel: "phone",
947
- conversationExternalId: fromNumber,
948
- actorExternalId: fromNumber,
949
- }),
950
- fromNumber,
951
- );
952
- }
953
-
954
- /**
955
- * Re-resolve mid-call trust and install it on the controller, deferring any
956
- * prompt that arrives during the async window. Guards the gap between
957
- * connectionState flipping to "connected" and the upgraded context landing so
958
- * a verified caller never starts a turn under the stale pre-verification
959
- * trust. Clears the guard in a finally and flushes buffered prompts under the
960
- * new context, so an IPC error can't wedge the call.
961
- */
962
- private async reResolveAndApplyTrustContext(
963
- assistantId: string,
964
- fromNumber: string,
965
- ): Promise<void> {
966
- if (!this.controller) return;
967
- this.trustReResolving = true;
968
- try {
969
- const context = await this.resolveMidCallTrustContext(
970
- assistantId,
971
- fromNumber,
972
- );
973
- this.controller.setTrustContext(context);
974
- } finally {
975
- this.trustReResolving = false;
976
- this.flushDeferredPrompts();
977
- }
978
- }
979
-
980
- /**
981
- * Replay prompts buffered while trust was re-resolving. Runs after the
982
- * upgraded context is installed so deferred utterances are answered under the
983
- * correct trust.
984
- */
985
- private flushDeferredPrompts(): void {
986
- if (this.trustReResolvePending.length === 0) return;
987
- const pending = this.trustReResolvePending;
988
- this.trustReResolvePending = [];
989
- for (const msg of pending) {
990
- void this.handlePrompt(msg);
991
- }
992
- }
993
-
994
874
  /**
995
875
  * Shared post-activation handoff for all trusted-contact success paths
996
876
  * (access-request approval, invite redemption, verification code).
@@ -998,7 +878,7 @@ export class RelayConnection {
998
878
  * transition copy, and marks the next utterance as opening-ack so the
999
879
  * LLM continues naturally.
1000
880
  */
1001
- private async continueCallAfterTrustedContactActivation(params: {
881
+ private continueCallAfterTrustedContactActivation(params: {
1002
882
  assistantId: string;
1003
883
  fromNumber: string;
1004
884
  activationReason?:
@@ -1013,25 +893,26 @@ export class RelayConnection {
1013
893
  * address.
1014
894
  */
1015
895
  inviteeName?: string | null;
1016
- }): Promise<void> {
896
+ }): void {
1017
897
  const { assistantId, fromNumber } = params;
1018
898
 
1019
899
  // Contact activation is handled by the gateway — the assistant no
1020
900
  // longer writes contact/channel records on inbound voice calls.
1021
901
 
1022
- // Reach connected and clear wait/verification flags before re-resolving
1023
- // trust, so a prompt buffered during re-resolution flushes onto the
1024
- // real-turn path, not the verification/wait branches.
1025
- this.connectionState = "connected";
1026
- this.verificationSessionActive = false;
1027
- this.inviteRedemptionActive = false;
1028
- this.accessRequestWaitActive = false;
1029
- updateCallSession(this.callSessionId, { status: "in_progress" });
902
+ const updatedTrust = resolveActorTrust({
903
+ assistantId,
904
+ sourceChannel: "phone",
905
+ conversationExternalId: fromNumber,
906
+ actorExternalId: fromNumber,
907
+ });
1030
908
 
1031
909
  if (this.controller) {
1032
- await this.reResolveAndApplyTrustContext(assistantId, fromNumber);
910
+ this.controller.setTrustContext(toTrustContext(updatedTrust, fromNumber));
1033
911
  }
1034
912
 
913
+ this.connectionState = "connected";
914
+ updateCallSession(this.callSessionId, { status: "in_progress" });
915
+
1035
916
  const guardianLabel = this.resolveGuardianLabel();
1036
917
  let handoffText: string;
1037
918
 
@@ -1164,7 +1045,7 @@ export class RelayConnection {
1164
1045
  const assistantId = this.verificationAssistantId;
1165
1046
  const fromNumber = this.verificationFromNumber;
1166
1047
 
1167
- const result = await attemptVerificationCode({
1048
+ const result = attemptVerificationCode({
1168
1049
  verificationAssistantId: assistantId,
1169
1050
  verificationFromNumber: fromNumber,
1170
1051
  enteredCode,
@@ -1210,7 +1091,15 @@ export class RelayConnection {
1210
1091
 
1211
1092
  // Update trust context on the controller so the LLM knows this is the guardian
1212
1093
  if (this.controller) {
1213
- await this.reResolveAndApplyTrustContext(assistantId, fromNumber);
1094
+ const verifiedActorTrust = resolveActorTrust({
1095
+ assistantId,
1096
+ sourceChannel: "phone",
1097
+ conversationExternalId: fromNumber,
1098
+ actorExternalId: fromNumber,
1099
+ });
1100
+ this.controller.setTrustContext(
1101
+ toTrustContext(verifiedActorTrust, fromNumber),
1102
+ );
1214
1103
  }
1215
1104
 
1216
1105
  // Mark session as in-progress and transition to guardian conversation
@@ -1227,7 +1116,7 @@ export class RelayConnection {
1227
1116
  );
1228
1117
  }
1229
1118
  } else if (result.verificationType === "trusted_contact") {
1230
- await this.continueCallAfterTrustedContactActivation({
1119
+ this.continueCallAfterTrustedContactActivation({
1231
1120
  assistantId,
1232
1121
  fromNumber,
1233
1122
  activationReason: "trusted_contact_verified",
@@ -1236,7 +1125,15 @@ export class RelayConnection {
1236
1125
  // Inbound guardian verification: binding already handled above,
1237
1126
  // proceed to normal call flow.
1238
1127
  if (this.controller) {
1239
- await this.reResolveAndApplyTrustContext(assistantId, fromNumber);
1128
+ const verifiedActorTrust = resolveActorTrust({
1129
+ assistantId,
1130
+ sourceChannel: "phone",
1131
+ conversationExternalId: fromNumber,
1132
+ actorExternalId: fromNumber,
1133
+ });
1134
+ this.controller.setTrustContext(
1135
+ toTrustContext(verifiedActorTrust, fromNumber),
1136
+ );
1240
1137
  this.startNormalCallFlow(this.controller, true);
1241
1138
  }
1242
1139
  }
@@ -1399,7 +1296,7 @@ export class RelayConnection {
1399
1296
  * Creates a canonical access request, notifies the guardian, and
1400
1297
  * enters the bounded wait loop for the guardian decision.
1401
1298
  */
1402
- private async handleNameCaptureResponse(callerName: string): Promise<void> {
1299
+ private handleNameCaptureResponse(callerName: string): void {
1403
1300
  if (!this.accessRequestAssistantId || !this.accessRequestFromNumber) {
1404
1301
  return;
1405
1302
  }
@@ -1420,7 +1317,7 @@ export class RelayConnection {
1420
1317
  // Create canonical access request and notify the guardian, including
1421
1318
  // the caller's spoken name and voice channel metadata.
1422
1319
  try {
1423
- const accessResult = await notifyGuardianOfAccessRequest({
1320
+ const accessResult = notifyGuardianOfAccessRequest({
1424
1321
  canonicalAssistantId: this.accessRequestAssistantId,
1425
1322
  sourceChannel: "phone",
1426
1323
  conversationExternalId: this.accessRequestFromNumber,
@@ -1513,7 +1410,7 @@ export class RelayConnection {
1513
1410
  }
1514
1411
 
1515
1412
  if (request.status === "approved") {
1516
- void this.handleAccessRequestApproved();
1413
+ this.handleAccessRequestApproved();
1517
1414
  } else if (request.status === "denied") {
1518
1415
  void this.handleAccessRequestDenied();
1519
1416
  }
@@ -1565,7 +1462,7 @@ export class RelayConnection {
1565
1462
  * Handle an approved access request: activate the caller as a trusted
1566
1463
  * contact, update runtime context, and continue with normal call flow.
1567
1464
  */
1568
- private async handleAccessRequestApproved(): Promise<void> {
1465
+ private handleAccessRequestApproved(): void {
1569
1466
  this.clearAccessRequestWait();
1570
1467
 
1571
1468
  const assistantId = this.accessRequestAssistantId!;
@@ -1583,7 +1480,7 @@ export class RelayConnection {
1583
1480
  "Access request approved — caller activated and continuing call",
1584
1481
  );
1585
1482
 
1586
- await this.continueCallAfterTrustedContactActivation({
1483
+ this.continueCallAfterTrustedContactActivation({
1587
1484
  assistantId,
1588
1485
  fromNumber,
1589
1486
  activationReason: "access_approved",
@@ -1791,7 +1688,7 @@ export class RelayConnection {
1791
1688
  "Voice invite redemption succeeded",
1792
1689
  );
1793
1690
 
1794
- await this.continueCallAfterTrustedContactActivation({
1691
+ this.continueCallAfterTrustedContactActivation({
1795
1692
  assistantId: this.inviteRedemptionAssistantId,
1796
1693
  fromNumber: this.inviteRedemptionFromNumber,
1797
1694
  activationReason: "invite_redeemed",
@@ -1834,20 +1731,15 @@ export class RelayConnection {
1834
1731
  * Resolve a human-readable guardian label for voice wait copy.
1835
1732
  * Delegates to the shared resolveGuardianName() which checks the
1836
1733
  * guardian's per-user persona file (users/<slug>.md) first, then falls
1837
- * back to the primed gateway-binding displayName, then
1838
- * DEFAULT_USER_REFERENCE.
1734
+ * back to Contact.displayName, then DEFAULT_USER_REFERENCE.
1839
1735
  */
1840
1736
  private resolveGuardianLabel(): string {
1841
- return resolveGuardianName(this.primedGuardianDisplayName);
1842
- }
1737
+ // Look up the guardian contact for a displayName fallback
1738
+ const voiceGuardian = findGuardianForChannel("phone");
1739
+ const guardianChannels = voiceGuardian ? null : listGuardianChannels();
1740
+ const guardianContact = voiceGuardian?.contact ?? guardianChannels?.contact;
1843
1741
 
1844
- /**
1845
- * Prime the guardian displayName from the gateway binding so the
1846
- * synchronous wait-label path can read it without an IPC round-trip.
1847
- */
1848
- private async primeGuardianDisplayName(): Promise<void> {
1849
- const list = await getGuardianDelivery();
1850
- this.primedGuardianDisplayName = voiceGuardianDisplayName(list);
1742
+ return resolveGuardianName(guardianContact?.displayName);
1851
1743
  }
1852
1744
 
1853
1745
  /**
@@ -2025,15 +1917,6 @@ export class RelayConnection {
2025
1917
  return;
2026
1918
  }
2027
1919
 
2028
- // Defer (don't drop) prompts while trust is being re-resolved mid-call so a
2029
- // verified caller's first utterance runs under the upgraded context, not the
2030
- // stale pre-verification one. flushDeferredPrompts replays them in order
2031
- // once the new context lands.
2032
- if (this.trustReResolving) {
2033
- this.trustReResolvePending.push(msg);
2034
- return;
2035
- }
2036
-
2037
1920
  // Prompts arriving before setup routing/ACL completes are dropped — never
2038
1921
  // persisted or emitted — so a not-yet-authorized caller's speech can't be
2039
1922
  // stored ahead of the admission floor / trust ACL decision.
@@ -2059,7 +1942,7 @@ export class RelayConnection {
2059
1942
  { callSessionId: this.callSessionId, callerName },
2060
1943
  "Name captured from unknown inbound caller",
2061
1944
  );
2062
- await this.handleNameCaptureResponse(callerName);
1945
+ this.handleNameCaptureResponse(callerName);
2063
1946
  return;
2064
1947
  }
2065
1948
 
@@ -6,7 +6,7 @@
6
6
  * next — without performing any side effects itself.
7
7
  */
8
8
 
9
- import type { AdmissionPolicy, TrustVerdict } from "@vellumai/gateway-client";
9
+ import type { AdmissionPolicy } from "@vellumai/gateway-client";
10
10
 
11
11
  import { getConfig } from "../config/loader.js";
12
12
  import { getContact } from "../contacts/contact-store.js";
@@ -21,10 +21,6 @@ import {
21
21
  type AdmissionPolicyResult,
22
22
  enforceAdmissionPolicy,
23
23
  } from "../runtime/routes/inbound-stages/admission-policy.js";
24
- import {
25
- actorTrustContextFromVerdict,
26
- verdictMemberUnresolvable,
27
- } from "../runtime/trust-verdict-consumer.js";
28
24
  import { getLogger } from "../util/logger.js";
29
25
  import type { CallSession } from "./types.js";
30
26
 
@@ -44,12 +40,6 @@ interface SetupContext {
44
40
  * preserving all pre-admission behavior.
45
41
  */
46
42
  admissionPolicy?: AdmissionPolicy | null;
47
- /**
48
- * Gateway-stamped caller trust verdict. When present and not
49
- * `resolutionFailed`, the caller's trust is built from it; otherwise the
50
- * router falls back to local resolution.
51
- */
52
- verdict?: TrustVerdict | null;
53
43
  }
54
44
 
55
45
  // ── Setup outcomes ───────────────────────────────────────────────────
@@ -122,32 +112,12 @@ export function routeSetup(ctx: SetupContext): {
122
112
  const isInbound = ctx.session?.initiatedFromConversationId == null;
123
113
  const otherPartyNumber = isInbound ? ctx.from : ctx.to;
124
114
 
125
- // Verdict-first: build caller trust from the gateway verdict when present.
126
- // Voice falls back to local resolution on a missing/failed verdict so a
127
- // gateway blip does not drop a known guardian's call — the deliberate
128
- // difference from the fail-closed text path.
129
- //
130
- // A verdict that claims a member (contactId/channelId) but whose ACL can't be
131
- // reassembled (malformed/mixed-version status·policy) also falls back to local
132
- // resolution, so voice never trusts a member it cannot ACL-check. A real
133
- // stranger verdict (no member identity) still takes the verdict path —
134
- // memberRecord null is correct there.
135
- const usable =
136
- ctx.verdict &&
137
- !ctx.verdict.resolutionFailed &&
138
- !verdictMemberUnresolvable(ctx.verdict);
139
- const actorTrust = usable
140
- ? actorTrustContextFromVerdict(ctx.verdict!, {
141
- sourceChannel: "phone",
142
- conversationExternalId: otherPartyNumber,
143
- actorDisplayName: undefined,
144
- })
145
- : resolveActorTrust({
146
- assistantId,
147
- sourceChannel: "phone",
148
- conversationExternalId: otherPartyNumber,
149
- actorExternalId: otherPartyNumber || undefined,
150
- });
115
+ const actorTrust = resolveActorTrust({
116
+ assistantId,
117
+ sourceChannel: "phone",
118
+ conversationExternalId: otherPartyNumber,
119
+ actorExternalId: otherPartyNumber || undefined,
120
+ });
151
121
 
152
122
  const resolved: SetupResolved = {
153
123
  assistantId,
@@ -112,9 +112,9 @@ type VerificationCallResult =
112
112
  * so the caller can apply side-effects (state mutations, TTS, session
113
113
  * updates) without this function needing access to the relay connection.
114
114
  */
115
- export async function attemptVerificationCode(
115
+ export function attemptVerificationCode(
116
116
  params: VerificationCallParams,
117
- ): Promise<VerificationCallResult> {
117
+ ): VerificationCallResult {
118
118
  const {
119
119
  verificationAssistantId,
120
120
  verificationFromNumber,
@@ -142,7 +142,7 @@ export async function attemptVerificationCode(
142
142
  let canonicalPrincipal: string | undefined;
143
143
 
144
144
  if (result.verificationType === "guardian") {
145
- const existingBinding = await getGuardianBinding(
145
+ const existingBinding = getGuardianBinding(
146
146
  verificationAssistantId,
147
147
  "phone",
148
148
  );
@@ -155,7 +155,7 @@ export async function attemptVerificationCode(
155
155
  };
156
156
  } else {
157
157
  // Resolve canonical principal from the vellum channel binding
158
- const vellumBinding = await getGuardianBinding(
158
+ const vellumBinding = getGuardianBinding(
159
159
  verificationAssistantId,
160
160
  "vellum",
161
161
  );
@@ -1,8 +1,9 @@
1
- import { findContactByAddress, listContacts } from "../contacts/contact-store.js";
2
1
  import {
3
- getGuardianDelivery,
4
- voiceGuardianDisplayName,
5
- } from "../contacts/guardian-delivery-reader.js";
2
+ findContactByAddress,
3
+ findGuardianForChannel,
4
+ listContacts,
5
+ listGuardianChannels,
6
+ } from "../contacts/contact-store.js";
6
7
  import { getAssistantName } from "../daemon/identity-helpers.js";
7
8
  import { DEFAULT_USER_REFERENCE, resolveGuardianName } from "../prompts/user-reference.js";
8
9
  import { getLogger } from "../util/logger.js";
@@ -118,7 +119,7 @@ export function buildSttHints(input: SttHintsInput): string {
118
119
  * {@link buildSttHints}. All DB lookups are best-effort — errors are
119
120
  * logged but never propagate so hints can never fail a call.
120
121
  */
121
- export async function resolveCallHints(
122
+ export function resolveCallHints(
122
123
  session: {
123
124
  task: string | null;
124
125
  toNumber: string;
@@ -128,14 +129,16 @@ export async function resolveCallHints(
128
129
  inviteGuardianName: string | null;
129
130
  } | null,
130
131
  staticHints: string[],
131
- ): Promise<string> {
132
+ ): string {
132
133
  const assistantName = getAssistantName();
133
134
 
134
- // Resolve the guardian displayName from the gateway binding for STT vocabulary.
135
+ // Look up the guardian contact for a displayName fallback (mirrors relay-server pattern)
135
136
  let guardianDisplayName: string | undefined;
136
137
  try {
137
- const list = await getGuardianDelivery();
138
- guardianDisplayName = voiceGuardianDisplayName(list);
138
+ const voiceGuardian = findGuardianForChannel("phone");
139
+ const guardianChannels = voiceGuardian ? null : listGuardianChannels();
140
+ const guardianContact = voiceGuardian?.contact ?? guardianChannels?.contact;
141
+ guardianDisplayName = guardianContact?.displayName;
139
142
  } catch (err) {
140
143
  logger.warn({ err }, "Failed to look up guardian contact for STT hints");
141
144
  }
@@ -55,7 +55,6 @@ import {
55
55
  updateCallSession,
56
56
  } from "./call-store.js";
57
57
  import { getChannelAdmissionPolicy } from "./channel-admission-reader.js";
58
- import { getPhoneCallerVerdict } from "./inbound-trust-reader.js";
59
58
  import { routeSetup } from "./relay-setup-router.js";
60
59
  import { resolveCallHints } from "./stt-hints.js";
61
60
  import { resolveTelephonySttRouting } from "./telephony-stt-routing.js";
@@ -299,7 +298,7 @@ async function processVoiceWebhook(
299
298
  "Inbound voice webhook — creating/reusing session",
300
299
  );
301
300
 
302
- const { session } = await createInboundVoiceSession({
301
+ const { session } = createInboundVoiceSession({
303
302
  callSid,
304
303
  fromNumber: callerFrom,
305
304
  toNumber: callerTo,
@@ -485,21 +484,12 @@ async function buildVoiceWebhookTwiml(
485
484
  // admits the caller.
486
485
  const admissionPolicy = await getChannelAdmissionPolicy("phone");
487
486
 
488
- // Verdict-first caller trust so this preflight matches handleSetup's ACL.
489
- // routeSetup uses it when present and not resolutionFailed, else falls back
490
- // to local resolution. The reader returns null on failure, keeping the
491
- // local path on a gateway blip.
492
- const isInbound = sessionContext?.direction !== "outbound";
493
- const otherPartyNumber = isInbound ? from : to;
494
- const verdict = await getPhoneCallerVerdict(otherPartyNumber);
495
-
496
487
  const { outcome } = routeSetup({
497
488
  callSessionId,
498
489
  session: session ?? null,
499
490
  from,
500
491
  to,
501
492
  admissionPolicy,
502
- verdict,
503
493
  });
504
494
 
505
495
  // The media-stream transport supports normal_call and deny (which speaks
@@ -532,7 +522,7 @@ async function buildVoiceWebhookTwiml(
532
522
  /**
533
523
  * Build ConversationRelay TwiML for Twilio-native STT providers.
534
524
  */
535
- async function buildConversationRelayTwiml(
525
+ function buildConversationRelayTwiml(
536
526
  callSessionId: string,
537
527
  profile: ReturnType<typeof resolveVoiceQualityProfile>,
538
528
  sessionContext: {
@@ -545,8 +535,8 @@ async function buildConversationRelayTwiml(
545
535
  } | null,
546
536
  verificationSessionId: string | null | undefined,
547
537
  sttAttrs: { transcriptionProvider: string; speechModel: string | undefined },
548
- ): Promise<string> {
549
- const rawHints = await resolveCallHints(sessionContext, profile.hints);
538
+ ): string {
539
+ const rawHints = resolveCallHints(sessionContext, profile.hints);
550
540
 
551
541
  const speechConfig: TwilioRelaySpeechConfig = {
552
542
  transcriptionProvider: sttAttrs.transcriptionProvider,
@@ -1,16 +1,26 @@
1
- import {
2
- CHANNEL_IDS,
3
- type ChannelId,
4
- isChannelId,
5
- } from "@vellumai/service-contracts/channels";
1
+ export const CHANNEL_IDS = [
2
+ "telegram",
3
+ "phone",
4
+ "vellum",
5
+ "whatsapp",
6
+ "slack",
7
+ "email",
8
+ "platform",
9
+ "a2a",
10
+ ] as const;
6
11
 
7
- // The assistant understands the full canonical channel set, so it adopts the
8
- // shared vocabulary wholesale. `parseChannelId` stays local — it is only used
9
- // daemon-side and is a thin convenience over the shared guard.
10
- export { CHANNEL_IDS, type ChannelId, isChannelId };
12
+ export type ChannelId = (typeof CHANNEL_IDS)[number];
13
+
14
+ export function isChannelId(value: unknown): value is ChannelId {
15
+ return (
16
+ typeof value === "string" &&
17
+ (CHANNEL_IDS as readonly string[]).includes(value)
18
+ );
19
+ }
11
20
 
12
21
  export function parseChannelId(value: unknown): ChannelId | null {
13
- return isChannelId(value) ? value : null;
22
+ if (isChannelId(value)) return value;
23
+ return null;
14
24
  }
15
25
 
16
26
  export interface TurnChannelContext {
@@ -88,15 +88,8 @@ mock.module("../../../util/logger.js", () => ({
88
88
  }));
89
89
 
90
90
  mock.module("../../lib/cache-fs.js", () => ({
91
- readFileSync: (path: string | number, encoding?: BufferEncoding) => {
92
- // Stdin must be read via fd 0, not by reopening "/dev/stdin": a spawned
93
- // subprocess whose stdin is a pipe (Bun.spawn stdin:"pipe") cannot reopen
94
- // its read-end by path — open("/dev/stdin") fails ENXIO. Throwing here on
95
- // the path makes any regression to path-based reading fail loudly.
91
+ readFileSync: (path: string, encoding?: BufferEncoding) => {
96
92
  if (path === "/dev/stdin") {
97
- throw new Error("ENXIO: no such device or address, open '/dev/stdin'");
98
- }
99
- if (path === 0) {
100
93
  if (mockStdinContent === null) {
101
94
  throw new Error("EAGAIN: resource temporarily unavailable");
102
95
  }