@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
@@ -39,10 +39,10 @@ function findProxyByTransferId(transferId: string) {
39
39
  // GET /v1/transfers/:transferId/content
40
40
  // ---------------------------------------------------------------------------
41
41
 
42
- async function handleTransferContentGet({
42
+ function handleTransferContentGet({
43
43
  pathParams = {},
44
44
  headers = {},
45
- }: RouteHandlerArgs): Promise<Uint8Array> {
45
+ }: RouteHandlerArgs): Uint8Array {
46
46
  const transferId = pathParams.transferId;
47
47
  if (!transferId) {
48
48
  throw new BadRequestError("transferId path parameter is required");
@@ -72,7 +72,7 @@ async function handleTransferContentGet({
72
72
  // the value persisted at registration time so a brief reconnect does
73
73
  // not 403 a legitimate fetch.
74
74
  enforceSameActorOrThrow({
75
- sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
75
+ sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
76
76
  headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
77
77
  ),
78
78
  targetActorPrincipalId:
@@ -151,7 +151,7 @@ async function handleTransferContentPut({
151
151
  );
152
152
 
153
153
  enforceSameActorOrThrow({
154
- sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
154
+ sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
155
155
  headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
156
156
  ),
157
157
  targetActorPrincipalId:
@@ -181,7 +181,7 @@ async function handleTransferContentPut({
181
181
  // POST /v1/host-transfer-result
182
182
  // ---------------------------------------------------------------------------
183
183
 
184
- async function handleTransferResult({ body, headers }: RouteHandlerArgs) {
184
+ function handleTransferResult({ body, headers }: RouteHandlerArgs) {
185
185
  if (!body || typeof body !== "object") {
186
186
  throw new BadRequestError("Request body is required");
187
187
  }
@@ -222,7 +222,7 @@ async function handleTransferResult({ body, headers }: RouteHandlerArgs) {
222
222
  );
223
223
 
224
224
  enforceSameActorOrThrow({
225
- sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
225
+ sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
226
226
  headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
227
227
  ),
228
228
  targetActorPrincipalId: peeked.targetActorPrincipalId,
@@ -51,7 +51,7 @@ export function routeDefinitionsToHTTPRoutes(
51
51
  handler: async ({ req, url, params, authContext }) => {
52
52
  try {
53
53
  if (r.requireGuardian) {
54
- const guardianError = await requireBoundGuardian(authContext);
54
+ const guardianError = requireBoundGuardian(authContext);
55
55
  if (guardianError) return guardianError;
56
56
  }
57
57
 
@@ -10,8 +10,7 @@ import { z } from "zod";
10
10
  import { getCpuLimit, getIsPlatform } from "../../config/env-registry.js";
11
11
  import { parseIdentityFields } from "../../daemon/handlers/identity.js";
12
12
  import { getProfilerRuntimeStatus } from "../../daemon/profiler-run-store.js";
13
- import { getMaxRollbackVersion } from "../../memory/migrations/run-migrations.js";
14
- import { migrationSteps } from "../../memory/steps.js";
13
+ import { getMaxMigrationVersion } from "../../memory/migrations/registry.js";
15
14
  import { getCesClient } from "../../security/secure-keys.js";
16
15
  import {
17
16
  getDiskUsageInfo,
@@ -336,7 +335,7 @@ function getDetailedHealth() {
336
335
  memory: getMemoryInfo(),
337
336
  cpu: getCpuInfo(),
338
337
  migrations: {
339
- dbVersion: getMaxRollbackVersion(migrationSteps),
338
+ dbVersion: getMaxMigrationVersion(),
340
339
  lastWorkspaceMigrationId:
341
340
  getLastWorkspaceMigrationId(WORKSPACE_MIGRATIONS),
342
341
  },
@@ -680,7 +680,7 @@ export async function handleChannelInbound({
680
680
  canonicalAssistantId,
681
681
  assistantId,
682
682
  content,
683
- channelId: resolvedMember?.channelId,
683
+ channelId: resolvedMember?.channel.id,
684
684
  });
685
685
  }
686
686
 
@@ -761,7 +761,7 @@ export async function handleChannelInbound({
761
761
  : enforceAdmissionPolicy({
762
762
  sourceChannel,
763
763
  trustClass: trustCtx.trustClass,
764
- memberStatus: resolvedMember?.status,
764
+ memberStatus: resolvedMember?.channel.status,
765
765
  policy: admissionPolicyFromGateway,
766
766
  });
767
767
  if (!admissionResult.admitted) {
@@ -801,7 +801,7 @@ export async function handleChannelInbound({
801
801
  // guardian sees "previously pending" etc.
802
802
  let guardianNotified = false;
803
803
  try {
804
- const accessResult = await notifyGuardianOfAccessRequest({
804
+ const accessResult = notifyGuardianOfAccessRequest({
805
805
  canonicalAssistantId,
806
806
  sourceChannel,
807
807
  conversationExternalId,
@@ -811,7 +811,7 @@ export async function handleChannelInbound({
811
811
  ...(resolvedMember
812
812
  ? {
813
813
  previousMemberStatus: channelStatusToMemberStatus(
814
- resolvedMember.status,
814
+ resolvedMember.channel.status,
815
815
  ),
816
816
  }
817
817
  : {}),
@@ -935,7 +935,7 @@ export async function handleChannelInbound({
935
935
  }
936
936
 
937
937
  // ── Ingress escalation ──
938
- const escalationResponse = await handleEscalationIntercept({
938
+ const escalationResponse = handleEscalationIntercept({
939
939
  resolvedMember,
940
940
  canonicalAssistantId,
941
941
  sourceChannel,
@@ -19,28 +19,14 @@ mock.module("../../../util/logger.js", () => ({
19
19
  }));
20
20
 
21
21
  // Track contact-store reads to prove findContactChannel is NOT used on the
22
- // verdict path.
22
+ // verdict path. findGuardianForChannel is still called by resolveGuardianLabel.
23
23
  const findContactChannelCalls: unknown[] = [];
24
24
  mock.module("../../../contacts/contact-store.js", () => ({
25
25
  findContactChannel: (params: unknown) => {
26
26
  findContactChannelCalls.push(params);
27
27
  return null;
28
28
  },
29
- }));
30
-
31
- // resolveGuardianLabel resolves the guardian via the gateway delivery reader.
32
- let guardianDeliveryList: Array<Record<string, unknown>> = [];
33
- mock.module("../../../contacts/guardian-delivery-reader.js", () => ({
34
- getGuardianDelivery: async () => guardianDeliveryList,
35
- guardianForChannel: (
36
- list: Array<Record<string, unknown>>,
37
- channelType: string,
38
- ) => list.find((g) => g.channelType === channelType && g.status === "active"),
39
- }));
40
-
41
- mock.module("../../../prompts/user-reference.js", () => ({
42
- resolveGuardianName: (displayName?: string | null) =>
43
- displayName && displayName.trim().length > 0 ? displayName.trim() : "my human",
29
+ findGuardianForChannel: () => null,
44
30
  }));
45
31
 
46
32
  const deliverReplyCalls: Array<{ url: string; payload: unknown }> = [];
@@ -140,7 +126,6 @@ beforeEach(() => {
140
126
  deliverReplyCalls.length = 0;
141
127
  accessRequestCalls.length = 0;
142
128
  inviteTokenForTest = undefined;
143
- guardianDeliveryList = [];
144
129
  });
145
130
 
146
131
  afterEach(() => {
@@ -155,8 +140,8 @@ describe("enforceIngressAcl — verdict-sourced member resolution", () => {
155
140
 
156
141
  expect(result.earlyResponse).toBeUndefined();
157
142
  expect(result.resolvedMember).not.toBeNull();
158
- expect(result.resolvedMember!.status).toBe("active");
159
- expect(result.resolvedMember!.policy).toBe("allow");
143
+ expect(result.resolvedMember!.channel.status).toBe("active");
144
+ expect(result.resolvedMember!.channel.policy).toBe("allow");
160
145
  // Member came from the verdict, never the local contact store.
161
146
  expect(findContactChannelCalls.length).toBe(0);
162
147
  });
@@ -171,8 +156,7 @@ describe("enforceIngressAcl — verdict-sourced member resolution", () => {
171
156
  );
172
157
 
173
158
  expect(result.earlyResponse).toBeUndefined();
174
- expect(result.resolvedMember).not.toBeNull();
175
- expect(result.resolvedMember!.status).toBe("active");
159
+ expect(result.resolvedMember!.contact.role).toBe("guardian");
176
160
  expect(findContactChannelCalls.length).toBe(0);
177
161
  });
178
162
  });
@@ -265,82 +249,6 @@ describe("enforceIngressAcl — fail-closed on absent verdict", () => {
265
249
  });
266
250
  });
267
251
 
268
- describe("enforceIngressAcl — fail-closed on resolutionFailed verdict", () => {
269
- test("resolutionFailed verdict → not_a_member deny, does not flow to intercepts", async () => {
270
- inviteTokenForTest = "iv_token123";
271
- const result = await enforceIngressAcl(
272
- makeParams({
273
- sourceMetadata: withVerdict({
274
- trustClass: "unknown",
275
- canonicalSenderId: "sender-1",
276
- resolutionFailed: true,
277
- }),
278
- effectiveAdmissionPolicy: "strangers",
279
- }),
280
- );
281
-
282
- expect(result.earlyResponse).toBeDefined();
283
- expect(result.earlyResponse!.reason).toBe("not_a_member");
284
- expect(result.resolvedMember).toBeNull();
285
- // Distinct from a stranger: no invite redemption, onboarding, or
286
- // guardian notification fires.
287
- expect(result.earlyResponse!.inviteRedemption).toBeUndefined();
288
- expect(deliverReplyCalls.length).toBe(0);
289
- expect(accessRequestCalls.length).toBe(0);
290
- expect(findContactChannelCalls.length).toBe(0);
291
- });
292
-
293
- test("real unknown stranger (no resolutionFailed) still redeems via intercept", async () => {
294
- inviteTokenForTest = "iv_token123";
295
- const result = await enforceIngressAcl(
296
- makeParams({
297
- sourceMetadata: withVerdict({
298
- trustClass: "unknown",
299
- canonicalSenderId: "sender-1",
300
- }),
301
- }),
302
- );
303
-
304
- expect(result.earlyResponse!.inviteRedemption).toBe("redeemed");
305
- expect(result.resolvedMember).toBeNull();
306
- });
307
- });
308
-
309
- describe("enforceIngressAcl — deny copy names the gateway guardian", () => {
310
- test("non-member deny reply uses the guardian displayName from the gateway list", async () => {
311
- guardianDeliveryList = [
312
- {
313
- channelType: "vellum",
314
- contactId: "c-1",
315
- principalId: "p-anchor",
316
- displayName: "Alice Guardian",
317
- address: "p-anchor",
318
- status: "active",
319
- },
320
- ];
321
-
322
- const result = await enforceIngressAcl(
323
- makeParams({
324
- sourceMetadata: withVerdict({
325
- trustClass: "unknown",
326
- canonicalSenderId: "stranger-1",
327
- }),
328
- }),
329
- );
330
-
331
- expect(result.earlyResponse!.reason).toBe("not_a_member");
332
- const denyReply = deliverReplyCalls.find((c) =>
333
- String((c.payload as { text?: string }).text ?? "").includes(
334
- "tried talking to me",
335
- ),
336
- );
337
- expect(denyReply).toBeDefined();
338
- expect((denyReply!.payload as { text: string }).text).toContain(
339
- "Alice Guardian",
340
- );
341
- });
342
- });
343
-
344
252
  describe("enforceIngressAcl — fail-closed on malformed member verdict", () => {
345
253
  test("member identity + unknown policy → not_a_member deny even under strangers", async () => {
346
254
  const result = await enforceIngressAcl(
@@ -7,7 +7,7 @@ import type { AdmissionPolicy, SourceMetadata } from "@vellumai/gateway-client";
7
7
 
8
8
  import { isInviteCodeRedemptionEnabled } from "../../../channels/config.js";
9
9
  import type { ChannelId } from "../../../channels/types.js";
10
- import { getGuardianDelivery } from "../../../contacts/guardian-delivery-reader.js";
10
+ import { findGuardianForChannel } from "../../../contacts/contact-store.js";
11
11
  import { channelStatusToMemberStatus } from "../../../contacts/member-status.js";
12
12
  import type {
13
13
  ContactChannel,
@@ -25,7 +25,6 @@ import { getLogger } from "../../../util/logger.js";
25
25
  import { truncate } from "../../../util/truncate.js";
26
26
  import { hashVoiceCode } from "../../../util/voice-code.js";
27
27
  import { notifyGuardianOfAccessRequest } from "../../access-request-helper.js";
28
- import { resolveAnchoredGuardian } from "../../anchored-guardian.js";
29
28
  import { getInviteAdapterRegistry } from "../../channel-invite-transport.js";
30
29
  import {
31
30
  createOutboundSession,
@@ -39,8 +38,7 @@ import {
39
38
  redeemInviteByCode,
40
39
  } from "../../invite-redemption-service.js";
41
40
  import { getInviteRedemptionReply } from "../../invite-redemption-templates.js";
42
- import type { VerdictMember } from "../../trust-verdict-consumer.js";
43
- import { verdictMemberFromVerdict } from "../../trust-verdict-consumer.js";
41
+ import { resolvedMemberFromVerdict } from "../../trust-verdict-consumer.js";
44
42
 
45
43
  const log = getLogger("runtime-http");
46
44
 
@@ -48,20 +46,28 @@ const log = getLogger("runtime-http");
48
46
  * Resolve the guardian's display name for use in requester-facing messages.
49
47
  *
50
48
  * Uses the assistant's anchored vellum principal to validate the guardian
51
- * binding, matching the same strategy used by `notifyGuardianOfAccessRequest`.
52
- * This prevents stale or cross-assistant bindings from leaking a wrong name.
53
- * Cosmetic copy, not an admission decision, so a null gateway list degrades
54
- * gracefully to the default reference.
49
+ * contact, matching the same strategy used by `notifyGuardianOfAccessRequest`.
50
+ * This prevents stale or cross-assistant contacts from leaking a wrong name.
55
51
  */
56
- async function resolveGuardianLabel(sourceChannel: ChannelId): Promise<string> {
57
- // Cosmetic copy, not an admission decision: no local-store fallback, and a
58
- // missing anchor principal degrades to the default reference.
59
- const anchored = resolveAnchoredGuardian({
60
- guardians: await getGuardianDelivery(),
61
- sourceChannel,
62
- requireAnchorPrincipal: true,
63
- });
64
- return resolveGuardianName(anchored?.displayName);
52
+ function resolveGuardianLabel(sourceChannel: ChannelId): string {
53
+ const vellumGuardian = findGuardianForChannel("vellum");
54
+ const anchoredPrincipalId = vellumGuardian?.contact.principalId;
55
+
56
+ if (!anchoredPrincipalId) {
57
+ return resolveGuardianName(undefined);
58
+ }
59
+
60
+ // Try source-channel guardian, but only accept it when the principal
61
+ // matches the assistant's anchor.
62
+ const sourceGuardian = findGuardianForChannel(sourceChannel);
63
+ if (
64
+ sourceGuardian &&
65
+ sourceGuardian.contact.principalId === anchoredPrincipalId
66
+ ) {
67
+ return resolveGuardianName(sourceGuardian.contact.displayName);
68
+ }
69
+
70
+ return resolveGuardianName(vellumGuardian.contact.displayName);
65
71
  }
66
72
 
67
73
  // ---------------------------------------------------------------------------
@@ -103,7 +109,7 @@ export type ResolvedMember = {
103
109
  };
104
110
 
105
111
  export interface AclResult {
106
- resolvedMember: VerdictMember | null;
112
+ resolvedMember: ResolvedMember | null;
107
113
  /** When set, the caller must return this response immediately. */
108
114
  earlyResponse?: Record<string, unknown>;
109
115
  /**
@@ -167,27 +173,9 @@ export async function enforceIngressAcl(
167
173
  };
168
174
  }
169
175
 
170
- // Gateway attempted resolution but failed (DB error) → fail-closed deny,
171
- // distinct from an absent verdict and from a real stranger. TEXT does not
172
- // fall back to local ACL reads; the sender can retry.
173
- if (verdict.resolutionFailed === true) {
174
- log.warn(
175
- { sourceChannel, externalUserId: canonicalSenderId },
176
- "Ingress ACL: gateway trust resolution failed, denying fail-closed",
177
- );
178
- return {
179
- resolvedMember: null,
180
- earlyResponse: {
181
- accepted: true,
182
- denied: true,
183
- reason: "not_a_member",
184
- },
185
- };
186
- }
187
-
188
176
  // Member resolved from the gateway verdict (ACL + identity only); null for a
189
177
  // stranger verdict, which falls through to the non-member intercepts.
190
- const resolvedMember: VerdictMember | null = verdictMemberFromVerdict(verdict);
178
+ const resolvedMember: ResolvedMember | null = resolvedMemberFromVerdict(verdict);
191
179
 
192
180
  // A verdict carrying member identity but no resolvable member
193
181
  // (malformed/unknown ACL) fails closed, not treated as a stranger.
@@ -341,7 +329,7 @@ export async function enforceIngressAcl(
341
329
  if (slackVerifyResult.initiated) {
342
330
  // Still notify the guardian about the access attempt
343
331
  try {
344
- await notifyGuardianOfAccessRequest({
332
+ notifyGuardianOfAccessRequest({
345
333
  canonicalAssistantId,
346
334
  sourceChannel,
347
335
  conversationExternalId,
@@ -381,7 +369,7 @@ export async function enforceIngressAcl(
381
369
  try {
382
370
  await deliverChannelReply(dmCallbackUrl, {
383
371
  chatId: senderUserId,
384
- text: `I don't recognize you yet! I've let ${await resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
372
+ text: `I don't recognize you yet! I've let ${resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
385
373
  assistantId,
386
374
  });
387
375
  } catch (err) {
@@ -416,7 +404,7 @@ export async function enforceIngressAcl(
416
404
 
417
405
  if (emailVerifyResult.initiated) {
418
406
  try {
419
- await notifyGuardianOfAccessRequest({
407
+ notifyGuardianOfAccessRequest({
420
408
  canonicalAssistantId,
421
409
  sourceChannel,
422
410
  conversationExternalId,
@@ -455,7 +443,7 @@ export async function enforceIngressAcl(
455
443
  // deduplication, canonical request creation, and notification emission.
456
444
  let guardianNotified = false;
457
445
  try {
458
- const accessResult = await notifyGuardianOfAccessRequest({
446
+ const accessResult = notifyGuardianOfAccessRequest({
459
447
  canonicalAssistantId,
460
448
  sourceChannel,
461
449
  conversationExternalId,
@@ -479,7 +467,7 @@ export async function enforceIngressAcl(
479
467
  }
480
468
 
481
469
  const replyText = guardianNotified
482
- ? `Hmm looks like you don't have access to talk to me. I'll let ${await resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
470
+ ? `Hmm looks like you don't have access to talk to me. I'll let ${resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
483
471
  : "Sorry, you haven't been approved to message this assistant.";
484
472
  let replyDelivered = false;
485
473
  if (replyCallbackUrl) {
@@ -519,8 +507,8 @@ export async function enforceIngressAcl(
519
507
  }
520
508
 
521
509
  if (resolvedMember) {
522
- if (resolvedMember.status !== "active") {
523
- const isBlockedMember = resolvedMember.status === "blocked";
510
+ if (resolvedMember.channel.status !== "active") {
511
+ const isBlockedMember = resolvedMember.channel.status === "blocked";
524
512
  // Bootstrap commands must pass through for re-verifiable states
525
513
  // (pending/revoked), but never for blocked members.
526
514
  let denyInactiveMember = true;
@@ -541,7 +529,7 @@ export async function enforceIngressAcl(
541
529
  log.info(
542
530
  {
543
531
  sourceChannel,
544
- channelId: resolvedMember.channelId,
532
+ channelId: resolvedMember.channel.id,
545
533
  hasValidBootstrapSession: false,
546
534
  },
547
535
  "Ingress ACL: inactive member bootstrap bypass denied",
@@ -626,11 +614,11 @@ export async function enforceIngressAcl(
626
614
  if (!isBlockedMember && denyInactiveMember) {
627
615
  if (
628
616
  (effectiveAdmissionPolicy === "strangers" &&
629
- resolvedMember.status !== "revoked") ||
617
+ resolvedMember.channel.status !== "revoked") ||
630
618
  ((effectiveAdmissionPolicy === "any_contact" ||
631
619
  effectiveAdmissionPolicy === "guardian_only") &&
632
- (resolvedMember.status === "pending" ||
633
- resolvedMember.status === "unverified"))
620
+ (resolvedMember.channel.status === "pending" ||
621
+ resolvedMember.channel.status === "unverified"))
634
622
  ) {
635
623
  denyInactiveMember = false;
636
624
  }
@@ -640,8 +628,8 @@ export async function enforceIngressAcl(
640
628
  log.info(
641
629
  {
642
630
  sourceChannel,
643
- channelId: resolvedMember.channelId,
644
- status: resolvedMember.status,
631
+ channelId: resolvedMember.channel.id,
632
+ status: resolvedMember.channel.status,
645
633
  },
646
634
  "Ingress ACL: member not active, denying",
647
635
  );
@@ -651,7 +639,7 @@ export async function enforceIngressAcl(
651
639
  // the guardian made an explicit decision to block them.
652
640
  if (
653
641
  sourceChannel === "slack" &&
654
- resolvedMember.status !== "blocked" &&
642
+ resolvedMember.channel.status !== "blocked" &&
655
643
  (canonicalSenderId ?? rawSenderId)
656
644
  ) {
657
645
  const slackVerifyResult = initiateSlackVerificationChallenge({
@@ -661,7 +649,7 @@ export async function enforceIngressAcl(
661
649
 
662
650
  if (slackVerifyResult.initiated) {
663
651
  try {
664
- await notifyGuardianOfAccessRequest({
652
+ notifyGuardianOfAccessRequest({
665
653
  canonicalAssistantId,
666
654
  sourceChannel,
667
655
  conversationExternalId,
@@ -669,7 +657,7 @@ export async function enforceIngressAcl(
669
657
  actorDisplayName,
670
658
  actorUsername,
671
659
  previousMemberStatus: channelStatusToMemberStatus(
672
- resolvedMember.status,
660
+ resolvedMember.channel.status,
673
661
  ),
674
662
  messagePreview: truncate(
675
663
  trimmedContent,
@@ -700,7 +688,7 @@ export async function enforceIngressAcl(
700
688
  try {
701
689
  await deliverChannelReply(dmCallbackUrl, {
702
690
  chatId: senderUserId,
703
- text: `I don't recognize you yet! I've let ${await resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
691
+ text: `I don't recognize you yet! I've let ${resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
704
692
  assistantId,
705
693
  });
706
694
  } catch (err) {
@@ -727,9 +715,9 @@ export async function enforceIngressAcl(
727
715
  // re-approve. Blocked members are intentionally excluded — the
728
716
  // guardian already made an explicit decision to block them.
729
717
  let guardianNotified = false;
730
- if (resolvedMember.status !== "blocked") {
718
+ if (resolvedMember.channel.status !== "blocked") {
731
719
  try {
732
- const accessResult = await notifyGuardianOfAccessRequest({
720
+ const accessResult = notifyGuardianOfAccessRequest({
733
721
  canonicalAssistantId,
734
722
  sourceChannel,
735
723
  conversationExternalId,
@@ -737,7 +725,7 @@ export async function enforceIngressAcl(
737
725
  actorDisplayName,
738
726
  actorUsername,
739
727
  previousMemberStatus: channelStatusToMemberStatus(
740
- resolvedMember.status,
728
+ resolvedMember.channel.status,
741
729
  ),
742
730
  messagePreview: truncate(
743
731
  trimmedContent,
@@ -757,7 +745,7 @@ export async function enforceIngressAcl(
757
745
  }
758
746
 
759
747
  const inactiveReplyText = guardianNotified
760
- ? `Hmm looks like you don't have access to talk to me. I'll let ${await resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
748
+ ? `Hmm looks like you don't have access to talk to me. I'll let ${resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
761
749
  : "Sorry, you haven't been approved to message this assistant.";
762
750
  let inactiveReplyDelivered = false;
763
751
  if (replyCallbackUrl) {
@@ -791,16 +779,16 @@ export async function enforceIngressAcl(
791
779
  earlyResponse: {
792
780
  accepted: true,
793
781
  denied: true,
794
- reason: `member_${channelStatusToMemberStatus(resolvedMember.status)}`,
782
+ reason: `member_${channelStatusToMemberStatus(resolvedMember.channel.status)}`,
795
783
  ...(!inactiveReplyDelivered && { replyText: inactiveReplyText }),
796
784
  },
797
785
  };
798
786
  }
799
787
  }
800
788
 
801
- if (resolvedMember.policy === "deny") {
789
+ if (resolvedMember.channel.policy === "deny") {
802
790
  log.info(
803
- { sourceChannel, channelId: resolvedMember.channelId },
791
+ { sourceChannel, channelId: resolvedMember.channel.id },
804
792
  "Ingress ACL: member policy deny",
805
793
  );
806
794
  const denyReplyText =
@@ -9,10 +9,6 @@
9
9
  */
10
10
  import type { ChannelId, InterfaceId } from "../../../channels/types.js";
11
11
  import { findGuardianForChannel } from "../../../contacts/contact-store.js";
12
- import {
13
- getGuardianDelivery,
14
- guardianForChannel,
15
- } from "../../../contacts/guardian-delivery-reader.js";
16
12
  import type { ServerMessage } from "../../../daemon/message-protocol.js";
17
13
  import type { TrustContext } from "../../../daemon/trust-context.js";
18
14
  import {
@@ -964,18 +960,10 @@ function startTrustedContactApprovalNotifier(params: {
964
960
 
965
961
  if (info && !globalNotifiedApprovalRequestIds.has(info.requestId)) {
966
962
  globalNotifiedApprovalRequestIds.set(info.requestId, conversationId);
967
- // Gateway-resolved guardian display name with the transitional
968
- // local fallback on null/no-match (display-only). Removed in Combo 11.
969
- const guardians = await getGuardianDelivery({
970
- channelTypes: [sourceChannel],
971
- });
972
- const gatewayDisplayName = guardians
973
- ? guardianForChannel(guardians, sourceChannel)?.displayName
974
- : undefined;
975
- const displayName =
976
- gatewayDisplayName ??
977
- findGuardianForChannel(sourceChannel)?.contact.displayName;
978
- const guardianName = resolveGuardianName(displayName);
963
+ const guardian = findGuardianForChannel(sourceChannel);
964
+ const guardianName = resolveGuardianName(
965
+ guardian?.contact.displayName,
966
+ );
979
967
  const waitingText = `Waiting for ${guardianName}'s approval...`;
980
968
  try {
981
969
  await deliverChannelReply(replyCallbackUrl, {
@@ -13,8 +13,8 @@ import { storePayload } from "../../../memory/delivery-crud.js";
13
13
  import { emitNotificationSignal } from "../../../notifications/emit-signal.js";
14
14
  import { getLogger } from "../../../util/logger.js";
15
15
  import { getGuardianBinding } from "../../channel-verification-service.js";
16
- import type { VerdictMember } from "../../trust-verdict-consumer.js";
17
16
  import { GUARDIAN_APPROVAL_TTL_MS } from "../channel-route-shared.js";
17
+ import type { ResolvedMember } from "./acl-enforcement.js";
18
18
 
19
19
  const log = getLogger("runtime-http");
20
20
 
@@ -23,7 +23,7 @@ const log = getLogger("runtime-http");
23
23
  // ---------------------------------------------------------------------------
24
24
 
25
25
  export interface EscalationInterceptParams {
26
- resolvedMember: VerdictMember | null;
26
+ resolvedMember: ResolvedMember | null;
27
27
  canonicalAssistantId: string;
28
28
  sourceChannel: ChannelId;
29
29
  sourceInterface: InterfaceId;
@@ -49,9 +49,9 @@ export interface EscalationInterceptParams {
49
49
  * Returns a Response if the escalation was handled (the pipeline should
50
50
  * short-circuit), or null to continue the pipeline.
51
51
  */
52
- export async function handleEscalationIntercept(
52
+ export function handleEscalationIntercept(
53
53
  params: EscalationInterceptParams,
54
- ): Promise<Record<string, unknown> | null> {
54
+ ): Record<string, unknown> | null {
55
55
  const {
56
56
  resolvedMember,
57
57
  canonicalAssistantId,
@@ -72,15 +72,15 @@ export async function handleEscalationIntercept(
72
72
  rawSenderId,
73
73
  } = params;
74
74
 
75
- if (resolvedMember?.policy !== "escalate") {
75
+ if (resolvedMember?.channel.policy !== "escalate") {
76
76
  return null;
77
77
  }
78
78
 
79
- const binding = await getGuardianBinding(canonicalAssistantId, sourceChannel);
79
+ const binding = getGuardianBinding(canonicalAssistantId, sourceChannel);
80
80
  if (!binding) {
81
81
  // Fail-closed: can't escalate without a guardian to route to
82
82
  log.info(
83
- { sourceChannel, channelId: resolvedMember.channelId },
83
+ { sourceChannel, channelId: resolvedMember.channel.id },
84
84
  "Ingress ACL: escalate policy but no guardian binding, denying",
85
85
  );
86
86
  return {