@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
@@ -5,8 +5,8 @@ import { createHash } from "node:crypto";
5
5
  import type { AssistantConfig } from "../../../../config/types.js";
6
6
  import { getLogger } from "../logging.js";
7
7
  import { getWorkspaceDir } from "../paths.js";
8
- import { getOrCreateRerankBackend } from "../rerank-local.js";
9
- import { readPage } from "../v3/substrate/page-store.js";
8
+ import { readPage } from "../substrate/page-store.js";
9
+ import { getOrCreateRerankBackend } from "./rerank-local.js";
10
10
 
11
11
  const log = getLogger("memory-v2-reranker");
12
12
 
@@ -36,13 +36,17 @@ function cacheKey(
36
36
 
37
37
  function evictExpired(now: number): void {
38
38
  for (const [k, v] of cache) {
39
- if (now - v.ts > CACHE_TTL_MS) cache.delete(k);
39
+ if (now - v.ts > CACHE_TTL_MS) {
40
+ cache.delete(k);
41
+ }
40
42
  }
41
43
  if (cache.size > CACHE_MAX_ENTRIES) {
42
44
  const toDrop = cache.size - CACHE_MAX_ENTRIES;
43
45
  let i = 0;
44
46
  for (const k of cache.keys()) {
45
- if (i++ >= toDrop) break;
47
+ if (i++ >= toDrop) {
48
+ break;
49
+ }
46
50
  cache.delete(k);
47
51
  }
48
52
  }
@@ -77,8 +81,12 @@ export async function rerankCandidates(
77
81
  candidates: readonly string[],
78
82
  config: AssistantConfig,
79
83
  ): Promise<Array<Map<string, number>>> {
80
- if (queries.length === 0) return [];
81
- if (candidates.length === 0) return queries.map(() => new Map());
84
+ if (queries.length === 0) {
85
+ return [];
86
+ }
87
+ if (candidates.length === 0) {
88
+ return queries.map(() => new Map());
89
+ }
82
90
 
83
91
  const { model, dtype } = config.memory.v2.rerank;
84
92
  const now = Date.now();
@@ -107,7 +115,9 @@ export async function rerankCandidates(
107
115
  const finalize = (): Array<Map<string, number>> =>
108
116
  results.map((r) => r ?? new Map());
109
117
 
110
- if (uncachedIndices.length === 0) return finalize();
118
+ if (uncachedIndices.length === 0) {
119
+ return finalize();
120
+ }
111
121
 
112
122
  const workspaceDir = getWorkspaceDir();
113
123
  const pages = await Promise.all(
@@ -122,13 +132,17 @@ export async function rerankCandidates(
122
132
  const slugsForPassages: string[] = [];
123
133
  for (let i = 0; i < candidates.length; i++) {
124
134
  const page = pages[i];
125
- if (!page) continue;
135
+ if (!page) {
136
+ continue;
137
+ }
126
138
  passages.push(buildPassage(candidates[i], page.body));
127
139
  slugsForPassages.push(candidates[i]);
128
140
  }
129
141
 
130
142
  if (passages.length === 0) {
131
- for (const i of uncachedIndices) results[i] = new Map();
143
+ for (const i of uncachedIndices) {
144
+ results[i] = new Map();
145
+ }
132
146
  return finalize();
133
147
  }
134
148
 
@@ -154,7 +168,9 @@ export async function rerankCandidates(
154
168
  { err, model, n: batchPassages.length },
155
169
  "Rerank backend failed; falling back to pure fused scores",
156
170
  );
157
- for (const i of uncachedIndices) results[i] = new Map();
171
+ for (const i of uncachedIndices) {
172
+ results[i] = new Map();
173
+ }
158
174
  return finalize();
159
175
  }
160
176
 
@@ -164,7 +180,9 @@ export async function rerankCandidates(
164
180
  const result = new Map<string, number>();
165
181
  for (let i = 0; i < slugsForPassages.length; i++) {
166
182
  const s = scores[offset + i];
167
- if (typeof s !== "number" || Number.isNaN(s)) continue;
183
+ if (typeof s !== "number" || Number.isNaN(s)) {
184
+ continue;
185
+ }
168
186
  // sigmoid output should already be in [0, 1]; clamp defensively.
169
187
  result.set(slugsForPassages[i], Math.max(0, Math.min(1, s)));
170
188
  }
@@ -47,14 +47,14 @@ import {
47
47
  type ToolDefinition,
48
48
  } from "../llm-helpers.js";
49
49
  import { getLogger } from "../logging.js";
50
- import type { PageIndex } from "../v3/substrate/page-index.js";
50
+ import type { PageIndex } from "../substrate/page-index.js";
51
51
  import {
52
52
  getPageIndex,
53
53
  partitionPageIndex,
54
54
  splitTier1,
55
55
  splitTier2,
56
- } from "../v3/substrate/page-index.js";
57
- import type { EverInjectedEntry } from "../v3/substrate/types.js";
56
+ } from "../substrate/page-index.js";
57
+ import type { EverInjectedEntry } from "../substrate/types.js";
58
58
  import { computeInjectionScores } from "./injection-events.js";
59
59
  import { resolveRouterPrompt } from "./prompts/router.js";
60
60
 
@@ -285,8 +285,12 @@ export async function runRouter(
285
285
  // Tag each batch with its provenance string. Tier 3 batches carry their
286
286
  // bucket index so the inspector can attribute selections per-bucket.
287
287
  const taggedBatches: Array<{ source: RouterSource; index: PageIndex }> = [];
288
- if (tier1) taggedBatches.push({ source: "tier1", index: tier1 });
289
- if (tier2) taggedBatches.push({ source: "tier2", index: tier2 });
288
+ if (tier1) {
289
+ taggedBatches.push({ source: "tier1", index: tier1 });
290
+ }
291
+ if (tier2) {
292
+ taggedBatches.push({ source: "tier2", index: tier2 });
293
+ }
290
294
  tier3Batches.forEach((index, i) => {
291
295
  taggedBatches.push({ source: `tier3:${i}` as const, index });
292
296
  });
@@ -322,7 +326,9 @@ export async function runRouter(
322
326
  const result = batchResults[i];
323
327
  const source = taggedBatches[i].source;
324
328
  for (const slug of result.selectedSlugs) {
325
- if (sourceBySlug.has(slug)) continue;
329
+ if (sourceBySlug.has(slug)) {
330
+ continue;
331
+ }
326
332
  sourceBySlug.set(slug, source);
327
333
  selectedSlugs.push(slug);
328
334
  }
@@ -354,7 +360,9 @@ export async function runRouter(
354
360
  "Router union across batches exceeded max_page_ids; truncating",
355
361
  );
356
362
  const dropped = selectedSlugs.splice(maxPageIds);
357
- for (const slug of dropped) sourceBySlug.delete(slug);
363
+ for (const slug of dropped) {
364
+ sourceBySlug.delete(slug);
365
+ }
358
366
  }
359
367
  }
360
368
  return { selectedSlugs, sourceBySlug, failureReason: null };
@@ -402,7 +410,9 @@ async function runRouterBatch(
402
410
  const priorIds: number[] = [];
403
411
  for (const entry of priorEverInjected) {
404
412
  const local = batchIndex.bySlug.get(entry.slug);
405
- if (local) priorIds.push(local.id);
413
+ if (local) {
414
+ priorIds.push(local.id);
415
+ }
406
416
  }
407
417
 
408
418
  // Trim the pairs down to the configured `<last_turn>` content budget,
@@ -513,7 +523,9 @@ async function runRouterBatch(
513
523
  const selectedSlugs: string[] = [];
514
524
  for (const id of finalIds) {
515
525
  const entry = batchIndex.byId.get(id);
516
- if (!entry) continue;
526
+ if (!entry) {
527
+ continue;
528
+ }
517
529
  selectedSlugs.push(entry.slug);
518
530
  }
519
531
 
@@ -542,7 +554,9 @@ export function applyHistoricalCharBudget(
542
554
  pairs: readonly RouterTurnPair[],
543
555
  maxChars: number | null,
544
556
  ): RouterTurnPair[] {
545
- if (maxChars === null || maxChars <= 0) return [...pairs];
557
+ if (maxChars === null || maxChars <= 0) {
558
+ return [...pairs];
559
+ }
546
560
 
547
561
  type WalkedMsg = {
548
562
  role: "user" | "assistant";
@@ -566,7 +580,9 @@ export function applyHistoricalCharBudget(
566
580
  const included = new Map<number, { assistant: string; user: string }>();
567
581
  for (const msg of walked) {
568
582
  const remaining = maxChars - used;
569
- if (remaining <= 0) break;
583
+ if (remaining <= 0) {
584
+ break;
585
+ }
570
586
  let textToInclude: string;
571
587
  let stop = false;
572
588
  if (msg.text.length <= remaining) {
@@ -577,17 +593,24 @@ export function applyHistoricalCharBudget(
577
593
  // connects to the next message (in chronological order) without
578
594
  // a syntactic seam. The marker counts toward the budget so the
579
595
  // emitted text never exceeds `maxChars` cumulatively.
580
- if (remaining <= HISTORICAL_TRUNCATION_MARKER.length) break;
596
+ if (remaining <= HISTORICAL_TRUNCATION_MARKER.length) {
597
+ break;
598
+ }
581
599
  const keepChars = remaining - HISTORICAL_TRUNCATION_MARKER.length;
582
600
  textToInclude = HISTORICAL_TRUNCATION_MARKER + msg.text.slice(-keepChars);
583
601
  used = maxChars;
584
602
  stop = true;
585
603
  }
586
604
  const slot = included.get(msg.pairIdx) ?? { assistant: "", user: "" };
587
- if (msg.role === "user") slot.user = textToInclude;
588
- else slot.assistant = textToInclude;
605
+ if (msg.role === "user") {
606
+ slot.user = textToInclude;
607
+ } else {
608
+ slot.assistant = textToInclude;
609
+ }
589
610
  included.set(msg.pairIdx, slot);
590
- if (stop) break;
611
+ if (stop) {
612
+ break;
613
+ }
591
614
  }
592
615
 
593
616
  const sortedIdxs = [...included.keys()].sort((a, b) => a - b);
@@ -44,8 +44,8 @@ let simBatchImpl: (
44
44
  text: string,
45
45
  slugs: readonly string[],
46
46
  ) => Promise<Map<string, number>> = async () => new Map();
47
- const realSim = await import("../substrate/sim.js");
48
- mock.module("../substrate/sim.js", () => ({
47
+ const realSim = await import("../../substrate/sim.js");
48
+ mock.module("../../substrate/sim.js", () => ({
49
49
  ...realSim,
50
50
  simBatch: (text: string, slugs: readonly string[]) =>
51
51
  simBatchImpl(text, slugs),
@@ -262,7 +262,9 @@ describe("nearestExistingSkills — default scorer retries transient failures",
262
262
  let calls = 0;
263
263
  simBatchImpl = async (_text, slugs) => {
264
264
  calls++;
265
- if (calls === 1) throw transientError();
265
+ if (calls === 1) {
266
+ throw transientError();
267
+ }
266
268
  // Second attempt succeeds: the skill's capability page scores high.
267
269
  return new Map(
268
270
  slugs
@@ -62,13 +62,13 @@ import { ensureMemoryV3SelectionsSchema } from "../../../../../persistence/migra
62
62
  import { ensureMemoryV3EverInjectedSchema } from "../../../../../persistence/migrations/345-move-memory-v3-ever-injected-to-memory-db.js";
63
63
  import * as schema from "../../../../../persistence/schema/index.js";
64
64
  import { unwrapMemoryBlock, wrapMemoryBlock } from "../../memory-marker.js";
65
+ import type { PageIndexEntry } from "../../substrate/page-index.js";
65
66
  import { cardBytes, renderCard } from "../card.js";
66
67
  import { loadCoreSet } from "../core-set.js";
67
68
  import type { EdgeGraph } from "../edge.js";
68
69
  import { buildEdgeGraph } from "../edge.js";
69
70
  import { buildSectionNeedle } from "../section-needle.js";
70
71
  import { buildSectionIndex } from "../sections.js";
71
- import type { PageIndexEntry } from "../substrate/page-index.js";
72
72
  import {
73
73
  MEMORY_V3_COMMIT_META_KEY,
74
74
  type SectionIndex,
@@ -490,7 +490,9 @@ function candidateSlugs(messages: Message[]): Slug[] {
490
490
  const entries: Array<{ id: number; slug: string }> = [];
491
491
  for (const msg of messages) {
492
492
  for (const block of msg.content) {
493
- if (block.type !== "text") continue;
493
+ if (block.type !== "text") {
494
+ continue;
495
+ }
494
496
  const cards = /<candidate_cards>\n([\s\S]*?)\n<\/candidate_cards>/.exec(
495
497
  block.text,
496
498
  );
@@ -507,7 +509,9 @@ function candidateSlugs(messages: Message[]): Slug[] {
507
509
  if (finder) {
508
510
  for (const line of finder[1].split("\n")) {
509
511
  const m = /^\[(\d+)\] (?:\([^)]*\) )?(\S+)(?: — |$)/.exec(line);
510
- if (m) entries.push({ id: Number(m[1]), slug: m[2]! });
512
+ if (m) {
513
+ entries.push({ id: Number(m[1]), slug: m[2]! });
514
+ }
511
515
  }
512
516
  }
513
517
  }
@@ -530,7 +534,9 @@ function makeProviderStub(): Provider {
530
534
  );
531
535
  const ids: number[] = [];
532
536
  candidateSlugs(messages).forEach((slug, i) => {
533
- if (keep.includes(slug)) ids.push(i + 1);
537
+ if (keep.includes(slug)) {
538
+ ids.push(i + 1);
539
+ }
534
540
  });
535
541
  return toolUseResponse({ ids });
536
542
  },
@@ -614,13 +620,16 @@ async function runTurn(
614
620
 
615
621
  const activeBefore = getActiveSlugs(convId);
616
622
  const cards = await memoryV3Injector.produce(ctx);
617
- if (!cards)
623
+ if (!cards) {
618
624
  throw new Error(`turn ${turnIndex}: cards injector returned null`);
625
+ }
619
626
  // Runtime assembly invokes the block's attachment-commit callback at its
620
627
  // user-tail commit point — this is where the everInjected store records
621
628
  // the turn's cards (and the prune valve is scheduled).
622
629
  const commit = cards.meta?.[MEMORY_V3_COMMIT_META_KEY];
623
- if (typeof commit === "function") (commit as () => void)();
630
+ if (typeof commit === "function") {
631
+ (commit as () => void)();
632
+ }
624
633
  const netNewSlugs = [...getActiveSlugs(convId)].filter(
625
634
  (slug) => !activeBefore.has(slug),
626
635
  );
@@ -883,7 +892,9 @@ beforeAll(async () => {
883
892
  afterAll(async () => {
884
893
  await flushPruneValveForTests();
885
894
  carryMockActive = false;
886
- if (workspaceDir) rmSync(workspaceDir, { recursive: true, force: true });
895
+ if (workspaceDir) {
896
+ rmSync(workspaceDir, { recursive: true, force: true });
897
+ }
887
898
  });
888
899
 
889
900
  // ---------------------------------------------------------------------------
@@ -993,7 +1004,9 @@ describe("memory-v3 carry integration — cache contract", () => {
993
1004
  let expected = 0;
994
1005
  for (const record of records) {
995
1006
  expected += record.netNewBytes;
996
- if (record.turn === 7) expected -= pruneWindow.bytesFreedExpected;
1007
+ if (record.turn === 7) {
1008
+ expected -= pruneWindow.bytesFreedExpected;
1009
+ }
997
1010
  expect(record.residentBytes).toBe(expected);
998
1011
  }
999
1012
  });
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
+ import type { PageIndexEntry } from "../../substrate/page-index.js";
3
4
  import { buildEdgeGraph, edgeExpand } from "../edge.js";
4
- import type { PageIndexEntry } from "../substrate/page-index.js";
5
5
  import type { Slug } from "../types.js";
6
6
 
7
7
  /** Minimal page-index entry factory — only the fields the edge lane reads. */
@@ -35,12 +35,12 @@ import { ensureMemoryV3SelectionsSchema } from "../../../../../persistence/migra
35
35
  import { ensureMemoryV3EverInjectedSchema } from "../../../../../persistence/migrations/345-move-memory-v3-ever-injected-to-memory-db.js";
36
36
  import * as schema from "../../../../../persistence/schema/index.js";
37
37
  import { wrapMemoryBlock } from "../../memory-marker.js";
38
+ import type { PageIndexEntry } from "../../substrate/page-index.js";
38
39
  import { cardBytes, renderCard } from "../card.js";
39
40
  import type { EdgeGraph } from "../edge.js";
40
41
  import { buildEdgeGraph } from "../edge.js";
41
42
  import { buildSectionNeedle } from "../section-needle.js";
42
43
  import { buildSectionIndex } from "../sections.js";
43
- import type { PageIndexEntry } from "../substrate/page-index.js";
44
44
  import type { MemoryRoutingTurn, SectionIndex, Slug } from "../types.js";
45
45
 
46
46
  // ---------------------------------------------------------------------------
@@ -7,6 +7,7 @@ import { EmbeddingBackendUnavailableError } from "../../../../../persistence/emb
7
7
  import { EmbeddingBillingBlockError } from "../../../../../persistence/embeddings/embedding-billing-breaker.js";
8
8
  import type { MemoryJob } from "../../../../../persistence/jobs-store.js";
9
9
  import type { SkillInstallMeta } from "../../../../../skills/install-meta.js";
10
+ import { skillSlugFor } from "../../substrate/skill-store.js";
10
11
  import { renderCapabilityBody } from "../capabilities.js";
11
12
  import {
12
13
  backfillAllSections,
@@ -17,7 +18,6 @@ import {
17
18
  type MaintainJobDeps,
18
19
  } from "../maintain-job.js";
19
20
  import { buildSectionIndex } from "../sections.js";
20
- import { skillSlugFor } from "../substrate/skill-store.js";
21
21
  import type { Section, SectionIndex, Slug } from "../types.js";
22
22
 
23
23
  // The skill usage-prune stage reads `memory.maintenance.skillPruneDays`; default
@@ -36,6 +36,9 @@ const CONFIG = makeConfig();
36
36
  let memoryV3LiveSlot = false;
37
37
  mock.module("../../../../../config/memory-v3-gate.js", () => ({
38
38
  isMemoryV3Live: () => memoryV3LiveSlot,
39
+ isV3TierActive: () => memoryV3LiveSlot,
40
+ isMemoryEnabled: (config?: { memory?: { enabled?: boolean } }) =>
41
+ config?.memory?.enabled !== false,
39
42
  usesConceptPageMemory: (memory?: {
40
43
  enabled?: boolean;
41
44
  v2?: { enabled?: boolean };
@@ -32,6 +32,7 @@ import {
32
32
  MEMORY_CONTEXT_PHASE_KEY,
33
33
  TurnLatencyTracker,
34
34
  } from "../../../../../daemon/turn-latency-tracker.js";
35
+ import type { PageIndexEntry } from "../../substrate/page-index.js";
35
36
  import { renderCard } from "../card.js";
36
37
  import type { EdgeGraph } from "../edge.js";
37
38
  import { buildEdgeGraph } from "../edge.js";
@@ -39,7 +40,6 @@ import type { V3GateConfig } from "../gate.js";
39
40
  import type { OrchestrateDeps } from "../orchestrate.js";
40
41
  import { buildSectionNeedle } from "../section-needle.js";
41
42
  import { buildSectionIndex } from "../sections.js";
42
- import type { PageIndexEntry } from "../substrate/page-index.js";
43
43
  import type { MemoryRoutingTurn, SectionIndex, Slug } from "../types.js";
44
44
 
45
45
  // ---------------------------------------------------------------------------
@@ -71,6 +71,12 @@ mock.module("../../../../../util/logger.js", () => ({
71
71
  const realDense = { ...(await import("../dense.js")) };
72
72
  let denseMockActive = false;
73
73
  let denseHits: Array<{ article: Slug; section: number; score?: number }> = [];
74
+ // Per-query hit override for tests that need the full-message and span-chunk
75
+ // dense calls to return DIFFERENT results; falls back to `denseHits`.
76
+ let denseHitsByQuery = new Map<
77
+ string,
78
+ Array<{ article: Slug; section: number; score?: number }>
79
+ >();
74
80
  let denseCalls: Array<{ query: string; k: number }> = [];
75
81
  mock.module("../dense.js", () => ({
76
82
  ...realDense,
@@ -79,7 +85,7 @@ mock.module("../dense.js", () => ({
79
85
  return realDense.denseLane(...args);
80
86
  }
81
87
  denseCalls.push({ query: args[1], k: args[2] });
82
- return args[2] <= 0 ? [] : denseHits;
88
+ return args[2] <= 0 ? [] : (denseHitsByQuery.get(args[1]) ?? denseHits);
83
89
  },
84
90
  // Orchestrate now calls the SCORED variant; the mock must intercept it too
85
91
  // (else the `...realDense` spread resolves the real lane and hits Qdrant).
@@ -94,7 +100,10 @@ mock.module("../dense.js", () => ({
94
100
  denseCalls.push({ query: args[1], k: args[2] });
95
101
  return args[2] <= 0
96
102
  ? []
97
- : denseHits.map((h) => ({ ...h, score: h.score ?? 1 }));
103
+ : (denseHitsByQuery.get(args[1]) ?? denseHits).map((h) => ({
104
+ ...h,
105
+ score: h.score ?? 1,
106
+ }));
98
107
  },
99
108
  }));
100
109
 
@@ -330,6 +339,7 @@ beforeEach(() => {
330
339
  watchdogMockActive = true;
331
340
  providerStub = null;
332
341
  denseHits = [];
342
+ denseHitsByQuery = new Map();
333
343
  denseCalls = [];
334
344
  recordedGateEvents = [];
335
345
  recordedSelectionEvents = [];
@@ -1753,3 +1763,171 @@ describe("latency sub-spans", () => {
1753
1763
  }
1754
1764
  });
1755
1765
  });
1766
+
1767
+ // ---------------------------------------------------------------------------
1768
+ // Span-query pass: the dense lane re-run over the current message's clause
1769
+ // chunks as separate queries at `spanQueryK`, union-additive into the pool.
1770
+ // ---------------------------------------------------------------------------
1771
+
1772
+ describe("orchestrate — span-query pass", () => {
1773
+ const TWO_CHUNK_MESSAGE =
1774
+ "apple appears in the first sentence here. elderberry shows up in the second sentence.";
1775
+ const CHUNK_1 = "apple appears in the first sentence here.";
1776
+ const CHUNK_2 = "elderberry shows up in the second sentence.";
1777
+
1778
+ test("spanQueryK omitted (default) runs no span dense calls", async () => {
1779
+ const lanes = await buildLanes();
1780
+
1781
+ await orchestrate(
1782
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1783
+ depsOf(lanes, { denseK: 100, selectorEnabled: false }),
1784
+ );
1785
+
1786
+ expect(denseCalls).toEqual([{ query: TWO_CHUNK_MESSAGE, k: 100 }]);
1787
+ });
1788
+
1789
+ test("span pass is inert when denseK=0", async () => {
1790
+ const lanes = await buildLanes();
1791
+
1792
+ await orchestrate(
1793
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1794
+ depsOf(lanes, { denseK: 0, spanQueryK: 7, selectorEnabled: false }),
1795
+ );
1796
+
1797
+ expect(denseCalls).toEqual([]);
1798
+ });
1799
+
1800
+ test("single-chunk message skips the span pass", async () => {
1801
+ const lanes = await buildLanes();
1802
+
1803
+ await orchestrate(
1804
+ makeTurn(1, "apple in one single sentence."),
1805
+ depsOf(lanes, { denseK: 100, spanQueryK: 7, selectorEnabled: false }),
1806
+ );
1807
+
1808
+ expect(denseCalls).toEqual([
1809
+ { query: "apple in one single sentence.", k: 100 },
1810
+ ]);
1811
+ });
1812
+
1813
+ test("multi-chunk message adds span-lane candidates additively", async () => {
1814
+ const lanes = await buildLanes();
1815
+ // Full-message dense (and any chunk without an override) returns topic-b;
1816
+ // chunk 1 re-surfaces topic-a (already a needle hit — attribution must
1817
+ // stay "needle"); chunk 2 surfaces topic-d, which no other lane reaches
1818
+ // ("grape" is not in the message, and the topic-a → topic-d curated edge
1819
+ // must not re-surface an already-seen slug).
1820
+ denseHits = [{ article: "topic-b", section: 0 }];
1821
+ denseHitsByQuery.set(CHUNK_1, [{ article: "topic-a", section: 1 }]);
1822
+ denseHitsByQuery.set(CHUNK_2, [{ article: "topic-d", section: 0 }]);
1823
+
1824
+ const result = await orchestrate(
1825
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1826
+ depsOf(lanes, { denseK: 100, spanQueryK: 7, selectorEnabled: false }),
1827
+ );
1828
+
1829
+ expect(denseCalls).toEqual([
1830
+ { query: TWO_CHUNK_MESSAGE, k: 100 },
1831
+ { query: CHUNK_1, k: 7 },
1832
+ { query: CHUNK_2, k: 7 },
1833
+ ]);
1834
+ const laneOf = new Map(
1835
+ result.lanes.finder.map((c) => [c.slug, c.lane] as const),
1836
+ );
1837
+ // "apple"/"elderberry" needle hits keep their lanes; the full-message
1838
+ // dense hit keeps "dense"; only the genuinely span-surfaced page tags
1839
+ // "span".
1840
+ expect(laneOf.get("topic-a")).toBe("needle");
1841
+ expect(laneOf.get("topic-c")).toBe("needle");
1842
+ expect(laneOf.get("topic-b")).toBe("dense");
1843
+ expect(laneOf.get("topic-d")).toBe("span");
1844
+ expect(result.lanes.finder.filter((c) => c.slug === "topic-a").length).toBe(
1845
+ 1,
1846
+ );
1847
+ // The span hit's matched section is recorded for injection/spotlight.
1848
+ expect(result.matchedSections.get("topic-d")?.article).toBe("topic-d");
1849
+ expect(result.matchedSections.get("topic-d")?.text).toContain(
1850
+ "lead for topic d",
1851
+ );
1852
+ // Additive: the span-only page joins the passthrough selections alongside
1853
+ // every other lane's candidates.
1854
+ expect(new Set(result.selections.map((s) => s.slug))).toEqual(
1855
+ new Set(["topic-a", "topic-b", "topic-c", "topic-d"]),
1856
+ );
1857
+ });
1858
+
1859
+ test("an article hit by several chunks records its highest-scoring section", async () => {
1860
+ const lanes = await buildLanes();
1861
+ // Both chunks surface topic-d; the EARLIER chunk's hit is the weaker one.
1862
+ // Chunk order must not decide the recorded section — the strong match
1863
+ // (ordinal 1, `## Notes`) wins over the lead (ordinal 0).
1864
+ denseHits = [];
1865
+ denseHitsByQuery.set(CHUNK_1, [
1866
+ { article: "topic-d", section: 0, score: 0.2 },
1867
+ ]);
1868
+ denseHitsByQuery.set(CHUNK_2, [
1869
+ { article: "topic-d", section: 1, score: 0.9 },
1870
+ ]);
1871
+
1872
+ const result = await orchestrate(
1873
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1874
+ depsOf(lanes, { denseK: 100, spanQueryK: 7, selectorEnabled: false }),
1875
+ );
1876
+
1877
+ expect(result.matchedSections.get("topic-d")?.ordinal).toBe(1);
1878
+ expect(result.matchedSections.get("topic-d")?.text).toContain("grape");
1879
+ expect(
1880
+ result.lanes.finder.filter((c) => c.slug === "topic-d"),
1881
+ ).toHaveLength(1);
1882
+ });
1883
+
1884
+ test("a strictly stronger span cosine upgrades a dense-recorded section, keeping the lane", async () => {
1885
+ const lanes = await buildLanes();
1886
+ // Full-message dense records topic-b's lead (ordinal 0) at cosine 0.4;
1887
+ // chunk 2 finds `## More` (ordinal 1) at 0.9 — same encoder and
1888
+ // collection, strictly stronger, so the recorded section and finder
1889
+ // descriptor upgrade while the lane attribution stays "dense".
1890
+ denseHits = [{ article: "topic-b", section: 0, score: 0.4 }];
1891
+ denseHitsByQuery.set(CHUNK_2, [
1892
+ { article: "topic-b", section: 1, score: 0.9 },
1893
+ ]);
1894
+
1895
+ const result = await orchestrate(
1896
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1897
+ depsOf(lanes, { denseK: 100, spanQueryK: 7, selectorEnabled: false }),
1898
+ );
1899
+
1900
+ expect(result.matchedSections.get("topic-b")?.ordinal).toBe(1);
1901
+ expect(result.matchedSections.get("topic-b")?.text).toContain(
1902
+ "cherry date",
1903
+ );
1904
+ const entry = result.lanes.finder.find((c) => c.slug === "topic-b");
1905
+ expect(entry?.lane).toBe("dense");
1906
+ expect(entry?.descriptor).toContain("cherry date");
1907
+ });
1908
+
1909
+ test("weaker span hits and needle-recorded sections are not overridden", async () => {
1910
+ const lanes = await buildLanes();
1911
+ // topic-b: span cosine 0.3 < full-message 0.4 — the lead stays recorded.
1912
+ // topic-a: needle recorded the `## Details` match; span scores are not
1913
+ // comparable to BM25, so the span hit must not touch it.
1914
+ denseHits = [{ article: "topic-b", section: 0, score: 0.4 }];
1915
+ denseHitsByQuery.set(CHUNK_1, [
1916
+ { article: "topic-a", section: 0, score: 0.99 },
1917
+ ]);
1918
+ denseHitsByQuery.set(CHUNK_2, [
1919
+ { article: "topic-b", section: 1, score: 0.3 },
1920
+ ]);
1921
+
1922
+ const result = await orchestrate(
1923
+ makeTurn(1, TWO_CHUNK_MESSAGE),
1924
+ depsOf(lanes, { denseK: 100, spanQueryK: 7, selectorEnabled: false }),
1925
+ );
1926
+
1927
+ expect(result.matchedSections.get("topic-b")?.ordinal).toBe(0);
1928
+ expect(result.matchedSections.get("topic-a")?.text).toContain("apple");
1929
+ expect(result.lanes.finder.find((c) => c.slug === "topic-a")?.lane).toBe(
1930
+ "needle",
1931
+ );
1932
+ });
1933
+ });
@@ -403,6 +403,7 @@ describe("summarizeSelections", () => {
403
403
  dense: 0,
404
404
  edge: 2,
405
405
  reply: 0,
406
+ span: 0,
406
407
  learned: 0,
407
408
  entity: 0,
408
409
  });
@@ -421,6 +422,7 @@ describe("summarizeSelections", () => {
421
422
  dense: 0,
422
423
  edge: 0,
423
424
  reply: 0,
425
+ span: 0,
424
426
  learned: 0,
425
427
  entity: 0,
426
428
  },
@@ -443,6 +445,7 @@ describe("summarizeSelections", () => {
443
445
  dense: 0,
444
446
  edge: 0,
445
447
  reply: 0,
448
+ span: 0,
446
449
  learned: 0,
447
450
  entity: 0,
448
451
  },