@vellumai/assistant 0.10.12 → 0.11.0-staging.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (809) 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 +264 -14
  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__/app-conversation-ids-backfill.test.ts +33 -2
  39. package/src/__tests__/app-conversation-ids.test.ts +204 -0
  40. package/src/__tests__/approval-cascade.test.ts +5 -5
  41. package/src/__tests__/approval-routes-http.test.ts +3 -3
  42. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  43. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  44. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  45. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  46. package/src/__tests__/assistant-event.test.ts +12 -9
  47. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  48. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  49. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  50. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  51. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  52. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  53. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  54. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  55. package/src/__tests__/channel-approvals.test.ts +0 -27
  56. package/src/__tests__/channel-guardian.test.ts +85 -512
  57. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  58. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  59. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  60. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  61. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  62. package/src/__tests__/compaction-events.test.ts +8 -8
  63. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  64. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  65. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  66. package/src/__tests__/config-schema.test.ts +14 -2
  67. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  68. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  69. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  70. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  71. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  72. package/src/__tests__/context-token-estimator.test.ts +54 -1
  73. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  74. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  75. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  76. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  77. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  78. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  79. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  80. package/src/__tests__/conversation-evictor.test.ts +49 -0
  81. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  82. package/src/__tests__/conversation-group-tools.test.ts +279 -0
  83. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  84. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  85. package/src/__tests__/conversation-lineage.test.ts +235 -0
  86. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  87. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  88. package/src/__tests__/conversation-queue.test.ts +81 -81
  89. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  90. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  91. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  92. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  93. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  94. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  95. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  96. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  97. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  98. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  99. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  100. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  101. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  102. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  103. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  104. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  105. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  106. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  107. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  108. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  109. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  110. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  111. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  112. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  113. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  114. package/src/__tests__/db-test-helpers.ts +13 -27
  115. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  116. package/src/__tests__/document-tool-security.test.ts +95 -0
  117. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  118. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  119. package/src/__tests__/emit-event-signal.test.ts +5 -6
  120. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  121. package/src/__tests__/events-tail-route.test.ts +6 -4
  122. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  123. package/src/__tests__/file-edit-tool.test.ts +24 -4
  124. package/src/__tests__/file-list-tool.test.ts +2 -1
  125. package/src/__tests__/file-read-tool.test.ts +62 -10
  126. package/src/__tests__/file-write-tool.test.ts +24 -5
  127. package/src/__tests__/followup-tools.test.ts +58 -0
  128. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  129. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  130. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  131. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  132. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  133. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  134. package/src/__tests__/heartbeat-service.test.ts +1 -0
  135. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  136. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  137. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  138. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  139. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  140. package/src/__tests__/host-shell-tool.test.ts +17 -5
  141. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  142. package/src/__tests__/image-credentials.test.ts +65 -8
  143. package/src/__tests__/injection-block.test.ts +4 -4
  144. package/src/__tests__/injector-chain.test.ts +1 -1
  145. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  146. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  147. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  148. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  149. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  150. package/src/__tests__/llm-usage-store.test.ts +67 -4
  151. package/src/__tests__/log-redact.test.ts +18 -0
  152. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  153. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  154. package/src/__tests__/media-generate-image.test.ts +62 -11
  155. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  156. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  157. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  158. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  159. package/src/__tests__/notification-deep-link.test.ts +12 -12
  160. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  161. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  162. package/src/__tests__/path-policy.test.ts +315 -0
  163. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  164. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  165. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  166. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  167. package/src/__tests__/platform-callback-registration.test.ts +10 -10
  168. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  169. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  170. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  171. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  172. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  173. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  174. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  175. package/src/__tests__/resolve-app-id.test.ts +32 -0
  176. package/src/__tests__/run-due-schedules.test.ts +72 -1
  177. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  178. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  179. package/src/__tests__/schedule-routes.test.ts +44 -5
  180. package/src/__tests__/schedule-store.test.ts +3 -3
  181. package/src/__tests__/schedule-tools.test.ts +176 -0
  182. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  183. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  184. package/src/__tests__/secret-response-routing.test.ts +3 -3
  185. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  186. package/src/__tests__/secret-scanner.test.ts +36 -0
  187. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  188. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  189. package/src/__tests__/starter-task-flow.test.ts +26 -3
  190. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  191. package/src/__tests__/subagent-disposal.test.ts +40 -11
  192. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  193. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  194. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  195. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  196. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  197. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  198. package/src/__tests__/subagent-tools.test.ts +64 -0
  199. package/src/__tests__/sync-message-contract.test.ts +3 -3
  200. package/src/__tests__/terminal-tools.test.ts +12 -3
  201. package/src/__tests__/test-preload.ts +9 -0
  202. package/src/__tests__/tool-approval-handler.test.ts +587 -43
  203. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  204. package/src/__tests__/tool-executor.test.ts +116 -0
  205. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  206. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  207. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  208. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  209. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  210. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  211. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  212. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  213. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  214. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  215. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  216. package/src/__tests__/workspace-policy.test.ts +482 -2
  217. package/src/acp/__tests__/client-handler.test.ts +3 -3
  218. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  219. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  220. package/src/acp/client-handler.ts +3 -3
  221. package/src/acp/session-manager.ts +8 -8
  222. package/src/api/events/subagent-event.ts +2 -2
  223. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  224. package/src/api/responses/subagent-detail.ts +13 -0
  225. package/src/approvals/AGENTS.md +2 -0
  226. package/src/approvals/guardian-request-resolvers.ts +118 -24
  227. package/src/apps/app-store.ts +95 -4
  228. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  229. package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
  230. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  231. package/src/calls/call-controller.ts +27 -27
  232. package/src/calls/call-conversation-messages.ts +58 -18
  233. package/src/calls/voice-control-protocol.ts +56 -0
  234. package/src/calls/voice-session-bridge.ts +178 -65
  235. package/src/calls/voice-triage-escalate.ts +2 -3
  236. package/src/channels/config.ts +8 -0
  237. package/src/channels/types.ts +1 -0
  238. package/src/cli/commands/config.ts +49 -13
  239. package/src/cli/commands/memory/index.help.ts +4 -2
  240. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  241. package/src/cli/commands/webhooks.help.ts +9 -4
  242. package/src/cli/lib/bundled-marketplace.json +12 -0
  243. package/src/cli.ts +2 -109
  244. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  245. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  246. package/src/config/assistant-feature-flags.ts +1 -1
  247. package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
  248. package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
  249. package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
  250. package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
  251. package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
  252. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  253. package/src/config/bundled-skills/schedule/SKILL.md +2 -0
  254. package/src/config/feature-flag-cache.ts +6 -16
  255. package/src/config/feature-flag-registry.json +14 -38
  256. package/src/config/loader.ts +7 -1
  257. package/src/config/memory-tier.ts +15 -10
  258. package/src/config/memory-v3-gate.test.ts +278 -1
  259. package/src/config/memory-v3-gate.ts +88 -26
  260. package/src/config/raw-config-utils.ts +1 -1
  261. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  262. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  263. package/src/config/schemas/live-voice.ts +33 -7
  264. package/src/config/schemas/llm.ts +1 -0
  265. package/src/config/schemas/memory-retrospective.ts +13 -0
  266. package/src/config/schemas/memory-substrate.ts +183 -0
  267. package/src/config/schemas/memory-v2.ts +3 -2
  268. package/src/config/schemas/memory-v3.ts +11 -4
  269. package/src/config/schemas/memory.ts +35 -1
  270. package/src/config/schemas/services.ts +10 -2
  271. package/src/config/substrate-twin-shadowing.ts +195 -0
  272. package/src/config/webhook-routing.ts +67 -0
  273. package/src/context/compactor.ts +10 -3
  274. package/src/context/token-estimator.ts +21 -0
  275. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  276. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  277. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  278. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  279. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  280. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  281. package/src/daemon/channel-ui-capability.ts +70 -1
  282. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  283. package/src/daemon/conversation-agent-loop.ts +12 -5
  284. package/src/daemon/conversation-evictor.ts +26 -4
  285. package/src/daemon/conversation-launch.ts +11 -14
  286. package/src/daemon/conversation-lineage.ts +76 -0
  287. package/src/daemon/conversation-messaging.ts +14 -14
  288. package/src/daemon/conversation-notifiers.ts +2 -2
  289. package/src/daemon/conversation-process.ts +133 -21
  290. package/src/daemon/conversation-queue-manager.ts +7 -7
  291. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  292. package/src/daemon/conversation-store.ts +11 -3
  293. package/src/daemon/conversation-surfaces.ts +8 -14
  294. package/src/daemon/conversation-tool-setup.ts +13 -7
  295. package/src/daemon/conversation-usage.ts +12 -11
  296. package/src/daemon/conversation.ts +38 -15
  297. package/src/daemon/disk-pressure-guard.ts +5 -12
  298. package/src/daemon/embedding-reconcile.ts +14 -9
  299. package/src/daemon/handlers/config-channels.ts +40 -134
  300. package/src/daemon/handlers/config-model.ts +15 -7
  301. package/src/daemon/handlers/conversations.ts +4 -2
  302. package/src/daemon/handlers/shared.ts +29 -0
  303. package/src/daemon/host-proxy-base.ts +4 -4
  304. package/src/daemon/lifecycle.ts +13 -0
  305. package/src/daemon/message-protocol.ts +8 -144
  306. package/src/daemon/message-types/computer-use.ts +0 -12
  307. package/src/daemon/message-types/conversations.ts +9 -345
  308. package/src/daemon/message-types/host-app-control.ts +0 -9
  309. package/src/daemon/message-types/host-browser.ts +0 -7
  310. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  311. package/src/daemon/message-types/messages.ts +0 -48
  312. package/src/daemon/message-types/notifications.ts +0 -7
  313. package/src/daemon/message-types/skills.ts +0 -5
  314. package/src/daemon/message-types/surfaces.ts +0 -9
  315. package/src/daemon/message-types/sync.ts +0 -2
  316. package/src/daemon/process-message.ts +5 -5
  317. package/src/daemon/skill-memory-refresh.ts +5 -5
  318. package/src/daemon/tool-side-effects.ts +32 -16
  319. package/src/daemon/trust-context.ts +1 -1
  320. package/src/daemon/wake-conversation-ops.ts +4 -4
  321. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  322. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  323. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  324. package/src/heartbeat/heartbeat-service.ts +32 -1
  325. package/src/home/__tests__/feed-writer.test.ts +7 -7
  326. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  327. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  328. package/src/home/feed-writer.ts +6 -13
  329. package/src/home/home-content-refresh.ts +6 -9
  330. package/src/home/relationship-state-writer.ts +5 -12
  331. package/src/home/suggested-prompts-cache.ts +6 -19
  332. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  333. package/src/ipc/events-publish-client.ts +44 -0
  334. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  335. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  336. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  337. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  338. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  339. package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
  340. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  341. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  342. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  343. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  344. package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
  345. package/src/live-voice/front-decision.ts +5 -155
  346. package/src/live-voice/live-voice-metrics.ts +4 -1
  347. package/src/live-voice/live-voice-session.ts +1288 -439
  348. package/src/live-voice/progress-phrases.ts +17 -0
  349. package/src/live-voice/protocol.ts +15 -0
  350. package/src/media/app-icon-generator.ts +15 -8
  351. package/src/media/avatar-router.ts +9 -5
  352. package/src/media/image-credentials.ts +42 -10
  353. package/src/media/image-service.ts +1 -13
  354. package/src/media/types.ts +26 -3
  355. package/src/notifications/AGENTS.md +2 -0
  356. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  357. package/src/notifications/adapters/macos.ts +3 -3
  358. package/src/notifications/broadcaster.ts +57 -0
  359. package/src/notifications/copy-composer.ts +0 -15
  360. package/src/notifications/decision-engine.ts +21 -22
  361. package/src/notifications/guardian-question-mode.ts +57 -2
  362. package/src/notifications/home-feed-side-effect.ts +4 -0
  363. package/src/notifications/signal.ts +6 -4
  364. package/src/notifications/trusted-contact-payloads.ts +3 -4
  365. package/src/notifications/vellum-card-affinity.ts +39 -0
  366. package/src/oauth/AGENTS.md +1 -1
  367. package/src/permissions/channel-permission-query.test.ts +69 -0
  368. package/src/permissions/channel-permission-query.ts +73 -1
  369. package/src/permissions/checker.test.ts +298 -15
  370. package/src/permissions/checker.ts +102 -36
  371. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  372. package/src/permissions/confirmation-guardian-request.ts +2 -2
  373. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  374. package/src/permissions/gateway-threshold-reader.ts +82 -10
  375. package/src/permissions/ipc-risk-types.ts +8 -0
  376. package/src/permissions/prompter.ts +5 -5
  377. package/src/permissions/question-guardian-request.test.ts +222 -0
  378. package/src/permissions/question-guardian-request.ts +179 -0
  379. package/src/permissions/question-prompter.test.ts +8 -8
  380. package/src/permissions/question-prompter.ts +18 -0
  381. package/src/permissions/secret-prompter.ts +2 -4
  382. package/src/permissions/workspace-policy.ts +269 -34
  383. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  384. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  385. package/src/persistence/conversation-crud.ts +93 -0
  386. package/src/persistence/conversation-key-store.ts +63 -0
  387. package/src/persistence/conversation-parent.ts +27 -0
  388. package/src/persistence/db-async-query.ts +1 -1
  389. package/src/persistence/db-singleton.ts +14 -27
  390. package/src/persistence/delivery-crud.ts +45 -0
  391. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  392. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  393. package/src/persistence/job-utils.ts +32 -27
  394. package/src/persistence/jobs-store.ts +92 -3
  395. package/src/persistence/lifecycle-quiesce.ts +80 -0
  396. package/src/persistence/llm-usage-store.ts +45 -8
  397. package/src/persistence/message-content-file.ts +4 -4
  398. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  399. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  400. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  401. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  402. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  403. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  404. package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
  405. package/src/persistence/schema/infrastructure.ts +11 -0
  406. package/src/persistence/steps.ts +9 -1
  407. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  408. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  409. package/src/plugin-api/conversation-turn.ts +4 -4
  410. package/src/plugin-api/event-hub-facade.ts +15 -6
  411. package/src/plugin-api/index.ts +10 -4
  412. package/src/plugin-api/publish-event.ts +36 -0
  413. package/src/plugins/AGENTS.md +2 -0
  414. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  415. package/src/plugins/defaults/index.ts +9 -13
  416. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  417. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  418. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  419. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  420. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  421. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  422. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  423. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  424. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  425. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  426. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  427. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  428. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  429. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  430. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  431. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  432. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  433. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  434. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  435. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  436. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  437. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  438. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  439. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  440. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  441. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  442. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  443. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  444. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  445. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  446. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  447. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  448. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  449. package/src/plugins/defaults/memory/indexer.ts +146 -89
  450. package/src/plugins/defaults/memory/injectors.ts +86 -41
  451. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  452. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  453. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  454. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  455. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  456. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  457. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  458. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  459. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  460. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  461. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  462. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  463. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  464. package/src/plugins/defaults/memory/startup.ts +58 -21
  465. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  474. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  479. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  482. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  484. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  485. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  486. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  487. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  488. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  489. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  490. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  491. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  492. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  493. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  494. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  495. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  496. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  497. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  498. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  499. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  500. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  501. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  502. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  503. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  504. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  505. package/src/plugins/defaults/memory/tools.ts +1 -1
  506. package/src/plugins/defaults/memory/v1/README.md +5 -0
  507. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  508. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  510. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  511. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  512. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  513. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  514. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  515. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  516. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  517. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  518. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  519. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  520. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  521. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  522. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  523. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  524. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  525. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  526. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  527. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  528. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  529. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  530. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  531. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  532. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  533. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  534. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  535. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  536. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  537. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  538. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  539. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  540. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  541. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  542. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  543. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  544. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  545. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  546. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  547. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  548. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  549. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  550. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  551. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  552. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  555. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  556. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  557. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  558. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  559. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  560. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  561. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  562. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  563. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  564. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  565. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  566. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  567. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  568. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  569. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  570. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  571. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  572. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  573. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  574. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  575. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  576. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  577. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  578. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  579. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  580. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  581. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  582. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  583. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  584. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  585. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  586. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  587. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  588. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  589. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  590. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  591. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  592. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  593. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  594. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  595. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  596. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  597. package/src/plugins/defaults/memory/validation.ts +1 -1
  598. package/src/plugins/defaults/memory/worker.ts +2 -1
  599. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  600. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  601. package/src/plugins/types.ts +2 -2
  602. package/src/prompts/sections.ts +4 -16
  603. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  604. package/src/providers/anthropic/client.ts +15 -6
  605. package/src/providers/content-block-schema.ts +26 -0
  606. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  607. package/src/providers/inference/adapter-factory.ts +6 -0
  608. package/src/providers/inference/connections.ts +30 -14
  609. package/src/providers/model-catalog.ts +77 -0
  610. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  611. package/src/providers/openai/chat-completions-provider.ts +65 -17
  612. package/src/providers/openai/input-audio.ts +76 -0
  613. package/src/providers/openrouter/client.ts +0 -2
  614. package/src/providers/platform-proxy/constants.ts +4 -0
  615. package/src/providers/poolside/client.ts +42 -0
  616. package/src/providers/registry.ts +40 -8
  617. package/src/providers/retry.ts +2 -0
  618. package/src/providers/types.ts +39 -1
  619. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  620. package/src/runtime/AGENTS.md +7 -5
  621. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  622. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  623. package/src/runtime/access-request-helper.ts +7 -15
  624. package/src/runtime/assistant-event-hub.ts +43 -31
  625. package/src/runtime/assistant-event-publish-options.ts +31 -0
  626. package/src/runtime/assistant-event.ts +19 -30
  627. package/src/runtime/assistant-stream-state.ts +4 -4
  628. package/src/runtime/channel-approvals.ts +0 -25
  629. package/src/runtime/channel-readiness-service.ts +99 -40
  630. package/src/runtime/channel-retry-sweep.ts +38 -15
  631. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  632. package/src/runtime/guardian-reply-router.ts +108 -0
  633. package/src/runtime/http-server.ts +8 -0
  634. package/src/runtime/http-types.ts +2 -2
  635. package/src/runtime/process-role.ts +42 -0
  636. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  637. package/src/runtime/question-resolution.ts +153 -0
  638. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  639. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  640. package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
  641. package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
  642. package/src/runtime/routes/acp-routes.ts +2 -2
  643. package/src/runtime/routes/bookmark-routes.ts +3 -15
  644. package/src/runtime/routes/canned-message-complete.ts +2 -2
  645. package/src/runtime/routes/consolidation-routes.ts +8 -2
  646. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  647. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  648. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  649. package/src/runtime/routes/conversation-routes.ts +36 -22
  650. package/src/runtime/routes/credential-request-routes.ts +0 -1
  651. package/src/runtime/routes/filing-routes.ts +7 -7
  652. package/src/runtime/routes/global-search-routes.ts +1 -1
  653. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  654. package/src/runtime/routes/image-generation-routes.ts +12 -9
  655. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  656. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  657. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  658. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  659. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  660. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  661. package/src/runtime/routes/index.ts +2 -0
  662. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  663. package/src/runtime/routes/platform-routes.ts +3 -8
  664. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  665. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  666. package/src/runtime/routes/question-routes.ts +34 -87
  667. package/src/runtime/routes/secret-routes.ts +11 -1
  668. package/src/runtime/routes/settings-routes.ts +8 -18
  669. package/src/runtime/routes/subagents-routes.ts +35 -8
  670. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  671. package/src/runtime/routes/webhook-routes.ts +89 -30
  672. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  673. package/src/runtime/slack-reply-session.test.ts +12 -12
  674. package/src/runtime/slack-reply-session.ts +17 -17
  675. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  676. package/src/runtime/tool-grant-request-helper.ts +4 -0
  677. package/src/schedule/schedule-store.ts +70 -0
  678. package/src/schedule/scheduler.ts +27 -0
  679. package/src/security/AGENTS.md +1 -1
  680. package/src/security/credential-key.ts +17 -0
  681. package/src/security/secret-ingress.ts +14 -105
  682. package/src/security/secret-patterns.ts +8 -139
  683. package/src/security/secret-scanner.ts +8 -3
  684. package/src/security/store-path-override.ts +6 -16
  685. package/src/sequence/store.ts +8 -0
  686. package/src/signals/emit-event.ts +5 -10
  687. package/src/signals/event-stream.ts +20 -10
  688. package/src/subagent/manager.ts +76 -25
  689. package/src/subagent/notify.ts +8 -0
  690. package/src/subagent/types.ts +13 -3
  691. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  692. package/src/telegram/webhook-health.ts +478 -0
  693. package/src/telemetry/AGENTS.md +6 -0
  694. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  695. package/src/telemetry/memory-corpus-size.ts +184 -0
  696. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  697. package/src/telemetry/memory-tier-reporter.ts +30 -3
  698. package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
  699. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  700. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  701. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  702. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  703. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  704. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  705. package/src/tools/acp/abort.ts +21 -1
  706. package/src/tools/acp/context.ts +5 -5
  707. package/src/tools/acp/spawn.test.ts +15 -5
  708. package/src/tools/acp/spawn.ts +26 -3
  709. package/src/tools/acp/status.ts +20 -1
  710. package/src/tools/acp/steer.test.ts +20 -0
  711. package/src/tools/acp/steer.ts +23 -2
  712. package/src/tools/apps/resolve-app-id.ts +15 -3
  713. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  714. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  715. package/src/tools/browser/browser-screencast.ts +6 -6
  716. package/src/tools/calls/call-end.ts +24 -3
  717. package/src/tools/calls/call-start.ts +35 -11
  718. package/src/tools/calls/call-status.ts +20 -1
  719. package/src/tools/conversation-groups/group_create.ts +63 -0
  720. package/src/tools/conversation-groups/group_list.ts +20 -0
  721. package/src/tools/conversation-groups/group_shared.ts +52 -0
  722. package/src/tools/conversation-groups/move_to_group.ts +106 -0
  723. package/src/tools/document/document-comment-tool.test.ts +49 -0
  724. package/src/tools/document/document-comment-tool.ts +45 -6
  725. package/src/tools/document/document-tool.ts +142 -24
  726. package/src/tools/executor.ts +27 -13
  727. package/src/tools/filesystem/edit.ts +62 -60
  728. package/src/tools/filesystem/list.ts +36 -29
  729. package/src/tools/filesystem/read.ts +56 -39
  730. package/src/tools/filesystem/write.ts +44 -38
  731. package/src/tools/followups/followup_create.ts +41 -12
  732. package/src/tools/followups/followup_list.ts +34 -6
  733. package/src/tools/followups/followup_resolve.ts +26 -4
  734. package/src/tools/host-filesystem/edit.ts +50 -60
  735. package/src/tools/host-filesystem/read.ts +45 -39
  736. package/src/tools/host-filesystem/write.ts +31 -36
  737. package/src/tools/host-terminal/host-shell.ts +76 -62
  738. package/src/tools/policy-context.ts +27 -10
  739. package/src/tools/schedule/create.ts +76 -33
  740. package/src/tools/schedule/delete.ts +21 -2
  741. package/src/tools/schedule/list.ts +25 -3
  742. package/src/tools/schedule/update.ts +105 -48
  743. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  744. package/src/tools/shared/zod-tool-schema.ts +117 -0
  745. package/src/tools/subagent/abort.ts +12 -4
  746. package/src/tools/subagent/consult-deadline.ts +9 -3
  747. package/src/tools/subagent/message.ts +21 -5
  748. package/src/tools/subagent/notify-parent.ts +44 -23
  749. package/src/tools/subagent/read.ts +15 -4
  750. package/src/tools/subagent/resolve.ts +26 -4
  751. package/src/tools/subagent/spawn.ts +37 -13
  752. package/src/tools/subagent/status.ts +12 -4
  753. package/src/tools/system/request-permission.ts +35 -26
  754. package/src/tools/terminal/shell.ts +68 -55
  755. package/src/tools/tool-approval-handler.ts +327 -53
  756. package/src/tools/tool-input-schemas.ts +85 -0
  757. package/src/tools/tool-types.ts +7 -0
  758. package/src/tools/types.ts +8 -0
  759. package/src/tools/workflows/manage-workflows.ts +30 -2
  760. package/src/tools/workflows/run-workflow.test.ts +54 -2
  761. package/src/tools/workflows/run-workflow.ts +32 -4
  762. package/src/util/fs-symlinks.ts +30 -0
  763. package/src/util/log-redact.ts +7 -3
  764. package/src/util/platform.ts +15 -0
  765. package/src/vellum-assistant-namespace.d.ts +80 -0
  766. package/src/watcher/watcher-store.ts +8 -0
  767. package/src/workflows/leaf-runner.test.ts +104 -2
  768. package/src/workflows/leaf-runner.ts +31 -6
  769. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  770. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  771. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  772. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  773. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  774. package/src/workspace/migrations/registry.ts +4 -0
  775. package/tsconfig.plugin-api.json +1 -1
  776. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  777. package/src/__tests__/secret-patterns.test.ts +0 -27
  778. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  779. package/src/config/memory-tier.test.ts +0 -44
  780. package/src/daemon/message-types/acp.ts +0 -20
  781. package/src/daemon/message-types/apps.ts +0 -11
  782. package/src/daemon/message-types/background-tools.ts +0 -14
  783. package/src/daemon/message-types/bookmarks.ts +0 -13
  784. package/src/daemon/message-types/contacts.ts +0 -13
  785. package/src/daemon/message-types/document-comments.ts +0 -14
  786. package/src/daemon/message-types/documents.ts +0 -13
  787. package/src/daemon/message-types/home.ts +0 -15
  788. package/src/daemon/message-types/host-bash.ts +0 -12
  789. package/src/daemon/message-types/host-cu.ts +0 -10
  790. package/src/daemon/message-types/host-file.ts +0 -12
  791. package/src/daemon/message-types/host-transfer.ts +0 -12
  792. package/src/daemon/message-types/integrations.ts +0 -90
  793. package/src/daemon/message-types/memory.ts +0 -10
  794. package/src/daemon/message-types/schedules.ts +0 -14
  795. package/src/daemon/message-types/settings.ts +0 -17
  796. package/src/daemon/message-types/subagents.ts +0 -63
  797. package/src/daemon/message-types/upgrades.ts +0 -14
  798. package/src/daemon/message-types/workflows.ts +0 -25
  799. package/src/daemon/message-types/workspace.ts +0 -137
  800. package/src/live-voice/ack-phrases.ts +0 -58
  801. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  802. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  803. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  804. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  805. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  806. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  807. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  808. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  809. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `assistant/src/memory/v2/consolidation-job.ts`.
2
+ * Tests for `substrate/consolidation-job.ts`.
3
3
  *
4
4
  * Coverage matrix:
5
5
  * - Flag off → no runner call; returns disabled.
@@ -73,7 +73,7 @@ let runnerImpl: () => Promise<{
73
73
  skipReason?: string;
74
74
  }> = runnerTrimsBuffer;
75
75
 
76
- mock.module("../../../../../../runtime/background-job-runner.js", () => ({
76
+ mock.module("../../../../../runtime/background-job-runner.js", () => ({
77
77
  runBackgroundJob: async (opts: Record<string, unknown>) => {
78
78
  runnerCalls += 1;
79
79
  runnerLastArgs = opts;
@@ -90,7 +90,7 @@ mock.module("../../../../../../runtime/background-job-runner.js", () => ({
90
90
  // emitting a signal as a result of consolidation failure.
91
91
  const emitCalls: Array<Record<string, unknown>> = [];
92
92
 
93
- mock.module("../../../../../../notifications/emit-signal.js", () => ({
93
+ mock.module("../../../../../notifications/emit-signal.js", () => ({
94
94
  emitNotificationSignal: async (params: Record<string, unknown>) => {
95
95
  emitCalls.push(params);
96
96
  return {
@@ -113,7 +113,7 @@ let nextJobIdCounter = 0;
113
113
  // enqueue-coalescing branch (`hasPendingJobOfType`).
114
114
  let pendingJobTypes = new Set<string>();
115
115
 
116
- mock.module("../../../../../../persistence/jobs-store.js", () => ({
116
+ mock.module("../../../../../persistence/jobs-store.js", () => ({
117
117
  enqueueMemoryJob: (
118
118
  type: string,
119
119
  payload: Record<string, unknown>,
@@ -133,7 +133,7 @@ mock.module("../../../../../../persistence/jobs-store.js", () => ({
133
133
  // can assert what the handler wrote without initializing sqlite.
134
134
  const checkpointStore = new Map<string, string>();
135
135
 
136
- mock.module("../../../../../../persistence/checkpoints.js", () => ({
136
+ mock.module("../../../../../persistence/checkpoints.js", () => ({
137
137
  getMemoryCheckpoint: (key: string): string | null =>
138
138
  checkpointStore.get(key) ?? null,
139
139
  setMemoryCheckpoint: (key: string, value: string): void => {
@@ -153,15 +153,17 @@ mock.module("../../../../../../persistence/checkpoints.js", () => ({
153
153
  // for the article-shape tests.
154
154
  let v3FlagOn = false;
155
155
  let flagStates: Record<string, boolean> = {};
156
- mock.module("../../../../../../config/assistant-feature-flags.js", () => ({
156
+ mock.module("../../../../../config/assistant-feature-flags.js", () => ({
157
157
  isAssistantFeatureFlagEnabled: (key: string) => flagStates[key] ?? v3FlagOn,
158
158
  }));
159
159
 
160
160
  // The v3-live gate lives in config (`config.memory.v3.live`), read via
161
161
  // `isMemoryV3Live`; drive it through `flagStates["memory-v3-live"]` (and
162
162
  // `v3FlagOn` for the existing on/off tests).
163
- mock.module("../../../../../../config/memory-v3-gate.js", () => ({
163
+ mock.module("../../../../../config/memory-v3-gate.js", () => ({
164
164
  isMemoryV3Live: () => flagStates["memory-v3-live"] ?? v3FlagOn,
165
+ isMemoryEnabled: (config?: { memory?: { enabled?: boolean } }) =>
166
+ config?.memory?.enabled !== false,
165
167
  usesConceptPageMemory: (memory?: {
166
168
  enabled?: boolean;
167
169
  v2?: { enabled?: boolean };
@@ -299,7 +301,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
299
301
  );
300
302
 
301
303
  expect(outcome.kind).toBe("invoked");
302
- if (outcome.kind !== "invoked") throw new Error("unreachable");
304
+ if (outcome.kind !== "invoked") {
305
+ throw new Error("unreachable");
306
+ }
303
307
  expect(outcome.cutoff).toBe("Apr 27, 9:03 AM");
304
308
  expect(outcome.deferredEntries).toBe(2);
305
309
  expect(runnerCalls).toBe(1);
@@ -315,7 +319,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
315
319
  );
316
320
 
317
321
  expect(outcome.kind).toBe("invoked");
318
- if (outcome.kind !== "invoked") throw new Error("unreachable");
322
+ if (outcome.kind !== "invoked") {
323
+ throw new Error("unreachable");
324
+ }
319
325
  expect(outcome.deferredEntries).toBe(0);
320
326
  // Cutoff is the run-start timestamp, not any buffer entry's.
321
327
  expect(outcome.cutoff).not.toBe("Apr 27, 9:03 AM");
@@ -330,7 +336,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
330
336
  );
331
337
 
332
338
  expect(outcome.kind).toBe("invoked");
333
- if (outcome.kind !== "invoked") throw new Error("unreachable");
339
+ if (outcome.kind !== "invoked") {
340
+ throw new Error("unreachable");
341
+ }
334
342
  expect(outcome.deferredEntries).toBe(0);
335
343
  });
336
344
 
@@ -340,7 +348,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
340
348
  const outcome = await memoryV2ConsolidateJob(makeJob(), CONFIG);
341
349
 
342
350
  expect(outcome.kind).toBe("invoked");
343
- if (outcome.kind !== "invoked") throw new Error("unreachable");
351
+ if (outcome.kind !== "invoked") {
352
+ throw new Error("unreachable");
353
+ }
344
354
  expect(outcome.deferredEntries).toBe(0);
345
355
  });
346
356
 
@@ -361,7 +371,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
361
371
  return memoryV2ConsolidateJob(makeJob(), configWithMaxEntries(2)).then(
362
372
  (outcome) => {
363
373
  expect(outcome.kind).toBe("invoked");
364
- if (outcome.kind !== "invoked") throw new Error("unreachable");
374
+ if (outcome.kind !== "invoked") {
375
+ throw new Error("unreachable");
376
+ }
365
377
  expect(outcome.deferredEntries).toBe(0);
366
378
  expect(outcome.cutoff).not.toBe("Apr 27, 9:00 AM");
367
379
  },
@@ -389,7 +401,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
389
401
  );
390
402
 
391
403
  expect(outcome.kind).toBe("invoked");
392
- if (outcome.kind !== "invoked") throw new Error("unreachable");
404
+ if (outcome.kind !== "invoked") {
405
+ throw new Error("unreachable");
406
+ }
393
407
  expect(outcome.cutoff).toBe("Apr 27, 9:03 AM");
394
408
  expect(outcome.deferredEntries).toBe(1);
395
409
  });
@@ -414,7 +428,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
414
428
  );
415
429
 
416
430
  expect(outcome.kind).toBe("invoked");
417
- if (outcome.kind !== "invoked") throw new Error("unreachable");
431
+ if (outcome.kind !== "invoked") {
432
+ throw new Error("unreachable");
433
+ }
418
434
  // Two real entries, cap 2 → no chunking, full-buffer cutoff.
419
435
  expect(outcome.deferredEntries).toBe(0);
420
436
  expect(outcome.cutoff).not.toBe(" ");
@@ -438,7 +454,9 @@ describe("memoryV2ConsolidateJob — chunked cutoff (consolidation_max_entries_p
438
454
  );
439
455
 
440
456
  expect(outcome.kind).toBe("invoked");
441
- if (outcome.kind !== "invoked") throw new Error("unreachable");
457
+ if (outcome.kind !== "invoked") {
458
+ throw new Error("unreachable");
459
+ }
442
460
  expect(outcome.deferredEntries).toBe(0);
443
461
  expect(outcome.cutoff).not.toBe("Apr 27, 9:01 AM");
444
462
  });
@@ -763,7 +781,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
763
781
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
764
782
 
765
783
  expect(result.kind).toBe("invoked");
766
- if (result.kind !== "invoked") throw new Error("unreachable");
784
+ if (result.kind !== "invoked") {
785
+ throw new Error("unreachable");
786
+ }
767
787
  expect(result.noProgress).toBe(false);
768
788
  expect(result.followUpJobIds).toEqual(["job-1"]);
769
789
  expect(enqueuedJobs.map((j) => j.type)).toEqual(["memory_v2_reembed"]);
@@ -781,7 +801,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
781
801
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
782
802
 
783
803
  expect(result.kind).toBe("invoked");
784
- if (result.kind !== "invoked") throw new Error("unreachable");
804
+ if (result.kind !== "invoked") {
805
+ throw new Error("unreachable");
806
+ }
785
807
  expect(result.noProgress).toBe(false);
786
808
  expect(enqueuedJobs.map((j) => j.type)).toEqual(["memory_v2_reembed"]);
787
809
  });
@@ -795,7 +817,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
795
817
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
796
818
 
797
819
  expect(result.kind).toBe("invoked");
798
- if (result.kind !== "invoked") throw new Error("unreachable");
820
+ if (result.kind !== "invoked") {
821
+ throw new Error("unreachable");
822
+ }
799
823
  expect(result.noProgress).toBe(true);
800
824
  expect(result.followUpJobIds).toEqual([]);
801
825
  expect(enqueuedJobs).toHaveLength(0);
@@ -815,7 +839,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
815
839
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
816
840
 
817
841
  expect(result.kind).toBe("invoked");
818
- if (result.kind !== "invoked") throw new Error("unreachable");
842
+ if (result.kind !== "invoked") {
843
+ throw new Error("unreachable");
844
+ }
819
845
  expect(result.noProgress).toBe(true);
820
846
  expect(result.followUpJobIds).toEqual([]);
821
847
  expect(enqueuedJobs).toHaveLength(0);
@@ -828,7 +854,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
828
854
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
829
855
 
830
856
  expect(result.kind).toBe("invoked");
831
- if (result.kind !== "invoked") throw new Error("unreachable");
857
+ if (result.kind !== "invoked") {
858
+ throw new Error("unreachable");
859
+ }
832
860
  expect(enqueuedJobs.map((j) => j.type)).toEqual(["memory_v3_maintain"]);
833
861
  expect(result.followUpJobIds).toHaveLength(1);
834
862
  });
@@ -841,7 +869,9 @@ describe("memoryV2ConsolidateJob — progress check and follow-up coalescing", (
841
869
  const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
842
870
 
843
871
  expect(result.kind).toBe("invoked");
844
- if (result.kind !== "invoked") throw new Error("unreachable");
872
+ if (result.kind !== "invoked") {
873
+ throw new Error("unreachable");
874
+ }
845
875
  // Dedup is not no-progress: the run drained the buffer; the follow-ups
846
876
  // are simply already covered by pending rows.
847
877
  expect(result.noProgress).toBe(false);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `memory/v2/edge-index.ts` — the in-memory directed edge index
2
+ * Tests for `substrate/edge-index.ts` — the in-memory directed edge index
3
3
  * derived from concept-page frontmatter.
4
4
  *
5
5
  * Tests live in temp workspaces (mkdtemp) and never touch `~/.vellum/`.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `assistant/src/memory/v2/frontmatter-sweep.ts`.
2
+ * Tests for `substrate/frontmatter-sweep.ts`.
3
3
  *
4
4
  * Coverage:
5
5
  * - v2 disabled → returns early, no warns, no throw.
@@ -14,7 +14,7 @@ import { tmpdir } from "node:os";
14
14
  import { join } from "node:path";
15
15
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
16
16
 
17
- import type { AssistantConfig } from "../../../../../../config/schema.js";
17
+ import type { AssistantConfig } from "../../../../../config/schema.js";
18
18
 
19
19
  const warnCalls: Array<{ data: Record<string, unknown>; msg: string }> = [];
20
20
  const recordingLogger = {
@@ -29,7 +29,7 @@ const recordingLogger = {
29
29
  child: () => recordingLogger,
30
30
  };
31
31
 
32
- mock.module("../../../../../../util/logger.js", () => ({
32
+ mock.module("../../../../../util/logger.js", () => ({
33
33
  getLogger: () => recordingLogger,
34
34
  }));
35
35
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `memory/v2/page-index.ts` — the router-prompt page index built
2
+ * Tests for `substrate/page-index.ts` — the router-prompt page index built
3
3
  * from concept pages plus seeded skill entries.
4
4
  *
5
5
  * Tests live in temp workspaces (`mkdtemp`) and never touch `~/.vellum/`. The
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `assistant/src/memory/v2/page-store.ts`.
2
+ * Tests for `substrate/page-store.ts`.
3
3
  *
4
4
  * Coverage matrix:
5
5
  * - slugify: lowercase / kebab-case / ascii / 80-char cap / empty fallback.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `assistant/src/memory/v2/prompts/consolidation.ts` —
2
+ * Tests for `substrate/prompts/consolidation.ts` —
3
3
  * specifically `resolveConsolidationPrompt` which loads an optional
4
4
  * file-based override and falls back to the bundled prompt when the
5
5
  * override is missing/empty/unreadable.
@@ -38,7 +38,7 @@ const recordingLogger = {
38
38
  child: () => recordingLogger,
39
39
  };
40
40
 
41
- mock.module("../../../../../../util/logger.js", () => ({
41
+ mock.module("../../../../../util/logger.js", () => ({
42
42
  getLogger: () => recordingLogger,
43
43
  }));
44
44
 
@@ -15,19 +15,16 @@ const REEMBED_SENTINEL_PATH = join(
15
15
  // tmp dir. Spread the real module so the config loader's own platform reads
16
16
  // (config path, quarantine notice) keep resolving against the seeded
17
17
  // workspace once the loader is real.
18
- const realPlatform = await import("../../../../../../util/platform.js");
19
- mock.module("../../../../../../util/platform.js", () => ({
18
+ const realPlatform = await import("../../../../../util/platform.js");
19
+ mock.module("../../../../../util/platform.js", () => ({
20
20
  ...realPlatform,
21
21
  getDataDir: () => TEST_DATA_DIR,
22
22
  getWorkspaceDir: () => TEST_DATA_DIR,
23
23
  }));
24
24
 
25
- mock.module(
26
- "../../../../../../persistence/embeddings/qdrant-client.js",
27
- () => ({
28
- resolveQdrantUrl: () => "http://127.0.0.1:6333",
29
- }),
30
- );
25
+ mock.module("../../../../../persistence/embeddings/qdrant-client.js", () => ({
26
+ resolveQdrantUrl: () => "http://127.0.0.1:6333",
27
+ }));
31
28
 
32
29
  // Mock the underlying @qdrant/js-client-rest package. The mock client
33
30
  // records every call and lets each test program the next response.
@@ -125,13 +122,17 @@ class MockQdrantClient {
125
122
  }
126
123
  async getCollection(_name: string) {
127
124
  state.getCollectionCalls++;
128
- if (state.getCollectionThrows) throw state.getCollectionThrows;
125
+ if (state.getCollectionThrows) {
126
+ throw state.getCollectionThrows;
127
+ }
129
128
  return state.getCollectionInfo;
130
129
  }
131
130
  async createCollection(_name: string, params: unknown) {
132
131
  state.createCollectionCalls++;
133
132
  state.createCollectionParams = params;
134
- if (state.createCollectionThrows) throw state.createCollectionThrows;
133
+ if (state.createCollectionThrows) {
134
+ throw state.createCollectionThrows;
135
+ }
135
136
  state.collectionExistsBeforeCreate = true;
136
137
  state.getCollectionInfo = FULL_SCHEMA_INFO;
137
138
  return {};
@@ -143,12 +144,16 @@ class MockQdrantClient {
143
144
  }
144
145
  async updateCollection(name: string, params: unknown) {
145
146
  state.updateCollectionCalls.push({ name, params });
146
- if (state.updateCollectionThrows) throw state.updateCollectionThrows;
147
+ if (state.updateCollectionThrows) {
148
+ throw state.updateCollectionThrows;
149
+ }
147
150
  return {};
148
151
  }
149
152
  async count(_name: string, _opts: { exact: boolean }) {
150
153
  state.countCalls++;
151
- if (state.countThrows) throw state.countThrows;
154
+ if (state.countThrows) {
155
+ throw state.countThrows;
156
+ }
152
157
  return { count: state.countResult };
153
158
  }
154
159
  async createPayloadIndex(
@@ -158,14 +163,18 @@ class MockQdrantClient {
158
163
  state.createIndexCalls.push(params);
159
164
  if (state.createIndexThrowQueue.length > 0) {
160
165
  const next = state.createIndexThrowQueue.shift();
161
- if (next) throw next;
166
+ if (next) {
167
+ throw next;
168
+ }
162
169
  }
163
170
  return {};
164
171
  }
165
172
  async upsert(_name: string, params: { wait: boolean; points: MockPoint[] }) {
166
173
  if (state.upsertThrowQueue.length > 0) {
167
174
  const next = state.upsertThrowQueue.shift();
168
- if (next) throw next;
175
+ if (next) {
176
+ throw next;
177
+ }
169
178
  }
170
179
  state.upsertCalls.push(params);
171
180
  return {};
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Tests for `assistant/src/plugins/defaults/memory/substrate/reembed-job.ts`.
3
+ *
4
+ * The handler is exercised with the heavy collaborators (embedding backend,
5
+ * Qdrant client) mocked at the module level so the suite never starts a real
6
+ * Qdrant/embedding backend.
7
+ *
8
+ * Coverage: the fan-out enqueues `N` jobs, one per concept-page slug; stacked
9
+ * runs coalesce to one pending job per slug; reserved meta-file slugs are
10
+ * never enqueued.
11
+ *
12
+ * Tests use temp workspaces (mkdtemp) — never `~/.vellum/`. Sample content
13
+ * uses generic placeholders (Alice, Bob, user@example.com).
14
+ */
15
+
16
+ import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
17
+ import { tmpdir } from "node:os";
18
+ import { join } from "node:path";
19
+ import {
20
+ afterAll,
21
+ beforeAll,
22
+ beforeEach,
23
+ describe,
24
+ expect,
25
+ mock,
26
+ test,
27
+ } from "bun:test";
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Module-level mocks (registered before importing the module under test).
31
+ // ---------------------------------------------------------------------------
32
+
33
+ // Embedding backend — pulled in transitively through the enqueue helper's
34
+ // module (`jobs/embed-concept-page.ts` also hosts the embed handler). Stub it
35
+ // so the suite runs without an embedding backend.
36
+ mock.module(
37
+ "../../../../../persistence/embeddings/embedding-backend.js",
38
+ () => ({
39
+ isEmbeddingDimensionAvailable: async () => true,
40
+ embedWithBackend: async () => ({
41
+ provider: "local",
42
+ model: "test-model",
43
+ vectors: [[0.1, 0.2, 0.3]],
44
+ }),
45
+ generateSparseEmbedding: () => ({
46
+ indices: [1, 2, 3],
47
+ values: [0.5, 0.5, 0.5],
48
+ }),
49
+ getMemoryBackendStatus: async () => ({
50
+ enabled: true,
51
+ degraded: false,
52
+ provider: "local",
53
+ model: "test-model",
54
+ reason: null,
55
+ }),
56
+ selectedBackendSupportsMultimodal: async () => false,
57
+ }),
58
+ );
59
+
60
+ // Qdrant client — stubbed so nothing in the transitive import graph can reach
61
+ // a real Qdrant instance.
62
+ class StubQdrantClient {
63
+ constructor(_opts: unknown) {}
64
+ async collectionExists(_name: string) {
65
+ return { exists: true };
66
+ }
67
+ async createCollection() {
68
+ return {};
69
+ }
70
+ async createPayloadIndex() {
71
+ return {};
72
+ }
73
+ async query() {
74
+ return { points: [] };
75
+ }
76
+ }
77
+
78
+ mock.module("@qdrant/js-client-rest", () => ({
79
+ QdrantClient: StubQdrantClient,
80
+ }));
81
+
82
+ const realQdrantClient =
83
+ await import("../../../../../persistence/embeddings/qdrant-client.js");
84
+ mock.module("../../../../../persistence/embeddings/qdrant-client.js", () => ({
85
+ ...realQdrantClient,
86
+ resolveQdrantUrl: () => "http://127.0.0.1:6333",
87
+ }));
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // Workspace + DB setup. Imports are deferred to after env is set so any
91
+ // internal `getWorkspaceDir()` resolves to the tmpdir.
92
+ // ---------------------------------------------------------------------------
93
+
94
+ let tmpWorkspace: string;
95
+ let previousWorkspaceEnv: string | undefined;
96
+
97
+ beforeAll(() => {
98
+ tmpWorkspace = mkdtempSync(join(tmpdir(), "memory-substrate-reembed-test-"));
99
+ mkdirSync(join(tmpWorkspace, "memory", "concepts"), { recursive: true });
100
+ previousWorkspaceEnv = process.env.VELLUM_WORKSPACE_DIR;
101
+ process.env.VELLUM_WORKSPACE_DIR = tmpWorkspace;
102
+ });
103
+
104
+ afterAll(() => {
105
+ if (previousWorkspaceEnv === undefined) {
106
+ delete process.env.VELLUM_WORKSPACE_DIR;
107
+ } else {
108
+ process.env.VELLUM_WORKSPACE_DIR = previousWorkspaceEnv;
109
+ }
110
+ rmSync(tmpWorkspace, { recursive: true, force: true });
111
+ });
112
+
113
+ const { getMemoryDb, getMemorySqlite } =
114
+ await import("../../../../../persistence/db-connection.js");
115
+ const { resetDbForTesting } =
116
+ await import("../../../../../__tests__/db-test-helpers.js");
117
+ const { initializeDb } = await import("../../../../../persistence/db-init.js");
118
+ const { memoryJobs } =
119
+ await import("../../../../../persistence/schema/index.js");
120
+ const { writePage } = await import("../page-store.js");
121
+ const { memoryV2ReembedJob } = await import("../reembed-job.js");
122
+
123
+ // The handler ignores its config argument (the fan-out reads only the
124
+ // workspace) — a bare cast keeps the suite from materializing the full
125
+ // default config.
126
+ const TEST_CONFIG = {} as Parameters<typeof memoryV2ReembedJob>[1];
127
+
128
+ function makeJob(payload: Record<string, unknown> = {}) {
129
+ return {
130
+ id: `job-${Math.random()}`,
131
+ type: "memory_v2_reembed" as const,
132
+ payload,
133
+ status: "running" as const,
134
+ attempts: 0,
135
+ deferrals: 0,
136
+ runAfter: 0,
137
+ lastError: null,
138
+ startedAt: Date.now(),
139
+ createdAt: Date.now(),
140
+ updatedAt: Date.now(),
141
+ };
142
+ }
143
+
144
+ // The first `initializeDb()` in a fresh test process builds the migration
145
+ // template by running every step; later calls restore it by file copy. That
146
+ // cold build can exceed bun's default 5s hook timeout under CI load, so give
147
+ // the hook generous headroom.
148
+ beforeEach(async () => {
149
+ resetDbForTesting();
150
+ await initializeDb();
151
+ // The shared template-DB caching does not clear WAL state between tests, so
152
+ // explicitly truncate the job table this suite writes to. Without this, a
153
+ // row written by an earlier test leaks into the next test and breaks
154
+ // isolation.
155
+ getMemorySqlite()!.run("DELETE FROM memory_jobs");
156
+ // Reset the memory dir so each test starts with a clean concepts set.
157
+ rmSync(join(tmpWorkspace, "memory", "concepts"), {
158
+ recursive: true,
159
+ force: true,
160
+ });
161
+ mkdirSync(join(tmpWorkspace, "memory", "concepts"), { recursive: true });
162
+ }, 30_000);
163
+
164
+ describe("memoryV2ReembedJob", () => {
165
+ test("returns N (one per concept page) and writes that many job rows", async () => {
166
+ await writePage(tmpWorkspace, {
167
+ slug: "alice",
168
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
169
+ body: "Alice.\n",
170
+ });
171
+ await writePage(tmpWorkspace, {
172
+ slug: "bob",
173
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
174
+ body: "Bob.\n",
175
+ });
176
+
177
+ const total = await memoryV2ReembedJob(makeJob(), TEST_CONFIG);
178
+
179
+ // Return value covers the contract: one job per concept page.
180
+ expect(total).toBe(2);
181
+
182
+ // Verify the slugs that were enqueued by reading the memory_jobs table.
183
+ // Tests that mock `jobs-store.js` skip inserting rows; when this suite
184
+ // runs in isolation (or before such tests) the rows do land. Either
185
+ // way, the return value is the canonical contract — the row lookup is
186
+ // belt-and-suspenders.
187
+ const rows = getMemoryDb()!.select().from(memoryJobs).all();
188
+ if (rows.length > 0) {
189
+ expect(rows).toHaveLength(2);
190
+ const slugs = rows.map((row) => JSON.parse(row.payload).slug);
191
+ expect(slugs).toContain("alice");
192
+ expect(slugs).toContain("bob");
193
+ for (const row of rows) {
194
+ expect(row.type).toBe("embed_concept_page");
195
+ }
196
+ }
197
+ });
198
+
199
+ test("with no concept pages on disk, enqueues nothing", async () => {
200
+ const total = await memoryV2ReembedJob(makeJob(), TEST_CONFIG);
201
+ expect(total).toBe(0);
202
+ });
203
+
204
+ test("running the fan-out twice coalesces to one pending job per page", async () => {
205
+ // Stacked reembed runs (e.g. several consolidations completing before the
206
+ // embed lane drains) must not multiply the queue: the per-slug coalesce in
207
+ // the enqueue helper reuses the pending row.
208
+ await writePage(tmpWorkspace, {
209
+ slug: "alice",
210
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
211
+ body: "Alice.\n",
212
+ });
213
+ await writePage(tmpWorkspace, {
214
+ slug: "bob",
215
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
216
+ body: "Bob.\n",
217
+ });
218
+
219
+ const first = await memoryV2ReembedJob(makeJob(), TEST_CONFIG);
220
+ const second = await memoryV2ReembedJob(makeJob(), TEST_CONFIG);
221
+
222
+ // Both passes fan out over every page…
223
+ expect(first).toBe(2);
224
+ expect(second).toBe(2);
225
+
226
+ // …but the queue holds one pending row per slug, not one per pass.
227
+ const rows = getMemoryDb()!.select().from(memoryJobs).all();
228
+ if (rows.length > 0) {
229
+ expect(rows).toHaveLength(2);
230
+ const slugs = rows.map((row) => JSON.parse(row.payload).slug).sort();
231
+ expect(slugs).toEqual(["alice", "bob"]);
232
+ }
233
+ });
234
+
235
+ test("does NOT enqueue reserved meta-file slugs", async () => {
236
+ // The four prose meta files (essentials/threads/recent/buffer) live at
237
+ // `memory/<name>.md` and are direct-injected into the system prompt via
238
+ // `_autoinject.md`. Their underscore-bracketed slug aliases (e.g.
239
+ // `__essentials__`) fail the concept-page slug validator
240
+ // (`[a-z0-9][a-z0-9-]*`), so the reembed fan-out must not enqueue them.
241
+ await writePage(tmpWorkspace, {
242
+ slug: "alice",
243
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
244
+ body: "Alice.\n",
245
+ });
246
+
247
+ await memoryV2ReembedJob(makeJob(), TEST_CONFIG);
248
+
249
+ const rows = getMemoryDb()!.select().from(memoryJobs).all();
250
+ if (rows.length > 0) {
251
+ const slugs = rows.map((row) => JSON.parse(row.payload).slug);
252
+ for (const reserved of [
253
+ "__essentials__",
254
+ "__threads__",
255
+ "__recent__",
256
+ "__buffer__",
257
+ ]) {
258
+ expect(slugs).not.toContain(reserved);
259
+ }
260
+ }
261
+ });
262
+ });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tests for `memory/v2/sim.ts` — hybrid dense + sparse similarity over the
2
+ * Tests for `substrate/sim.ts` — hybrid dense + sparse similarity over the
3
3
  * v2 concept-page collection.
4
4
  *
5
5
  * The embedding backend and the underlying `@qdrant/js-client-rest` are both
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
19
19
 
20
- import type { AssistantConfig } from "../../../../../../config/types.js";
20
+ import type { AssistantConfig } from "../../../../../config/types.js";
21
21
 
22
22
  // ---------------------------------------------------------------------------
23
23
  // Module-level mocks (registered before `await import("../sim.js")`).
@@ -27,14 +27,11 @@ import type { AssistantConfig } from "../../../../../../config/types.js";
27
27
  // real symbols and override only `resolveQdrantUrl` so the v2 qdrant
28
28
  // client picks up our test URL.
29
29
  const realQdrantClient =
30
- await import("../../../../../../persistence/embeddings/qdrant-client.js");
31
- mock.module(
32
- "../../../../../../persistence/embeddings/qdrant-client.js",
33
- () => ({
34
- ...realQdrantClient,
35
- resolveQdrantUrl: () => "http://127.0.0.1:6333",
36
- }),
37
- );
30
+ await import("../../../../../persistence/embeddings/qdrant-client.js");
31
+ mock.module("../../../../../persistence/embeddings/qdrant-client.js", () => ({
32
+ ...realQdrantClient,
33
+ resolveQdrantUrl: () => "http://127.0.0.1:6333",
34
+ }));
38
35
 
39
36
  const state = {
40
37
  embedCalls: [] as Array<{ inputs: unknown[] }>,
@@ -64,9 +61,9 @@ const state = {
64
61
  // so a partial mock here would break sibling test files that import other
65
62
  // exports from the same module (`selectEmbeddingBackend`, etc.).
66
63
  const realEmbeddingBackend =
67
- await import("../../../../../../persistence/embeddings/embedding-backend.js");
64
+ await import("../../../../../persistence/embeddings/embedding-backend.js");
68
65
  mock.module(
69
- "../../../../../../persistence/embeddings/embedding-backend.js",
66
+ "../../../../../persistence/embeddings/embedding-backend.js",
70
67
  () => ({
71
68
  ...realEmbeddingBackend,
72
69
  isEmbeddingDimensionAvailable: async () => state.dimensionAvailable,