@vellumai/assistant 0.10.12 → 0.11.0-staging.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (776) hide show
  1. package/AGENTS.md +1 -1
  2. package/ARCHITECTURE.md +4 -5
  3. package/README.md +1 -1
  4. package/docs/architecture/memory.md +60 -23
  5. package/docs/error-handling.md +3 -3
  6. package/docs/guardian-request-flow.md +112 -0
  7. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  8. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  9. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  10. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  11. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  12. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
  13. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
  14. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
  15. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
  16. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
  17. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
  18. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
  19. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
  20. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  21. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  22. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  23. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  24. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  25. package/node_modules/@vellumai/gateway-client/package.json +1 -1
  26. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
  27. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
  28. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  29. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  30. package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  31. package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  32. package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  33. package/openapi.yaml +246 -10
  34. package/package.json +2 -2
  35. package/src/__tests__/acp-session.test.ts +3 -3
  36. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
  37. package/src/__tests__/anthropic-provider.test.ts +40 -0
  38. package/src/__tests__/approval-cascade.test.ts +5 -5
  39. package/src/__tests__/approval-routes-http.test.ts +3 -3
  40. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  41. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  42. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  43. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  44. package/src/__tests__/assistant-event.test.ts +12 -9
  45. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  46. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  47. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  48. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  49. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  50. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  51. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  52. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  53. package/src/__tests__/channel-approvals.test.ts +0 -27
  54. package/src/__tests__/channel-guardian.test.ts +85 -512
  55. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  56. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  57. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  58. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  59. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  60. package/src/__tests__/compaction-events.test.ts +8 -8
  61. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  62. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  63. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  64. package/src/__tests__/config-schema.test.ts +14 -2
  65. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  66. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  67. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  68. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  69. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  70. package/src/__tests__/context-token-estimator.test.ts +54 -1
  71. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  72. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  73. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  74. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  75. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  76. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  77. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  78. package/src/__tests__/conversation-evictor.test.ts +49 -0
  79. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  80. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  81. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  82. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  83. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  84. package/src/__tests__/conversation-queue.test.ts +81 -81
  85. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  86. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  89. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  90. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  91. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  92. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  93. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  94. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  95. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  96. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  97. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  98. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  99. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  100. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  101. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  102. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  103. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  105. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  107. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  108. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  109. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  110. package/src/__tests__/db-test-helpers.ts +13 -27
  111. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  112. package/src/__tests__/document-tool-security.test.ts +95 -0
  113. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  114. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  115. package/src/__tests__/emit-event-signal.test.ts +5 -6
  116. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  117. package/src/__tests__/events-tail-route.test.ts +6 -4
  118. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  119. package/src/__tests__/file-edit-tool.test.ts +24 -4
  120. package/src/__tests__/file-list-tool.test.ts +2 -1
  121. package/src/__tests__/file-read-tool.test.ts +62 -10
  122. package/src/__tests__/file-write-tool.test.ts +24 -5
  123. package/src/__tests__/followup-tools.test.ts +58 -0
  124. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  125. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  126. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  127. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  128. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  129. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  130. package/src/__tests__/heartbeat-service.test.ts +1 -0
  131. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  132. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  133. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  134. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  135. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  136. package/src/__tests__/host-shell-tool.test.ts +17 -5
  137. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  138. package/src/__tests__/image-credentials.test.ts +65 -8
  139. package/src/__tests__/injection-block.test.ts +4 -4
  140. package/src/__tests__/injector-chain.test.ts +1 -1
  141. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  142. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  143. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  144. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  145. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  146. package/src/__tests__/llm-usage-store.test.ts +67 -4
  147. package/src/__tests__/log-redact.test.ts +18 -0
  148. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  149. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  150. package/src/__tests__/media-generate-image.test.ts +62 -11
  151. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  153. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  154. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  155. package/src/__tests__/notification-deep-link.test.ts +12 -12
  156. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  157. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  158. package/src/__tests__/path-policy.test.ts +315 -0
  159. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  160. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  161. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  162. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  163. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  164. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  165. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  166. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  167. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  168. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  169. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  170. package/src/__tests__/run-due-schedules.test.ts +72 -1
  171. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  172. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  173. package/src/__tests__/schedule-routes.test.ts +44 -5
  174. package/src/__tests__/schedule-store.test.ts +3 -3
  175. package/src/__tests__/schedule-tools.test.ts +176 -0
  176. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  177. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  178. package/src/__tests__/secret-response-routing.test.ts +3 -3
  179. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  180. package/src/__tests__/secret-scanner.test.ts +36 -0
  181. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  182. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  183. package/src/__tests__/starter-task-flow.test.ts +6 -3
  184. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  185. package/src/__tests__/subagent-disposal.test.ts +40 -11
  186. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  187. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  188. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  189. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  190. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  191. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  192. package/src/__tests__/subagent-tools.test.ts +64 -0
  193. package/src/__tests__/sync-message-contract.test.ts +3 -3
  194. package/src/__tests__/terminal-tools.test.ts +12 -3
  195. package/src/__tests__/test-preload.ts +9 -0
  196. package/src/__tests__/tool-approval-handler.test.ts +583 -43
  197. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  198. package/src/__tests__/tool-executor.test.ts +116 -0
  199. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  200. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  201. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  202. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  203. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  204. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  205. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  206. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  207. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  208. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  209. package/src/__tests__/workspace-policy.test.ts +399 -0
  210. package/src/acp/__tests__/client-handler.test.ts +3 -3
  211. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  212. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  213. package/src/acp/client-handler.ts +3 -3
  214. package/src/acp/session-manager.ts +8 -8
  215. package/src/api/events/subagent-event.ts +2 -2
  216. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  217. package/src/approvals/AGENTS.md +2 -0
  218. package/src/approvals/guardian-request-resolvers.ts +118 -24
  219. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  220. package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
  221. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  222. package/src/calls/call-controller.ts +27 -27
  223. package/src/calls/call-conversation-messages.ts +58 -18
  224. package/src/calls/voice-control-protocol.ts +56 -0
  225. package/src/calls/voice-session-bridge.ts +156 -58
  226. package/src/calls/voice-triage-escalate.ts +2 -3
  227. package/src/channels/config.ts +8 -0
  228. package/src/channels/types.ts +1 -0
  229. package/src/cli/commands/config.ts +49 -13
  230. package/src/cli/commands/memory/index.help.ts +4 -2
  231. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  232. package/src/cli/lib/bundled-marketplace.json +12 -0
  233. package/src/cli.ts +2 -109
  234. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  235. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  236. package/src/config/assistant-feature-flags.ts +1 -1
  237. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  238. package/src/config/feature-flag-cache.ts +6 -16
  239. package/src/config/feature-flag-registry.json +14 -30
  240. package/src/config/loader.ts +7 -1
  241. package/src/config/memory-tier.ts +15 -10
  242. package/src/config/memory-v3-gate.test.ts +278 -1
  243. package/src/config/memory-v3-gate.ts +88 -26
  244. package/src/config/raw-config-utils.ts +1 -1
  245. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  246. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  247. package/src/config/schemas/live-voice.ts +33 -7
  248. package/src/config/schemas/llm.ts +1 -0
  249. package/src/config/schemas/memory-retrospective.ts +13 -0
  250. package/src/config/schemas/memory-substrate.ts +183 -0
  251. package/src/config/schemas/memory-v2.ts +3 -2
  252. package/src/config/schemas/memory-v3.ts +11 -4
  253. package/src/config/schemas/memory.ts +35 -1
  254. package/src/config/schemas/services.ts +10 -2
  255. package/src/config/substrate-twin-shadowing.ts +195 -0
  256. package/src/config/webhook-routing.ts +67 -0
  257. package/src/context/compactor.ts +10 -3
  258. package/src/context/token-estimator.ts +21 -0
  259. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  260. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  261. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  262. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  263. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  264. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  265. package/src/daemon/channel-ui-capability.ts +70 -1
  266. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  267. package/src/daemon/conversation-agent-loop.ts +12 -5
  268. package/src/daemon/conversation-evictor.ts +26 -4
  269. package/src/daemon/conversation-launch.ts +11 -14
  270. package/src/daemon/conversation-messaging.ts +14 -14
  271. package/src/daemon/conversation-notifiers.ts +2 -2
  272. package/src/daemon/conversation-process.ts +133 -21
  273. package/src/daemon/conversation-queue-manager.ts +7 -7
  274. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  275. package/src/daemon/conversation-store.ts +11 -3
  276. package/src/daemon/conversation-surfaces.ts +4 -4
  277. package/src/daemon/conversation-tool-setup.ts +13 -7
  278. package/src/daemon/conversation-usage.ts +12 -11
  279. package/src/daemon/conversation.ts +38 -15
  280. package/src/daemon/disk-pressure-guard.ts +5 -12
  281. package/src/daemon/embedding-reconcile.ts +14 -9
  282. package/src/daemon/handlers/config-channels.ts +40 -134
  283. package/src/daemon/handlers/config-model.ts +15 -7
  284. package/src/daemon/handlers/conversations.ts +4 -2
  285. package/src/daemon/handlers/shared.ts +29 -0
  286. package/src/daemon/host-proxy-base.ts +4 -4
  287. package/src/daemon/lifecycle.ts +13 -0
  288. package/src/daemon/message-protocol.ts +8 -144
  289. package/src/daemon/message-types/computer-use.ts +0 -12
  290. package/src/daemon/message-types/conversations.ts +9 -345
  291. package/src/daemon/message-types/host-app-control.ts +0 -9
  292. package/src/daemon/message-types/host-browser.ts +0 -7
  293. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  294. package/src/daemon/message-types/messages.ts +0 -48
  295. package/src/daemon/message-types/notifications.ts +0 -7
  296. package/src/daemon/message-types/skills.ts +0 -5
  297. package/src/daemon/message-types/surfaces.ts +0 -9
  298. package/src/daemon/message-types/sync.ts +0 -2
  299. package/src/daemon/process-message.ts +5 -5
  300. package/src/daemon/skill-memory-refresh.ts +5 -5
  301. package/src/daemon/tool-side-effects.ts +13 -13
  302. package/src/daemon/trust-context.ts +1 -1
  303. package/src/daemon/wake-conversation-ops.ts +4 -4
  304. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  305. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  306. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  307. package/src/heartbeat/heartbeat-service.ts +32 -1
  308. package/src/home/__tests__/feed-writer.test.ts +7 -7
  309. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  310. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  311. package/src/home/feed-writer.ts +6 -13
  312. package/src/home/home-content-refresh.ts +6 -9
  313. package/src/home/relationship-state-writer.ts +5 -12
  314. package/src/home/suggested-prompts-cache.ts +6 -19
  315. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  316. package/src/ipc/events-publish-client.ts +44 -0
  317. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  318. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  319. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  320. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  321. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  322. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  323. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  324. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  325. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  326. package/src/live-voice/__tests__/live-voice-vad.test.ts +218 -422
  327. package/src/live-voice/front-decision.ts +5 -155
  328. package/src/live-voice/live-voice-metrics.ts +4 -1
  329. package/src/live-voice/live-voice-session.ts +650 -333
  330. package/src/live-voice/progress-phrases.ts +17 -0
  331. package/src/live-voice/protocol.ts +15 -0
  332. package/src/media/app-icon-generator.ts +15 -8
  333. package/src/media/avatar-router.ts +9 -5
  334. package/src/media/image-credentials.ts +42 -10
  335. package/src/media/image-service.ts +1 -13
  336. package/src/media/types.ts +26 -3
  337. package/src/notifications/AGENTS.md +2 -0
  338. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  339. package/src/notifications/adapters/macos.ts +3 -3
  340. package/src/notifications/broadcaster.ts +57 -0
  341. package/src/notifications/copy-composer.ts +0 -15
  342. package/src/notifications/decision-engine.ts +21 -22
  343. package/src/notifications/guardian-question-mode.ts +57 -2
  344. package/src/notifications/home-feed-side-effect.ts +4 -0
  345. package/src/notifications/signal.ts +6 -4
  346. package/src/notifications/trusted-contact-payloads.ts +3 -4
  347. package/src/notifications/vellum-card-affinity.ts +39 -0
  348. package/src/oauth/AGENTS.md +1 -1
  349. package/src/permissions/channel-permission-query.test.ts +69 -0
  350. package/src/permissions/channel-permission-query.ts +73 -1
  351. package/src/permissions/checker.test.ts +85 -9
  352. package/src/permissions/checker.ts +17 -22
  353. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  354. package/src/permissions/confirmation-guardian-request.ts +2 -2
  355. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  356. package/src/permissions/gateway-threshold-reader.ts +82 -10
  357. package/src/permissions/ipc-risk-types.ts +8 -0
  358. package/src/permissions/prompter.ts +5 -5
  359. package/src/permissions/question-guardian-request.test.ts +222 -0
  360. package/src/permissions/question-guardian-request.ts +179 -0
  361. package/src/permissions/question-prompter.test.ts +8 -8
  362. package/src/permissions/question-prompter.ts +18 -0
  363. package/src/permissions/secret-prompter.ts +2 -4
  364. package/src/permissions/workspace-policy.ts +236 -34
  365. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  366. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  367. package/src/persistence/conversation-crud.ts +93 -0
  368. package/src/persistence/conversation-key-store.ts +63 -0
  369. package/src/persistence/db-async-query.ts +1 -1
  370. package/src/persistence/db-singleton.ts +14 -27
  371. package/src/persistence/delivery-crud.ts +45 -0
  372. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  373. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  374. package/src/persistence/job-utils.ts +32 -27
  375. package/src/persistence/jobs-store.ts +92 -3
  376. package/src/persistence/lifecycle-quiesce.ts +80 -0
  377. package/src/persistence/llm-usage-store.ts +45 -8
  378. package/src/persistence/message-content-file.ts +4 -4
  379. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  380. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  381. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  382. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  383. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  384. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  385. package/src/persistence/schema/infrastructure.ts +11 -0
  386. package/src/persistence/steps.ts +7 -1
  387. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  388. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  389. package/src/plugin-api/conversation-turn.ts +4 -4
  390. package/src/plugin-api/event-hub-facade.ts +15 -6
  391. package/src/plugin-api/index.ts +10 -4
  392. package/src/plugin-api/publish-event.ts +36 -0
  393. package/src/plugins/AGENTS.md +2 -0
  394. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  395. package/src/plugins/defaults/index.ts +9 -13
  396. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  397. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  398. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  399. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  400. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  401. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  402. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  403. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  404. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  405. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  406. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  407. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  408. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  409. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  410. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  411. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  412. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  413. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  414. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  415. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  416. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  417. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  418. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  419. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  420. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  421. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  422. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  423. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  424. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  425. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  426. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  427. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  428. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  429. package/src/plugins/defaults/memory/indexer.ts +146 -89
  430. package/src/plugins/defaults/memory/injectors.ts +86 -41
  431. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  432. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  433. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  434. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  435. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  436. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  437. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  438. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  439. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  440. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  441. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  442. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  443. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  444. package/src/plugins/defaults/memory/startup.ts +58 -21
  445. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  446. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  447. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  448. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  449. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  450. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  451. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  452. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  453. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  454. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  455. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  456. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  457. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  458. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  459. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  460. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  461. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  462. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  463. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  464. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  465. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  474. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  479. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  482. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  484. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  485. package/src/plugins/defaults/memory/tools.ts +1 -1
  486. package/src/plugins/defaults/memory/v1/README.md +5 -0
  487. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  488. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  489. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  490. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  491. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  492. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  493. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  494. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  495. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  496. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  497. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  498. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  499. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  500. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  501. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  502. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  503. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  504. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  505. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  506. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  507. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  508. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  510. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  511. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  512. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  513. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  514. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  515. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  516. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  517. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  518. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  519. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  520. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  521. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  522. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  523. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  524. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  525. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  526. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  527. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  528. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  529. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  530. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  531. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  532. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  533. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  534. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  535. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  536. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  537. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  538. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  539. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  540. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  541. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  542. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  543. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  544. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  545. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  546. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  547. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  548. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  549. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  550. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  551. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  552. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  555. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  556. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  557. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  558. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  559. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  560. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  561. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  562. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  563. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  564. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  565. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  566. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  567. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  568. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  569. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  570. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  571. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  572. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  573. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  574. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  575. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  576. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  577. package/src/plugins/defaults/memory/validation.ts +1 -1
  578. package/src/plugins/defaults/memory/worker.ts +2 -1
  579. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  580. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  581. package/src/plugins/types.ts +2 -2
  582. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  583. package/src/providers/anthropic/client.ts +15 -6
  584. package/src/providers/content-block-schema.ts +26 -0
  585. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  586. package/src/providers/inference/adapter-factory.ts +6 -0
  587. package/src/providers/inference/connections.ts +30 -14
  588. package/src/providers/model-catalog.ts +77 -0
  589. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  590. package/src/providers/openai/chat-completions-provider.ts +65 -17
  591. package/src/providers/openai/input-audio.ts +76 -0
  592. package/src/providers/openrouter/client.ts +0 -2
  593. package/src/providers/platform-proxy/constants.ts +4 -0
  594. package/src/providers/poolside/client.ts +42 -0
  595. package/src/providers/registry.ts +40 -8
  596. package/src/providers/retry.ts +2 -0
  597. package/src/providers/types.ts +39 -1
  598. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  599. package/src/runtime/AGENTS.md +7 -5
  600. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  601. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  602. package/src/runtime/access-request-helper.ts +7 -15
  603. package/src/runtime/assistant-event-hub.ts +43 -31
  604. package/src/runtime/assistant-event-publish-options.ts +31 -0
  605. package/src/runtime/assistant-event.ts +19 -30
  606. package/src/runtime/assistant-stream-state.ts +4 -4
  607. package/src/runtime/channel-approvals.ts +0 -25
  608. package/src/runtime/channel-readiness-service.ts +99 -40
  609. package/src/runtime/channel-retry-sweep.ts +38 -15
  610. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  611. package/src/runtime/guardian-reply-router.ts +108 -0
  612. package/src/runtime/http-server.ts +8 -0
  613. package/src/runtime/http-types.ts +2 -2
  614. package/src/runtime/process-role.ts +42 -0
  615. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  616. package/src/runtime/question-resolution.ts +153 -0
  617. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  618. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  619. package/src/runtime/routes/acp-routes.ts +2 -2
  620. package/src/runtime/routes/bookmark-routes.ts +3 -15
  621. package/src/runtime/routes/canned-message-complete.ts +2 -2
  622. package/src/runtime/routes/consolidation-routes.ts +8 -2
  623. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  624. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  625. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  626. package/src/runtime/routes/conversation-routes.ts +36 -22
  627. package/src/runtime/routes/credential-request-routes.ts +0 -1
  628. package/src/runtime/routes/filing-routes.ts +7 -7
  629. package/src/runtime/routes/global-search-routes.ts +1 -1
  630. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  631. package/src/runtime/routes/image-generation-routes.ts +12 -9
  632. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  633. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  634. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  635. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  636. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  637. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  638. package/src/runtime/routes/index.ts +2 -0
  639. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  640. package/src/runtime/routes/platform-routes.ts +3 -8
  641. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  642. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  643. package/src/runtime/routes/question-routes.ts +34 -87
  644. package/src/runtime/routes/secret-routes.ts +11 -1
  645. package/src/runtime/routes/settings-routes.ts +8 -18
  646. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  647. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  648. package/src/runtime/slack-reply-session.test.ts +12 -12
  649. package/src/runtime/slack-reply-session.ts +17 -17
  650. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  651. package/src/runtime/tool-grant-request-helper.ts +4 -0
  652. package/src/schedule/schedule-store.ts +70 -0
  653. package/src/schedule/scheduler.ts +27 -0
  654. package/src/security/AGENTS.md +1 -1
  655. package/src/security/credential-key.ts +17 -0
  656. package/src/security/secret-ingress.ts +14 -105
  657. package/src/security/secret-patterns.ts +8 -139
  658. package/src/security/secret-scanner.ts +8 -3
  659. package/src/security/store-path-override.ts +6 -16
  660. package/src/sequence/store.ts +8 -0
  661. package/src/signals/emit-event.ts +5 -10
  662. package/src/signals/event-stream.ts +20 -10
  663. package/src/subagent/manager.ts +76 -25
  664. package/src/subagent/notify.ts +8 -0
  665. package/src/subagent/types.ts +13 -3
  666. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  667. package/src/telegram/webhook-health.ts +478 -0
  668. package/src/telemetry/AGENTS.md +6 -0
  669. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  670. package/src/telemetry/memory-corpus-size.ts +184 -0
  671. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  672. package/src/telemetry/memory-tier-reporter.ts +30 -3
  673. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  674. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  675. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  676. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  677. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  678. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  679. package/src/tools/acp/abort.ts +21 -1
  680. package/src/tools/acp/context.ts +5 -5
  681. package/src/tools/acp/spawn.test.ts +15 -5
  682. package/src/tools/acp/spawn.ts +26 -3
  683. package/src/tools/acp/status.ts +20 -1
  684. package/src/tools/acp/steer.test.ts +20 -0
  685. package/src/tools/acp/steer.ts +23 -2
  686. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  687. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  688. package/src/tools/browser/browser-screencast.ts +6 -6
  689. package/src/tools/calls/call-end.ts +24 -3
  690. package/src/tools/calls/call-start.ts +35 -11
  691. package/src/tools/calls/call-status.ts +20 -1
  692. package/src/tools/document/document-comment-tool.test.ts +49 -0
  693. package/src/tools/document/document-comment-tool.ts +45 -6
  694. package/src/tools/document/document-tool.ts +142 -24
  695. package/src/tools/executor.ts +27 -13
  696. package/src/tools/filesystem/edit.ts +62 -60
  697. package/src/tools/filesystem/list.ts +36 -29
  698. package/src/tools/filesystem/read.ts +56 -39
  699. package/src/tools/filesystem/write.ts +44 -38
  700. package/src/tools/followups/followup_create.ts +41 -12
  701. package/src/tools/followups/followup_list.ts +34 -6
  702. package/src/tools/followups/followup_resolve.ts +26 -4
  703. package/src/tools/host-filesystem/edit.ts +50 -60
  704. package/src/tools/host-filesystem/read.ts +45 -39
  705. package/src/tools/host-filesystem/write.ts +31 -36
  706. package/src/tools/host-terminal/host-shell.ts +76 -62
  707. package/src/tools/policy-context.ts +27 -10
  708. package/src/tools/schedule/create.ts +76 -33
  709. package/src/tools/schedule/delete.ts +21 -2
  710. package/src/tools/schedule/list.ts +25 -3
  711. package/src/tools/schedule/update.ts +105 -48
  712. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  713. package/src/tools/shared/zod-tool-schema.ts +117 -0
  714. package/src/tools/subagent/abort.ts +12 -4
  715. package/src/tools/subagent/consult-deadline.ts +9 -3
  716. package/src/tools/subagent/message.ts +21 -5
  717. package/src/tools/subagent/notify-parent.ts +44 -23
  718. package/src/tools/subagent/read.ts +15 -4
  719. package/src/tools/subagent/resolve.ts +26 -4
  720. package/src/tools/subagent/spawn.ts +37 -13
  721. package/src/tools/subagent/status.ts +12 -4
  722. package/src/tools/system/request-permission.ts +35 -26
  723. package/src/tools/terminal/shell.ts +68 -55
  724. package/src/tools/tool-approval-handler.ts +327 -53
  725. package/src/tools/tool-input-schemas.ts +85 -0
  726. package/src/tools/tool-types.ts +7 -0
  727. package/src/tools/types.ts +8 -0
  728. package/src/tools/workflows/manage-workflows.ts +30 -2
  729. package/src/tools/workflows/run-workflow.test.ts +54 -2
  730. package/src/tools/workflows/run-workflow.ts +32 -4
  731. package/src/util/fs-symlinks.ts +30 -0
  732. package/src/util/log-redact.ts +7 -3
  733. package/src/vellum-assistant-namespace.d.ts +80 -0
  734. package/src/watcher/watcher-store.ts +8 -0
  735. package/src/workflows/leaf-runner.test.ts +104 -2
  736. package/src/workflows/leaf-runner.ts +31 -6
  737. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  738. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  739. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  740. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  741. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  742. package/src/workspace/migrations/registry.ts +4 -0
  743. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  744. package/src/__tests__/secret-patterns.test.ts +0 -27
  745. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  746. package/src/config/memory-tier.test.ts +0 -44
  747. package/src/daemon/message-types/acp.ts +0 -20
  748. package/src/daemon/message-types/apps.ts +0 -11
  749. package/src/daemon/message-types/background-tools.ts +0 -14
  750. package/src/daemon/message-types/bookmarks.ts +0 -13
  751. package/src/daemon/message-types/contacts.ts +0 -13
  752. package/src/daemon/message-types/document-comments.ts +0 -14
  753. package/src/daemon/message-types/documents.ts +0 -13
  754. package/src/daemon/message-types/home.ts +0 -15
  755. package/src/daemon/message-types/host-bash.ts +0 -12
  756. package/src/daemon/message-types/host-cu.ts +0 -10
  757. package/src/daemon/message-types/host-file.ts +0 -12
  758. package/src/daemon/message-types/host-transfer.ts +0 -12
  759. package/src/daemon/message-types/integrations.ts +0 -90
  760. package/src/daemon/message-types/memory.ts +0 -10
  761. package/src/daemon/message-types/schedules.ts +0 -14
  762. package/src/daemon/message-types/settings.ts +0 -17
  763. package/src/daemon/message-types/subagents.ts +0 -63
  764. package/src/daemon/message-types/upgrades.ts +0 -14
  765. package/src/daemon/message-types/workflows.ts +0 -25
  766. package/src/daemon/message-types/workspace.ts +0 -137
  767. package/src/live-voice/ack-phrases.ts +0 -58
  768. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  769. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  770. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  771. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  772. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  773. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  774. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  775. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  776. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -3,6 +3,7 @@ import { and, asc, desc, eq, isNull, lt, lte, sql } from "drizzle-orm";
3
3
  import { v4 as uuid } from "uuid";
4
4
 
5
5
  import { getDb } from "../persistence/db-connection.js";
6
+ import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
6
7
  import { rawChanges } from "../persistence/raw-query.js";
7
8
  import { scheduleJobs, scheduleRuns } from "../persistence/schema/index.js";
8
9
  import { publishSchedulesChanged } from "../runtime/sync/resource-sync-events.js";
@@ -465,6 +466,15 @@ export async function deleteSchedule(id: string): Promise<boolean> {
465
466
  * next_run_at <= now and enabled = true and cron_expression IS NULL.
466
467
  */
467
468
  export async function claimDueSchedules(now: number): Promise<ScheduleJob[]> {
469
+ // Drain gate: while a quiesce lease is active, claim nothing so in-flight
470
+ // runs can drain before a stop. The check lives here — immediately before
471
+ // the claim writes — rather than at the tick boundary, to shrink the window
472
+ // in which a lease armed mid-tick could miss a claim that already passed an
473
+ // earlier check. Fail-open via the lease read.
474
+ if (isLifecycleQuiesced()) {
475
+ return [];
476
+ }
477
+
468
478
  const db = getDb();
469
479
  const claimed: ScheduleJob[] = [];
470
480
 
@@ -750,6 +760,27 @@ export async function createScheduleRun(
750
760
  return id;
751
761
  }
752
762
 
763
+ /** Currently-running schedule runs with their job names, oldest first. */
764
+ export function listRunningScheduleRuns(): Array<{
765
+ runId: string;
766
+ scheduleName: string | null;
767
+ startedAt: number;
768
+ }> {
769
+ const db = getDb();
770
+ return db
771
+ .select({
772
+ runId: scheduleRuns.id,
773
+ scheduleName: scheduleJobs.name,
774
+ startedAt: scheduleRuns.startedAt,
775
+ })
776
+ .from(scheduleRuns)
777
+ .leftJoin(scheduleJobs, eq(scheduleRuns.jobId, scheduleJobs.id))
778
+ .where(eq(scheduleRuns.status, "running"))
779
+ .orderBy(asc(scheduleRuns.startedAt))
780
+ .limit(20)
781
+ .all();
782
+ }
783
+
753
784
  export async function setScheduleRunConversationId(
754
785
  runId: string,
755
786
  conversationId: string,
@@ -1082,6 +1113,45 @@ export function describeCronExpression(expr: string | null): string {
1082
1113
  }
1083
1114
  }
1084
1115
 
1116
+ /**
1117
+ * Return a claimed-but-not-started schedule to the queue (drain deferral).
1118
+ *
1119
+ * Restores everything the claim mutated before any execution began:
1120
+ * `nextRunAt` is pulled to `nextRetryAt`, a one-shot's `firing` reverts to
1121
+ * `active`, and `enabled` is restored — a bounded recurring schedule's final
1122
+ * occurrence is claimed by exhausting the job (`enabled = false`,
1123
+ * `nextRunAt = 0`), so without the restore that deferred final occurrence
1124
+ * would never fire.
1125
+ */
1126
+ export async function deferClaimedSchedule(
1127
+ id: string,
1128
+ nextRetryAt: number,
1129
+ ): Promise<void> {
1130
+ const db = getDb();
1131
+ const now = Date.now();
1132
+ await withSqliteRetry(
1133
+ () => {
1134
+ db.update(scheduleJobs)
1135
+ .set({ nextRunAt: nextRetryAt, enabled: true, updatedAt: now })
1136
+ .where(eq(scheduleJobs.id, id))
1137
+ .run();
1138
+ return rawChanges() > 0;
1139
+ },
1140
+ { op: "deferClaimedSchedule.requeue", context: { scheduleId: id } },
1141
+ );
1142
+ await withSqliteRetry(
1143
+ () => {
1144
+ db.update(scheduleJobs)
1145
+ .set({ status: "active", updatedAt: now })
1146
+ .where(and(eq(scheduleJobs.id, id), eq(scheduleJobs.status, "firing")))
1147
+ .run();
1148
+ return rawChanges() > 0;
1149
+ },
1150
+ { op: "deferClaimedSchedule.status", context: { scheduleId: id } },
1151
+ );
1152
+ notifySchedulesChanged();
1153
+ }
1154
+
1085
1155
  /**
1086
1156
  * Set the next retry time for a schedule and revert one-shot status from
1087
1157
  * "firing" to "active" so the scheduler will claim it again when nextRetryAt
@@ -9,6 +9,7 @@ import { processMessage } from "../daemon/process-message.js";
9
9
  import { INTERNAL_GUARDIAN_TRUST_CONTEXT } from "../daemon/trust-context.js";
10
10
  import { emitNotificationSignal } from "../notifications/emit-signal.js";
11
11
  import { getConversation } from "../persistence/conversation-crud.js";
12
+ import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
12
13
  import { invalidateAssistantInferredItemsForConversation } from "../plugins/defaults/memory/task-memory-cleanup.js";
13
14
  import { wakeAgentForOpportunity } from "../runtime/agent-wake.js";
14
15
  import { broadcastMessage } from "../runtime/assistant-event-hub.js";
@@ -33,6 +34,7 @@ import {
33
34
  completeOneShot,
34
35
  completeScheduleRun,
35
36
  createScheduleRun,
37
+ deferClaimedSchedule,
36
38
  failOneShotPermanently,
37
39
  getLastScheduleConversationId,
38
40
  resetRetryCount,
@@ -434,6 +436,9 @@ export async function runScheduleDueWorkOnce(
434
436
  return result;
435
437
  }
436
438
 
439
+ // The drain quiesce gates live inside claimDueWatchers and
440
+ // claimDueEnrollments, immediately before their claim writes.
441
+
437
442
  // ── Watchers (event-driven polling) ────────────────────────────────
438
443
  try {
439
444
  const watcherProcessed = await runWatchersOnce(emitWatcherNotifySignal);
@@ -463,6 +468,9 @@ export async function runScheduleDueWorkOnce(
463
468
  * (`worker.ts`). Claims are atomic in the schedule store, so overlapping ticks
464
469
  * cannot double-run a job another claim already took.
465
470
  */
471
+ /** How far a claimed-but-quiesced schedule is pushed back into the queue. */
472
+ const QUIESCE_DEFER_MS = 30_000;
473
+
466
474
  export async function runDueSchedulesOnce(
467
475
  now: number = Date.now(),
468
476
  ): Promise<SchedulerDueWorkResult> {
@@ -490,9 +498,28 @@ export async function runDueSchedulesOnce(
490
498
  return result;
491
499
  }
492
500
 
501
+ // The drain quiesce gate lives inside claimDueSchedules, immediately
502
+ // before the claim writes.
493
503
  const jobs = await claimDueSchedules(now);
494
504
  result.claimed = jobs.length;
495
505
  for (const job of jobs) {
506
+ // Lease re-check per claimed job: a lease armed between the batch claim
507
+ // and this job's start returns the job to the queue untouched instead of
508
+ // starting work the drain snapshot cannot see — notify mode especially,
509
+ // which emits before any run row exists.
510
+ if (isLifecycleQuiesced()) {
511
+ try {
512
+ await deferClaimedSchedule(job.id, Date.now() + QUIESCE_DEFER_MS);
513
+ } catch (err) {
514
+ log.warn(
515
+ { err, jobId: job.id },
516
+ "Failed to defer claimed schedule under quiesce",
517
+ );
518
+ }
519
+ result.skipped += 1;
520
+ continue;
521
+ }
522
+
496
523
  const isOneShot = job.expression == null;
497
524
 
498
525
  // ── Notify mode (one-shot or recurring) ─────────────────────────
@@ -2,6 +2,6 @@
2
2
 
3
3
  ## Integration API Key Patterns
4
4
 
5
- When adding a new third-party integration, check whether the service uses a recognizable API key prefix (e.g., `lin_api_`, `sk-ant-`, `ghp_`). If it does, add a corresponding entry to `PREFIX_PATTERNS` in `secret-patterns.ts`. This is the single source of truth for prefix-based secret detection — ingress blocking, tool output scanning, and log redaction all consume this list.
5
+ When adding a new third-party integration, check whether the service uses a recognizable API key prefix (e.g., `lin_api_`, `sk-ant-`, `ghp_`). If it does, add a corresponding entry to `PREFIX_PATTERNS` in `packages/service-contracts/src/secret-detection.ts` (`@vellumai/service-contracts/secret-detection`). This is the single source of truth for prefix-based secret detection — ingress blocking, tool output scanning, log redaction, and the web composer guard all consume this list. `secret-patterns.ts` in this directory is a re-export that preserves existing daemon import paths.
6
6
 
7
7
  OAuth-only services with opaque access tokens (no fixed prefix) do not need a pattern.
@@ -12,3 +12,20 @@
12
12
  export function credentialKey(service: string, field: string): string {
13
13
  return `credential/${service}/${field}`;
14
14
  }
15
+
16
+ /**
17
+ * Normalize a credential reference to the vault-key form.
18
+ *
19
+ * The secrets API names credentials `{service}:{field}` on the wire (e.g.
20
+ * `openrouter:api_key`), while the vault stores them as
21
+ * `credential/{service}/{field}`. Callers routinely reuse the wire name where
22
+ * a vault key is expected, producing references that never resolve. Map the
23
+ * wire name to the vault key (same lastIndexOf split the secrets routes use);
24
+ * leave anything else untouched.
25
+ */
26
+ export function normalizeCredentialRef(ref: string): string {
27
+ if (ref.startsWith("credential/")) return ref;
28
+ const colonIdx = ref.lastIndexOf(":");
29
+ if (colonIdx < 1 || colonIdx === ref.length - 1) return ref;
30
+ return credentialKey(ref.slice(0, colonIdx), ref.slice(colonIdx + 1));
31
+ }
@@ -9,6 +9,15 @@
9
9
  * false positives on legitimate user input.
10
10
  */
11
11
 
12
+ import {
13
+ isPlaceholderContext,
14
+ isPlaceholderValue,
15
+ TOKEN_SHAPE,
16
+ TOKEN_SHAPE_LABEL,
17
+ TOKEN_SHAPE_MAX_LENGTH,
18
+ TOKEN_SHAPE_MIN_LENGTH,
19
+ } from "@vellumai/service-contracts/secret-detection";
20
+
12
21
  import { getConfig } from "../config/loader.js";
13
22
  import { memoizePluginPatternDerivation } from "./plugin-secret-patterns.js";
14
23
  import { isAllowlisted } from "./secret-allowlist.js";
@@ -52,112 +61,10 @@ const getGlobalPatterns = memoizePluginPatternDerivation(
52
61
  ],
53
62
  );
54
63
 
55
- // ---------------------------------------------------------------------------
56
- // Placeholder detection (inline — not imported from secret-scanner.ts)
57
- // ---------------------------------------------------------------------------
58
-
59
- const KNOWN_PLACEHOLDERS = new Set([
60
- "your-api-key-here",
61
- "your_api_key_here",
62
- "insert-your-key-here",
63
- "insert_your_key_here",
64
- "replace-with-your-key",
65
- "replace_with_your_key",
66
- "xxx",
67
- "xxxxxxxx",
68
- "test",
69
- "example",
70
- "sample",
71
- "demo",
72
- "placeholder",
73
- "changeme",
74
- "CHANGEME",
75
- "TODO",
76
- "FIXME",
77
- "your-token-here",
78
- "your_token_here",
79
- "my-api-key",
80
- "my_api_key",
81
- ]);
82
-
83
- const PLACEHOLDER_PREFIXES = [
84
- "sk-test-",
85
- "sk_test_",
86
- "fake_",
87
- "fake-",
88
- "dummy_",
89
- "dummy-",
90
- "test_",
91
- "test-",
92
- "example_",
93
- "example-",
94
- "sample_",
95
- "sample-",
96
- "mock_",
97
- "mock-",
98
- ];
99
-
100
- /**
101
- * Check if the text immediately before a matched value indicates
102
- * a placeholder context (e.g. "fake_", "test_").
103
- */
104
- function isPlaceholderContext(preContext: string): boolean {
105
- const lower = preContext.toLowerCase();
106
- for (const prefix of PLACEHOLDER_PREFIXES) {
107
- if (lower.endsWith(prefix)) return true;
108
- }
109
- return false;
110
- }
111
-
112
- /**
113
- * Check if a matched value is a placeholder/test value that should not
114
- * trigger blocking.
115
- */
116
- function isPlaceholder(value: string): boolean {
117
- const lower = value.toLowerCase();
118
-
119
- // Known placeholder values
120
- if (KNOWN_PLACEHOLDERS.has(lower)) return true;
121
-
122
- // Placeholder prefixes
123
- for (const prefix of PLACEHOLDER_PREFIXES) {
124
- if (lower.startsWith(prefix)) return true;
125
- }
126
-
127
- // Repeated characters in the variable portion (e.g. "AKIA" + "X" x 16)
128
- // Strip known prefixes to isolate the variable part
129
- const variablePart = value
130
- .replace(
131
- /^(?:AKIA|gh[pousr]_|github_pat_|glpat-|sk_live_|rk_live_|xoxb-|xoxp-|xapp-|sk-ant-|sk-proj-|sk-or-v1-|AIza|GOCSPX-|SK|SG\.|npm_|pypi-|key-|lin_api_|ntn_|fw_|pplx-|-----BEGIN [A-Z ]*PRIVATE KEY-----)/,
132
- "",
133
- )
134
- .replace(/[^A-Za-z0-9]/g, "");
135
- if (variablePart.length >= 8) {
136
- const firstChar = variablePart[0];
137
- if (variablePart.split("").every((c) => c === firstChar)) return true;
138
- }
139
-
140
- return false;
141
- }
142
-
143
64
  // ---------------------------------------------------------------------------
144
65
  // Token-shape heuristic (whole-message only)
145
66
  // ---------------------------------------------------------------------------
146
67
 
147
- /**
148
- * A single token-shaped value: an alphanumeric head, a separator-delimited
149
- * secret keyword infix, and a >=16-char tail (e.g. `virlo_tkn_JF…`). The
150
- * capture group isolates the tail for placeholder checks. Applied only when
151
- * the entire trimmed message is one such token — the whole-message and
152
- * keyword-infix requirements keep false positives near zero without any
153
- * entropy scoring.
154
- */
155
- const TOKEN_SHAPE =
156
- /^[A-Za-z0-9][A-Za-z0-9_-]*[_-](?:tkn|token|key|secret|api|pat|sk|auth)[_-]([A-Za-z0-9_-]{16,})$/i;
157
-
158
- const TOKEN_SHAPE_MIN_LENGTH = 20;
159
- const TOKEN_SHAPE_MAX_LENGTH = 512;
160
-
161
68
  /**
162
69
  * Check whether the entire message content is a single token-shaped value
163
70
  * that should be blocked (no whitespace, plausible length, keyword infix,
@@ -181,7 +88,7 @@ function isBlockedTokenShapedMessage(content: string): boolean {
181
88
  // Check both the full value (test_/fake_ prefixes) and the tail after the
182
89
  // keyword infix (repeated-char fillers like "xxxxxxxxxxxxxxxx")
183
90
  const tail = match[1]!;
184
- if (isPlaceholder(trimmed) || isPlaceholder(tail)) {
91
+ if (isPlaceholderValue(trimmed) || isPlaceholderValue(tail)) {
185
92
  return false;
186
93
  }
187
94
 
@@ -226,7 +133,9 @@ export function checkIngressForSecrets(content: string): IngressCheckResult {
226
133
  // a small window before it for placeholder prefixes like "fake_")
227
134
  const contextStart = Math.max(0, match.index - 10);
228
135
  const preContext = content.slice(contextStart, match.index);
229
- if (isPlaceholder(value) || isPlaceholderContext(preContext)) continue;
136
+ if (isPlaceholderValue(value) || isPlaceholderContext(preContext)) {
137
+ continue;
138
+ }
230
139
 
231
140
  // Skip user-allowlisted values
232
141
  if (isAllowlisted(value)) continue;
@@ -242,7 +151,7 @@ export function checkIngressForSecrets(content: string): IngressCheckResult {
242
151
  secretDetection.blockTokenShapedMessages &&
243
152
  isBlockedTokenShapedMessage(content)
244
153
  ) {
245
- detectedTypes.push("Token-shaped value");
154
+ detectedTypes.push(TOKEN_SHAPE_LABEL);
246
155
  }
247
156
 
248
157
  if (detectedTypes.length === 0) {
@@ -1,142 +1,11 @@
1
1
  /**
2
- * Shared prefix-based secret patterns — the single source of truth.
3
- *
4
- * Ingress blocking, tool output scanning, and log redaction all consume
5
- * this list. When adding a new integration, add its API key pattern here.
6
- *
7
- * This module is intentionally data-only: no imports, no entropy logic,
8
- * no config — safe for hot-path consumers like log serializers.
2
+ * Prefix-based secret patterns — sourced from the shared
3
+ * `@vellumai/service-contracts/secret-detection` module, the single source
4
+ * of truth for prefix-based secret detection across the daemon and clients.
9
5
  */
10
6
 
11
- // ---------------------------------------------------------------------------
12
- // Types
13
- // ---------------------------------------------------------------------------
14
-
15
- export interface SecretPrefixPattern {
16
- /** Human-readable label shown in block notices and redaction tags. */
17
- label: string;
18
- /**
19
- * Regex that matches the token value. Must NOT include the `g` flag or
20
- * capture groups — consumers add those as needed.
21
- */
22
- regex: RegExp;
23
- }
24
-
25
- // ---------------------------------------------------------------------------
26
- // Prefix patterns
27
- // ---------------------------------------------------------------------------
28
-
29
- /**
30
- * High-confidence, prefix-based secret patterns.
31
- *
32
- * Each entry matches a known API key / token format by its distinctive
33
- * prefix. Patterns that require surrounding context (entropy analysis,
34
- * keyword proximity, URL structure) do NOT belong here — they stay in
35
- * `secret-scanner.ts` as scanner-only patterns.
36
- *
37
- * **When adding a new third-party integration, add its API key pattern
38
- * here.** If the service uses only opaque OAuth access tokens (no fixed
39
- * prefix), no pattern is needed.
40
- */
41
- export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
42
- // -- AWS --
43
- { label: "AWS Access Key", regex: /AKIA[0-9A-Z]{16}/ },
44
-
45
- // -- GitHub --
46
- { label: "GitHub Token", regex: /gh[pousr]_[A-Za-z0-9_]{36,}/ },
47
- { label: "GitHub Fine-Grained PAT", regex: /github_pat_[A-Za-z0-9_]{22,}/ },
48
-
49
- // -- GitLab --
50
- { label: "GitLab Token", regex: /glpat-[A-Za-z0-9\-_]{20,}/ },
51
-
52
- // -- Stripe --
53
- { label: "Stripe Secret Key", regex: /sk_live_[A-Za-z0-9]{24,}/ },
54
- { label: "Stripe Restricted Key", regex: /rk_live_[A-Za-z0-9]{24,}/ },
55
-
56
- // -- Slack --
57
- {
58
- label: "Slack Bot Token",
59
- regex: /xoxb-[0-9]{10,}-[0-9]{10,}-[A-Za-z0-9]{24,}/,
60
- },
61
- {
62
- label: "Slack User Token",
63
- regex: /xoxp-[0-9]{10,}-[0-9]{10,}-[0-9]{10,}-[a-f0-9]{32}/,
64
- },
65
- {
66
- label: "Slack App Token",
67
- regex: /xapp-[0-9]+-[A-Za-z0-9]+-[0-9]+-[A-Za-z0-9]+/,
68
- },
69
-
70
- // -- Telegram --
71
- {
72
- label: "Telegram Bot Token",
73
- // Format: <bot_id>:<secret> where bot_id is 8–10 digits, secret is 35 chars
74
- regex: /[0-9]{8,10}:[A-Za-z0-9_-]{35}/,
75
- },
76
-
77
- // -- Anthropic --
78
- { label: "Anthropic API Key", regex: /sk-ant-[A-Za-z0-9\-_]{80,}/ },
79
-
80
- // -- OpenAI --
81
- {
82
- label: "OpenAI API Key",
83
- regex: /sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}/,
84
- },
85
- { label: "OpenAI Project Key", regex: /sk-proj-[A-Za-z0-9\-_]{40,}/ },
86
-
87
- // -- Google --
88
- { label: "Google API Key", regex: /AIza[A-Za-z0-9\-_]{35}/ },
89
- {
90
- label: "Google OAuth Client Secret",
91
- regex: /GOCSPX-[A-Za-z0-9\-_]{28}/,
92
- },
93
-
94
- // -- Twilio --
95
- { label: "Twilio API Key", regex: /SK[0-9a-f]{32}/ },
96
-
97
- // -- SendGrid --
98
- {
99
- label: "SendGrid API Key",
100
- regex: /SG\.[A-Za-z0-9\-_]{22}\.[A-Za-z0-9\-_]{43}/,
101
- },
102
-
103
- // -- Mailgun --
104
- { label: "Mailgun API Key", regex: /key-[A-Za-z0-9]{32}/ },
105
-
106
- // -- npm --
107
- { label: "npm Token", regex: /npm_[A-Za-z0-9]{36}/ },
108
-
109
- // -- PyPI --
110
- { label: "PyPI API Token", regex: /pypi-[A-Za-z0-9\-_]{50,}/ },
111
-
112
- // -- Private keys --
113
- {
114
- label: "Private Key",
115
- regex:
116
- /-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY(?:\s+BLOCK)?-----/,
117
- },
118
-
119
- // -- Linear --
120
- { label: "Linear API Key", regex: /lin_api_[A-Za-z0-9]{32,}/ },
121
-
122
- // -- Notion --
123
- { label: "Notion Integration Token", regex: /ntn_[A-Za-z0-9]{40,}/ },
124
-
125
- // -- OpenRouter --
126
- { label: "OpenRouter API Key", regex: /sk-or-v1-[A-Za-z0-9\-_]{40,}/ },
127
-
128
- // -- Vercel AI Gateway --
129
- { label: "Vercel AI Gateway API Key", regex: /vck_[A-Za-z0-9\-_]{24,}/ },
130
-
131
- // -- Fireworks --
132
- { label: "Fireworks API Key", regex: /fw_[A-Za-z0-9]{32,}/ },
133
-
134
- // -- Perplexity --
135
- { label: "Perplexity API Key", regex: /pplx-[A-Za-z0-9]{40,}/ },
136
-
137
- // -- Tavily --
138
- { label: "Tavily API Key", regex: /tvly-[A-Za-z0-9]{20,}/ },
139
-
140
- // -- Firecrawl --
141
- { label: "Firecrawl API Key", regex: /fc-[A-Za-z0-9]{20,}/ },
142
- ];
7
+ export {
8
+ PREFIX_PATTERNS,
9
+ REDACTION_PREFIX_PATTERNS,
10
+ type SecretPrefixPattern,
11
+ } from "@vellumai/service-contracts/secret-detection";
@@ -12,7 +12,7 @@
12
12
  import { memoizePluginPatternDerivation } from "./plugin-secret-patterns.js";
13
13
  import { isAllowlisted } from "./secret-allowlist.js";
14
14
  import {
15
- PREFIX_PATTERNS,
15
+ REDACTION_PREFIX_PATTERNS,
16
16
  type SecretPrefixPattern,
17
17
  } from "./secret-patterns.js";
18
18
 
@@ -71,9 +71,14 @@ function derivePluginScannerPattern(p: SecretPrefixPattern): SecretPattern {
71
71
  };
72
72
  }
73
73
 
74
- // Static patterns derived from the shared source of truth.
74
+ // Static patterns derived from the shared source of truth. This scanner
75
+ // redacts by replacing the matched span in place, so it uses the bounded
76
+ // whole-block private-key matcher (via REDACTION_PREFIX_PATTERNS): the match
77
+ // must cover header → body → footer or the key body would survive redaction.
78
+ // The bound keeps it O(n) on large serialized strings; `detectSecretsInText`
79
+ // (chat) keeps the unbounded whole-block matcher for full-key capture.
75
80
  const PREFIX_DERIVED: SecretPattern[] =
76
- PREFIX_PATTERNS.map(deriveScannerPattern);
81
+ REDACTION_PREFIX_PATTERNS.map(deriveScannerPattern);
77
82
 
78
83
  // Scanner-only patterns that require surrounding context or are not
79
84
  // simple prefix matches — these stay defined here.
@@ -11,10 +11,10 @@
11
11
  *
12
12
  * State is held on `globalThis.vellumAssistant.storePathOverride` so
13
13
  * test helpers in `__tests__/` can read/write it WITHOUT importing this
14
- * module — they declare the same slot shape locally and access the
15
- * globalThis namespace directly. See
16
- * `__tests__/encrypted-store-test-helpers.ts` for the test-side mirror;
17
- * the slot shape MUST stay in sync between the two.
14
+ * module. Both sides reference the shared ambient `VellumStorePathOverride`
15
+ * type (declared in `src/vellum-assistant-namespace.d.ts`), which types the
16
+ * slot without adding a runtime import between them. See
17
+ * `__tests__/encrypted-store-test-helpers.ts` for the test-side writer.
18
18
  *
19
19
  * Note: the new test preload places `VELLUM_WORKSPACE_DIR` at
20
20
  * `<tmpRoot>/workspace`, so `getProtectedDir()` resolves to
@@ -27,18 +27,8 @@
27
27
  * - `__tests__/encrypted-store-test-helpers.ts` (writes for tests, via globalThis)
28
28
  */
29
29
 
30
- type PathSlot = {
31
- storePath: string | null;
32
- storeKeyPath: string | null;
33
- };
34
-
35
- type VellumAssistantNamespace = {
36
- storePathOverride?: PathSlot;
37
- };
38
-
39
- function slot(): PathSlot {
40
- const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
41
- const ns = (g.vellumAssistant ??= {});
30
+ function slot(): VellumStorePathOverride {
31
+ const ns = (globalThis.vellumAssistant ??= {});
42
32
  return (ns.storePathOverride ??= { storePath: null, storeKeyPath: null });
43
33
  }
44
34
 
@@ -11,6 +11,7 @@ import { and, asc, eq, lte, sql } from "drizzle-orm";
11
11
  import { v4 as uuid } from "uuid";
12
12
 
13
13
  import { getDb } from "../persistence/db-connection.js";
14
+ import { isLifecycleQuiesced } from "../persistence/lifecycle-quiesce.js";
14
15
  import { rawChanges } from "../persistence/raw-query.js";
15
16
  import { sequenceEnrollments, sequences } from "../persistence/schema/index.js";
16
17
  import { AssistantError, ErrorCode } from "../util/errors.js";
@@ -224,6 +225,13 @@ export function claimDueEnrollments(
224
225
  now: number,
225
226
  limit = 10,
226
227
  ): SequenceEnrollment[] {
228
+ // Drain gate: while a quiesce lease is active, claim nothing — a sequence
229
+ // step's outreach starts before any row the drain snapshot can see.
230
+ // Fail-open via the lease read.
231
+ if (isLifecycleQuiesced()) {
232
+ return [];
233
+ }
234
+
227
235
  const db = getDb();
228
236
  const candidates = db
229
237
  .select()
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Handle generic event signals from the CLI.
3
3
  *
4
- * When the CLI writes a JSON-encoded {@link ServerMessage} to
4
+ * When the CLI writes a JSON-encoded {@link AssistantEvent} to
5
5
  * `signals/emit-event`, the daemon's ConfigWatcher detects the file
6
6
  * change and invokes {@link handleEmitEventSignal}, which reads the
7
7
  * payload and publishes it to connected clients via the in-process
@@ -15,9 +15,8 @@
15
15
  import { readFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
17
 
18
- import type { ServerMessage } from "../daemon/message-protocol.js";
19
- import { buildAssistantEvent } from "../runtime/assistant-event.js";
20
- import { assistantEventHub } from "../runtime/assistant-event-hub.js";
18
+ import type { AssistantEvent } from "../api/index.js";
19
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
21
20
  import { getLogger } from "../util/logger.js";
22
21
  import { getSignalsDir } from "../util/platform.js";
23
22
 
@@ -26,13 +25,9 @@ const log = getLogger("signal:emit-event");
26
25
  export function handleEmitEventSignal(): void {
27
26
  try {
28
27
  const content = readFileSync(join(getSignalsDir(), "emit-event"), "utf-8");
29
- const message = JSON.parse(content) as ServerMessage;
28
+ const message = JSON.parse(content) as AssistantEvent;
30
29
 
31
- assistantEventHub
32
- .publish(buildAssistantEvent(message))
33
- .catch((err: unknown) => {
34
- log.error({ err }, "Failed to publish event from signal");
35
- });
30
+ broadcastMessage(message);
36
31
 
37
32
  log.info({ type: message.type }, "Emit-event signal handled");
38
33
  } catch (err) {