@vellumai/assistant 0.10.4-dev.202607022227.14c7770 → 0.10.4-staging.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 (864) hide show
  1. package/ARCHITECTURE.md +91 -94
  2. package/Dockerfile +16 -5
  3. package/README.md +10 -7
  4. package/bun.lock +4 -0
  5. package/docs/architecture/security.md +20 -20
  6. package/docs/stt-provider-onboarding.md +5 -4
  7. package/docs/trusted-contact-access.md +7 -7
  8. package/drizzle/0000_dizzy_maggott.sql +301 -0
  9. package/drizzle/meta/0000_snapshot.json +1933 -0
  10. package/drizzle/meta/_journal.json +13 -0
  11. package/eslint-rules/cli-no-daemon-internals.js +0 -4
  12. package/eslint.config.mjs +1 -7
  13. package/knip.json +1 -0
  14. package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +0 -36
  15. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -40
  16. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +8 -20
  17. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +0 -10
  18. package/node_modules/@vellumai/gateway-client/src/index.ts +0 -33
  19. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +0 -91
  20. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +3 -39
  21. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +8 -0
  22. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +5 -1
  23. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +14 -3
  24. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +887 -0
  25. package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
  26. package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
  27. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +97 -0
  28. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1349 -0
  29. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
  30. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
  31. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
  32. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +333 -0
  33. package/{src/tools → node_modules/@vellumai/skill-host-contracts/src}/tool-types.ts +17 -16
  34. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
  35. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
  36. package/openapi.yaml +246 -1094
  37. package/package.json +4 -1
  38. package/scripts/test.sh +13 -35
  39. package/src/__tests__/access-request-seed-content-blocks.test.ts +4 -60
  40. package/src/__tests__/acp-session.test.ts +1 -4
  41. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +6 -0
  42. package/src/__tests__/app-conversation-ids-backfill.test.ts +0 -3
  43. package/src/__tests__/app-source-watcher.test.ts +0 -11
  44. package/src/__tests__/approval-interception-trust-gates.test.ts +3 -148
  45. package/src/__tests__/assistant-attachments.test.ts +4 -62
  46. package/src/__tests__/assistant-id-boundary-guard.test.ts +1 -0
  47. package/src/__tests__/attachments-store.test.ts +0 -3
  48. package/src/__tests__/background-shell-bash.test.ts +0 -34
  49. package/src/__tests__/background-shell-host-bash.test.ts +0 -12
  50. package/src/__tests__/background-tool-registry.test.ts +0 -97
  51. package/src/__tests__/background-tool-routes.test.ts +1 -72
  52. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -2
  53. package/src/__tests__/btw-routes.test.ts +3 -57
  54. package/src/__tests__/call-controller.test.ts +84 -474
  55. package/src/__tests__/call-domain.test.ts +1 -48
  56. package/src/__tests__/call-pointer-messages.test.ts +19 -57
  57. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +6 -2
  58. package/src/__tests__/call-routes-http.test.ts +14 -15
  59. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -0
  60. package/src/__tests__/channel-guardian.test.ts +7 -4
  61. package/src/__tests__/channel-readiness-service.test.ts +6 -0
  62. package/src/__tests__/channel-readiness-slack-remote.test.ts +4 -0
  63. package/src/__tests__/channel-retry-sweep.test.ts +64 -76
  64. package/src/__tests__/config-loader-backfill.test.ts +5 -5
  65. package/src/__tests__/config-schema.test.ts +0 -17
  66. package/src/__tests__/contact-store-interaction-info.test.ts +70 -27
  67. package/src/__tests__/contacts-relay-reads.test.ts +23 -188
  68. package/src/__tests__/contacts-tools.test.ts +1 -42
  69. package/src/__tests__/contacts-write.test.ts +0 -181
  70. package/src/__tests__/context-search-conversations-source.test.ts +81 -220
  71. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -1
  72. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -1
  73. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -1
  74. package/src/__tests__/conversation-agent-loop.test.ts +0 -39
  75. package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
  76. package/src/__tests__/conversation-app-control-instantiation.test.ts +0 -2
  77. package/src/__tests__/conversation-clear-safety.test.ts +1 -0
  78. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -0
  79. package/src/__tests__/conversation-disk-view.test.ts +0 -1
  80. package/src/__tests__/conversation-error.test.ts +18 -0
  81. package/src/__tests__/conversation-fork-crud.test.ts +0 -67
  82. package/src/__tests__/conversation-history-web-search.test.ts +137 -7
  83. package/src/__tests__/conversation-process-callsite.test.ts +0 -37
  84. package/src/__tests__/conversation-queue.test.ts +0 -149
  85. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -84
  86. package/src/__tests__/conversation-runtime-assembly.test.ts +16 -36
  87. package/src/__tests__/conversation-skill-tools.test.ts +0 -73
  88. package/src/__tests__/conversation-wipe.test.ts +5 -20
  89. package/src/__tests__/credential-prompt-route.test.ts +0 -69
  90. package/src/__tests__/credential-security-invariants.test.ts +3 -1
  91. package/src/__tests__/deterministic-verification-control-plane.test.ts +62 -1
  92. package/src/__tests__/edit-propagation.test.ts +2 -56
  93. package/src/__tests__/empty-state-greeting-cache.test.ts +0 -9
  94. package/src/__tests__/gateway-only-enforcement.test.ts +110 -15
  95. package/src/__tests__/guardian-expiry-notifier.test.ts +0 -1
  96. package/src/__tests__/guardian-question-mode.test.ts +0 -57
  97. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  98. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +2 -33
  99. package/src/__tests__/helpers/seed-contact-channel.ts +2 -0
  100. package/src/__tests__/http-conversation-lineage.test.ts +1 -6
  101. package/src/__tests__/inbound-invite-redemption.test.ts +341 -72
  102. package/src/__tests__/invite-redemption-service.test.ts +1180 -0
  103. package/src/__tests__/invite-routes-http.test.ts +420 -246
  104. package/src/__tests__/invite-service-ipc.test.ts +350 -0
  105. package/src/__tests__/job-handler-registry-guard.test.ts +125 -0
  106. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
  107. package/src/__tests__/list-messages-attachments.test.ts +0 -159
  108. package/src/__tests__/list-messages-queued.test.ts +0 -25
  109. package/src/__tests__/managed-store.test.ts +1 -129
  110. package/src/__tests__/media-stream-output.test.ts +19 -350
  111. package/src/__tests__/media-stream-server-integration.test.ts +169 -943
  112. package/src/__tests__/media-stream-stt-session.test.ts +1 -498
  113. package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
  114. package/src/__tests__/model-intents.test.ts +1 -1
  115. package/src/__tests__/mtime-cache.test.ts +0 -19
  116. package/src/__tests__/non-member-access-request.test.ts +3 -349
  117. package/src/__tests__/notification-decision-fallback.test.ts +8 -104
  118. package/src/__tests__/notification-decision-strategy.test.ts +8 -57
  119. package/src/__tests__/onboarding-template-contract.test.ts +43 -27
  120. package/src/__tests__/openai-provider.test.ts +0 -33
  121. package/src/__tests__/openai-responses-provider.test.ts +0 -40
  122. package/src/__tests__/persistence-layering-guard.test.ts +20 -29
  123. package/src/__tests__/persona-resolver.test.ts +2 -56
  124. package/src/__tests__/phone.test.ts +15 -1
  125. package/src/__tests__/plugin-bootstrap.test.ts +196 -25
  126. package/src/__tests__/plugin-disabled-state.test.ts +0 -33
  127. package/src/__tests__/plugin-import-boundary-guard.test.ts +42 -156
  128. package/src/__tests__/plugin-injector-contribution.test.ts +20 -4
  129. package/src/__tests__/plugin-pipeline.test.ts +1 -63
  130. package/src/__tests__/plugin-route-contribution.test.ts +115 -62
  131. package/src/__tests__/plugin-tool-contribution.test.ts +22 -0
  132. package/src/__tests__/plugin-types.test.ts +1 -0
  133. package/src/__tests__/pointer-conversation-trust.test.ts +6 -38
  134. package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
  135. package/src/__tests__/public-ingress-urls.test.ts +48 -0
  136. package/src/__tests__/qdrant-collection-migration.test.ts +2 -145
  137. package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +1 -0
  138. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +203 -0
  139. package/src/__tests__/relay-server.test.ts +6153 -0
  140. package/src/__tests__/resolve-trust-class.test.ts +10 -28
  141. package/src/__tests__/scaffold-managed-skill-tool.test.ts +0 -137
  142. package/src/__tests__/schedule-retry.test.ts +14 -38
  143. package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
  144. package/src/__tests__/schedule-routes.test.ts +6 -14
  145. package/src/__tests__/schedule-store.test.ts +1 -3
  146. package/src/__tests__/scheduler-disk-pressure.test.ts +6 -17
  147. package/src/__tests__/scheduler-recurrence.test.ts +107 -57
  148. package/src/__tests__/scheduler-reuse-conversation.test.ts +46 -51
  149. package/src/__tests__/scheduler-wake.test.ts +23 -13
  150. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
  151. package/src/__tests__/shell-observability.test.ts +0 -1
  152. package/src/__tests__/skill-boundary-guard.test.ts +4 -3
  153. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -2
  154. package/src/__tests__/skill-script-runner-host.test.ts +0 -53
  155. package/src/__tests__/skill-script-runner-sandbox.test.ts +2 -5
  156. package/src/__tests__/skill-tool-factory.test.ts +1 -73
  157. package/src/__tests__/slack-app-setup-skill-regression.test.ts +14 -37
  158. package/src/__tests__/slack-inbound-verification.test.ts +0 -36
  159. package/src/__tests__/slack-notification-approval-card.test.ts +2 -89
  160. package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -51
  161. package/src/__tests__/stt-hints.test.ts +256 -2
  162. package/src/__tests__/subagent-call-site-routing.test.ts +0 -72
  163. package/src/__tests__/subagent-fork-notifications.test.ts +2 -14
  164. package/src/__tests__/subagent-spawn-and-await.test.ts +0 -1
  165. package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -78
  166. package/src/__tests__/system-prompt.test.ts +118 -17
  167. package/src/__tests__/task-scheduler.test.ts +89 -68
  168. package/src/__tests__/telephony-stt-routing.test.ts +329 -0
  169. package/src/__tests__/title-generate-hook.test.ts +0 -16
  170. package/src/__tests__/tool-approval-handler.test.ts +1 -87
  171. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +20 -45
  172. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -39
  173. package/src/__tests__/trust-context-guards.test.ts +10 -21
  174. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  175. package/src/__tests__/twilio-provider.test.ts +17 -17
  176. package/src/__tests__/twilio-routes-twiml.test.ts +543 -6
  177. package/src/__tests__/twilio-routes.test.ts +387 -257
  178. package/src/__tests__/twilio-validation.test.ts +1 -1
  179. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -5
  180. package/src/__tests__/voice-ingress-preflight.test.ts +0 -61
  181. package/src/__tests__/voice-invite-redemption.test.ts +702 -0
  182. package/src/__tests__/voice-quality.test.ts +2 -2
  183. package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -1
  184. package/src/__tests__/voice-session-bridge.test.ts +10 -1
  185. package/src/__tests__/workspace-git-service.test.ts +1 -1
  186. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +0 -1
  187. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +241 -235
  188. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  189. package/src/acp/__tests__/session-manager-persistence.test.ts +0 -2
  190. package/src/acp/__tests__/session-manager-resume.test.ts +0 -8
  191. package/src/acp/__tests__/session-manager-usage.test.ts +0 -6
  192. package/src/acp/__tests__/session-manager.test.ts +0 -6
  193. package/src/acp/agent-process.ts +0 -71
  194. package/src/acp/auto-install.ts +8 -12
  195. package/src/acp/prepare-agent-env.ts +12 -0
  196. package/src/acp/resolve-agent.test.ts +45 -6
  197. package/src/acp/resolve-agent.ts +4 -2
  198. package/src/acp/session-manager.ts +46 -102
  199. package/src/agent/ax-tree-compaction.test.ts +1 -4
  200. package/src/agent/image-optimize.ts +127 -17
  201. package/src/agent/loop.ts +192 -45
  202. package/src/api/events/conversation-error.ts +1 -0
  203. package/src/api/events/subagent-status-changed.ts +1 -4
  204. package/src/api/index.ts +0 -19
  205. package/src/api/responses/conversation-message.ts +0 -34
  206. package/src/approvals/guardian-decision-primitive.ts +24 -74
  207. package/src/approvals/guardian-request-resolvers.ts +122 -450
  208. package/src/apps/app-store.ts +0 -1
  209. package/src/apps/shared-app-links-store.ts +0 -1
  210. package/src/avatar/identity-avatar.ts +7 -3
  211. package/src/background-wake/wake-intent-hooks.test.ts +1 -1
  212. package/src/calls/__tests__/relay-setup-router.test.ts +102 -126
  213. package/src/calls/call-controller.ts +48 -134
  214. package/src/calls/call-domain.ts +42 -18
  215. package/src/calls/call-pointer-messages.ts +67 -51
  216. package/src/calls/call-speech-output.ts +23 -87
  217. package/src/calls/call-store.ts +0 -4
  218. package/src/calls/call-transport.ts +36 -22
  219. package/src/calls/fish-audio-client.ts +0 -3
  220. package/src/calls/media-stream-audio-transcode.ts +2 -82
  221. package/src/calls/media-stream-output.ts +36 -142
  222. package/src/calls/media-stream-server.ts +178 -297
  223. package/src/calls/media-stream-stt-session.ts +50 -393
  224. package/src/calls/media-turn-detector.ts +6 -4
  225. package/src/calls/relay-access-wait.ts +4 -3
  226. package/src/calls/relay-server.ts +2463 -0
  227. package/src/calls/relay-setup-router.ts +43 -22
  228. package/src/calls/relay-verification.ts +24 -17
  229. package/src/calls/resolve-call-tts-provider.ts +29 -96
  230. package/src/calls/stt-hints.ts +87 -24
  231. package/src/calls/telephony-stt-routing.ts +145 -0
  232. package/src/calls/tts-call-strategy.ts +20 -18
  233. package/src/calls/twilio-provider.ts +2 -3
  234. package/src/calls/twilio-routes.ts +351 -47
  235. package/src/calls/types.ts +3 -5
  236. package/src/calls/voice-ingress-preflight.ts +0 -9
  237. package/src/calls/voice-quality.ts +18 -13
  238. package/src/calls/voice-session-bridge.ts +35 -25
  239. package/src/channels/__tests__/types.test.ts +0 -28
  240. package/src/channels/channel-verification-sessions.ts +2 -7
  241. package/src/channels/config.ts +42 -0
  242. package/src/channels/slack-thread-store.ts +0 -12
  243. package/src/channels/types.ts +0 -23
  244. package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
  245. package/src/cli/commands/__tests__/schedules.test.ts +34 -83
  246. package/src/cli/commands/__tests__/status.test.ts +2 -42
  247. package/src/cli/commands/contacts.ts +2 -2
  248. package/src/cli/commands/credentials.ts +0 -17
  249. package/src/cli/commands/schedules.ts +43 -169
  250. package/src/cli/commands/status.ts +1 -12
  251. package/src/cli/commands/tools.ts +1 -5
  252. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +0 -1
  253. package/src/cli/lib/__tests__/search-plugins.test.ts +1 -29
  254. package/src/cli/lib/__tests__/toggle-plugin.test.ts +0 -7
  255. package/src/cli/lib/search-plugins.ts +0 -6
  256. package/src/cli/lib/toggle-plugin.ts +2 -21
  257. package/src/cli/program.ts +1 -3
  258. package/src/config/__tests__/deployment-context-defaults.test.ts +0 -23
  259. package/src/config/acp-defaults.test.ts +10 -0
  260. package/src/config/acp-defaults.ts +6 -0
  261. package/src/config/bundled-skills/acp/SKILL.md +45 -13
  262. package/src/config/bundled-skills/acp/TOOLS.json +3 -3
  263. package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
  264. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
  265. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
  266. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
  267. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  268. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
  269. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +7 -10
  270. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -10
  271. package/src/config/call-site-defaults.ts +2 -0
  272. package/src/config/feature-flag-registry.json +8 -16
  273. package/src/config/loader.ts +0 -11
  274. package/src/config/schema.ts +1 -9
  275. package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
  276. package/src/config/schemas/__tests__/memory-v3.test.ts +0 -64
  277. package/src/config/schemas/call-site-catalog.ts +12 -0
  278. package/src/config/schemas/calls.ts +0 -8
  279. package/src/config/schemas/elevenlabs.ts +1 -1
  280. package/src/config/schemas/llm.ts +2 -0
  281. package/src/config/schemas/memory-v2.ts +1 -1
  282. package/src/config/schemas/memory-v3.ts +0 -82
  283. package/src/config/seed-inference-profiles.ts +2 -2
  284. package/src/config/skills.ts +0 -26
  285. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +128 -0
  286. package/src/contacts/__tests__/member-write-relay.test.ts +4 -156
  287. package/src/contacts/canonical-guardian-store.ts +0 -5
  288. package/src/contacts/contact-store.ts +35 -81
  289. package/src/contacts/contacts-write.ts +25 -50
  290. package/src/contacts/member-write-relay.ts +31 -115
  291. package/src/contacts/types.ts +8 -0
  292. package/src/context/compactor.ts +15 -29
  293. package/src/daemon/__tests__/daemon-skill-host.test.ts +273 -0
  294. package/src/daemon/__tests__/embedding-reconcile.test.ts +16 -99
  295. package/src/{plugins/defaults/memory/v2 → daemon}/__tests__/memory-v2-startup.test.ts +6 -6
  296. package/src/daemon/app-source-watcher.ts +0 -9
  297. package/src/daemon/assistant-attachments.ts +0 -42
  298. package/src/daemon/conversation-agent-loop-handlers.ts +147 -256
  299. package/src/daemon/conversation-agent-loop.ts +68 -61
  300. package/src/daemon/conversation-error.ts +15 -1
  301. package/src/daemon/conversation-history.ts +236 -32
  302. package/src/daemon/conversation-lifecycle.ts +1 -25
  303. package/src/daemon/conversation-messaging.ts +2 -2
  304. package/src/daemon/conversation-process.ts +14 -50
  305. package/src/daemon/conversation-runtime-assembly.ts +6 -36
  306. package/src/daemon/conversation-skill-tools.ts +3 -19
  307. package/src/daemon/conversation-store.ts +3 -3
  308. package/src/daemon/conversation-surfaces.ts +0 -171
  309. package/src/daemon/conversation-tool-setup.ts +1 -116
  310. package/src/daemon/conversation.ts +1 -92
  311. package/src/daemon/daemon-skill-host.ts +262 -0
  312. package/src/daemon/disk-pressure-policy.ts +1 -2
  313. package/src/daemon/event-loop-watchdog.ts +6 -22
  314. package/src/daemon/external-plugins-bootstrap.ts +134 -47
  315. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  316. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +14 -26
  317. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +14 -27
  318. package/src/daemon/handlers/__tests__/config-channels.test.ts +5 -0
  319. package/src/daemon/handlers/config-a2a.ts +14 -7
  320. package/src/daemon/handlers/config-channels.ts +10 -2
  321. package/src/daemon/handlers/conversation-history.ts +1 -3
  322. package/src/daemon/handlers/conversations.ts +52 -0
  323. package/src/daemon/handlers/shared.ts +24 -4
  324. package/src/daemon/handlers/skills.ts +1 -4
  325. package/src/daemon/host-cu-proxy.ts +1 -1
  326. package/src/daemon/lifecycle.ts +472 -59
  327. package/src/{plugins/defaults/memory/v2 → daemon}/memory-v2-startup.test.ts +8 -8
  328. package/src/{plugins/defaults/memory/v2 → daemon}/memory-v2-startup.ts +22 -20
  329. package/src/daemon/message-protocol.ts +3 -3
  330. package/src/daemon/message-provenance.ts +14 -12
  331. package/src/daemon/message-types/contacts.ts +10 -2
  332. package/src/daemon/message-types/conversations.ts +0 -10
  333. package/src/daemon/message-types/integrations.ts +0 -2
  334. package/src/daemon/message-types/meet.ts +143 -0
  335. package/src/daemon/message-types/surfaces.ts +0 -1
  336. package/src/daemon/message-types/sync.ts +0 -1
  337. package/src/daemon/pointer-conversation-trust.ts +9 -23
  338. package/src/daemon/providers-setup.ts +0 -16
  339. package/src/daemon/shutdown-handlers.ts +47 -139
  340. package/src/daemon/shutdown-registry.ts +40 -0
  341. package/src/daemon/skill-memory-refresh.ts +2 -2
  342. package/src/daemon/tool-setup-types.ts +0 -8
  343. package/src/daemon/trust-context.ts +6 -21
  344. package/src/daemon/turn-latency-tracker.test.ts +0 -93
  345. package/src/daemon/turn-latency-tracker.ts +0 -38
  346. package/src/daemon/wake-conversation-ops.ts +8 -10
  347. package/src/documents/document-comments-store.test.ts +1 -7
  348. package/src/documents/document-comments-store.ts +0 -8
  349. package/src/documents/document-store.ts +0 -15
  350. package/src/export/__tests__/transcript-formatter.test.ts +0 -11
  351. package/src/export/transcript-formatter.ts +67 -49
  352. package/src/home/__tests__/feed-writer.test.ts +1 -247
  353. package/src/home/conversation-starter-checkpoints.ts +0 -1
  354. package/src/home/feed-writer.ts +0 -61
  355. package/src/home/job-handlers/conversation-starters.ts +0 -1
  356. package/src/hooks/hook-loader.ts +0 -12
  357. package/src/hooks/registry.ts +4 -32
  358. package/src/inbound/public-ingress-urls.ts +17 -0
  359. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +253 -0
  360. package/src/ipc/__tests__/skill-server.test.ts +182 -0
  361. package/src/ipc/assistant-server.ts +7 -28
  362. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +4 -60
  363. package/src/ipc/routes/db-proxy.ts +2 -5
  364. package/src/ipc/routes/invite-ipc-routes.ts +39 -53
  365. package/src/ipc/skill-ipc-types.ts +54 -0
  366. package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
  367. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +448 -0
  368. package/src/ipc/skill-routes/__tests__/identity.test.ts +62 -0
  369. package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
  370. package/src/ipc/skill-routes/__tests__/memory.test.ts +203 -0
  371. package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
  372. package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
  373. package/src/ipc/skill-routes/__tests__/registries.test.ts +400 -0
  374. package/src/ipc/skill-routes/config.ts +47 -0
  375. package/src/ipc/skill-routes/events.ts +147 -0
  376. package/src/ipc/skill-routes/identity.ts +21 -0
  377. package/src/ipc/skill-routes/index.ts +37 -0
  378. package/src/ipc/skill-routes/log.ts +40 -0
  379. package/src/ipc/skill-routes/memory.ts +92 -0
  380. package/src/ipc/skill-routes/platform.ts +39 -0
  381. package/src/ipc/skill-routes/providers.ts +162 -0
  382. package/src/ipc/skill-routes/registries.ts +338 -0
  383. package/src/ipc/skill-server.ts +831 -0
  384. package/src/ipc/skill-socket-path.ts +20 -0
  385. package/src/jobs/register-job-handlers.ts +74 -0
  386. package/src/jobs/worker.ts +2 -9
  387. package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -10
  388. package/src/live-voice/live-voice-archive.ts +0 -5
  389. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +6 -22
  390. package/src/messaging/providers/channel-transport.ts +0 -6
  391. package/src/messaging/providers/index.ts +0 -3
  392. package/src/messaging/providers/slack/api.test.ts +1 -49
  393. package/src/messaging/providers/slack/api.ts +0 -110
  394. package/src/messaging/providers/slack/send.test.ts +0 -85
  395. package/src/messaging/providers/slack/send.ts +28 -100
  396. package/src/messaging/providers/slack/transport.ts +13 -7
  397. package/src/messaging/providers/whatsapp/send.ts +9 -29
  398. package/src/notifications/README.md +1 -1
  399. package/src/notifications/access-request-copy.ts +23 -94
  400. package/src/notifications/adapters/slack.ts +21 -89
  401. package/src/notifications/approval-card-builder.ts +18 -33
  402. package/src/notifications/approval-card-data.ts +15 -48
  403. package/src/notifications/broadcaster.ts +16 -29
  404. package/src/notifications/decision-engine.ts +32 -131
  405. package/src/notifications/guardian-question-mode.ts +10 -58
  406. package/src/permissions/approval-policy.ts +1 -8
  407. package/src/permissions/checker.ts +0 -2
  408. package/src/permissions/gateway-threshold-reader.ts +6 -7
  409. package/src/permissions/ipc-risk-types.ts +0 -1
  410. package/src/permissions/secret-prompter.ts +3 -11
  411. package/src/permissions/types.ts +2 -2
  412. package/src/persistence/attachments-store.ts +10 -94
  413. package/src/persistence/checkpoints.ts +0 -45
  414. package/src/persistence/conversation-crud.ts +260 -453
  415. package/src/persistence/conversation-display-order-migration.ts +2 -8
  416. package/src/persistence/conversation-group-migration.test.ts +0 -8
  417. package/src/persistence/conversation-group-migration.ts +0 -9
  418. package/src/persistence/conversation-queries.ts +125 -244
  419. package/src/persistence/conversation-row-batch-delete.ts +5 -9
  420. package/src/persistence/db-async-query.ts +0 -42
  421. package/src/persistence/db-connection.ts +0 -13
  422. package/src/persistence/delivery-channels.ts +82 -0
  423. package/src/persistence/delivery-crud.ts +6 -27
  424. package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +5 -18
  425. package/src/persistence/embeddings/embedding-identity.ts +5 -17
  426. package/src/persistence/embeddings/embedding-runtime-manager.ts +0 -31
  427. package/src/persistence/embeddings/qdrant-client.ts +5 -81
  428. package/src/persistence/group-crud.ts +1 -13
  429. package/src/persistence/invite-store.ts +481 -0
  430. package/src/persistence/job-handlers/cleanup.ts +9 -57
  431. package/src/persistence/jobs-store.ts +8 -102
  432. package/src/persistence/jobs-worker.ts +28 -68
  433. package/src/persistence/llm-request-log-store.ts +19 -35
  434. package/src/persistence/llm-usage-store.ts +0 -11
  435. package/src/persistence/memory-lifecycle-hooks.test.ts +0 -65
  436. package/src/persistence/memory-lifecycle-hooks.ts +1 -55
  437. package/src/persistence/migrations/028-call-session-mode.ts +1 -1
  438. package/src/persistence/migrations/116-messages-fts.ts +1 -8
  439. package/src/persistence/raw-query.ts +11 -50
  440. package/src/persistence/schema/a2a.ts +0 -14
  441. package/src/persistence/schema/contacts.ts +62 -0
  442. package/src/persistence/schema/conversations.ts +0 -2
  443. package/src/persistence/schema/guardian.ts +0 -4
  444. package/src/persistence/schema/index.ts +0 -4
  445. package/src/persistence/steps.ts +0 -16
  446. package/src/persistence/worker-control.ts +238 -45
  447. package/src/plugin-api/index.ts +1 -9
  448. package/src/plugin-api/types.ts +9 -40
  449. package/src/plugins/defaults/index.ts +29 -19
  450. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +67 -46
  451. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +1 -36
  452. package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +4 -2
  453. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
  454. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +0 -9
  455. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -7
  456. package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
  457. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +113 -124
  458. package/src/plugins/defaults/memory/graph/bootstrap.test.ts +10 -36
  459. package/src/plugins/defaults/memory/graph/bootstrap.ts +5 -6
  460. package/src/plugins/defaults/memory/graph/consolidation.ts +5 -3
  461. package/src/plugins/defaults/memory/graph/extraction.ts +6 -3
  462. package/src/plugins/defaults/memory/graph/graph-search.ts +23 -12
  463. package/src/plugins/defaults/memory/graph/narrative.ts +5 -3
  464. package/src/plugins/defaults/memory/graph/pattern-scan.ts +5 -3
  465. package/src/plugins/defaults/memory/graph/retriever.test.ts +6 -1
  466. package/src/plugins/defaults/memory/graph/retriever.ts +10 -5
  467. package/src/plugins/defaults/memory/graph/tools.ts +1 -1
  468. package/src/plugins/defaults/memory/hooks/init.ts +5 -31
  469. package/src/plugins/defaults/memory/indexer.ts +3 -2
  470. package/src/plugins/defaults/memory/injectors.ts +2 -2
  471. package/src/plugins/defaults/memory/job-handlers/backfill.ts +26 -4
  472. package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +19 -6
  473. package/src/plugins/defaults/memory/job-handlers/embedding.ts +22 -9
  474. package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +3 -2
  475. package/src/plugins/defaults/memory/job-handlers.ts +12 -13
  476. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
  477. package/src/plugins/defaults/memory/memory-retrospective-job.ts +5 -8
  478. package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
  479. package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +0 -2
  480. package/src/plugins/defaults/memory/persistence-hooks.ts +1 -46
  481. package/src/plugins/defaults/memory/pkb/pkb-index.ts +5 -1
  482. package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
  483. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +6 -4
  484. package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
  485. package/src/plugins/defaults/memory/search/semantic.ts +2 -2
  486. package/src/plugins/defaults/memory/task-memory-cleanup.ts +0 -8
  487. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +13 -2
  488. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +5 -4
  489. package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +8 -1
  490. package/src/plugins/defaults/memory/v2/activation.ts +4 -2
  491. package/src/plugins/defaults/memory/v2/cli-command-store.ts +4 -2
  492. package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
  493. package/src/plugins/defaults/memory/v2/migration.ts +5 -2
  494. package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
  495. package/src/plugins/defaults/memory/v2/qdrant.ts +3 -2
  496. package/src/plugins/defaults/memory/v2/router.ts +5 -5
  497. package/src/plugins/defaults/memory/v2/sim.ts +4 -2
  498. package/src/plugins/defaults/memory/v2/skill-store.ts +4 -2
  499. package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
  500. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +9 -11
  501. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +2 -107
  502. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +3 -7
  503. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +8 -345
  504. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +4 -1
  505. package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +0 -64
  506. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +13 -18
  507. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +1 -62
  508. package/src/plugins/defaults/memory/v3/card.ts +4 -1
  509. package/src/plugins/defaults/memory/v3/dense.ts +25 -60
  510. package/src/plugins/defaults/memory/v3/edge.ts +1 -1
  511. package/src/plugins/defaults/memory/v3/maintain-job.ts +4 -2
  512. package/src/plugins/defaults/memory/v3/orchestrate.ts +25 -186
  513. package/src/plugins/defaults/memory/v3/pool-select.test.ts +9 -7
  514. package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
  515. package/src/plugins/defaults/memory/v3/prune.ts +2 -2
  516. package/src/plugins/defaults/memory/v3/section-dense-store.ts +11 -8
  517. package/src/plugins/defaults/memory/v3/section-needle.ts +7 -27
  518. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +0 -10
  519. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +4 -1
  520. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +0 -5
  521. package/src/plugins/defaults/turn-context/injectors.ts +0 -1
  522. package/src/plugins/defaults/turn-context/unified-turn-context.ts +0 -12
  523. package/src/plugins/injector-registry.ts +2 -13
  524. package/src/plugins/job-handler-registry.ts +94 -0
  525. package/src/plugins/mtime-cache.ts +47 -36
  526. package/src/plugins/pipeline.ts +1 -15
  527. package/src/plugins/types.ts +23 -14
  528. package/src/prompts/__tests__/system-prompt.test.ts +32 -170
  529. package/src/prompts/persona-resolver.ts +9 -13
  530. package/src/prompts/system-prompt.ts +9 -30
  531. package/src/prompts/templates/BOOTSTRAP.md +119 -16
  532. package/src/prompts/templates/SOUL.md +13 -43
  533. package/src/prompts/templates/system-sections.ts +27 -32
  534. package/src/prompts/templates/users/default.md +0 -19
  535. package/src/providers/__tests__/placeholder-sentinels.test.ts +0 -56
  536. package/src/providers/cache-control.ts +26 -0
  537. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -96
  538. package/src/providers/model-intents.ts +2 -2
  539. package/src/providers/openai/chat-completions-provider.ts +1 -14
  540. package/src/providers/openai/responses-provider.ts +0 -18
  541. package/src/providers/placeholder-sentinels.ts +8 -18
  542. package/src/providers/retry.ts +0 -1
  543. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +64 -0
  544. package/src/providers/speech-to-text/__tests__/resolve.test.ts +79 -92
  545. package/src/providers/speech-to-text/deepgram-realtime.test.ts +0 -98
  546. package/src/providers/speech-to-text/deepgram-realtime.ts +3 -62
  547. package/src/providers/speech-to-text/provider-catalog.ts +89 -0
  548. package/src/providers/speech-to-text/resolve.ts +0 -55
  549. package/src/providers/types.ts +1 -1
  550. package/src/runtime/AGENTS.md +4 -5
  551. package/src/runtime/__tests__/agent-wake.test.ts +1 -158
  552. package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
  553. package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
  554. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +8 -37
  555. package/src/runtime/access-request-helper.ts +3 -154
  556. package/src/runtime/actor-trust-resolver.ts +21 -7
  557. package/src/runtime/agent-wake.ts +1 -41
  558. package/src/runtime/assistant-event.ts +12 -86
  559. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -31
  560. package/src/runtime/channel-approval-types.ts +2 -52
  561. package/src/runtime/channel-approvals.ts +8 -23
  562. package/src/runtime/channel-invite-transport.ts +2 -2
  563. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  564. package/src/runtime/channel-readiness-service.ts +5 -3
  565. package/src/runtime/channel-retry-sweep.ts +24 -18
  566. package/src/runtime/channel-verification-service.ts +11 -9
  567. package/src/runtime/finalize-event-delivery.ts +16 -30
  568. package/src/runtime/guardian-action-service.ts +11 -10
  569. package/src/runtime/guardian-reply-router.ts +21 -122
  570. package/src/runtime/http-server.ts +101 -44
  571. package/src/runtime/invite-redemption-service.ts +828 -0
  572. package/src/runtime/invite-redemption-templates.ts +46 -0
  573. package/src/runtime/invite-service.ts +361 -104
  574. package/src/runtime/local-actor-identity.test.ts +0 -38
  575. package/src/runtime/local-actor-identity.ts +0 -14
  576. package/src/runtime/middleware/__tests__/rate-limiter.test.ts +0 -22
  577. package/src/runtime/middleware/rate-limiter.ts +0 -30
  578. package/src/runtime/middleware/twilio-validation.ts +7 -5
  579. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +0 -28
  580. package/src/runtime/migrations/origin-mode.ts +6 -6
  581. package/src/runtime/pre-first-message-gate.ts +0 -1
  582. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +35 -6
  583. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +3 -24
  584. package/src/runtime/routes/__tests__/contact-routes.test.ts +15 -80
  585. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -7
  586. package/src/runtime/routes/__tests__/global-search-routes.test.ts +3 -0
  587. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +1 -142
  588. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +30 -119
  589. package/src/runtime/routes/__tests__/plugins-routes.test.ts +29 -755
  590. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +0 -4
  591. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
  592. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
  593. package/src/runtime/routes/acp-routes.ts +3 -15
  594. package/src/runtime/routes/app-management-routes.ts +7 -4
  595. package/src/runtime/routes/approval-routes.ts +0 -4
  596. package/src/runtime/routes/attachment-routes.ts +3 -54
  597. package/src/runtime/routes/avatar-routes.ts +4 -0
  598. package/src/runtime/routes/background-tool-routes.ts +5 -34
  599. package/src/runtime/routes/btw-routes.ts +4 -32
  600. package/src/runtime/routes/channel-route-shared.ts +14 -18
  601. package/src/runtime/routes/channel-verification-routes.ts +3 -0
  602. package/src/runtime/routes/contact-routes.ts +117 -298
  603. package/src/runtime/routes/conversation-list-routes.ts +0 -6
  604. package/src/runtime/routes/conversation-management-routes.ts +37 -74
  605. package/src/runtime/routes/conversation-query-routes.ts +2 -5
  606. package/src/runtime/routes/conversation-routes.ts +82 -222
  607. package/src/runtime/routes/conversations-import-routes.ts +1 -8
  608. package/src/runtime/routes/credential-prompt-routes.ts +5 -20
  609. package/src/runtime/routes/debug-routes.ts +0 -1
  610. package/src/runtime/routes/documents-routes.ts +2 -5
  611. package/src/runtime/routes/empty-state-greeting-cache.ts +10 -37
  612. package/src/runtime/routes/global-search-routes.ts +1 -2
  613. package/src/runtime/routes/guardian-approval-interception.ts +0 -51
  614. package/src/runtime/routes/home-feed-routes.ts +1 -60
  615. package/src/runtime/routes/identity-routes.ts +87 -4
  616. package/src/runtime/routes/inbound-message-handler.ts +41 -82
  617. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +57 -430
  618. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +572 -302
  619. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +270 -76
  620. package/src/runtime/routes/inbound-stages/background-dispatch.ts +116 -21
  621. package/src/runtime/routes/inbound-stages/edit-intercept.ts +1 -9
  622. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -22
  623. package/src/runtime/routes/index.ts +0 -6
  624. package/src/runtime/routes/inference-provider-connection-routes.ts +16 -22
  625. package/src/runtime/routes/internal-twilio-routes.ts +15 -0
  626. package/src/runtime/routes/migration-routes.ts +6 -69
  627. package/src/runtime/routes/plugins-routes.ts +8 -329
  628. package/src/runtime/routes/schedule-routes.ts +8 -49
  629. package/src/runtime/routes/secret-routes.ts +1 -1
  630. package/src/runtime/routes/surface-conversation-resolver.ts +0 -1
  631. package/src/runtime/runtime-mode.ts +40 -0
  632. package/src/runtime/services/__tests__/analyze-conversation.test.ts +9 -54
  633. package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +6 -30
  634. package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +8 -43
  635. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -20
  636. package/src/runtime/services/analyze-conversation.ts +4 -14
  637. package/src/runtime/services/conversation-serializer.ts +0 -5
  638. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  639. package/src/runtime/sync/resource-sync-events.ts +0 -25
  640. package/src/runtime/tool-grant-request-helper.ts +1 -17
  641. package/src/runtime/trust-verdict-consumer.ts +6 -7
  642. package/src/schedule/run-script.ts +6 -13
  643. package/src/schedule/schedule-usage-store.ts +0 -1
  644. package/src/schedule/scheduler.ts +127 -178
  645. package/src/skills/categories-cache.ts +5 -40
  646. package/src/skills/managed-store.ts +6 -41
  647. package/src/skills/validate-input.ts +0 -47
  648. package/src/stt/types.ts +9 -5
  649. package/src/subagent/manager.ts +39 -267
  650. package/src/subagent/types.ts +2 -6
  651. package/src/tools/acp/list-agents.test.ts +6 -0
  652. package/src/tools/background-tool-registry.ts +0 -61
  653. package/src/tools/document/document-comment-tool.test.ts +0 -4
  654. package/src/tools/host-terminal/host-shell.ts +14 -203
  655. package/src/tools/skills/find-similar-skills.test.ts +1 -152
  656. package/src/tools/skills/find-similar-skills.ts +4 -30
  657. package/src/tools/skills/load.ts +0 -36
  658. package/src/tools/skills/scaffold-managed.ts +34 -66
  659. package/src/tools/skills/skill-script-runner.ts +0 -17
  660. package/src/tools/skills/skill-tool-factory.ts +1 -5
  661. package/src/tools/terminal/safe-env.ts +0 -3
  662. package/src/tools/terminal/shell.ts +4 -98
  663. package/src/tools/tool-approval-handler.ts +29 -106
  664. package/src/tools/types.ts +17 -29
  665. package/src/tools/ui-surface/definitions.ts +1 -3
  666. package/src/tts/__tests__/provider-adapters.test.ts +0 -37
  667. package/src/tts/__tests__/provider-catalog.test.ts +0 -21
  668. package/src/tts/provider-catalog.ts +9 -40
  669. package/src/tts/providers/fish-audio-provider.ts +10 -19
  670. package/src/tts/types.ts +4 -3
  671. package/src/util/__tests__/process-tree.test.ts +2 -10
  672. package/src/util/phone.ts +8 -1
  673. package/src/util/platform.ts +0 -33
  674. package/src/util/process-tree.ts +2 -10
  675. package/src/util/voice-code.ts +31 -0
  676. package/src/workflows/journal-store.ts +1 -16
  677. package/src/workflows/library.test.ts +20 -35
  678. package/src/workflows/library.ts +66 -105
  679. package/src/workspace/git-service.ts +0 -1
  680. package/src/workspace/migrations/011-backfill-installation-id.ts +31 -83
  681. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +22 -41
  682. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
  683. package/src/workspace/migrations/registry.ts +0 -12
  684. package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +0 -233
  685. package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +0 -216
  686. package/src/__tests__/add-message-preassigned-id.test.ts +0 -56
  687. package/src/__tests__/agent-loop-set-system-prompt.test.ts +0 -139
  688. package/src/__tests__/attachments-store-heic-normalize.test.ts +0 -230
  689. package/src/__tests__/call-setup-flow-invite.test.ts +0 -568
  690. package/src/__tests__/call-setup-flow-midcall-trust.test.ts +0 -231
  691. package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -754
  692. package/src/__tests__/call-setup-flow-verification.test.ts +0 -925
  693. package/src/__tests__/call-setup-flow.test.ts +0 -311
  694. package/src/__tests__/channel-setup-panel-ack.test.ts +0 -184
  695. package/src/__tests__/clear-all-lexical.test.ts +0 -90
  696. package/src/__tests__/compactor-media-strip.test.ts +0 -177
  697. package/src/__tests__/conversation-crud-enabled-plugins.test.ts +0 -60
  698. package/src/__tests__/conversation-enabledplugins-route.test.ts +0 -184
  699. package/src/__tests__/conversation-initial-prompt.test.ts +0 -110
  700. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +0 -191
  701. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +0 -392
  702. package/src/__tests__/conversation-routes-hidden-queue.test.ts +0 -407
  703. package/src/__tests__/db-drop-messages-fts.test.ts +0 -115
  704. package/src/__tests__/guardian-wait-controller.test.ts +0 -619
  705. package/src/__tests__/heic-fixture.ts +0 -55
  706. package/src/__tests__/image-conversion.test.ts +0 -170
  707. package/src/__tests__/introduction-card-resolver.test.ts +0 -354
  708. package/src/__tests__/invite-redeemed-ipc.test.ts +0 -97
  709. package/src/__tests__/job-handler-registration-guard.test.ts +0 -104
  710. package/src/__tests__/lexical-index-dual-write.test.ts +0 -426
  711. package/src/__tests__/list-messages-background-tool-completion.test.ts +0 -141
  712. package/src/__tests__/media-stream-audio-transcode.test.ts +0 -113
  713. package/src/__tests__/personal-memory-auth-bypass.test.ts +0 -62
  714. package/src/__tests__/plugin-effective-enabled-set.test.ts +0 -227
  715. package/src/__tests__/plugin-event-hub-facade.test.ts +0 -323
  716. package/src/__tests__/prune-old-tool-invocations-job.test.ts +0 -97
  717. package/src/__tests__/scheduler-worker-standdown.test.ts +0 -220
  718. package/src/__tests__/skill-load-plugin-scope.test.ts +0 -238
  719. package/src/__tests__/subagent-allowlist-validation.test.ts +0 -47
  720. package/src/__tests__/subagent-persistence.test.ts +0 -122
  721. package/src/__tests__/subagent-terminal-message.test.ts +0 -99
  722. package/src/__tests__/telephony-credential-preflight.test.ts +0 -312
  723. package/src/__tests__/telephony-tts-guard.test.ts +0 -538
  724. package/src/__tests__/unified-turn-context-client-os.test.ts +0 -45
  725. package/src/__tests__/voice-approval-resolver-relay.test.ts +0 -150
  726. package/src/__tests__/voice-session-bridge-processing-wait.test.ts +0 -27
  727. package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +0 -120
  728. package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +0 -175
  729. package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +0 -118
  730. package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +0 -119
  731. package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +0 -191
  732. package/src/acp/agent-process.test.ts +0 -116
  733. package/src/acp/failure-error.test.ts +0 -109
  734. package/src/acp/failure-error.ts +0 -111
  735. package/src/acp/session-manager.test.ts +0 -312
  736. package/src/api/events/background-tool-completed.test.ts +0 -51
  737. package/src/api/events/background-tool-completed.ts +0 -29
  738. package/src/api/events/background-tool-started.test.ts +0 -36
  739. package/src/api/events/background-tool-started.ts +0 -28
  740. package/src/api/events/open-panel.ts +0 -33
  741. package/src/calls/__tests__/fish-audio-client.test.ts +0 -73
  742. package/src/calls/__tests__/gateway-invite-reader.test.ts +0 -170
  743. package/src/calls/call-setup-flow-types.ts +0 -76
  744. package/src/calls/call-setup-flow.ts +0 -1743
  745. package/src/calls/gateway-invite-reader.ts +0 -98
  746. package/src/calls/guardian-wait-controller.ts +0 -451
  747. package/src/calls/telephony-credential-preflight.ts +0 -159
  748. package/src/calls/telephony-tts-capability.ts +0 -183
  749. package/src/cli/commands/monitoring.ts +0 -191
  750. package/src/cli/commands/schedules-worker.ts +0 -175
  751. package/src/config/schemas/monitoring.ts +0 -61
  752. package/src/config/schemas/schedules.ts +0 -35
  753. package/src/config/skills-plugin-filter.test.ts +0 -96
  754. package/src/context/outbound-sanitize.ts +0 -202
  755. package/src/daemon/__tests__/abort-null-controller.test.ts +0 -167
  756. package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +0 -122
  757. package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +0 -107
  758. package/src/daemon/abort-watchdog.ts +0 -7
  759. package/src/daemon/conversation-initial-prompt.ts +0 -77
  760. package/src/daemon/conversation-plugin-scope.ts +0 -38
  761. package/src/daemon/conversation-tool-setup.test.ts +0 -95
  762. package/src/daemon/conversation-turn-finalize.ts +0 -211
  763. package/src/daemon/message-types/background-tools.ts +0 -28
  764. package/src/daemon/pointer-turn-runner.ts +0 -174
  765. package/src/daemon/sqlite-corruption-watchdog.test.ts +0 -217
  766. package/src/daemon/sqlite-corruption-watchdog.ts +0 -155
  767. package/src/ipc/__tests__/contacts-info-ipc.test.ts +0 -285
  768. package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +0 -62
  769. package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +0 -272
  770. package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +0 -322
  771. package/src/ipc/routes/contacts-info-ipc-routes.ts +0 -239
  772. package/src/ipc/routes/contacts-mirror-ipc-routes.ts +0 -202
  773. package/src/monitoring/__tests__/control.test.ts +0 -235
  774. package/src/monitoring/__tests__/sample-ring-buffer.test.ts +0 -96
  775. package/src/monitoring/control.ts +0 -105
  776. package/src/monitoring/resource-sampler.ts +0 -258
  777. package/src/monitoring/sample-ring-buffer.ts +0 -108
  778. package/src/monitoring/worker.ts +0 -94
  779. package/src/persistence/__tests__/conversation-queries-search.test.ts +0 -397
  780. package/src/persistence/__tests__/conversation-search-lexical.test.ts +0 -103
  781. package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +0 -95
  782. package/src/persistence/__tests__/slow-query-log.test.ts +0 -266
  783. package/src/persistence/__tests__/slow-sync-log.test.ts +0 -155
  784. package/src/persistence/a2a-invite-store.ts +0 -205
  785. package/src/persistence/conversation-search-lexical.ts +0 -49
  786. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +0 -334
  787. package/src/persistence/embeddings/messages-lexical-index.ts +0 -396
  788. package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +0 -506
  789. package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +0 -164
  790. package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +0 -259
  791. package/src/persistence/job-handlers/message-lexical-backfill.ts +0 -187
  792. package/src/persistence/job-handlers/message-lexical.ts +0 -251
  793. package/src/persistence/migrations/311-create-subagents-table.ts +0 -50
  794. package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +0 -15
  795. package/src/persistence/migrations/313-drop-messages-fts.ts +0 -17
  796. package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +0 -25
  797. package/src/persistence/migrations/315-create-a2a-invites.ts +0 -58
  798. package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +0 -28
  799. package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +0 -24
  800. package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +0 -32
  801. package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +0 -161
  802. package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +0 -156
  803. package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +0 -134
  804. package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +0 -99
  805. package/src/persistence/schema/conversation-groups.ts +0 -12
  806. package/src/persistence/schema/documents.ts +0 -65
  807. package/src/persistence/schema/memory-injection.ts +0 -62
  808. package/src/persistence/schema/workflows.ts +0 -55
  809. package/src/persistence/slow-query-log.ts +0 -437
  810. package/src/persistence/slow-sync-log.ts +0 -204
  811. package/src/persistence/subagent-store.ts +0 -125
  812. package/src/plugin-api/event-hub-facade.ts +0 -172
  813. package/src/plugins/defaults/default-plugin-names.ts +0 -60
  814. package/src/plugins/defaults/memory/config.ts +0 -11
  815. package/src/plugins/defaults/memory/embeddings.ts +0 -77
  816. package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +0 -66
  817. package/src/plugins/defaults/memory/frontmatter.ts +0 -50
  818. package/src/plugins/defaults/memory/job-handler-registration.ts +0 -96
  819. package/src/plugins/defaults/memory/llm-helpers.ts +0 -76
  820. package/src/plugins/defaults/memory/startup.ts +0 -244
  821. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  822. package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +0 -181
  823. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  824. package/src/plugins/defaults/memory/v3/gate.ts +0 -158
  825. package/src/providers/tool-progress-events.test.ts +0 -50
  826. package/src/providers/tool-progress-events.ts +0 -99
  827. package/src/runtime/introduction-policy.test.ts +0 -214
  828. package/src/runtime/introduction-policy.ts +0 -284
  829. package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +0 -70
  830. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +0 -194
  831. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +0 -70
  832. package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +0 -161
  833. package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +0 -158
  834. package/src/runtime/routes/messages-lexical-routes.ts +0 -75
  835. package/src/runtime/routes/monitoring-routes.ts +0 -237
  836. package/src/runtime/routes/schedule-worker-routes.ts +0 -210
  837. package/src/runtime/slack-no-response.ts +0 -47
  838. package/src/runtime/slack-reply-session.test.ts +0 -633
  839. package/src/runtime/slack-reply-session.ts +0 -382
  840. package/src/runtime/slack-task-progress.ts +0 -95
  841. package/src/runtime/trust-class.test.ts +0 -141
  842. package/src/runtime/trust-class.ts +0 -121
  843. package/src/schedule/__tests__/run-script.test.ts +0 -21
  844. package/src/schedule/__tests__/worker-control.test.ts +0 -241
  845. package/src/schedule/worker-control.ts +0 -118
  846. package/src/schedule/worker.ts +0 -131
  847. package/src/skills/__tests__/categories-cache.test.ts +0 -38
  848. package/src/subagent/validate-allowlists.ts +0 -65
  849. package/src/telemetry/watchdog-direct-emit.test.ts +0 -109
  850. package/src/telemetry/watchdog-direct-emit.ts +0 -89
  851. package/src/tools/host-terminal/host-shell.test.ts +0 -397
  852. package/src/tools/terminal/shell.test.ts +0 -177
  853. package/src/util/__tests__/text-spacing.test.ts +0 -53
  854. package/src/util/cgroup-memory.ts +0 -142
  855. package/src/util/image-conversion.ts +0 -281
  856. package/src/util/text-spacing.ts +0 -53
  857. package/src/util/worker-process.ts +0 -271
  858. package/src/workspace/migrations/118-seed-now-md.ts +0 -64
  859. package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +0 -169
  860. package/src/workspace/migrations/120-revise-onboarding-threads.ts +0 -47
  861. package/src/workspace/migrations/121-seed-default-user-guardrails.ts +0 -82
  862. package/src/workspace/migrations/122-relocate-default-user-boundary.ts +0 -111
  863. package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +0 -85
  864. package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +0 -181
package/ARCHITECTURE.md CHANGED
@@ -16,10 +16,10 @@ This document owns assistant-runtime architecture details. The repo-level archit
16
16
  - Guardian/non-guardian/unverified classification is centralized in `assistant/src/runtime/trust-context-resolver.ts`.
17
17
  - The same resolver is used by:
18
18
  - `/channels/inbound` (Telegram/WhatsApp path) before run orchestration.
19
- - Inbound Twilio voice setup (media-stream `routeSetup`) to seed call-time actor context.
19
+ - Inbound Twilio voice setup (`RelayConnection.handleSetup`) to seed call-time actor context.
20
20
  - Runtime channel runs pass this as `trustContext`, and conversation runtime assembly includes actor context in the unified `<turn_context>` block (via `buildUnifiedTurnContextBlock()`) injected into provider-facing prompts.
21
21
  - Voice calls mirror the same prompt contract: `CallController` receives guardian context on setup and refreshes it immediately after successful voice challenge verification, so the first post-verification turn is grounded as `actor_role: guardian`.
22
- - Voice-specific behavior (DTMF/speech verification flow, call-setup state machine) remains voice-local; only actor-role resolution is shared.
22
+ - Voice-specific behavior (DTMF/speech verification flow, relay state machine) remains voice-local; only actor-role resolution is shared.
23
23
 
24
24
  ### Safe Storage Limits
25
25
 
@@ -289,17 +289,17 @@ When a voice call's ASK_GUARDIAN consultation times out before the guardian resp
289
289
 
290
290
  **Key source files:**
291
291
 
292
- | File | Purpose |
293
- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
294
- | `src/memory/guardian-action-store.ts` | Follow-up state machine with atomic transitions (`startFollowupFromExpiredRequest`, `progressFollowupState`, `finalizeFollowup`) and query helpers for pending/expired/follow-up deliveries |
295
- | `src/runtime/guardian-action-message-composer.ts` | 2-tier text generation: daemon-injected LLM generator with deterministic fallback templates. Covers all scenarios from timeout acknowledgment through follow-up completion |
296
- | `src/runtime/guardian-action-followup-executor.ts` | Action dispatch: resolves counterparty from call session, executes `call_back` (outbound call via `startCall`), finalizes follow-up state |
297
- | `src/daemon/guardian-action-generators.ts` | Daemon-injected generator factory: `createGuardianActionCopyGenerator` (latency-optimized text rewriting for guardian-facing copy) |
298
- | `src/calls/call-controller.ts` | Voice timeout handling: marks requests as timed out, sends expiry notices, injects `[GUARDIAN_TIMEOUT]` instruction for generated voice response |
299
- | `src/runtime/routes/inbound-message-handler.ts` | Late reply interception for Telegram channels: matches late answers to expired requests, routes follow-up conversation turns, dispatches actions |
300
- | `src/daemon/conversation-process.ts` | Late reply interception for mac channel: same logic as inbound-message-handler but using conversation-ID-based delivery lookup |
301
- | `src/calls/guardian-action-sweep.ts` | Periodic sweep for stale pending requests; sends expiry notices to guardian destinations |
302
- | `src/persistence/migrations/030-guardian-action-followup.ts` | Schema migration adding follow-up columns (`followup_state`, `late_answer_text`, `late_answered_at`, `followup_action`, `followup_completed_at`) |
292
+ | File | Purpose |
293
+ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
294
+ | `src/memory/guardian-action-store.ts` | Follow-up state machine with atomic transitions (`startFollowupFromExpiredRequest`, `progressFollowupState`, `finalizeFollowup`) and query helpers for pending/expired/follow-up deliveries |
295
+ | `src/runtime/guardian-action-message-composer.ts` | 2-tier text generation: daemon-injected LLM generator with deterministic fallback templates. Covers all scenarios from timeout acknowledgment through follow-up completion |
296
+ | `src/runtime/guardian-action-followup-executor.ts` | Action dispatch: resolves counterparty from call session, executes `call_back` (outbound call via `startCall`), finalizes follow-up state |
297
+ | `src/daemon/guardian-action-generators.ts` | Daemon-injected generator factory: `createGuardianActionCopyGenerator` (latency-optimized text rewriting for guardian-facing copy) |
298
+ | `src/calls/call-controller.ts` | Voice timeout handling: marks requests as timed out, sends expiry notices, injects `[GUARDIAN_TIMEOUT]` instruction for generated voice response |
299
+ | `src/runtime/routes/inbound-message-handler.ts` | Late reply interception for Telegram channels: matches late answers to expired requests, routes follow-up conversation turns, dispatches actions |
300
+ | `src/daemon/conversation-process.ts` | Late reply interception for mac channel: same logic as inbound-message-handler but using conversation-ID-based delivery lookup |
301
+ | `src/calls/guardian-action-sweep.ts` | Periodic sweep for stale pending requests; sends expiry notices to guardian destinations |
302
+ | `src/memory/migrations/030-guardian-action-followup.ts` | Schema migration adding follow-up columns (`followup_state`, `late_answer_text`, `late_answered_at`, `followup_action`, `followup_completed_at`) |
303
303
 
304
304
  ### WhatsApp Channel (Meta Cloud API)
305
305
 
@@ -429,8 +429,9 @@ External users who are not the guardian can gain access to the assistant through
429
429
  | `src/runtime/routes/access-request-decision.ts` | Guardian decision → verification session creation |
430
430
  | `src/runtime/routes/guardian-approval-interception.ts` | Routes guardian decisions (button + conversational) to access request handler |
431
431
  | `src/runtime/channel-verification-service.ts` | Verification session lifecycle, identity binding, rate limiting |
432
- | `src/runtime/routes/contact-routes.ts` | HTTP/IPC handlers for contacts, channels, and invites (invite ops relay to gateway IPC) |
433
- | `src/runtime/invite-service.ts` | Daemon-owned invite presentation (share link, guardian instruction) over gateway-minted invites |
432
+ | `src/runtime/routes/contact-routes.ts` | HTTP API handlers for contact and channel management |
433
+ | `src/runtime/routes/invite-routes.ts` | HTTP API handlers for invite management |
434
+ | `src/runtime/invite-service.ts` | Business logic for invite operations |
434
435
  | `src/contacts/contact-store.ts` | Contact read queries — lookup, search, list, and channel operations |
435
436
  | `src/memory/guardian-approvals.ts` | Approval request persistence |
436
437
  | `src/channels/channel-verification-sessions.ts` | Verification challenge persistence |
@@ -454,12 +455,11 @@ A complementary access-granting flow where the guardian proactively creates a sh
454
455
  │ • extractInboundToken(payload) → token | undefined │
455
456
  │ Registered: Telegram │ Deferred: Slack, Voice │
456
457
  ├─────────────────────────────────────────────────────────────┤
457
- │ Core Redemption Engine (gateway-native)
458
- gateway/src/verification/invite-redemption.ts
459
- Token/code validation, expiry, use-count, channel-match
460
- │ enforcement, atomic claim, gateway ACL activation │
458
+ │ Core Redemption Engine (invite-redemption-service.ts)
459
+ Channel-agnostic token validation, expiry, use-count,
460
+ channel-match enforcement, contact activation/reactivation
461
461
  │ Returns: InviteRedemptionOutcome (discriminated union) │
462
- Daemon mirrors contact info via the invite_redeemed event
462
+ Reply templates: invite-redemption-templates.ts
463
463
  └─────────────────────────────────────────────────────────────┘
464
464
  ```
465
465
 
@@ -467,42 +467,42 @@ A complementary access-granting flow where the guardian proactively creates a sh
467
467
 
468
468
  1. Guardian asks the assistant to create an invite via desktop chat.
469
469
  2. `guardian-invite-intent.ts` detects the intent and rewrites the message to force-load the `contacts` skill.
470
- 3. The skill calls the invites HTTP API; the daemon relays the mint to the gateway (`invites_create` IPC), which writes the canonical `ingress_invites` row, then the daemon's Telegram transport adapter builds a deep link: `https://t.me/<bot>?start=iv_<token>`.
470
+ 3. The skill calls the ingress HTTP API to create an invite token, then calls the Telegram transport adapter to build a deep link: `https://t.me/<bot>?start=iv_<token>`.
471
471
  4. Guardian shares the link with the invitee out-of-band.
472
472
  5. Invitee clicks the link, opening Telegram which sends `/start iv_<token>` to the bot.
473
- 6. The gateway intercepts the `/start iv_<token>` message at ingress (before any daemon forwarding) and redeems the token against its canonical `ingress_invites` row.
474
- 7. The gateway's redemption engine validates, activates the channel in the gateway ACL, and notifies the daemon (`invite_redeemed`) to mirror the contact info locally.
473
+ 6. The gateway forwards the message to `/channels/inbound`. The inbound handler calls `getInviteAdapterRegistry().get('telegram').extractInboundToken()` to parse the `iv_` token.
474
+ 7. The token is redeemed via `invite-redemption-service.ts`, which validates, activates the contact, and returns a `redeemed` outcome.
475
475
  8. A deterministic welcome message is delivered to the invitee (bypasses the LLM pipeline).
476
476
 
477
477
  **Token prefix convention:** The `iv_` prefix distinguishes invite tokens from `gv_` (guardian verification) tokens. Both use the same Telegram `/start` deep-link mechanism but are routed to different handlers.
478
478
 
479
- **Inbound intercept points:** Invite token/code extraction runs at gateway ingress for non-member senders, before ACL denial, so valid invites short-circuit the contact check. The engine handles: (a) unknown contacts — the invite creates their first channel record; (b) inactive contacts (revoked) — the invite reactivates them; blocked channels are never reactivated.
479
+ **Inbound intercept points:** Invite token extraction runs early in the inbound handler, before ACL denial, so valid invites short-circuit the contact check. Two intercept branches handle: (a) unknown contacts — the invite creates their first contact record; (b) inactive contacts (revoked/pending) — the invite reactivates them.
480
480
 
481
481
  **Channel adapter status:**
482
482
 
483
483
  | Channel | Status | Prerequisites |
484
484
  | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
485
485
  | Telegram | Shipped | Bot username resolved from credential metadata or config |
486
- | Voice | Shipped | Identity-bound voice code redemption via DTMF/speech in the call setup flow. Always-on canonical behavior with personalized friend/guardian name prompts. |
486
+ | Voice | Shipped | Identity-bound voice code redemption via DTMF/speech in the relay state machine. Always-on canonical behavior with personalized friend/guardian name prompts. |
487
487
  | Slack | Deferred | Needs DM-safe ingress — Socket Mode handles channel messages but DM-initiated invite flows need routing |
488
488
 
489
- ### Voice Invite Flow (invite_redemption)
489
+ ### Voice Invite Flow (invite_redemption_pending)
490
490
 
491
- Voice invites use a short numeric code (6 digits) instead of a URL token. The guardian creates an invite bound to the invitee's E.164 phone number; the invitee redeems it by entering the code during an inbound voice call.
491
+ Voice invites use a short numeric code (4-10 digits, default 6) instead of a URL token. The guardian creates an invite bound to the invitee's E.164 phone number; the invitee redeems it by entering the code during an inbound voice call.
492
492
 
493
493
  **Creation flow:**
494
494
 
495
495
  1. Guardian creates a voice invite via `POST /v1/contacts/invites` with `sourceChannel: "phone"` and `expectedExternalUserId` (E.164 phone).
496
- 2. The daemon relays the mint to the gateway (`invites_create` IPC), which generates a cryptographically random numeric code and stores only its SHA-256 hash on the canonical `ingress_invites` row.
496
+ 2. `invite-service.ts` generates a cryptographically random numeric code (`generateVoiceCode`), hashes it with SHA-256 (`hashVoiceCode`), and stores only the hash.
497
497
  3. The one-time plaintext `voiceCode` is returned in the creation response. The raw token is NOT returned for voice invites — redemption uses the identity-bound code flow exclusively.
498
498
  4. Guardian communicates the code to the invitee out-of-band.
499
499
 
500
- **Call-time redemption subflow (`invite_redemption`):**
500
+ **Call-time redemption subflow (`invite_redemption_pending`):**
501
501
 
502
- 1. Unknown caller dials in. The media-stream server resolves trust (gateway trust verdict first, `resolveActorTrust` fallback inside `routeSetup`). Caller is `unknown`, no pending guardian challenge.
503
- 2. `routeSetup` asks the gateway for the active voice invite bound to the caller's phone number (`get_active_voice_invite` IPC via `calls/gateway-invite-reader.ts`; fail-soft — any gateway failure falls through to the unverified path).
504
- 3. If an active, non-expired invite exists, the `CallSetupFlow` runs the `invite_redemption` sub-flow (collecting the code via DTMF or spoken digits) and prompts the caller with personalized copy: `Welcome <friend-name>. Please enter the 6-digit code that <guardian-name> provided you to verify your identity.`
505
- 4. The gateway's `redeem_voice_invite` engine validates: identity match, code hash match, expiry, use count. On success, the phone channel is activated in the gateway ACL and the call transitions to the normal call flow.
502
+ 1. Unknown caller dials in. `relay-server.ts` resolves trust via `resolveActorTrust`. Caller is `unknown`, no pending guardian challenge.
503
+ 2. The relay checks `findActiveVoiceInvites` for invites bound to the caller's phone number.
504
+ 3. If active, non-expired invites exist, the relay enters the `invite_redemption_pending` state (reuses the `verification_pending` connection state) and prompts the caller with personalized copy: `Welcome <friend-name>. Please enter the 6-digit code that <guardian-name> provided you to verify your identity.`
505
+ 4. `redeemVoiceInviteCode` validates: identity match, code hash match, expiry, use count. On success, the contact is activated and the call transitions to the normal call flow.
506
506
  5. On invalid/expired code, the caller hears deterministic failure copy: `Sorry, the code you provided is incorrect or has since expired. Please ask <guardian-name> for a new code. Goodbye.` and the call ends immediately.
507
507
 
508
508
  **Security invariants:**
@@ -516,19 +516,22 @@ Voice invites use a short numeric code (6 digits) instead of a URL token. The gu
516
516
 
517
517
  | File | Purpose |
518
518
  | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
519
- | `gateway/src/verification/invite-redemption.ts` (gateway) | Core redemption engine + gateway-ingress token/code intercept — validation, atomic claim, ACL activation, discriminated-union outcomes |
519
+ | `src/runtime/invite-redemption-service.ts` | Core redemption engine token validation, voice code redemption, contact activation, discriminated-union outcomes |
520
+ | `src/runtime/invite-redemption-templates.ts` | Deterministic reply templates for each redemption outcome |
520
521
  | `src/runtime/channel-invite-transport.ts` | Transport adapter registry with `buildShareableInvite` / `extractInboundToken` interface |
521
522
  | `src/runtime/channel-invite-transports/telegram.ts` | Telegram adapter — `t.me/<bot>?start=iv_<token>` deep links, `/start iv_<token>` extraction |
522
523
  | `src/runtime/channel-invite-transports/voice.ts` | Voice transport adapter — code-based redemption metadata |
523
524
  | `src/daemon/guardian-invite-intent.ts` | Intent detection — routes create/list/revoke requests into the contacts skill |
524
- | `src/runtime/invite-service.ts` | Daemon-owned invite presentation (share link, guardian instruction, channel handle) over gateway-minted invites |
525
- | `src/runtime/routes/contact-routes.ts` | HTTP/IPC invite handlers relay mint/list/revoke/redeem to the gateway's invite IPC routes |
526
- | `src/calls/call-setup-flow.ts` | Transport-agnostic call setup flow `invite_redemption` sub-flow (always-on canonical behavior) |
527
- | `src/calls/gateway-invite-reader.ts` | Gateway IPC read of the active voice invite for a caller identity |
525
+ | `src/runtime/invite-service.ts` | Shared business logic for invite operations (used by HTTP routes) |
526
+ | `src/runtime/routes/invite-routes.ts` | HTTP API handlers for invite management including voice invite creation and redemption |
527
+ | `src/runtime/routes/inbound-message-handler.ts` | Invite token intercept in the inbound flow (unknown-contact and inactive-contact branches) |
528
+ | `src/calls/relay-server.ts` | Voice relay state machine `invite_redemption_pending` subflow (always-on canonical behavior) |
529
+ | `src/util/voice-code.ts` | Cryptographic voice code generation and SHA-256 hashing |
530
+ | `src/memory/invite-store.ts` | Invite persistence including `findActiveVoiceInvites` for identity-bound lookup |
528
531
 
529
532
  ### Voice Inbound Security Model (Canonical)
530
533
 
531
- The voice inbound security model determines how unknown callers are handled when they dial in. Three paths exist, evaluated in priority order by `routeSetup` (`relay-setup-router.ts`) when the media-stream session starts. All guardian decisions route through `applyCanonicalGuardianDecision` in the canonical guardian request system.
534
+ The voice inbound security model determines how unknown callers are handled when they dial in. Three paths exist, evaluated in priority order by `relay-server.ts` during the `handleSetup` phase. All guardian decisions route through `applyCanonicalGuardianDecision` in the canonical guardian request system.
532
535
 
533
536
  **Decision tree for inbound unknown callers:**
534
537
 
@@ -547,7 +550,7 @@ resolveActorTrust() → trustClass
547
550
  |
548
551
  ┌────────────────────┼──────────────────────┐
549
552
  | | |
550
- pendingChallenge? activeVoiceInvite? no invite, no challenge
553
+ pendingChallenge? activeVoiceInvites? no invite, no challenge
551
554
  | | |
552
555
  v v v
553
556
  Guardian verification Invite redemption Name capture +
@@ -556,17 +559,17 @@ resolveActorTrust() → trustClass
556
559
 
557
560
  **Path 1: Voice invite code redemption (guardian-initiated)**
558
561
 
559
- The guardian proactively creates a voice invite bound to the caller's E.164 phone number. When the unknown caller dials in and has an active, non-expired invite, the setup flow enters the `invite_redemption` sub-flow with personalized prompts using the friend's and guardian's names. This is always-on canonical behavior (no feature flag). See [Voice Invite Flow](#voice-invite-flow-invite_redemption) above.
562
+ The guardian proactively creates a voice invite bound to the caller's E.164 phone number. When the unknown caller dials in and has an active, non-expired invite, the relay enters the `invite_redemption_pending` subflow with personalized prompts using the friend's and guardian's names. This is always-on canonical behavior (no feature flag). See [Voice Invite Flow](#voice-invite-flow-invite_redemption_pending) above.
560
563
 
561
564
  **Path 2: Live in-call guardian approval (friend-initiated)**
562
565
 
563
- When no invite exists and no pending guardian challenge is active, the setup flow enters the name capture + guardian approval wait flow:
566
+ When no invite exists and no pending guardian challenge is active, the relay enters the name capture + guardian approval wait flow:
564
567
 
565
- 1. The setup flow transitions to `capturing_name` state and prompts the caller for their name with a timeout.
568
+ 1. The relay transitions to `awaiting_name` state and prompts the caller for their name with a timeout.
566
569
  2. On name capture, `notifyGuardianOfAccessRequest` creates a canonical guardian request (`kind: 'access_request'`) and notifies the guardian via the notification pipeline.
567
- 3. The setup flow hands off to a `GuardianWaitController` (`awaiting_guardian_decision`), which speaks hold messaging and heartbeat updates while polling the canonical request status.
570
+ 3. The relay transitions to `awaiting_guardian_decision` and plays hold music/messaging while polling the canonical request status.
568
571
  4. The guardian approves or denies via any channel (Telegram, desktop). All decisions route through `applyCanonicalGuardianDecision`, which dispatches to the `access_request` resolver in `guardian-request-resolvers.ts`.
569
- 5. On approval: the resolver directly activates the caller as a trusted contact (sets channel `status: 'active'`, `policy: 'allow'`), the poll detects the approved status, and the setup flow completes into the normal call flow with the caller's guardian context updated.
572
+ 5. On approval: the resolver directly activates the caller as a trusted contact (sets channel `status: 'active'`, `policy: 'allow'`), the poll detects the approved status, the relay transitions to the normal call flow with the caller's guardian context updated.
570
573
  6. On denial or timeout: the caller hears a denial message and the call ends.
571
574
 
572
575
  **Path 3: Inbound guardian verification (pending challenge)**
@@ -586,9 +589,7 @@ All guardian decisions for voice access requests flow through:
586
589
 
587
590
  | File | Purpose |
588
591
  | ---------------------------------------------- | -------------------------------------------------------------------------------------- |
589
- | `src/calls/relay-setup-router.ts` | Inbound call decision tree (`routeSetup`) |
590
- | `src/calls/call-setup-flow.ts` | Name capture, verification, and invite sub-flows over the media-stream transport |
591
- | `src/calls/guardian-wait-controller.ts` | Guardian approval wait — hold messaging, heartbeats, poll/timeout |
592
+ | `src/calls/relay-server.ts` | Inbound call decision tree, name capture, guardian approval wait polling |
592
593
  | `src/runtime/access-request-helper.ts` | Creates canonical access request and notifies guardian |
593
594
  | `src/approvals/guardian-decision-primitive.ts` | `applyCanonicalGuardianDecision` — unified decision primitive |
594
595
  | `src/approvals/guardian-request-resolvers.ts` | `access_request` resolver — voice direct activation, text-channel verification session |
@@ -605,41 +606,37 @@ Audio-to-text conversion occurs in six distinct runtime boundaries, each with it
605
606
 
606
607
  | Boundary | Runtime | Provider (current) | Adapter module | Caller |
607
608
  | -------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
608
- | **Telephony (media-stream)** | Daemon process (Twilio Media Streams WebSocket) | Configured STT provider (via `services.stt`) | `src/calls/media-stream-stt-session.ts`, `src/providers/speech-to-text/resolve.ts`, streaming provider adapters | `src/calls/media-stream-server.ts` |
609
+ | **Telephony (hybrid)** | Twilio-native ConversationRelay or daemon media-stream (provider-conditional) | Configured STT provider (via `services.stt`) | `src/calls/telephony-stt-routing.ts` | `src/calls/twilio-routes.ts` |
609
610
  | **Daemon batch** | Daemon process (REST API to provider) | Configured STT provider (via `services.stt`) | `src/stt/daemon-batch-transcriber.ts` | `src/runtime/routes/inbound-stages/transcribe-audio.ts` |
610
611
  | **Conversation streaming** | Daemon process (WebSocket-based) | Configured STT provider (via `services.stt`) | `src/stt/stt-stream-session.ts`, `src/providers/speech-to-text/deepgram-realtime.ts`, `src/providers/speech-to-text/google-gemini-live-stream.ts`, `src/providers/speech-to-text/openai-whisper-stream.ts`, `src/providers/speech-to-text/xai-realtime.ts` | Web/Electron dictation client via gateway WS proxy |
611
612
  | **Live voice channel** | Assistant process (gateway-authenticated WebSocket) | Configured STT provider (via `services.stt`) | `src/runtime/http-server.ts`, `src/live-voice/live-voice-session-manager.ts`, `src/live-voice/live-voice-session.ts`, `src/providers/speech-to-text/resolve.ts`, streaming provider adapters | Web/Electron live voice client via `/v1/live-voice` |
612
613
  | **Client service-first** | Web/Electron via gateway → daemon | Configured STT provider (via `services.stt`) | `src/runtime/routes/stt-routes.ts` | Web/Electron dictation and voice clients |
613
614
 
614
- **Telephony boundary (media-stream):**
615
+ **Telephony boundary (hybrid routing):**
615
616
 
616
- Every phone call connects over Twilio Media Streams: the voice webhook emits `<Connect><Stream>` TwiML pointing to the gateway's media-stream proxy, and the daemon performs both STT and TTS itself — Twilio only carries mu-law audio frames. The `<Stream url="...">` encodes `callSessionId` and auth `token` as **URL path segments** (e.g. `.../media-stream/<callSessionId>/<token>`) because Twilio Media Streams does not reliably preserve query parameters across the WebSocket upgrade. The gateway extracts metadata from path segments (with query-parameter fallback for backward compatibility) and proxies raw audio frames to the daemon.
617
+ Telephony STT uses a provider-conditional hybrid model driven by `services.stt.provider`. The routing resolver (`src/calls/telephony-stt-routing.ts`) maps the configured provider to a discriminated strategy at call setup time:
617
618
 
618
- Transcription mode is selected once per session in `media-stream-stt-session.ts`:
619
+ - **`conversation-relay-native`** (Deepgram, Google) TwiML emits `<Connect><ConversationRelay>` with `transcriptionProvider` and `speechModel` attributes. Twilio handles audio ingestion and transcription natively; the daemon receives transcribed text via the relay WebSocket. The Twilio-native provider name and default speech model are read from the provider catalog entry's `telephonyRouting.twilioNativeMapping` (e.g. Deepgram maps to `provider: "Deepgram"` with `defaultSpeechModel: "nova-3"`; Google maps to `provider: "Google"` with `defaultSpeechModel: undefined`).
619
620
 
620
- - **Streaming** (default) — when `calls.voice.telephonyStreaming` is enabled and the configured provider resolves a streaming transcriber (`resolveStreamingTranscriber()`), inbound audio is decoded (mu-law PCM16, resampled 8 kHz 16 kHz) and fed to the provider's realtime adapter. Replies trigger only on utterance-boundary finals (for Deepgram, `speech_final`/`UtteranceEnd`, never mid-sentence `is_final` segments), and barge-in fires from local energy VAD, never from transcriber partials.
621
- - **Batch fallback** — otherwise the session segments turns with the energy-based `MediaTurnDetector` and transcribes each completed turn via the provider's batch API.
622
-
623
- A credential preflight (`resolveTelephonyCredentialReadiness()` in `src/calls/telephony-credential-preflight.ts`) gates every call: it requires a credentialed, telephony-capable STT provider **and** a media-stream-playable TTS provider (the configured one or a credentialed playable fallback). Inbound calls that fail the preflight receive `<Say>` setup-required copy plus `<Hangup/>` instead of a doomed stream; outbound placement fails before dialing via `preflightVoiceIngress()` with the same user-facing message.
621
+ - **`media-stream-custom`** (OpenAI Whisper) — TwiML emits `<Connect><Stream>` pointing to the gateway's media-stream proxy. The `<Stream url="...">` encodes `callSessionId` and auth `token` as **URL path segments** (e.g. `.../media-stream/<callSessionId>/<token>`) because Twilio Media Streams does not reliably preserve query parameters across the WebSocket upgrade. The gateway extracts metadata from path segments (with query-parameter fallback for backward compatibility) and proxies raw audio frames to the daemon, which transcribes server-side via the provider's batch API.
624
622
 
625
623
  Key modules:
626
624
 
627
- | Module | Purpose |
628
- | --------------------------------------------------- | -------------------------------------------------------------------------------- |
629
- | `src/calls/twilio-routes.ts` | Voice webhook handler; generates `<Connect><Stream>` TwiML, enforces the inbound credential preflight |
630
- | `src/calls/telephony-credential-preflight.ts` | Combined STT + TTS credential-readiness resolver |
631
- | `src/calls/media-stream-parser.ts` | Twilio Media Streams protocol parser |
632
- | `src/calls/media-turn-detector.ts` | Energy-based VAD turn detector for raw audio (batch mode) |
633
- | `src/calls/media-stream-stt-session.ts` | STT session streaming/batch mode selection and transcription via `services.stt` |
634
- | `src/calls/media-stream-audio-transcode.ts` | Mu-law PCM16 codecs and resampling |
635
- | `src/calls/call-transport.ts` | Transport interface decoupling CallController from wire protocol |
636
- | `src/calls/media-stream-output.ts` | Output adapter for sending TTS audio back via Media Streams |
637
- | `src/calls/media-stream-server.ts` | WebSocket server binding media-stream lifecycle to call sessions and setup flows |
638
- | `gateway/src/http/routes/twilio-media-websocket.ts` | Gateway WebSocket proxy for Media Streams frames |
625
+ | Module | Purpose |
626
+ | --------------------------------------------------- | ---------------------------------------------------------------------- |
627
+ | `src/calls/telephony-stt-routing.ts` | Maps `services.stt.provider` to a discriminated `TelephonySttStrategy` |
628
+ | `src/calls/twilio-routes.ts` | Voice webhook handler; generates provider-conditional TwiML |
629
+ | `src/calls/media-stream-parser.ts` | Twilio Media Streams protocol parser |
630
+ | `src/calls/media-turn-detector.ts` | Energy-based VAD turn detector for raw audio |
631
+ | `src/calls/media-stream-stt-session.ts` | STT session that transcribes audio turns via `services.stt` |
632
+ | `src/calls/call-transport.ts` | Transport interface decoupling CallController from wire protocol |
633
+ | `src/calls/media-stream-output.ts` | Output adapter for sending TTS audio back via Media Streams |
634
+ | `src/calls/media-stream-server.ts` | WebSocket server binding media-stream lifecycle to call sessions |
635
+ | `gateway/src/http/routes/twilio-media-websocket.ts` | Gateway WebSocket proxy for Media Streams frames |
639
636
 
640
- Guard tests in `__tests__/twilio-routes-twiml.test.ts` and `__tests__/twilio-routes.test.ts` assert that every supported STT provider yields `<Connect><Stream>` TwiML for both inbound and outbound calls.
637
+ Guard tests in `__tests__/twilio-routes-twiml.test.ts` and `__tests__/twilio-routes.test.ts` assert that TwiML generation matches the provider-conditional strategy for each supported provider.
641
638
 
642
- To add a new telephony STT provider: declare `telephonyMode` and `supportedBoundaries` on the provider's catalog entry in `provider-catalog.ts`. The telephony capability resolver (`resolveTelephonySttCapability()`) reads these fields plus credential availability from the catalog — no per-provider routing maps exist.
639
+ To add a new telephony STT provider: add a `telephonyRouting` entry to the provider's catalog entry in `provider-catalog.ts`. Set `strategyKind` to `"conversation-relay-native"` for Twilio-native providers (and include a `twilioNativeMapping` with the Twilio `provider` name and `defaultSpeechModel`), or `"media-stream-custom"` for providers that require daemon-side transcription. The routing resolver reads these fields from the catalog — no hardcoded maps to update.
643
640
 
644
641
  **Daemon batch boundary:**
645
642
 
@@ -750,7 +747,7 @@ The web client implements these flows in `clients/web/src/domains/chat/voice/`:
750
747
 
751
748
  **Cross-boundary notes:**
752
749
 
753
- - The `services.stt` config block is the single source of truth for STT provider selection across the daemon batch boundary, the conversation streaming boundary, the client service-first boundary, and the telephony boundary. The batch and streaming resolvers (`resolveBatchTranscriber()`, `resolveStreamingTranscriber()`) both read from `services.stt.provider` and resolve credentials through the same catalog; the telephony boundary's media-stream STT session uses these same resolvers — it selects streaming vs batch transcription via `resolveStreamingTranscriber()`/`resolveBatchTranscriber()` under the `calls.voice.telephonyStreaming` flag, gated by `resolveTelephonySttCapability()`, while call placement/TwiML is gated by `resolveTelephonyCredentialReadiness()`. The daemon provider catalog (`src/providers/speech-to-text/provider-catalog.ts`) is the authoritative registry of supported providers. Native clients fetch display metadata via `GET /v1/stt/providers`.
750
+ - The `services.stt` config block is the single source of truth for STT provider selection across the daemon batch boundary, the conversation streaming boundary, the client service-first boundary, and the telephony boundary. The batch and streaming resolvers (`resolveBatchTranscriber()`, `resolveStreamingTranscriber()`) both read from `services.stt.provider` and resolve credentials through the same catalog; the telephony boundary uses `resolveTelephonySttRouting()` to determine the Twilio integration strategy. The daemon provider catalog (`src/providers/speech-to-text/provider-catalog.ts`) is the authoritative registry of supported providers. Native clients fetch display metadata via `GET /v1/stt/providers`.
754
751
  - Conversation streaming does not replace the client service-first batch path. When streaming is available, it runs concurrently during recording and provides real-time partials and finals. The batch path remains the fallback for providers that do not support streaming, when streaming fails mid-session, or when streaming produces no final transcript.
755
752
  - Credential mapping is catalog-driven: `provider-secret-catalog.ts` derives STT API-key provider names from the daemon catalog via `listCredentialProviderNames()`, deduplicating against the LLM/search provider list. Adding a provider to the catalog automatically includes its credential name in `API_KEY_PROVIDERS`.
756
753
  - Terminology: "STT", "transcription", and "speech recognition" all refer to the same operation (converting audio to text).
@@ -802,14 +799,14 @@ The assistant feature-flag resolver (`src/config/assistant-feature-flags.ts`) is
802
799
 
803
800
  **Skill-gating guarantee:** Skill feature-flag gating is **opt-in**: only skills whose SKILL.md frontmatter contains a `featureFlag` field are gated. Skills without the field are always available regardless of feature flag state. For skills that declare a `featureFlag`, when the corresponding flag is OFF the skill is unavailable everywhere — it cannot appear in client UIs, model context, or runtime tool execution. This is enforced at six independent points:
804
801
 
805
- | Enforcement Point | Module | Effect |
806
- | -------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
807
- | **1. Client skill list** | `resolveSkillStates()` in `config/skill-state.ts` | Skills with flag OFF are excluded from the resolved list returned to clients (macOS skill list, settings UI). The skill never appears in the client. |
808
- | **2. Capability memory seeding** | `seedSkillGraphNodes()` in `plugins/defaults/memory/graph/capability-seed.ts` | Skills with flag OFF are excluded from capability memory seeding. The model cannot discover them via semantic recall. |
809
- | **3. `skill_load` tool** | `executeSkillLoad()` in `tools/skills/load.ts` | If the model attempts to load a flagged-off skill by name, the tool returns an error: `"skill is currently unavailable (disabled by feature flag)"`. |
810
- | **4. Runtime tool projection** | `projectSkillTools()` in `daemon/conversation-skill-tools.ts` | Even if a skill was previously active in a session (has `<loaded_skill>` markers in history), the per-turn projection drops it when the flag is OFF. Already-registered tools are unregistered. |
811
- | **5. Included child skills** | `executeSkillLoad()` in `tools/skills/load.ts` | When a parent skill includes children via the `includes` directive, each child is independently checked against its feature flag. Flagged-off children are silently excluded from the loaded skill content. |
812
- | **6. Skill install gate** | `installSkill()` in `daemon/handlers/skills.ts` | When a client requests skill installation, the function checks the skill's feature flag before proceeding. If the flag is OFF, the install is rejected with an error. |
802
+ | Enforcement Point | Module | Effect |
803
+ | -------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
804
+ | **1. Client skill list** | `resolveSkillStates()` in `config/skill-state.ts` | Skills with flag OFF are excluded from the resolved list returned to clients (macOS skill list, settings UI). The skill never appears in the client. |
805
+ | **2. Capability memory seeding** | `seedSkillGraphNodes()` in `memory/graph/capability-seed.ts` | Skills with flag OFF are excluded from capability memory seeding. The model cannot discover them via semantic recall. |
806
+ | **3. `skill_load` tool** | `executeSkillLoad()` in `tools/skills/load.ts` | If the model attempts to load a flagged-off skill by name, the tool returns an error: `"skill is currently unavailable (disabled by feature flag)"`. |
807
+ | **4. Runtime tool projection** | `projectSkillTools()` in `daemon/conversation-skill-tools.ts` | Even if a skill was previously active in a session (has `<loaded_skill>` markers in history), the per-turn projection drops it when the flag is OFF. Already-registered tools are unregistered. |
808
+ | **5. Included child skills** | `executeSkillLoad()` in `tools/skills/load.ts` | When a parent skill includes children via the `includes` directive, each child is independently checked against its feature flag. Flagged-off children are silently excluded from the loaded skill content. |
809
+ | **6. Skill install gate** | `installSkill()` in `daemon/handlers/skills.ts` | When a client requests skill installation, the function checks the skill's feature flag before proceeding. If the flag is OFF, the install is rejected with an error. |
813
810
 
814
811
  All six enforcement points derive the flag key via `skillFlagKey(skill)` — which returns `undefined` for ungated skills, short-circuiting the check — and then call `isAssistantFeatureFlagEnabled(flagKey, config)` for consistency.
815
812
 
@@ -817,17 +814,17 @@ All six enforcement points derive the flag key via `skillFlagKey(skill)` — whi
817
814
 
818
815
  **Key source files:**
819
816
 
820
- | File | Purpose |
821
- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
822
- | `src/config/assistant-feature-flags.ts` | Canonical resolver: `isAssistantFeatureFlagEnabled()`, registry loader |
823
- | `src/config/skill-state.ts` | `skillFlagKey(skill)` — returns canonical flag key for skills with a `featureFlag` frontmatter field, `undefined` otherwise; `resolveSkillStates()` — enforcement point 1 |
824
- | `src/plugins/defaults/memory/graph/capability-seed.ts` | `seedSkillGraphNodes()` — enforcement point 2 |
825
- | `src/tools/skills/load.ts` | `executeSkillLoad()` — enforcement points 3 and 5 |
826
- | `src/daemon/conversation-skill-tools.ts` | `projectSkillTools()` — enforcement point 4 |
827
- | `src/config/schema.ts` | `AssistantConfig` Zod schema definition (feature flag values are no longer stored here) |
828
- | `src/daemon/handlers/skills.ts` | `listSkills()` — uses `resolveSkillStates()` for client responses; `installSkill()` — enforcement point 6 |
829
- | `meta/feature-flags/feature-flag-registry.json` | Unified feature flag registry (repo root) — all declared flags with scope, label, default values, and descriptions |
830
- | `src/config/feature-flag-registry.json` | Bundled copy of the unified registry for compiled binary resolution |
817
+ | File | Purpose |
818
+ | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
819
+ | `src/config/assistant-feature-flags.ts` | Canonical resolver: `isAssistantFeatureFlagEnabled()`, registry loader |
820
+ | `src/config/skill-state.ts` | `skillFlagKey(skill)` — returns canonical flag key for skills with a `featureFlag` frontmatter field, `undefined` otherwise; `resolveSkillStates()` — enforcement point 1 |
821
+ | `src/memory/graph/capability-seed.ts` | `seedSkillGraphNodes()` — enforcement point 2 |
822
+ | `src/tools/skills/load.ts` | `executeSkillLoad()` — enforcement points 3 and 5 |
823
+ | `src/daemon/conversation-skill-tools.ts` | `projectSkillTools()` — enforcement point 4 |
824
+ | `src/config/schema.ts` | `AssistantConfig` Zod schema definition (feature flag values are no longer stored here) |
825
+ | `src/daemon/handlers/skills.ts` | `listSkills()` — uses `resolveSkillStates()` for client responses; `installSkill()` — enforcement point 6 |
826
+ | `meta/feature-flags/feature-flag-registry.json` | Unified feature flag registry (repo root) — all declared flags with scope, label, default values, and descriptions |
827
+ | `src/config/feature-flag-registry.json` | Bundled copy of the unified registry for compiled binary resolution |
831
828
 
832
829
  ---
833
830
 
@@ -2204,12 +2201,12 @@ The `TtsUseCase` discriminator (`"phone-call"` or `"message-playback"`) lets pro
2204
2201
 
2205
2202
  **Synthesis orchestrator (`synthesize-text.ts`):** `synthesizeText()` is the top-level entry point. It resolves the globally configured provider via the config resolver, looks up the adapter in the registry, and delegates synthesis. Provider selection is always global — per-use-case policy only gates capabilities (e.g. format checks), never overrides the chosen provider.
2206
2203
 
2207
- **Call strategy abstraction (`tts-call-strategy.ts`):** The call strategy layer determines how a TTS provider integrates with the telephony path. Instead of inferring call behavior from runtime capabilities, `resolveCallStrategy(config)` reads the provider's `callMode` from the canonical catalog and returns a `TtsCallStrategy` with the provider ID and call mode. Two modes exist:
2204
+ **Call strategy abstraction (`tts-call-strategy.ts`):** The call strategy layer determines how a TTS provider integrates with the Twilio ConversationRelay telephony path. Instead of inferring call behavior from runtime capabilities, `resolveCallStrategy(config)` reads the provider's `callMode` from the canonical catalog and returns a `TtsCallStrategy` with the provider ID and call mode. Two modes exist:
2208
2205
 
2209
- - **`native-twilio`** — the text-token path: spoken text is sent via `sendTextToken()`, which the media-stream transport re-synthesizes through daemon TTS. The profile carries a real `ttsProvider` name (e.g. `"ElevenLabs"`) and a provider-specific voice spec string built by a registered `NativeTwilioVoiceSpecBuilder`. Collapsing this mode is a documented deferred follow-up.
2210
- - **`synthesized-play`** — The assistant synthesises audio via the provider's HTTP API and streams it through the audio store / `sendPlayUrl()` path. Uses a placeholder TTS provider (`"Google"`) and an empty voice string.
2206
+ - **`native-twilio`** — Twilio handles TTS natively via ConversationRelay. The profile needs a real `ttsProvider` name (e.g. `"ElevenLabs"`) and a provider-specific voice spec string. New native providers plug in by registering a `NativeTwilioVoiceSpecBuilder` via `registerNativeTwilioVoiceSpec()` no edits to core call routing logic required.
2207
+ - **`synthesized-play`** — The assistant synthesises audio via the provider's HTTP API and streams chunks to Twilio via `play` messages. Uses a placeholder TTS provider (`"Google"`) and an empty voice string because Twilio never drives TTS itself on this path.
2211
2208
 
2212
- **Phone call integration:** Phone calls run on the media-stream transport, where the daemon synthesises speech via the configured TTS provider and transcodes it to mu-law 8 kHz frames (`media-stream-output.ts`). Each catalog entry declares `mediaStreamPlayback.outputFormat` (`pcm`, `wav`, or `none`); `resolveTelephonyTtsCapability()` (`src/calls/telephony-tts-capability.ts`) combines that field with credential availability into a playable / not-playable verdict, and the call TTS resolver falls back to a credentialed playable provider rather than producing silence. `resolveVoiceQualityProfile()` in `voice-quality.ts` uses `resolveCallStrategy()` to determine the call mode and build the voice profile.
2209
+ **Phone call integration:** `resolveVoiceQualityProfile()` in `voice-quality.ts` uses `resolveCallStrategy()` to determine the call mode, then dispatches to the appropriate path. For `native-twilio`, it looks up the registered `NativeTwilioVoiceSpec` to build the voice string. For `synthesized-play`, it uses the placeholder profile. This replaces the previous `supportsStreaming`-based branching with explicit catalog-declared modes.
2213
2210
 
2214
2211
  **Adding a new TTS provider (catalog-first checklist):**
2215
2212
 
package/Dockerfile CHANGED
@@ -24,6 +24,7 @@ COPY packages/egress-proxy ./packages/egress-proxy
24
24
  COPY packages/environments ./packages/environments
25
25
  COPY packages/gateway-client ./packages/gateway-client
26
26
  COPY packages/ipc-server-utils ./packages/ipc-server-utils
27
+ COPY packages/skill-host-contracts ./packages/skill-host-contracts
27
28
  COPY packages/slack-text ./packages/slack-text
28
29
  COPY packages/twilio-client ./packages/twilio-client
29
30
 
@@ -51,6 +52,17 @@ RUN set -eu; for pkg in /app/skills/*/package.json; do \
51
52
  (cd "$dir" && (bun install --frozen-lockfile 2>/dev/null || bun install)); \
52
53
  done
53
54
 
55
+ # Copy assistant source so emit-manifest can resolve the skill's remaining
56
+ # `../../assistant/src/...` imports while walking the register() module
57
+ # graph. Those imports disappear when skill-isolation Phase 1 completes
58
+ # (plan PR 18); the collector host short-circuits before any runtime path
59
+ # touches them, so the emitted manifest is correct in the meantime.
60
+ COPY assistant ./assistant
61
+
62
+ # Emit the meet-join manifest consumed by the daemon-side loader to
63
+ # register proxy tools/routes without importing the skill in-process.
64
+ RUN bun run /app/skills/meet-join/scripts/emit-manifest.ts \
65
+ --output /app/skills/meet-join/manifest.json
54
66
 
55
67
  # Final stage
56
68
  FROM debian:trixie-slim@sha256:4ffb3a1511099754cddc70eb1b12e50ffdb67619aa0ab6c13fcd800a78ef7c7a AS runner
@@ -121,11 +133,6 @@ RUN apt-get update && apt-get install -y \
121
133
  COPY --from=builder /root/.bun/bin/bun /usr/local/bin/bun
122
134
  RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
123
135
 
124
- # Copy installed deps, shared packages, and bundled skills from the builder stage.
125
- COPY --from=builder /app /app
126
-
127
- COPY assistant /app/assistant
128
-
129
136
  # Install assistant CLI launcher backed by the bundled assistant package
130
137
  RUN printf '#!/usr/bin/env sh\nexec bun run /app/assistant/src/index.ts "$@"\n' > /usr/local/bin/assistant && \
131
138
  chmod +x /usr/local/bin/assistant
@@ -231,6 +238,10 @@ EXPOSE 3001
231
238
  ENV RUNTIME_HTTP_PORT=3001
232
239
  ENV IS_CONTAINERIZED=true
233
240
 
241
+ # Copy installed deps, shared packages, bundled skills, assistant source,
242
+ # and the generated meet-join manifest from the builder stage.
243
+ COPY --from=builder /app /app
244
+
234
245
  COPY packages/block-volume-bootstrap/scripts/*.sh /usr/local/bin/
235
246
 
236
247
  RUN chmod +x \
package/README.md CHANGED
@@ -174,7 +174,7 @@ Guardian actor-role _classification_ (determining whether a sender is guardian,
174
174
 
175
175
  ### Ingress Boundary Guarantees (Gateway-Only Mode)
176
176
 
177
- The runtime operates in **gateway-only mode**: all public-facing webhook paths are blocked at the runtime level. Direct access to Twilio webhook routes (`/webhooks/twilio/voice`, `/webhooks/twilio/status`) and their legacy equivalents (`/v1/calls/twilio/*`) returns `410 GATEWAY_ONLY`. This ensures external webhook traffic can only reach the runtime through the gateway, which performs signature validation before forwarding.
177
+ The runtime operates in **gateway-only mode**: all public-facing webhook paths are blocked at the runtime level. Direct access to Twilio webhook routes (`/webhooks/twilio/voice`, `/webhooks/twilio/status`, `/webhooks/twilio/connect-action`) and their legacy equivalents (`/v1/calls/twilio/*`) returns `410 GATEWAY_ONLY`. This ensures external webhook traffic can only reach the runtime through the gateway, which performs signature validation before forwarding.
178
178
 
179
179
  Internal forwarding routes (`/v1/internal/twilio/*`) are unaffected — these accept pre-validated payloads from the gateway over the private network.
180
180
 
@@ -309,6 +309,7 @@ Guardian verification and ingress contact management are complementary but indep
309
309
  | `src/runtime/trust-context-resolver.ts` | Actor role classification: guardian / non-guardian / unverified_channel |
310
310
  | `src/runtime/routes/inbound-message-handler.ts` | Ingress ACL enforcement, verification-code intercept, escalation creation |
311
311
  | `src/contacts/contact-store.ts` | Contact + channel CRUD: `findContactChannel`, `upsertContact`, `updateChannelStatus`, `searchContacts` |
312
+ | `src/memory/invite-store.ts` | Invite lifecycle: `createInvite`, `redeemInvite` (atomically creates member record) |
312
313
  | `src/memory/channel-verification-sessions.ts` | Guardian binding types and verification challenge persistence |
313
314
  | `src/memory/guardian-approvals.ts` | Approval request persistence |
314
315
  | `src/runtime/verification-outbound-actions.ts` | Shared business logic for outbound verification (start/resend/cancel) |
@@ -382,7 +383,7 @@ External users join through **invite tokens**. There are two invite flows:
382
383
  1. **Guardian requests invite** — The guardian asks the assistant (via desktop chat) to create a Telegram invite link. The `guardian-invite-intent.ts` module detects the intent and routes the request into the `contacts` skill.
383
384
  2. **Invite creation** — The skill creates an invite token via the ingress HTTP API, looks up the Telegram bot username from the integration config endpoint, and constructs a shareable deep link: `https://t.me/<bot>?start=iv_<token>`.
384
385
  3. **Guardian shares link** — The guardian copies the deep link and shares it with the invitee through any messaging channel.
385
- 4. **Invitee redeems** — The invitee clicks the link, which opens Telegram and sends `/start iv_<token>` to the bot. The gateway intercepts the token at ingress, redeems it against its canonical invite row, activates the member channel in the gateway ACL, and notifies the daemon to mirror the contact info.
386
+ 4. **Invitee redeems** — The invitee clicks the link, which opens Telegram and sends `/start iv_<token>` to the bot. The inbound message handler extracts the token via the transport adapter, redeems it through the invite redemption service, and auto-creates an active member record.
386
387
  5. **Access granted** — The invitee receives a welcome message and all subsequent messages pass the ingress ACL.
387
388
 
388
389
  The `iv_` prefix distinguishes invite tokens from `gv_` (guardian verification) tokens, which use the same Telegram `/start` deep-link mechanism.
@@ -391,7 +392,7 @@ The `iv_` prefix distinguishes invite tokens from `gv_` (guardian verification)
391
392
 
392
393
  The invite redemption system uses a three-layer architecture:
393
394
 
394
- - **Core redemption engine** (gateway-native, `gateway/src/verification/invite-redemption.ts`) — Channel-agnostic business logic that validates tokens and codes, enforces expiry/use-count/channel-match constraints, handles member reactivation, and returns a discriminated-union `InviteRedemptionOutcome`. Deterministic reply templates map each outcome to a user-facing message without passing through the LLM.
395
+ - **Core redemption engine** (`invite-redemption-service.ts`) — Channel-agnostic business logic that validates tokens, enforces expiry/use-count/channel-match constraints, handles member reactivation, and returns a discriminated-union `InviteRedemptionOutcome`. Deterministic reply templates (`invite-redemption-templates.ts`) map each outcome to a user-facing message without passing through the LLM.
395
396
  - **Channel transport adapters** (`channel-invite-transport.ts` + `channel-invite-transports/`) — A registry of per-channel adapters that know how to build shareable links (`buildShareLink`) and extract inbound tokens (`extractInboundToken`). Adapters are implemented for Telegram, Voice, Email, WhatsApp, and Slack.
396
397
  - **Conversational orchestration** (`guardian-invite-intent.ts`) — Pattern-based intent detection that intercepts guardian invite management requests (create, list, revoke) in the session pipeline and forces immediate entry into the `contacts` skill, bypassing the normal agent loop.
397
398
 
@@ -421,14 +422,16 @@ If no guardian binding exists, escalation fails closed — the message is denied
421
422
 
422
423
  | File | Purpose |
423
424
  | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
425
+ | `src/memory/invite-store.ts` | CRUD for invite tokens with SHA-256 hashing and expiry |
424
426
  | `src/contacts/contact-store.ts` | Contact + channel CRUD with policy enforcement |
425
- | `src/runtime/routes/contact-routes.ts` | HTTP/IPC invite handlers relay mint/list/revoke/redeem to the gateway's invite IPC routes |
426
- | `src/runtime/routes/inbound-message-handler.ts` | ACL enforcement point — member lookup, policy check, escalation creation |
427
- | `gateway/src/verification/invite-redemption.ts` (gateway) | Core redemption engine — token/code validation, atomic claim, ACL activation, discriminated-union outcomes |
427
+ | `src/daemon/handlers/config-inbox.ts` | HTTP handlers for invite operations |
428
+ | `src/runtime/routes/channel-routes.ts` | ACL enforcement point — member lookup, policy check, escalation creation |
429
+ | `src/runtime/invite-redemption-service.ts` | Core redemption engine — token validation, member creation, discriminated-union outcomes |
430
+ | `src/runtime/invite-redemption-templates.ts` | Deterministic reply templates for each redemption outcome |
428
431
  | `src/runtime/channel-invite-transport.ts` | Transport adapter registry — `buildShareableInvite` / `extractInboundToken` per channel |
429
432
  | `src/runtime/channel-invite-transports/telegram.ts` | Telegram adapter — builds `t.me/<bot>?start=iv_<token>` deep links, extracts `iv_` tokens from `/start` commands |
430
433
  | `src/daemon/guardian-invite-intent.ts` | Intent detection — routes guardian invite management requests into the `contacts` skill |
431
- | `src/runtime/invite-service.ts` | Daemon-owned invite presentation (share link, guardian instruction) over gateway-minted invites |
434
+ | `src/runtime/invite-service.ts` | Shared business logic for invite and contact operations |
432
435
 
433
436
  ## Database
434
437
 
package/bun.lock CHANGED
@@ -21,6 +21,7 @@
21
21
  "@vellumai/gateway-client": "file:../packages/gateway-client",
22
22
  "@vellumai/ipc-server-utils": "file:../packages/ipc-server-utils",
23
23
  "@vellumai/service-contracts": "file:../packages/service-contracts",
24
+ "@vellumai/skill-host-contracts": "file:../packages/skill-host-contracts",
24
25
  "@vellumai/slack-text": "file:../packages/slack-text",
25
26
  "@vellumai/twilio-client": "file:../packages/twilio-client",
26
27
  "commander": "13.1.0",
@@ -37,6 +38,7 @@
37
38
  "pino": "9.14.0",
38
39
  "pino-pretty": "13.1.3",
39
40
  "playwright": "1.58.2",
41
+ "postgres": "3.4.8",
40
42
  "quickjs-emscripten": "0.32.0",
41
43
  "re2js": "2.8.3",
42
44
  "remark-gfm": "4.0.1",
@@ -503,6 +505,8 @@
503
505
 
504
506
  "@vellumai/service-contracts": ["@vellumai/service-contracts@file:../packages/service-contracts", { "dependencies": { "zod": "4.3.6" }, "devDependencies": { "@types/bun": "1.2.4", "typescript": "5.7.3" } }],
505
507
 
508
+ "@vellumai/skill-host-contracts": ["@vellumai/skill-host-contracts@file:../packages/skill-host-contracts", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
509
+
506
510
  "@vellumai/slack-text": ["@vellumai/slack-text@file:../packages/slack-text", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
507
511
 
508
512
  "@vellumai/twilio-client": ["@vellumai/twilio-client@file:../packages/twilio-client", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],