@vellumai/assistant 0.7.2 → 0.8.0

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 (424) hide show
  1. package/ARCHITECTURE.md +45 -29
  2. package/Dockerfile +1 -0
  3. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  4. package/bun.lock +3 -0
  5. package/docs/architecture/memory.md +5 -2
  6. package/knip.json +1 -0
  7. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  8. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  9. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  10. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  11. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  12. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  13. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  14. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  16. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  17. package/openapi.yaml +470 -25
  18. package/package.json +3 -1
  19. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  20. package/src/__tests__/app-control-flow.test.ts +21 -11
  21. package/src/__tests__/approval-cascade.test.ts +8 -16
  22. package/src/__tests__/approval-routes-http.test.ts +6 -0
  23. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  24. package/src/__tests__/assistant-event.test.ts +0 -10
  25. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  26. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  29. package/src/__tests__/call-constants.test.ts +10 -1
  30. package/src/__tests__/call-controller.test.ts +127 -0
  31. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  32. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  33. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  34. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
  35. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  36. package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
  37. package/src/__tests__/config-schema.test.ts +1 -0
  38. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  39. package/src/__tests__/config-watcher.test.ts +140 -69
  40. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  41. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  42. package/src/__tests__/context-search-fanout.test.ts +0 -1
  43. package/src/__tests__/context-search-memory-source.test.ts +6 -33
  44. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  45. package/src/__tests__/context-search-pkb-source.test.ts +12 -7
  46. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  47. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
  48. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  51. package/src/__tests__/conversation-agent-loop.test.ts +457 -8
  52. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  53. package/src/__tests__/conversation-error.test.ts +150 -3
  54. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  55. package/src/__tests__/conversation-process-callsite.test.ts +38 -0
  56. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
  58. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  59. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  60. package/src/__tests__/conversation-store.test.ts +0 -18
  61. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  62. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  63. package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
  65. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  66. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  67. package/src/__tests__/credentials-cli.test.ts +7 -0
  68. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  69. package/src/__tests__/date-context.test.ts +164 -2
  70. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  71. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  72. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  73. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  74. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  75. package/src/__tests__/disk-usage.test.ts +150 -0
  76. package/src/__tests__/events-client-registration.test.ts +52 -0
  77. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  78. package/src/__tests__/file-write-tool.test.ts +4 -10
  79. package/src/__tests__/filing-service.test.ts +2 -20
  80. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  82. package/src/__tests__/heartbeat-service.test.ts +260 -11
  83. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  84. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  85. package/src/__tests__/host-bash-routes.test.ts +178 -13
  86. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  87. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  88. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  89. package/src/__tests__/host-file-proxy.test.ts +268 -6
  90. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  91. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  92. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  93. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  94. package/src/__tests__/injector-chain.test.ts +36 -16
  95. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  96. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
  98. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  99. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  100. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  101. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  102. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  103. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  104. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  105. package/src/__tests__/oauth-cli.test.ts +121 -0
  106. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  107. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  108. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  109. package/src/__tests__/openai-provider.test.ts +45 -8
  110. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  111. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  112. package/src/__tests__/platform.test.ts +2 -1
  113. package/src/__tests__/playbook-execution.test.ts +0 -43
  114. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  115. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  116. package/src/__tests__/provider-tool-name.test.ts +23 -0
  117. package/src/__tests__/relay-server.test.ts +60 -5
  118. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  119. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  120. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  121. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  122. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  123. package/src/__tests__/secret-response-routing.test.ts +7 -5
  124. package/src/__tests__/server-history-render.test.ts +82 -0
  125. package/src/__tests__/skill-include-graph.test.ts +31 -0
  126. package/src/__tests__/skill-load-tool.test.ts +44 -16
  127. package/src/__tests__/skills.test.ts +39 -0
  128. package/src/__tests__/suggestion-routes.test.ts +46 -0
  129. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  130. package/src/__tests__/tool-executor.test.ts +155 -0
  131. package/src/__tests__/twilio-validation.test.ts +2 -2
  132. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  133. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  134. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  136. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +120 -0
  137. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  138. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
  139. package/src/agent/loop.ts +11 -0
  140. package/src/approvals/guardian-request-resolvers.ts +3 -32
  141. package/src/backup/snapshot-lock.ts +2 -27
  142. package/src/bundler/compiler-tools.ts +3 -2
  143. package/src/calls/call-constants.ts +5 -8
  144. package/src/calls/call-controller.ts +130 -67
  145. package/src/calls/call-conversation-messages.ts +46 -10
  146. package/src/calls/relay-server.ts +7 -1
  147. package/src/calls/voice-session-bridge.ts +1 -1
  148. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  149. package/src/cli/commands/bash.ts +35 -108
  150. package/src/cli/commands/contacts.ts +64 -25
  151. package/src/cli/commands/credentials.ts +56 -0
  152. package/src/cli/commands/memory-v2.ts +11 -10
  153. package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
  154. package/src/cli/commands/oauth/connect.ts +124 -40
  155. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  156. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  157. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  158. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  159. package/src/cli/commands/platform/index.ts +16 -7
  160. package/src/cli/commands/status.ts +57 -0
  161. package/src/cli/program.ts +4 -2
  162. package/src/config/assistant-feature-flags.ts +13 -3
  163. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  164. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  165. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  166. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  167. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  168. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  169. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  170. package/src/config/env.ts +0 -8
  171. package/src/config/feature-flag-registry.json +13 -5
  172. package/src/config/loader.ts +199 -27
  173. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  174. package/src/config/schemas/call-site-catalog.ts +14 -0
  175. package/src/config/schemas/channels.ts +0 -5
  176. package/src/config/schemas/heartbeat.ts +1 -1
  177. package/src/config/schemas/llm.ts +2 -0
  178. package/src/config/schemas/memory-lifecycle.ts +13 -0
  179. package/src/config/schemas/memory-v2.ts +76 -12
  180. package/src/config/schemas/platform.ts +43 -3
  181. package/src/config/schemas/services.ts +28 -0
  182. package/src/config/seed-inference-profiles.ts +230 -33
  183. package/src/contacts/contact-store.ts +0 -25
  184. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
  185. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  186. package/src/daemon/assistant-attachments.ts +4 -4
  187. package/src/daemon/config-watcher.ts +85 -57
  188. package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
  189. package/src/daemon/conversation-agent-loop.ts +183 -43
  190. package/src/daemon/conversation-error.ts +87 -15
  191. package/src/daemon/conversation-lifecycle.ts +22 -10
  192. package/src/daemon/conversation-process.ts +8 -0
  193. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  194. package/src/daemon/conversation-store.ts +2 -2
  195. package/src/daemon/conversation-surfaces.ts +211 -29
  196. package/src/daemon/conversation-tool-setup.ts +66 -19
  197. package/src/daemon/conversation.ts +18 -23
  198. package/src/daemon/date-context.ts +71 -22
  199. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  200. package/src/daemon/disk-pressure-guard.ts +343 -0
  201. package/src/daemon/disk-pressure-policy.ts +163 -0
  202. package/src/daemon/handlers/shared.ts +26 -1
  203. package/src/daemon/handlers/skills.ts +3 -4
  204. package/src/daemon/host-app-control-proxy.ts +137 -41
  205. package/src/daemon/host-bash-proxy.ts +47 -22
  206. package/src/daemon/host-browser-proxy.ts +1 -1
  207. package/src/daemon/host-cu-proxy.ts +50 -4
  208. package/src/daemon/host-file-proxy.ts +44 -8
  209. package/src/daemon/host-transfer-proxy.ts +97 -6
  210. package/src/daemon/lifecycle.ts +167 -101
  211. package/src/daemon/meet-host-supervisor.ts +4 -4
  212. package/src/daemon/meet-manifest-loader.ts +0 -1
  213. package/src/daemon/memory-v2-startup.ts +66 -15
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/conversations.ts +4 -0
  216. package/src/daemon/message-types/disk-pressure.ts +9 -0
  217. package/src/daemon/message-types/messages.ts +22 -1
  218. package/src/daemon/profiler-run-store.ts +5 -5
  219. package/src/daemon/tool-setup-types.ts +2 -2
  220. package/src/documents/document-store.ts +119 -0
  221. package/src/filing/filing-service.ts +29 -5
  222. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  223. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  224. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  225. package/src/heartbeat/heartbeat-service.ts +205 -31
  226. package/src/home/feed-scheduler.ts +18 -0
  227. package/src/inbound/platform-callback-registration.ts +8 -15
  228. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  229. package/src/ipc/assistant-server.ts +149 -38
  230. package/src/ipc/gateway-client.ts +37 -3
  231. package/src/ipc/skill-server.ts +99 -42
  232. package/src/live-voice/live-voice-archive.ts +4 -4
  233. package/src/live-voice/protocol.ts +5 -7
  234. package/src/media/image-service.ts +1 -7
  235. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  236. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +34 -51
  237. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  238. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  239. package/src/memory/admin.ts +5 -9
  240. package/src/memory/context-search/agent-runner.ts +19 -2
  241. package/src/memory/context-search/sources/conversations.ts +2 -11
  242. package/src/memory/context-search/sources/memory-v2.ts +1 -16
  243. package/src/memory/context-search/sources/memory.ts +2 -3
  244. package/src/memory/context-search/sources/pkb.ts +2 -3
  245. package/src/memory/context-search/types.ts +0 -1
  246. package/src/memory/conversation-crud.ts +4 -12
  247. package/src/memory/db-init.ts +2 -0
  248. package/src/memory/embedding-runtime-manager.ts +119 -5
  249. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
  250. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  251. package/src/memory/graph/conversation-graph-memory.ts +72 -61
  252. package/src/memory/graph/extraction.ts +1 -3
  253. package/src/memory/graph/graph-search.test.ts +11 -67
  254. package/src/memory/graph/graph-search.ts +4 -24
  255. package/src/memory/graph/retriever.test.ts +12 -1
  256. package/src/memory/graph/retriever.ts +10 -15
  257. package/src/memory/graph/tool-handlers.ts +3 -4
  258. package/src/memory/graph/tools.ts +4 -4
  259. package/src/memory/indexer.ts +53 -45
  260. package/src/memory/job-handlers/backfill.ts +2 -11
  261. package/src/memory/job-handlers/cleanup.ts +43 -0
  262. package/src/memory/job-handlers/embedding.ts +6 -8
  263. package/src/memory/job-handlers/summarization.ts +2 -7
  264. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +116 -0
  265. package/src/memory/jobs/embed-concept-page.ts +223 -87
  266. package/src/memory/jobs-store.ts +48 -0
  267. package/src/memory/jobs-worker.ts +85 -43
  268. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  269. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  270. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  271. package/src/memory/migrations/index.ts +1 -0
  272. package/src/memory/pkb/pkb-search.test.ts +7 -0
  273. package/src/memory/pkb/pkb-search.ts +4 -5
  274. package/src/memory/qdrant-client.ts +3 -13
  275. package/src/memory/rerank-local.ts +374 -0
  276. package/src/memory/search/semantic.ts +10 -72
  277. package/src/memory/trace-event-store.ts +1 -17
  278. package/src/memory/v2/__tests__/activation.test.ts +346 -255
  279. package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
  280. package/src/memory/v2/__tests__/injection.test.ts +297 -190
  281. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  282. package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
  283. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  284. package/src/memory/v2/__tests__/sim.test.ts +113 -196
  285. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  286. package/src/memory/v2/__tests__/static-context.test.ts +77 -14
  287. package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
  288. package/src/memory/v2/activation.ts +149 -156
  289. package/src/memory/v2/consolidation-job.ts +69 -20
  290. package/src/memory/v2/injection.ts +75 -68
  291. package/src/memory/v2/page-store.ts +39 -0
  292. package/src/memory/v2/prompts/consolidation.ts +41 -1
  293. package/src/memory/v2/qdrant.ts +306 -46
  294. package/src/memory/v2/reranker.ts +177 -0
  295. package/src/memory/v2/sim.ts +77 -110
  296. package/src/memory/v2/skill-content.ts +4 -3
  297. package/src/memory/v2/skill-store.ts +82 -59
  298. package/src/memory/v2/static-context.ts +26 -8
  299. package/src/memory/v2/sweep-job.ts +5 -6
  300. package/src/memory/v2/types.ts +17 -10
  301. package/src/notifications/copy-composer.ts +47 -0
  302. package/src/notifications/decision-engine.ts +46 -0
  303. package/src/notifications/signal.ts +4 -0
  304. package/src/oauth/AGENTS.md +3 -1
  305. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  306. package/src/oauth/connect-orchestrator.ts +2 -0
  307. package/src/oauth/connection-resolver.test.ts +66 -1
  308. package/src/oauth/connection-resolver.ts +55 -1
  309. package/src/oauth/oauth-connect-state.ts +77 -0
  310. package/src/oauth/seed-providers.ts +58 -1
  311. package/src/permissions/gateway-threshold-reader.ts +116 -8
  312. package/src/permissions/prompter.ts +86 -96
  313. package/src/permissions/secret-prompter.ts +31 -31
  314. package/src/plugins/defaults/injectors.ts +36 -4
  315. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  316. package/src/plugins/types.ts +7 -0
  317. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  318. package/src/proactive-artifact/decision.test.ts +226 -0
  319. package/src/proactive-artifact/decision.ts +165 -0
  320. package/src/proactive-artifact/index.ts +7 -0
  321. package/src/proactive-artifact/job.test.ts +914 -0
  322. package/src/proactive-artifact/job.ts +366 -0
  323. package/src/proactive-artifact/message-copy.ts +58 -0
  324. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  325. package/src/proactive-artifact/trigger-state.ts +119 -0
  326. package/src/prompts/normalize-onboarding.ts +80 -0
  327. package/src/prompts/persona-resolver.ts +101 -9
  328. package/src/prompts/system-prompt.ts +21 -7
  329. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  330. package/src/prompts/templates/SOUL.md +13 -28
  331. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  332. package/src/providers/model-intents.ts +7 -0
  333. package/src/providers/openrouter/client.ts +8 -0
  334. package/src/providers/retry.ts +50 -0
  335. package/src/providers/types.ts +1 -0
  336. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  337. package/src/runtime/agent-wake.ts +238 -100
  338. package/src/runtime/assistant-event-hub.ts +36 -6
  339. package/src/runtime/assistant-event.ts +0 -1
  340. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  341. package/src/runtime/auth/route-policy.ts +15 -1
  342. package/src/runtime/auth/same-actor.ts +216 -0
  343. package/src/runtime/channel-approvals.ts +3 -2
  344. package/src/runtime/channel-retry-sweep.ts +65 -1
  345. package/src/runtime/local-actor-identity.ts +52 -11
  346. package/src/runtime/pending-interactions.ts +27 -15
  347. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  348. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  349. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  350. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  351. package/src/runtime/routes/approval-routes.ts +7 -3
  352. package/src/runtime/routes/client-routes.ts +20 -2
  353. package/src/runtime/routes/consolidation-routes.ts +8 -9
  354. package/src/runtime/routes/contact-routes.ts +0 -25
  355. package/src/runtime/routes/conversation-query-routes.ts +44 -1
  356. package/src/runtime/routes/conversation-routes.ts +35 -26
  357. package/src/runtime/routes/debug-bash-routes.ts +165 -0
  358. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  359. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  360. package/src/runtime/routes/documents-routes.ts +2 -75
  361. package/src/runtime/routes/events-routes.ts +41 -9
  362. package/src/runtime/routes/filing-routes.ts +2 -3
  363. package/src/runtime/routes/host-bash-routes.ts +23 -3
  364. package/src/runtime/routes/host-cu-routes.ts +33 -6
  365. package/src/runtime/routes/host-file-routes.ts +32 -6
  366. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  367. package/src/runtime/routes/identity-routes.ts +7 -138
  368. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  369. package/src/runtime/routes/index.ts +6 -0
  370. package/src/runtime/routes/memory-item-routes.test.ts +37 -17
  371. package/src/runtime/routes/memory-item-routes.ts +5 -6
  372. package/src/runtime/routes/memory-v2-routes.ts +136 -17
  373. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  374. package/src/runtime/verification-outbound-actions.ts +4 -4
  375. package/src/schedule/run-script.ts +37 -5
  376. package/src/schedule/scheduler.ts +20 -1
  377. package/src/security/encrypted-store.ts +2 -0
  378. package/src/security/secure-keys.ts +55 -0
  379. package/src/skills/include-graph.ts +35 -13
  380. package/src/skills/remote-skill-policy.ts +4 -10
  381. package/src/subagent/index.ts +1 -7
  382. package/src/subagent/manager.ts +1 -15
  383. package/src/tasks/task-runner.ts +0 -1
  384. package/src/tasks/task-store.ts +0 -3
  385. package/src/tools/background-tool-registry.ts +17 -3
  386. package/src/tools/document/document-tool.ts +20 -0
  387. package/src/tools/executor.ts +18 -2
  388. package/src/tools/host-filesystem/edit.test.ts +151 -0
  389. package/src/tools/host-filesystem/edit.ts +43 -1
  390. package/src/tools/host-filesystem/read.test.ts +129 -0
  391. package/src/tools/host-filesystem/read.ts +43 -1
  392. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  393. package/src/tools/host-filesystem/transfer.ts +56 -11
  394. package/src/tools/host-filesystem/write.test.ts +134 -0
  395. package/src/tools/host-filesystem/write.ts +43 -1
  396. package/src/tools/host-terminal/host-shell.ts +13 -6
  397. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  398. package/src/tools/memory/register.test.ts +14 -9
  399. package/src/tools/memory/register.ts +1 -2
  400. package/src/tools/permission-checker.ts +15 -0
  401. package/src/tools/provider-tool-name.ts +28 -0
  402. package/src/tools/registry.ts +30 -9
  403. package/src/tools/skills/load.ts +24 -20
  404. package/src/tools/terminal/shell.ts +9 -1
  405. package/src/tools/tool-approval-handler.ts +31 -6
  406. package/src/tools/tool-name-aliases.ts +19 -0
  407. package/src/tools/types.ts +43 -3
  408. package/src/tts/provider-catalog.ts +3 -5
  409. package/src/util/disk-usage.ts +138 -0
  410. package/src/util/platform.ts +21 -11
  411. package/src/util/process-liveness.ts +26 -0
  412. package/src/workspace/heartbeat-service.ts +19 -0
  413. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  414. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  415. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +14 -0
  416. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  417. package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
  418. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  419. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  420. package/src/workspace/migrations/registry.ts +14 -0
  421. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  422. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  423. package/src/memory/v2/skill-qdrant.ts +0 -404
  424. package/src/signals/bash.ts +0 -198
@@ -7,10 +7,7 @@ import { reconcileCallsOnStartup } from "../calls/call-recovery.js";
7
7
  import { setRelayBroadcast } from "../calls/relay-server.js";
8
8
  import { TwilioConversationRelayProvider } from "../calls/twilio-provider.js";
9
9
  import { setVoiceBridgeDeps } from "../calls/voice-session-bridge.js";
10
- import {
11
- initFeatureFlagOverrides,
12
- isAssistantFeatureFlagEnabled,
13
- } from "../config/assistant-feature-flags.js";
10
+ import { initFeatureFlagOverrides } from "../config/assistant-feature-flags.js";
14
11
  import {
15
12
  getPlatformAssistantId,
16
13
  getRuntimeHttpHost,
@@ -54,7 +51,6 @@ import { startMemoryJobsWorker } from "../memory/jobs-worker.js";
54
51
  import { initQdrantClient, resolveQdrantUrl } from "../memory/qdrant-client.js";
55
52
  import { QdrantManager } from "../memory/qdrant-manager.js";
56
53
  import { rotateToolInvocations } from "../memory/tool-usage-store.js";
57
- import { deleteOldTraceEvents } from "../memory/trace-event-store.js";
58
54
  import {
59
55
  emitNotificationSignal,
60
56
  registerBroadcastFn,
@@ -62,6 +58,7 @@ import {
62
58
  import { backfillManualTokenConnections } from "../oauth/manual-token-connection.js";
63
59
  import { seedOAuthProviders } from "../oauth/seed-providers.js";
64
60
  import { loadUserPlugins } from "../plugins/user-loader.js";
61
+ import { backfillGuardIfNeeded } from "../proactive-artifact/index.js";
65
62
  import { ensurePromptFiles } from "../prompts/system-prompt.js";
66
63
  import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
67
64
  import { broadcastMessage } from "../runtime/assistant-event-hub.js";
@@ -105,6 +102,11 @@ import {
105
102
  cleanupPidFileIfOwner,
106
103
  writePid,
107
104
  } from "./daemon-control.js";
105
+ import {
106
+ evaluateDiskPressureNow,
107
+ startDiskPressureGuard,
108
+ stopDiskPressureGuard,
109
+ } from "./disk-pressure-guard.js";
108
110
  import { bootstrapPlugins } from "./external-plugins-bootstrap.js";
109
111
  import {
110
112
  createGuardianActionCopyGenerator,
@@ -112,7 +114,10 @@ import {
112
114
  } from "./guardian-action-generators.js";
113
115
  import { backfillSlackInjectionTemplates } from "./handlers/config-slack-channel.js";
114
116
  import { installAssistantSymlink } from "./install-symlink.js";
115
- import { maybeSeedMemoryV2Skills } from "./memory-v2-startup.js";
117
+ import {
118
+ maybeRebuildMemoryV2Concepts,
119
+ maybeSeedMemoryV2Skills,
120
+ } from "./memory-v2-startup.js";
116
121
  import { processMessage } from "./process-message.js";
117
122
  import { runProfilerSweep } from "./profiler-run-store.js";
118
123
  import {
@@ -125,11 +130,57 @@ import { DaemonServer } from "./server.js";
125
130
  import { installShutdownHandlers } from "./shutdown-handlers.js";
126
131
 
127
132
  const log = getLogger("lifecycle");
133
+ let diskPressureStartupSampleTimer: ReturnType<typeof setTimeout> | null = null;
128
134
 
129
135
  function loadDotEnv(): void {
130
136
  dotenvConfig({ path: getDotEnvPath(), quiet: true });
131
137
  }
132
138
 
139
+ function runDeferredDiskPressureStartupSample(): void {
140
+ diskPressureStartupSampleTimer = null;
141
+ try {
142
+ const status = evaluateDiskPressureNow();
143
+ if (status.error) {
144
+ log.warn(
145
+ { error: status.error },
146
+ "Disk pressure guard sample failed during startup — continuing unlocked",
147
+ );
148
+ }
149
+ } catch (err) {
150
+ log.warn(
151
+ { err },
152
+ "Disk pressure guard failed during startup — continuing unlocked",
153
+ );
154
+ }
155
+ }
156
+
157
+ export function startDiskPressureGuardForLifecycle(): void {
158
+ try {
159
+ const startedStatus = startDiskPressureGuard();
160
+ if (!startedStatus.enabled) return;
161
+ if (!diskPressureStartupSampleTimer) {
162
+ diskPressureStartupSampleTimer = setTimeout(
163
+ runDeferredDiskPressureStartupSample,
164
+ 0,
165
+ );
166
+ (diskPressureStartupSampleTimer as { unref?: () => void }).unref?.();
167
+ }
168
+ } catch (err) {
169
+ log.warn(
170
+ { err },
171
+ "Disk pressure guard failed during startup — continuing unlocked",
172
+ );
173
+ }
174
+ }
175
+
176
+ export function stopDiskPressureGuardForLifecycle(): void {
177
+ if (diskPressureStartupSampleTimer) {
178
+ clearTimeout(diskPressureStartupSampleTimer);
179
+ diskPressureStartupSampleTimer = null;
180
+ }
181
+ stopDiskPressureGuard();
182
+ }
183
+
133
184
  export interface CesStartupResult {
134
185
  client: CesClient | undefined;
135
186
  processManager: CesProcessManager | undefined;
@@ -267,21 +318,16 @@ export async function runDaemon(): Promise<void> {
267
318
  const signingKey = resolveSigningKey();
268
319
  initAuthSigningKey(signingKey);
269
320
 
270
- // Pre-populate
271
- // subsequent sync isAssistantFeatureFlagEnabled() calls have data.
272
- // Fired non-blocking so a slow or unreachable gateway doesn't delay
273
- // daemon startup (the IPC call has a 3s connect + 5s call timeout
274
- // that would otherwise stall the critical path).
275
- //
276
- // On resolve, retry the v2 skill seed: the synchronous gate at the
277
- // skill-seed call site below evaluates the memory-v2-enabled flag
278
- // before the gateway has populated overrides, so a cold-boot race
279
- // can leave the v2 skill collection unseeded for the lifetime of
280
- // the daemon. seedV2SkillEntries is idempotent, so re-running after
281
- // overrides land is safe.
282
- void initFeatureFlagOverrides()
283
- .then(() => maybeSeedMemoryV2Skills(loadConfig()))
284
- .catch((err) => log.warn({ err }, "Background feature flag init failed"));
321
+ // Pre-populate feature flag overrides so subsequent sync
322
+ // isAssistantFeatureFlagEnabled() calls have data. Fired non-blocking
323
+ // so a slow or unreachable gateway doesn't delay daemon startup (the
324
+ // IPC call has a 3s connect + 5s call timeout that would otherwise
325
+ // stall the critical path).
326
+ void initFeatureFlagOverrides().catch((err) =>
327
+ log.warn({ err }, "Background feature flag init failed"),
328
+ );
329
+
330
+ maybeSeedMemoryV2Skills(loadConfig());
285
331
 
286
332
  seedInterfaceFiles();
287
333
 
@@ -448,12 +494,22 @@ export async function runDaemon(): Promise<void> {
448
494
  }
449
495
  } // end if (dbReady)
450
496
 
451
- // Seed managed inference profiles into the workspace config. Runs
452
- // after workspace migrations (which may have created the initial
453
- // profile slots) and before mergeDefaultWorkspaceConfig / loadConfig
454
- // so the profiles are on disk for the first config load.
497
+ // Merge CLI-provided default config (from VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH)
498
+ // into the workspace config file before profile seeding and the first
499
+ // loadConfig() call so onboarding/platform preferences are visible to the
500
+ // seeder and persisted alongside schema defaults.
501
+ const defaultConfigMerge = mergeDefaultWorkspaceConfig();
502
+
503
+ // Seed managed inference profiles into the workspace config. Runs after
504
+ // workspace migrations and default-config merge, but before loadConfig() so
505
+ // fresh hatches have profiles on disk before the first config load. Any
506
+ // profile fields explicitly supplied by the default overlay stay
507
+ // authoritative for this startup.
455
508
  try {
456
- seedInferenceProfiles();
509
+ seedInferenceProfiles({
510
+ preserveProfileNames: defaultConfigMerge.providedLlmProfileNames,
511
+ preserveActiveProfile: defaultConfigMerge.providedLlmActiveProfile,
512
+ });
457
513
  log.info("Inference profile seeding complete");
458
514
  } catch (err) {
459
515
  log.warn(
@@ -462,11 +518,6 @@ export async function runDaemon(): Promise<void> {
462
518
  );
463
519
  }
464
520
 
465
- // Merge CLI-provided default config (from VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH)
466
- // into the workspace config file before the first loadConfig() call so
467
- // onboarding preferences are persisted alongside schema defaults.
468
- mergeDefaultWorkspaceConfig();
469
-
470
521
  log.info("Daemon startup: loading config");
471
522
  const config = loadConfig();
472
523
 
@@ -625,6 +676,7 @@ export async function runDaemon(): Promise<void> {
625
676
 
626
677
  await server.start();
627
678
  log.info("Daemon startup: DaemonServer started");
679
+ startDiskPressureGuardForLifecycle();
628
680
 
629
681
  // Kick off the update bulletin background job AFTER `server.start()`
630
682
  // resolves. The conversation store must be initialized before wake
@@ -684,64 +736,87 @@ export async function runDaemon(): Promise<void> {
684
736
  }
685
737
 
686
738
  if (qdrantStarted) {
687
- try {
688
- const embeddingSelection = await selectEmbeddingBackend(config);
689
- // Sentinel only encodes the dense provider+model identity; sparse
690
- // encoder changes never require collection recreation, so they
691
- // intentionally do not contribute to the v1 collection identity.
692
- const embeddingModel = embeddingSelection.backend
693
- ? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}`
694
- : undefined;
695
- const qdrantClient = initQdrantClient({
696
- url: qdrantUrl,
697
- collection: config.memory.qdrant.collection,
698
- vectorSize: config.memory.qdrant.vectorSize,
699
- onDisk: config.memory.qdrant.onDisk,
700
- quantization: config.memory.qdrant.quantization,
701
- embeddingModel,
702
- });
739
+ // Skip the v1 Qdrant collection lifecycle when memory v2 is active —
740
+ // the v1 collection has no writers (handleRemember returns early) or
741
+ // readers (graph search is bypassed) under v2, so ensuring/migrating
742
+ // it just maintains a dead-on-arrival collection. Existing on-disk
743
+ // collections are left intact so flipping v2 off restores v1 cleanly.
744
+ if (!config.memory.v2.enabled) {
745
+ try {
746
+ const embeddingSelection = await selectEmbeddingBackend(config);
747
+ // Sentinel only encodes the dense provider+model identity; sparse
748
+ // encoder changes never require collection recreation, so they
749
+ // intentionally do not contribute to the v1 collection identity.
750
+ const embeddingModel = embeddingSelection.backend
751
+ ? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}`
752
+ : undefined;
753
+ const qdrantClient = initQdrantClient({
754
+ url: qdrantUrl,
755
+ collection: config.memory.qdrant.collection,
756
+ vectorSize: config.memory.qdrant.vectorSize,
757
+ onDisk: config.memory.qdrant.onDisk,
758
+ quantization: config.memory.qdrant.quantization,
759
+ embeddingModel,
760
+ });
761
+
762
+ // Eagerly ensure the collection exists so we detect migrations
763
+ // (unnamed→named vectors, dimension/model changes) at startup.
764
+ // If a destructive migration occurred, enqueue a rebuild_index job
765
+ // to re-embed all memory items from the SQLite cache.
766
+ const { migrated } = await qdrantClient.ensureCollection();
767
+ if (migrated) {
768
+ enqueueMemoryJob("rebuild_index", {});
769
+ log.info(
770
+ "Qdrant collection was migrated — enqueued rebuild_index job",
771
+ );
772
+ }
703
773
 
704
- // Eagerly ensure the collection exists so we detect migrations
705
- // (unnamed→named vectors, dimension/model changes) at startup.
706
- // If a destructive migration occurred, enqueue a rebuild_index job
707
- // to re-embed all memory items from the SQLite cache.
708
- const { migrated } = await qdrantClient.ensureCollection();
709
- if (migrated) {
710
- enqueueMemoryJob("rebuild_index", {});
711
- log.info(
712
- "Qdrant collection was migrated — enqueued rebuild_index job",
774
+ log.info("Qdrant vector store initialized");
775
+ } catch (err) {
776
+ log.warn(
777
+ { err },
778
+ "Qdrant client initialization failed memory features will be degraded",
713
779
  );
714
780
  }
781
+ }
715
782
 
716
- log.info("Qdrant vector store initialized");
783
+ // Detect schema drift on the v2 concept-page collection (e.g.
784
+ // pre-#29823 collections lacking summary_dense / summary_sparse) and
785
+ // recreate + enqueue a reembed when needed. Awaited inline so the
786
+ // reembed enqueue happens before the memory worker drains its first
787
+ // batch; the call's own try/catch keeps any v2-side failure from
788
+ // blocking the v1 PKB reconcile or BM25 build below.
789
+ try {
790
+ await maybeRebuildMemoryV2Concepts(config);
717
791
  } catch (err) {
718
792
  log.warn(
719
793
  { err },
720
- "Qdrant client initialization failed memory features will be degraded",
794
+ "Memory v2 collection schema check threw continuing startup",
721
795
  );
722
796
  }
723
797
 
724
- // Reconcile the PKB Qdrant index against the on-disk tree. Kept
725
- // inside the `qdrantStarted` guard so we don't call
726
- // `getQdrantClient()` (which throws "not initialized") on every
727
- // startup when Qdrant is unavailable. Fire-and-forget so enqueued
728
- // re-index jobs drain in the background and first-turn latency
729
- // stays unaffected.
730
- void (async () => {
731
- try {
732
- const { reconcilePkbIndex } =
733
- await import("../memory/pkb/pkb-reconcile.js");
734
- const { PKB_WORKSPACE_SCOPE } =
735
- await import("../memory/pkb/types.js");
736
- const pkbRoot = join(getWorkspaceDir(), "pkb");
737
- await reconcilePkbIndex(pkbRoot, PKB_WORKSPACE_SCOPE);
738
- } catch (err) {
739
- log.warn(
740
- { err },
741
- "PKB index reconciliation failed — continuing startup",
742
- );
743
- }
744
- })();
798
+ // Reconcile the PKB Qdrant index against the on-disk tree. Gated on
799
+ // !v2 because PKB is the v1 storage layer; under v2 the v1 collection
800
+ // is not initialized, so calling `getQdrantClient()` here would throw.
801
+ // Fire-and-forget so enqueued re-index jobs drain in the background
802
+ // and first-turn latency stays unaffected.
803
+ if (!config.memory.v2.enabled) {
804
+ void (async () => {
805
+ try {
806
+ const { reconcilePkbIndex } =
807
+ await import("../memory/pkb/pkb-reconcile.js");
808
+ const { PKB_WORKSPACE_SCOPE } =
809
+ await import("../memory/pkb/types.js");
810
+ const pkbRoot = join(getWorkspaceDir(), "pkb");
811
+ await reconcilePkbIndex(pkbRoot, PKB_WORKSPACE_SCOPE);
812
+ } catch (err) {
813
+ log.warn(
814
+ { err },
815
+ "PKB index reconciliation failed — continuing startup",
816
+ );
817
+ }
818
+ })();
819
+ }
745
820
 
746
821
  // Build the BM25 corpus stats (per-token document frequencies and
747
822
  // average document length) used by the v2 sparse channel. Without
@@ -1198,22 +1273,6 @@ export async function runDaemon(): Promise<void> {
1198
1273
  }
1199
1274
  }
1200
1275
 
1201
- // Prune trace events older than 7 days to keep the database lean.
1202
- // Deferred so synchronous cleanup doesn't block the startup path.
1203
- setTimeout(() => {
1204
- try {
1205
- const deletedTraceEvents = deleteOldTraceEvents(7);
1206
- if (deletedTraceEvents > 0) {
1207
- log.debug(
1208
- { deletedTraceEvents },
1209
- `Pruned ${deletedTraceEvents} trace event(s) older than 7 days`,
1210
- );
1211
- }
1212
- } catch (err) {
1213
- log.warn({ err }, "Trace event cleanup failed");
1214
- }
1215
- }, 0);
1216
-
1217
1276
  const workspaceHeartbeat = new WorkspaceHeartbeatService();
1218
1277
  workspaceHeartbeat.start();
1219
1278
 
@@ -1236,14 +1295,17 @@ export async function runDaemon(): Promise<void> {
1236
1295
  "Heartbeat service configured",
1237
1296
  );
1238
1297
 
1239
- // Filing yields to the memory v2 consolidation job when the flag is on —
1298
+ try {
1299
+ backfillGuardIfNeeded();
1300
+ } catch (err) {
1301
+ log.warn({ err }, "Proactive artifact backfill failed");
1302
+ }
1303
+
1304
+ // Filing yields to the memory v2 consolidation job when v2 is enabled —
1240
1305
  // both serve the same role (periodic background memory processing) and
1241
1306
  // running both is redundant. The consolidation job runs through the
1242
1307
  // memory jobs worker (see `maybeEnqueueGraphMaintenanceJobs`).
1243
- const memoryV2Enabled = isAssistantFeatureFlagEnabled(
1244
- "memory-v2-enabled",
1245
- config,
1246
- );
1308
+ const memoryV2Enabled = config.memory.v2.enabled;
1247
1309
  let filing: FilingService | null = null;
1248
1310
  if (!memoryV2Enabled) {
1249
1311
  const filingConfig = config.filing;
@@ -1281,10 +1343,14 @@ export async function runDaemon(): Promise<void> {
1281
1343
  getQdrantManager: () => bgRefs.qdrantManager,
1282
1344
  mcpManager,
1283
1345
  telemetryReporter,
1284
- cleanupPidFile,
1346
+ cleanupPidFile: () => {
1347
+ stopDiskPressureGuardForLifecycle();
1348
+ cleanupPidFile();
1349
+ },
1285
1350
  });
1286
1351
  } catch (err) {
1287
1352
  log.error({ err }, "Daemon startup failed — cleaning up");
1353
+ stopDiskPressureGuardForLifecycle();
1288
1354
  cleanupPidFileIfOwner(process.pid);
1289
1355
  throw err;
1290
1356
  }
@@ -72,7 +72,7 @@ import { getLogger } from "../util/logger.js";
72
72
  * keeps the supervisor free of path assumptions and simplifies
73
73
  * tests.
74
74
  */
75
- export interface MeetHostManifest {
75
+ interface MeetHostManifest {
76
76
  /** SHA-256 of the shipped skill source tree. */
77
77
  sourceHash: string;
78
78
  }
@@ -84,7 +84,7 @@ export interface MeetHostManifest {
84
84
  * protocol version) can be threaded through later without a
85
85
  * signature break.
86
86
  */
87
- export interface MeetHostHandshakePayload {
87
+ interface MeetHostHandshakePayload {
88
88
  sourceHash: string;
89
89
  }
90
90
 
@@ -97,7 +97,7 @@ export interface MeetHostHandshakePayload {
97
97
  * supervisor unaware of the rest of the IPC server's surface and avoids a
98
98
  * circular import in tests that already stub `skill-server.js`.
99
99
  */
100
- export interface SkillRequestSender {
100
+ interface SkillRequestSender {
101
101
  sendRequest(
102
102
  connection: SkillIpcConnection,
103
103
  method: string,
@@ -111,7 +111,7 @@ export interface SkillRequestSender {
111
111
  * child. All are optional on construction — production callers
112
112
  * rely on the defaults and tests override one or two at a time.
113
113
  */
114
- export interface MeetHostSupervisorDeps {
114
+ interface MeetHostSupervisorDeps {
115
115
  /** Absolute path to the shipped `meet-join` skill dir, containing `register.ts`. */
116
116
  skillRuntimePath: string;
117
117
  /** Absolute path to a standalone bun binary, or `"bun"` for PATH lookup. */
@@ -109,7 +109,6 @@ const SERIALIZABLE_TOOL_CONTEXT_KEYS = [
109
109
  "callSessionId",
110
110
  "principal",
111
111
  "toolUseId",
112
- "memoryScopeId",
113
112
  "requesterExternalUserId",
114
113
  "requesterChatId",
115
114
  "requesterIdentifier",
@@ -6,30 +6,81 @@
6
6
  // startup work invoked from `lifecycle.ts`. Lives in its own file so the unit
7
7
  // test for the gate does not have to mount the entire lifecycle import graph.
8
8
 
9
- import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
10
9
  import type { AssistantConfig } from "../config/schema.js";
11
10
  import { getLogger } from "../util/logger.js";
11
+ import { getWorkspaceDir } from "../util/platform.js";
12
12
 
13
13
  const log = getLogger("memory-v2-startup");
14
14
 
15
15
  /**
16
- * Fire-and-forget seed of the v2 parallel skill embedding collection. Gated
17
- * on both the `memory-v2-enabled` feature flag and the workspace-level
18
- * `config.memory.v2.enabled` switch so v2 modules stay out of the v1 startup
19
- * path when v2 is off.
20
- *
21
- * Uses a dynamic import so v2 code does not load unless the gate passes.
22
- * Never awaits — startup must not block on this (see `assistant/CLAUDE.md`
23
- * daemon startup philosophy).
16
+ * Fire-and-forget seed of the v2 skill entries (now indexed alongside concept
17
+ * pages in `memory_v2_concept_pages` under the `skills/<id>` slug prefix), and
18
+ * a one-shot best-effort cleanup of the legacy `memory_v2_skills` Qdrant
19
+ * collection. Uses a dynamic import so v2 code does not load unless the gate
20
+ * passes. Never awaits — startup must not block on this (see
21
+ * `assistant/CLAUDE.md` daemon startup philosophy).
24
22
  */
25
23
  export function maybeSeedMemoryV2Skills(config: AssistantConfig): void {
26
- if (
27
- !isAssistantFeatureFlagEnabled("memory-v2-enabled", config) ||
28
- !config.memory.v2.enabled
29
- ) {
30
- return;
31
- }
24
+ if (!config.memory.v2.enabled) return;
32
25
  void import("../memory/v2/skill-store.js")
33
26
  .then(({ seedV2SkillEntries }) => seedV2SkillEntries())
34
27
  .catch((err) => log.warn({ err }, "Failed to seed v2 skill entries"));
28
+ void import("../memory/v2/qdrant.js")
29
+ .then(({ dropLegacySkillsCollection }) => dropLegacySkillsCollection())
30
+ .catch((err) =>
31
+ log.warn(
32
+ { err },
33
+ "Failed to drop legacy memory_v2_skills collection — non-fatal",
34
+ ),
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Reconcile the v2 concept-page Qdrant collection with the expected schema
40
+ * and enqueue `memory_v2_reembed` when the collection is missing data.
41
+ * Triggers reembed in two cases:
42
+ * - Drift: `ensureConceptPageCollection` returned `{ migrated: true }`
43
+ * after destructively recreating the collection (e.g. pre-#29823
44
+ * schemas lacking `summary_*` named vectors).
45
+ * - Empty-after-create: the collection has zero points but pages exist on
46
+ * disk — covers crash-mid-rebuild and external Qdrant wipes.
47
+ *
48
+ * Awaited inline by `lifecycle.ts` so the enqueue happens before the memory
49
+ * worker drains its first batch; the body is wrapped in try/catch so a v2
50
+ * failure never blocks startup.
51
+ */
52
+ export async function maybeRebuildMemoryV2Concepts(
53
+ config: AssistantConfig,
54
+ ): Promise<void> {
55
+ if (!config.memory.v2.enabled) return;
56
+
57
+ try {
58
+ const { ensureConceptPageCollection, countConceptPagePoints } =
59
+ await import("../memory/v2/qdrant.js");
60
+ const { hasConceptPages } = await import("../memory/v2/page-store.js");
61
+ const { enqueueMemoryJob } = await import("../memory/jobs-store.js");
62
+
63
+ const { migrated } = await ensureConceptPageCollection();
64
+
65
+ let shouldReembed = migrated;
66
+ if (!shouldReembed) {
67
+ const points = await countConceptPagePoints();
68
+ if (points === 0 && (await hasConceptPages(getWorkspaceDir()))) {
69
+ shouldReembed = true;
70
+ }
71
+ }
72
+
73
+ if (shouldReembed) {
74
+ const jobId = enqueueMemoryJob("memory_v2_reembed", {});
75
+ log.info(
76
+ { jobId, collectionMigrated: migrated },
77
+ "Memory v2 collection rebuild required — enqueued reembed job",
78
+ );
79
+ }
80
+ } catch (err) {
81
+ log.warn(
82
+ { err },
83
+ "Memory v2 collection schema check failed — continuing startup; v2 retrieval may be degraded",
84
+ );
85
+ }
35
86
  }
@@ -20,6 +20,7 @@ export * from "./message-types/computer-use.js";
20
20
  export * from "./message-types/contacts.js";
21
21
  export * from "./message-types/conversations.js";
22
22
  export * from "./message-types/diagnostics.js";
23
+ export * from "./message-types/disk-pressure.js";
23
24
  export * from "./message-types/documents.js";
24
25
  export * from "./message-types/guardian-actions.js";
25
26
  export * from "./message-types/home.js";
@@ -71,6 +72,7 @@ import type {
71
72
  _DiagnosticsClientMessages,
72
73
  _DiagnosticsServerMessages,
73
74
  } from "./message-types/diagnostics.js";
75
+ import type { _DiskPressureServerMessages } from "./message-types/disk-pressure.js";
74
76
  import type {
75
77
  _DocumentsClientMessages,
76
78
  _DocumentsServerMessages,
@@ -203,6 +205,7 @@ export type ServerMessage =
203
205
  | _NotificationsServerMessages
204
206
  | _UpgradesServerMessages
205
207
  | _AcpServerMessages
208
+ | _DiskPressureServerMessages
206
209
  | SubagentEvent;
207
210
 
208
211
  // === Contract schema ===
@@ -29,6 +29,8 @@ interface BaseTransportMetadata {
29
29
  uxBrief?: string;
30
30
  /** Chat type from the gateway (e.g. "private", "group", "supergroup", "channel"). */
31
31
  chatType?: string;
32
+ /** IANA timezone reported by the active client for the current turn. */
33
+ clientTimezone?: string;
32
34
  }
33
35
 
34
36
  /**
@@ -522,6 +524,7 @@ export interface CompactionCircuitClosed {
522
524
  export type ConversationErrorCode =
523
525
  | "PROVIDER_NETWORK"
524
526
  | "PROVIDER_RATE_LIMIT"
527
+ | "MANAGED_USAGE_LIMIT"
525
528
  | "PROVIDER_OVERLOADED"
526
529
  | "PROVIDER_API"
527
530
  | "PROVIDER_BILLING"
@@ -532,6 +535,7 @@ export type ConversationErrorCode =
532
535
  | "CONTEXT_TOO_LARGE"
533
536
  | "CONVERSATION_ABORTED"
534
537
  | "CONVERSATION_PROCESSING_FAILED"
538
+ | "DISK_SPACE_CRITICAL"
535
539
  | "REGENERATE_FAILED"
536
540
  | "UNKNOWN";
537
541
 
@@ -0,0 +1,9 @@
1
+ import type { DiskPressureStatus } from "../disk-pressure-guard.js";
2
+
3
+ /** Server push when the disk pressure status snapshot changes. */
4
+ export interface DiskPressureStatusChanged {
5
+ type: "disk_pressure_status_changed";
6
+ status: DiskPressureStatus;
7
+ }
8
+
9
+ export type _DiskPressureServerMessages = DiskPressureStatusChanged;
@@ -147,8 +147,26 @@ export interface ToolResult {
147
147
  matchedTrustRuleId?: string;
148
148
  /** Whether the daemon is running in a containerized (Docker) environment. */
149
149
  isContainerized?: boolean;
150
- /** Scope options ladder for the rule editor modal (narrowest to broadest). */
150
+ /**
151
+ * Display-only ladder of scope option labels for the rule editor
152
+ * (narrowest to broadest). The `pattern` here is regex-style and is
153
+ * NOT a valid trust rule pattern. Clients must use
154
+ * `riskAllowlistOptions` for the pattern that gets saved.
155
+ */
151
156
  riskScopeOptions?: Array<{ pattern: string; label: string }>;
157
+ /**
158
+ * Allowlist options for the rule editor save path (narrowest to
159
+ * broadest). Each `pattern` is a Minimatch-glob compatible string —
160
+ * what the gateway actually matches against. Mirrors the
161
+ * `allowlistOptions` field on `ConfirmationRequest`. May be absent
162
+ * for tools whose classifier does not produce an allowlist (e.g.
163
+ * web-risk classifier, MCP tools without classifier coverage).
164
+ */
165
+ riskAllowlistOptions?: Array<{
166
+ label: string;
167
+ description: string;
168
+ pattern: string;
169
+ }>;
152
170
  /** Directory scope ladder for the rule editor modal (narrowest to broadest). */
153
171
  riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
154
172
  /** How the approval decision was reached: prompted, auto, blocked, or unknown (legacy). */
@@ -236,10 +254,13 @@ export interface MessageComplete {
236
254
  export interface ErrorMessage {
237
255
  type: "error";
238
256
  conversationId?: string;
257
+ requestId?: string;
239
258
  code?: string;
240
259
  message: string;
241
260
  /** Categorizes the error so the client can offer contextual actions (e.g. "Send Anyway" for secret_blocked). */
242
261
  category?: string;
262
+ /** Machine-readable conversation error category for clients that need source-aware recovery UI. */
263
+ errorCategory?: string;
243
264
  }
244
265
 
245
266
  export interface MessageQueued {