@vellumai/assistant 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/ARCHITECTURE.md +45 -29
  2. package/Dockerfile +1 -0
  3. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  4. package/bun.lock +3 -0
  5. package/docs/architecture/memory.md +5 -2
  6. package/knip.json +1 -0
  7. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  8. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  9. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  10. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  11. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  12. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  13. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  14. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  16. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  17. package/openapi.yaml +470 -25
  18. package/package.json +3 -1
  19. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  20. package/src/__tests__/app-control-flow.test.ts +21 -11
  21. package/src/__tests__/approval-cascade.test.ts +8 -16
  22. package/src/__tests__/approval-routes-http.test.ts +6 -0
  23. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  24. package/src/__tests__/assistant-event.test.ts +0 -10
  25. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  26. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  29. package/src/__tests__/call-constants.test.ts +10 -1
  30. package/src/__tests__/call-controller.test.ts +127 -0
  31. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  32. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  33. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  34. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
  35. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  36. package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
  37. package/src/__tests__/config-schema.test.ts +1 -0
  38. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  39. package/src/__tests__/config-watcher.test.ts +140 -69
  40. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  41. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  42. package/src/__tests__/context-search-fanout.test.ts +0 -1
  43. package/src/__tests__/context-search-memory-source.test.ts +6 -33
  44. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  45. package/src/__tests__/context-search-pkb-source.test.ts +12 -7
  46. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  47. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
  48. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  51. package/src/__tests__/conversation-agent-loop.test.ts +457 -8
  52. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  53. package/src/__tests__/conversation-error.test.ts +150 -3
  54. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  55. package/src/__tests__/conversation-process-callsite.test.ts +38 -0
  56. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
  58. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  59. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  60. package/src/__tests__/conversation-store.test.ts +0 -18
  61. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  62. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  63. package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
  65. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  66. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  67. package/src/__tests__/credentials-cli.test.ts +7 -0
  68. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  69. package/src/__tests__/date-context.test.ts +164 -2
  70. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  71. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  72. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  73. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  74. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  75. package/src/__tests__/disk-usage.test.ts +150 -0
  76. package/src/__tests__/events-client-registration.test.ts +52 -0
  77. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  78. package/src/__tests__/file-write-tool.test.ts +4 -10
  79. package/src/__tests__/filing-service.test.ts +2 -20
  80. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  82. package/src/__tests__/heartbeat-service.test.ts +260 -11
  83. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  84. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  85. package/src/__tests__/host-bash-routes.test.ts +178 -13
  86. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  87. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  88. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  89. package/src/__tests__/host-file-proxy.test.ts +268 -6
  90. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  91. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  92. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  93. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  94. package/src/__tests__/injector-chain.test.ts +36 -16
  95. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  96. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
  98. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  99. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  100. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  101. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  102. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  103. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  104. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  105. package/src/__tests__/oauth-cli.test.ts +121 -0
  106. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  107. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  108. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  109. package/src/__tests__/openai-provider.test.ts +45 -8
  110. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  111. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  112. package/src/__tests__/platform.test.ts +2 -1
  113. package/src/__tests__/playbook-execution.test.ts +0 -43
  114. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  115. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  116. package/src/__tests__/provider-tool-name.test.ts +23 -0
  117. package/src/__tests__/relay-server.test.ts +60 -5
  118. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  119. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  120. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  121. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  122. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  123. package/src/__tests__/secret-response-routing.test.ts +7 -5
  124. package/src/__tests__/server-history-render.test.ts +82 -0
  125. package/src/__tests__/skill-include-graph.test.ts +31 -0
  126. package/src/__tests__/skill-load-tool.test.ts +44 -16
  127. package/src/__tests__/skills.test.ts +39 -0
  128. package/src/__tests__/suggestion-routes.test.ts +46 -0
  129. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  130. package/src/__tests__/tool-executor.test.ts +155 -0
  131. package/src/__tests__/twilio-validation.test.ts +2 -2
  132. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  133. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  134. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  136. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +120 -0
  137. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  138. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
  139. package/src/agent/loop.ts +11 -0
  140. package/src/approvals/guardian-request-resolvers.ts +3 -32
  141. package/src/backup/snapshot-lock.ts +2 -27
  142. package/src/bundler/compiler-tools.ts +3 -2
  143. package/src/calls/call-constants.ts +5 -8
  144. package/src/calls/call-controller.ts +130 -67
  145. package/src/calls/call-conversation-messages.ts +46 -10
  146. package/src/calls/relay-server.ts +7 -1
  147. package/src/calls/voice-session-bridge.ts +1 -1
  148. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  149. package/src/cli/commands/bash.ts +35 -108
  150. package/src/cli/commands/contacts.ts +64 -25
  151. package/src/cli/commands/credentials.ts +56 -0
  152. package/src/cli/commands/memory-v2.ts +11 -10
  153. package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
  154. package/src/cli/commands/oauth/connect.ts +124 -40
  155. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  156. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  157. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  158. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  159. package/src/cli/commands/platform/index.ts +16 -7
  160. package/src/cli/commands/status.ts +57 -0
  161. package/src/cli/program.ts +4 -2
  162. package/src/config/assistant-feature-flags.ts +13 -3
  163. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  164. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  165. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  166. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  167. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  168. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  169. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  170. package/src/config/env.ts +0 -8
  171. package/src/config/feature-flag-registry.json +13 -5
  172. package/src/config/loader.ts +199 -27
  173. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  174. package/src/config/schemas/call-site-catalog.ts +14 -0
  175. package/src/config/schemas/channels.ts +0 -5
  176. package/src/config/schemas/heartbeat.ts +1 -1
  177. package/src/config/schemas/llm.ts +2 -0
  178. package/src/config/schemas/memory-lifecycle.ts +13 -0
  179. package/src/config/schemas/memory-v2.ts +76 -12
  180. package/src/config/schemas/platform.ts +43 -3
  181. package/src/config/schemas/services.ts +28 -0
  182. package/src/config/seed-inference-profiles.ts +230 -33
  183. package/src/contacts/contact-store.ts +0 -25
  184. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
  185. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  186. package/src/daemon/assistant-attachments.ts +4 -4
  187. package/src/daemon/config-watcher.ts +85 -57
  188. package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
  189. package/src/daemon/conversation-agent-loop.ts +183 -43
  190. package/src/daemon/conversation-error.ts +87 -15
  191. package/src/daemon/conversation-lifecycle.ts +22 -10
  192. package/src/daemon/conversation-process.ts +8 -0
  193. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  194. package/src/daemon/conversation-store.ts +2 -2
  195. package/src/daemon/conversation-surfaces.ts +211 -29
  196. package/src/daemon/conversation-tool-setup.ts +66 -19
  197. package/src/daemon/conversation.ts +18 -23
  198. package/src/daemon/date-context.ts +71 -22
  199. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  200. package/src/daemon/disk-pressure-guard.ts +343 -0
  201. package/src/daemon/disk-pressure-policy.ts +163 -0
  202. package/src/daemon/handlers/shared.ts +26 -1
  203. package/src/daemon/handlers/skills.ts +3 -4
  204. package/src/daemon/host-app-control-proxy.ts +137 -41
  205. package/src/daemon/host-bash-proxy.ts +47 -22
  206. package/src/daemon/host-browser-proxy.ts +1 -1
  207. package/src/daemon/host-cu-proxy.ts +50 -4
  208. package/src/daemon/host-file-proxy.ts +44 -8
  209. package/src/daemon/host-transfer-proxy.ts +97 -6
  210. package/src/daemon/lifecycle.ts +167 -101
  211. package/src/daemon/meet-host-supervisor.ts +4 -4
  212. package/src/daemon/meet-manifest-loader.ts +0 -1
  213. package/src/daemon/memory-v2-startup.ts +66 -15
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/conversations.ts +4 -0
  216. package/src/daemon/message-types/disk-pressure.ts +9 -0
  217. package/src/daemon/message-types/messages.ts +22 -1
  218. package/src/daemon/profiler-run-store.ts +5 -5
  219. package/src/daemon/tool-setup-types.ts +2 -2
  220. package/src/documents/document-store.ts +119 -0
  221. package/src/filing/filing-service.ts +29 -5
  222. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  223. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  224. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  225. package/src/heartbeat/heartbeat-service.ts +205 -31
  226. package/src/home/feed-scheduler.ts +18 -0
  227. package/src/inbound/platform-callback-registration.ts +8 -15
  228. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  229. package/src/ipc/assistant-server.ts +149 -38
  230. package/src/ipc/gateway-client.ts +37 -3
  231. package/src/ipc/skill-server.ts +99 -42
  232. package/src/live-voice/live-voice-archive.ts +4 -4
  233. package/src/live-voice/protocol.ts +5 -7
  234. package/src/media/image-service.ts +1 -7
  235. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  236. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +34 -51
  237. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  238. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  239. package/src/memory/admin.ts +5 -9
  240. package/src/memory/context-search/agent-runner.ts +19 -2
  241. package/src/memory/context-search/sources/conversations.ts +2 -11
  242. package/src/memory/context-search/sources/memory-v2.ts +1 -16
  243. package/src/memory/context-search/sources/memory.ts +2 -3
  244. package/src/memory/context-search/sources/pkb.ts +2 -3
  245. package/src/memory/context-search/types.ts +0 -1
  246. package/src/memory/conversation-crud.ts +4 -12
  247. package/src/memory/db-init.ts +2 -0
  248. package/src/memory/embedding-runtime-manager.ts +119 -5
  249. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
  250. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  251. package/src/memory/graph/conversation-graph-memory.ts +72 -61
  252. package/src/memory/graph/extraction.ts +1 -3
  253. package/src/memory/graph/graph-search.test.ts +11 -67
  254. package/src/memory/graph/graph-search.ts +4 -24
  255. package/src/memory/graph/retriever.test.ts +12 -1
  256. package/src/memory/graph/retriever.ts +10 -15
  257. package/src/memory/graph/tool-handlers.ts +3 -4
  258. package/src/memory/graph/tools.ts +4 -4
  259. package/src/memory/indexer.ts +53 -45
  260. package/src/memory/job-handlers/backfill.ts +2 -11
  261. package/src/memory/job-handlers/cleanup.ts +43 -0
  262. package/src/memory/job-handlers/embedding.ts +6 -8
  263. package/src/memory/job-handlers/summarization.ts +2 -7
  264. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +116 -0
  265. package/src/memory/jobs/embed-concept-page.ts +223 -87
  266. package/src/memory/jobs-store.ts +48 -0
  267. package/src/memory/jobs-worker.ts +85 -43
  268. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  269. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  270. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  271. package/src/memory/migrations/index.ts +1 -0
  272. package/src/memory/pkb/pkb-search.test.ts +7 -0
  273. package/src/memory/pkb/pkb-search.ts +4 -5
  274. package/src/memory/qdrant-client.ts +3 -13
  275. package/src/memory/rerank-local.ts +374 -0
  276. package/src/memory/search/semantic.ts +10 -72
  277. package/src/memory/trace-event-store.ts +1 -17
  278. package/src/memory/v2/__tests__/activation.test.ts +346 -255
  279. package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
  280. package/src/memory/v2/__tests__/injection.test.ts +297 -190
  281. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  282. package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
  283. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  284. package/src/memory/v2/__tests__/sim.test.ts +113 -196
  285. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  286. package/src/memory/v2/__tests__/static-context.test.ts +77 -14
  287. package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
  288. package/src/memory/v2/activation.ts +149 -156
  289. package/src/memory/v2/consolidation-job.ts +69 -20
  290. package/src/memory/v2/injection.ts +75 -68
  291. package/src/memory/v2/page-store.ts +39 -0
  292. package/src/memory/v2/prompts/consolidation.ts +41 -1
  293. package/src/memory/v2/qdrant.ts +306 -46
  294. package/src/memory/v2/reranker.ts +177 -0
  295. package/src/memory/v2/sim.ts +77 -110
  296. package/src/memory/v2/skill-content.ts +4 -3
  297. package/src/memory/v2/skill-store.ts +82 -59
  298. package/src/memory/v2/static-context.ts +26 -8
  299. package/src/memory/v2/sweep-job.ts +5 -6
  300. package/src/memory/v2/types.ts +17 -10
  301. package/src/notifications/copy-composer.ts +47 -0
  302. package/src/notifications/decision-engine.ts +46 -0
  303. package/src/notifications/signal.ts +4 -0
  304. package/src/oauth/AGENTS.md +3 -1
  305. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  306. package/src/oauth/connect-orchestrator.ts +2 -0
  307. package/src/oauth/connection-resolver.test.ts +66 -1
  308. package/src/oauth/connection-resolver.ts +55 -1
  309. package/src/oauth/oauth-connect-state.ts +77 -0
  310. package/src/oauth/seed-providers.ts +58 -1
  311. package/src/permissions/gateway-threshold-reader.ts +116 -8
  312. package/src/permissions/prompter.ts +86 -96
  313. package/src/permissions/secret-prompter.ts +31 -31
  314. package/src/plugins/defaults/injectors.ts +36 -4
  315. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  316. package/src/plugins/types.ts +7 -0
  317. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  318. package/src/proactive-artifact/decision.test.ts +226 -0
  319. package/src/proactive-artifact/decision.ts +165 -0
  320. package/src/proactive-artifact/index.ts +7 -0
  321. package/src/proactive-artifact/job.test.ts +914 -0
  322. package/src/proactive-artifact/job.ts +366 -0
  323. package/src/proactive-artifact/message-copy.ts +58 -0
  324. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  325. package/src/proactive-artifact/trigger-state.ts +119 -0
  326. package/src/prompts/normalize-onboarding.ts +80 -0
  327. package/src/prompts/persona-resolver.ts +101 -9
  328. package/src/prompts/system-prompt.ts +21 -7
  329. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  330. package/src/prompts/templates/SOUL.md +13 -28
  331. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  332. package/src/providers/model-intents.ts +7 -0
  333. package/src/providers/openrouter/client.ts +8 -0
  334. package/src/providers/retry.ts +50 -0
  335. package/src/providers/types.ts +1 -0
  336. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  337. package/src/runtime/agent-wake.ts +238 -100
  338. package/src/runtime/assistant-event-hub.ts +36 -6
  339. package/src/runtime/assistant-event.ts +0 -1
  340. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  341. package/src/runtime/auth/route-policy.ts +15 -1
  342. package/src/runtime/auth/same-actor.ts +216 -0
  343. package/src/runtime/channel-approvals.ts +3 -2
  344. package/src/runtime/channel-retry-sweep.ts +65 -1
  345. package/src/runtime/local-actor-identity.ts +52 -11
  346. package/src/runtime/pending-interactions.ts +27 -15
  347. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  348. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  349. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  350. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  351. package/src/runtime/routes/approval-routes.ts +7 -3
  352. package/src/runtime/routes/client-routes.ts +20 -2
  353. package/src/runtime/routes/consolidation-routes.ts +8 -9
  354. package/src/runtime/routes/contact-routes.ts +0 -25
  355. package/src/runtime/routes/conversation-query-routes.ts +44 -1
  356. package/src/runtime/routes/conversation-routes.ts +35 -26
  357. package/src/runtime/routes/debug-bash-routes.ts +165 -0
  358. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  359. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  360. package/src/runtime/routes/documents-routes.ts +2 -75
  361. package/src/runtime/routes/events-routes.ts +41 -9
  362. package/src/runtime/routes/filing-routes.ts +2 -3
  363. package/src/runtime/routes/host-bash-routes.ts +23 -3
  364. package/src/runtime/routes/host-cu-routes.ts +33 -6
  365. package/src/runtime/routes/host-file-routes.ts +32 -6
  366. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  367. package/src/runtime/routes/identity-routes.ts +7 -138
  368. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  369. package/src/runtime/routes/index.ts +6 -0
  370. package/src/runtime/routes/memory-item-routes.test.ts +37 -17
  371. package/src/runtime/routes/memory-item-routes.ts +5 -6
  372. package/src/runtime/routes/memory-v2-routes.ts +136 -17
  373. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  374. package/src/runtime/verification-outbound-actions.ts +4 -4
  375. package/src/schedule/run-script.ts +37 -5
  376. package/src/schedule/scheduler.ts +20 -1
  377. package/src/security/encrypted-store.ts +2 -0
  378. package/src/security/secure-keys.ts +55 -0
  379. package/src/skills/include-graph.ts +35 -13
  380. package/src/skills/remote-skill-policy.ts +4 -10
  381. package/src/subagent/index.ts +1 -7
  382. package/src/subagent/manager.ts +1 -15
  383. package/src/tasks/task-runner.ts +0 -1
  384. package/src/tasks/task-store.ts +0 -3
  385. package/src/tools/background-tool-registry.ts +17 -3
  386. package/src/tools/document/document-tool.ts +20 -0
  387. package/src/tools/executor.ts +18 -2
  388. package/src/tools/host-filesystem/edit.test.ts +151 -0
  389. package/src/tools/host-filesystem/edit.ts +43 -1
  390. package/src/tools/host-filesystem/read.test.ts +129 -0
  391. package/src/tools/host-filesystem/read.ts +43 -1
  392. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  393. package/src/tools/host-filesystem/transfer.ts +56 -11
  394. package/src/tools/host-filesystem/write.test.ts +134 -0
  395. package/src/tools/host-filesystem/write.ts +43 -1
  396. package/src/tools/host-terminal/host-shell.ts +13 -6
  397. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  398. package/src/tools/memory/register.test.ts +14 -9
  399. package/src/tools/memory/register.ts +1 -2
  400. package/src/tools/permission-checker.ts +15 -0
  401. package/src/tools/provider-tool-name.ts +28 -0
  402. package/src/tools/registry.ts +30 -9
  403. package/src/tools/skills/load.ts +24 -20
  404. package/src/tools/terminal/shell.ts +9 -1
  405. package/src/tools/tool-approval-handler.ts +31 -6
  406. package/src/tools/tool-name-aliases.ts +19 -0
  407. package/src/tools/types.ts +43 -3
  408. package/src/tts/provider-catalog.ts +3 -5
  409. package/src/util/disk-usage.ts +138 -0
  410. package/src/util/platform.ts +21 -11
  411. package/src/util/process-liveness.ts +26 -0
  412. package/src/workspace/heartbeat-service.ts +19 -0
  413. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  414. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  415. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +14 -0
  416. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  417. package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
  418. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  419. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  420. package/src/workspace/migrations/registry.ts +14 -0
  421. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  422. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  423. package/src/memory/v2/skill-qdrant.ts +0 -404
  424. package/src/signals/bash.ts +0 -198
@@ -0,0 +1,150 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ const MIB = 1024 * 1024;
4
+ const GIB = 1024 * MIB;
5
+
6
+ let existingPaths = new Set<string>();
7
+ const workspaceDir = "/workspace";
8
+ let minikubeStorageSize: string | undefined;
9
+ let statfsResult = {
10
+ bsize: 4096,
11
+ blocks: 0,
12
+ bavail: 0,
13
+ };
14
+ let spawnResult: {
15
+ status: number | null;
16
+ stdout: string;
17
+ } = {
18
+ status: 0,
19
+ stdout: "",
20
+ };
21
+ let spawnCalls: Array<{ command: string; args: string[] }> = [];
22
+
23
+ mock.module("node:fs", () => ({
24
+ existsSync: (path: string) => existingPaths.has(path),
25
+ statfsSync: () => statfsResult,
26
+ }));
27
+
28
+ mock.module("node:child_process", () => ({
29
+ spawnSync: (command: string, args: string[]) => {
30
+ spawnCalls.push({ command, args });
31
+ return spawnResult;
32
+ },
33
+ }));
34
+
35
+ mock.module("../config/env-registry.js", () => ({
36
+ getMinikubeStorageSize: () => minikubeStorageSize,
37
+ }));
38
+
39
+ mock.module("../util/platform.js", () => ({
40
+ getWorkspaceDir: () => workspaceDir,
41
+ }));
42
+
43
+ const { __resetDiskUsageCacheForTests, getDiskUsageInfo, parseK8sMemoryBytes } =
44
+ await import("../util/disk-usage.js");
45
+
46
+ function statfsFor(totalBytes: number, freeBytes: number) {
47
+ return {
48
+ bsize: MIB,
49
+ blocks: totalBytes / MIB,
50
+ bavail: freeBytes / MIB,
51
+ };
52
+ }
53
+
54
+ describe("disk usage sampler", () => {
55
+ beforeEach(() => {
56
+ existingPaths = new Set([workspaceDir]);
57
+ minikubeStorageSize = undefined;
58
+ statfsResult = statfsFor(100 * MIB, 25 * MIB);
59
+ spawnResult = { status: 0, stdout: "" };
60
+ spawnCalls = [];
61
+ __resetDiskUsageCacheForTests();
62
+ });
63
+
64
+ test("reports regular statfs usage", () => {
65
+ const usage = getDiskUsageInfo();
66
+
67
+ expect(usage).toEqual({
68
+ path: "/workspace",
69
+ totalMb: 100,
70
+ usedMb: 75,
71
+ freeMb: 25,
72
+ });
73
+ expect(spawnCalls).toHaveLength(0);
74
+ });
75
+
76
+ test("falls back to root when the workspace path does not exist", () => {
77
+ existingPaths = new Set();
78
+
79
+ const usage = getDiskUsageInfo();
80
+
81
+ expect(usage?.path).toBe("/");
82
+ });
83
+
84
+ test("uses PVC capacity and du usage when host filesystem is larger", () => {
85
+ minikubeStorageSize = "1Gi";
86
+ statfsResult = statfsFor(10 * GIB, 8 * GIB);
87
+ spawnResult = {
88
+ status: 0,
89
+ stdout: `${100 * MIB}\t/workspace\n`,
90
+ };
91
+
92
+ const usage = getDiskUsageInfo();
93
+
94
+ expect(usage).toEqual({
95
+ path: "/workspace",
96
+ totalMb: 1024,
97
+ usedMb: 100,
98
+ freeMb: 924,
99
+ });
100
+ expect(spawnCalls).toEqual([
101
+ { command: "du", args: ["-sb", "/workspace"] },
102
+ ]);
103
+ });
104
+
105
+ test("includes /data in PVC du usage when it exists separately", () => {
106
+ existingPaths = new Set([workspaceDir, "/data"]);
107
+ minikubeStorageSize = "1Gi";
108
+ statfsResult = statfsFor(10 * GIB, 8 * GIB);
109
+ spawnResult = {
110
+ status: 0,
111
+ stdout: `${100 * MIB}\t/workspace\n${20 * MIB}\t/data\n`,
112
+ };
113
+
114
+ const usage = getDiskUsageInfo();
115
+
116
+ expect(usage?.usedMb).toBe(120);
117
+ expect(spawnCalls).toEqual([
118
+ { command: "du", args: ["-sb", "/workspace", "/data"] },
119
+ ]);
120
+ });
121
+
122
+ test("returns null for malformed Kubernetes memory strings", () => {
123
+ expect(parseK8sMemoryBytes("")).toBeNull();
124
+ expect(parseK8sMemoryBytes("abc")).toBeNull();
125
+ expect(parseK8sMemoryBytes("12Zi")).toBeNull();
126
+ expect(parseK8sMemoryBytes("-1Gi")).toBeNull();
127
+ expect(parseK8sMemoryBytes("0Gi")).toBeNull();
128
+ });
129
+
130
+ test("falls back to statfs when du fails in PVC mode", () => {
131
+ minikubeStorageSize = "1Gi";
132
+ statfsResult = statfsFor(10 * GIB, 8 * GIB);
133
+ spawnResult = {
134
+ status: 1,
135
+ stdout: "",
136
+ };
137
+
138
+ const usage = getDiskUsageInfo();
139
+
140
+ expect(usage).toEqual({
141
+ path: "/workspace",
142
+ totalMb: 10240,
143
+ usedMb: 2048,
144
+ freeMb: 8192,
145
+ });
146
+ expect(spawnCalls).toEqual([
147
+ { command: "du", args: ["-sb", "/workspace"] },
148
+ ]);
149
+ });
150
+ });
@@ -395,6 +395,58 @@ describe("events client registration", () => {
395
395
  ac2.abort();
396
396
  });
397
397
 
398
+ // ── actorPrincipalId capture ──────────────────────────────────────────────
399
+
400
+ test("captures actorPrincipalId from x-vellum-actor-principal-id header", () => {
401
+ const ac = new AbortController();
402
+ const hub = new AssistantEventHub();
403
+
404
+ handleSubscribeAssistantEvents(
405
+ {
406
+ headers: {
407
+ "x-vellum-client-id": "principal-client-001",
408
+ "x-vellum-interface-id": "macos",
409
+ "x-vellum-actor-principal-id": "user-A",
410
+ },
411
+ abortSignal: ac.signal,
412
+ },
413
+ { hub },
414
+ );
415
+
416
+ const entry = hub.getClientById("principal-client-001");
417
+ expect(entry?.actorPrincipalId).toBe("user-A");
418
+ expect(hub.getActorPrincipalIdForClient("principal-client-001")).toBe(
419
+ "user-A",
420
+ );
421
+
422
+ ac.abort();
423
+ });
424
+
425
+ test("registers client with undefined actorPrincipalId when header is absent", () => {
426
+ const ac = new AbortController();
427
+ const hub = new AssistantEventHub();
428
+
429
+ handleSubscribeAssistantEvents(
430
+ {
431
+ headers: {
432
+ "x-vellum-client-id": "principal-client-002",
433
+ "x-vellum-interface-id": "macos",
434
+ },
435
+ abortSignal: ac.signal,
436
+ },
437
+ { hub },
438
+ );
439
+
440
+ const entry = hub.getClientById("principal-client-002");
441
+ expect(entry).toBeDefined();
442
+ expect(entry?.actorPrincipalId).toBeUndefined();
443
+ expect(
444
+ hub.getActorPrincipalIdForClient("principal-client-002"),
445
+ ).toBeUndefined();
446
+
447
+ ac.abort();
448
+ });
449
+
398
450
  // ── disposeClient (force disconnect) ──────────────────────────────────────
399
451
 
400
452
  test("disposeClient removes all subscribers for the clientId", () => {
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Regression tests for the SSE registration dev-bypass actor principal
3
+ * translation.
4
+ *
5
+ * In `DISABLE_HTTP_AUTH=true` (platform-managed) deployments the synthetic
6
+ * dev-bypass `AuthContext` injects `actorPrincipalId="dev-bypass"` for every
7
+ * request. Tool-side trust resolution still resolves to the real local
8
+ * guardian's principalId via `resolveLocalTrustContext`. Without translation,
9
+ * `ClientEntry.actorPrincipalId === "dev-bypass"` and
10
+ * `ToolContext.sourceActorPrincipalId === "<real-guardian>"` mismatch, so the
11
+ * same-user check in HostBashProxy / HostFileProxy / HostCuProxy /
12
+ * conversation-surfaces rejects every targeted host proxy invocation and the
13
+ * auto-resolve path silently falls through to untargeted broadcast.
14
+ *
15
+ * The events-routes handler translates `"dev-bypass"` to the real guardian's
16
+ * principalId at registration time so both sides agree. This keeps targeted
17
+ * host proxy execution working on Docker / platform-managed deployments.
18
+ */
19
+ import { afterAll, describe, expect, mock, test } from "bun:test";
20
+
21
+ // ── Module mocks (must be set up before importing the route) ──────────────
22
+
23
+ let fakeHttpAuthDisabled = false;
24
+ let fakeGuardianPrincipalId: string | undefined = undefined;
25
+
26
+ mock.module("../config/env.js", () => ({
27
+ isHttpAuthDisabled: () => fakeHttpAuthDisabled,
28
+ hasUngatedHttpAuthDisabled: () => false,
29
+ }));
30
+
31
+ mock.module("../runtime/local-actor-identity.js", () => ({
32
+ findLocalGuardianPrincipalId: () => fakeGuardianPrincipalId,
33
+ }));
34
+
35
+ mock.module("../util/logger.js", () => ({
36
+ getLogger: () =>
37
+ new Proxy({} as Record<string, unknown>, {
38
+ get: () => () => {},
39
+ }),
40
+ }));
41
+
42
+ // ── Real imports (after mocks) ────────────────────────────────────────────
43
+
44
+ import { AssistantEventHub } from "../runtime/assistant-event-hub.js";
45
+ import { handleSubscribeAssistantEvents } from "../runtime/routes/events-routes.js";
46
+
47
+ afterAll(() => {
48
+ mock.restore();
49
+ });
50
+
51
+ describe("events SSE registration — dev-bypass actor translation", () => {
52
+ test("translates 'dev-bypass' to the real guardian principalId when auth is disabled", () => {
53
+ fakeHttpAuthDisabled = true;
54
+ fakeGuardianPrincipalId = "guardian-real-id";
55
+
56
+ const ac = new AbortController();
57
+ const hub = new AssistantEventHub();
58
+
59
+ handleSubscribeAssistantEvents(
60
+ {
61
+ headers: {
62
+ "x-vellum-client-id": "devbypass-client-001",
63
+ "x-vellum-interface-id": "macos",
64
+ "x-vellum-actor-principal-id": "dev-bypass",
65
+ },
66
+ abortSignal: ac.signal,
67
+ },
68
+ { hub },
69
+ );
70
+
71
+ const entry = hub.getClientById("devbypass-client-001");
72
+ expect(entry?.actorPrincipalId).toBe("guardian-real-id");
73
+ expect(hub.getActorPrincipalIdForClient("devbypass-client-001")).toBe(
74
+ "guardian-real-id",
75
+ );
76
+
77
+ ac.abort();
78
+ });
79
+
80
+ test("registers without principalId when dev-bypass is set but no guardian is bound", () => {
81
+ fakeHttpAuthDisabled = true;
82
+ fakeGuardianPrincipalId = undefined;
83
+
84
+ const ac = new AbortController();
85
+ const hub = new AssistantEventHub();
86
+
87
+ handleSubscribeAssistantEvents(
88
+ {
89
+ headers: {
90
+ "x-vellum-client-id": "devbypass-client-002",
91
+ "x-vellum-interface-id": "macos",
92
+ "x-vellum-actor-principal-id": "dev-bypass",
93
+ },
94
+ abortSignal: ac.signal,
95
+ },
96
+ { hub },
97
+ );
98
+
99
+ const entry = hub.getClientById("devbypass-client-002");
100
+ expect(entry).toBeDefined();
101
+ expect(entry?.actorPrincipalId).toBeUndefined();
102
+
103
+ ac.abort();
104
+ });
105
+
106
+ test("does NOT translate when auth is enabled (production mode)", () => {
107
+ // Defense in depth: make sure we never silently rewrite a real
108
+ // principalId that legitimately happens to be the literal "dev-bypass"
109
+ // string in a non-dev-bypass deployment. The translation is gated on
110
+ // isHttpAuthDisabled() === true.
111
+ fakeHttpAuthDisabled = false;
112
+ fakeGuardianPrincipalId = "guardian-real-id";
113
+
114
+ const ac = new AbortController();
115
+ const hub = new AssistantEventHub();
116
+
117
+ handleSubscribeAssistantEvents(
118
+ {
119
+ headers: {
120
+ "x-vellum-client-id": "prod-client-003",
121
+ "x-vellum-interface-id": "macos",
122
+ "x-vellum-actor-principal-id": "dev-bypass",
123
+ },
124
+ abortSignal: ac.signal,
125
+ },
126
+ { hub },
127
+ );
128
+
129
+ const entry = hub.getClientById("prod-client-003");
130
+ expect(entry?.actorPrincipalId).toBe("dev-bypass");
131
+
132
+ ac.abort();
133
+ });
134
+
135
+ test("passes through non-dev-bypass principalId verbatim in dev-bypass mode", () => {
136
+ // Edge case: a service-token connection that happens to be made while
137
+ // the daemon runs in DISABLE_HTTP_AUTH=true mode should still register
138
+ // with its own principalId, not the guardian's.
139
+ fakeHttpAuthDisabled = true;
140
+ fakeGuardianPrincipalId = "guardian-real-id";
141
+
142
+ const ac = new AbortController();
143
+ const hub = new AssistantEventHub();
144
+
145
+ handleSubscribeAssistantEvents(
146
+ {
147
+ headers: {
148
+ "x-vellum-client-id": "service-client-004",
149
+ "x-vellum-interface-id": "macos",
150
+ "x-vellum-actor-principal-id": "service-account-A",
151
+ },
152
+ abortSignal: ac.signal,
153
+ },
154
+ { hub },
155
+ );
156
+
157
+ const entry = hub.getClientById("service-client-004");
158
+ expect(entry?.actorPrincipalId).toBe("service-account-A");
159
+
160
+ ac.abort();
161
+ });
162
+ });
@@ -197,26 +197,20 @@ describe("file_write tool PKB re-index hook", () => {
197
197
  });
198
198
  });
199
199
 
200
- test("always uses PKB_WORKSPACE_SCOPE regardless of context.memoryScopeId", async () => {
200
+ test("always uses PKB_WORKSPACE_SCOPE", async () => {
201
201
  const workingDir = makeTempDir();
202
202
  setWorkspaceDir(workingDir);
203
203
  mkdirSync(join(workingDir, "pkb"), { recursive: true });
204
204
 
205
- const ctx: ToolContext = {
206
- ...makeContext(workingDir),
207
- memoryScopeId: "subagent:abc123",
208
- };
209
-
210
205
  const result = await fileWriteTool.execute(
211
206
  { path: "pkb/private.md", content: "secret\n" },
212
- ctx,
207
+ makeContext(workingDir),
213
208
  );
214
209
 
215
210
  expect(result.isError).toBe(false);
216
211
  expect(enqueueCalls).toHaveLength(1);
217
- // PKB files are workspace-level — the per-conversation scopeId is NOT
218
- // threaded through so different conversations can't overwrite each
219
- // other's Qdrant points via target_id upsert deduplication.
212
+ // PKB files are workspace-level — points are keyed by PKB_WORKSPACE_SCOPE
213
+ // so all conversations share one PKB index.
220
214
  expect(enqueueCalls[0]?.memoryScopeId).toBe(PKB_WORKSPACE_SCOPE);
221
215
  });
222
216
 
@@ -34,9 +34,6 @@ mock.module("../config/loader.js", () => ({
34
34
  invalidateConfigCache: () => {},
35
35
  }));
36
36
 
37
- const { _setOverridesForTesting } =
38
- await import("../config/assistant-feature-flags.js");
39
-
40
37
  // Mock conversation store
41
38
  const createdConversations: Array<{ title: string; conversationType: string }> =
42
39
  [];
@@ -128,7 +125,6 @@ describe("FilingService", () => {
128
125
  } catch {
129
126
  // best-effort
130
127
  }
131
- _setOverridesForTesting({});
132
128
  });
133
129
 
134
130
  beforeEach(() => {
@@ -331,8 +327,7 @@ describe("FilingService", () => {
331
327
  });
332
328
 
333
329
  describe("memory v2 gate", () => {
334
- test("start() does not schedule timers when v2 flag and config are both on", () => {
335
- _setOverridesForTesting({ "memory-v2-enabled": true });
330
+ test("start() does not schedule timers when memory.v2.enabled is true", () => {
336
331
  mockConfig.memory.v2.enabled = true;
337
332
 
338
333
  const service = createService();
@@ -342,8 +337,7 @@ describe("FilingService", () => {
342
337
  expect(service.nextCompactionAt).toBeNull();
343
338
  });
344
339
 
345
- test("start() schedules timers when only the flag is on", () => {
346
- _setOverridesForTesting({ "memory-v2-enabled": true });
340
+ test("start() schedules timers when memory.v2.enabled is false (v1 filing runs)", () => {
347
341
  mockConfig.memory.v2.enabled = false;
348
342
 
349
343
  const service = createService();
@@ -353,18 +347,6 @@ describe("FilingService", () => {
353
347
  expect(service.nextCompactionAt).not.toBeNull();
354
348
  service.stop();
355
349
  });
356
-
357
- test("start() schedules timers when only the config is on", () => {
358
- _setOverridesForTesting({ "memory-v2-enabled": false });
359
- mockConfig.memory.v2.enabled = true;
360
-
361
- const service = createService();
362
- service.start();
363
-
364
- expect(service.nextRunAt).not.toBeNull();
365
- expect(service.nextCompactionAt).not.toBeNull();
366
- service.stop();
367
- });
368
350
  });
369
351
 
370
352
  describe("llm.callSites.filingAgent resolution", () => {
@@ -5,17 +5,16 @@
5
5
  * One representative call site (the `installSkill` bundled branch) is
6
6
  * exercised — all 5 sites share the same delegation to
7
7
  * `maybeSeedMemoryV2Skills`, so a single suite covers behavior. Validates:
8
- * - flag + config both on → helper invoked after seedSkillGraphNodes
9
- * and the seed observed (callOrder picks up "v2")
10
- * - flag off → helper still invoked, but the seed short-circuits
11
- * - config.memory.v2.enabled off → helper still invoked, seed short-circuits
8
+ * - config on → helper invoked after seedSkillGraphNodes and the seed
9
+ * observed (callOrder picks up "v2")
10
+ * - config off → helper still invoked, but the seed short-circuits
12
11
  *
13
12
  * The handler delegates to `maybeSeedMemoryV2Skills` from
14
13
  * `daemon/memory-v2-startup.ts`. We mock that module directly so the test
15
14
  * does not have to drain the dynamic-import microtask chain. The helper's
16
- * gate semantics (flag + config + rejection swallowing) are covered by
17
- * `lifecycle-memory-v2-seed.test.ts`; here we only verify that the
18
- * handler invokes the helper synchronously with the live config.
15
+ * gate semantics are covered by `lifecycle-memory-v2-seed.test.ts`; here
16
+ * we only verify that the handler invokes the helper synchronously with
17
+ * the live config.
19
18
  */
20
19
  import { beforeEach, describe, expect, mock, test } from "bun:test";
21
20
 
@@ -23,7 +22,7 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
23
22
  // Programmable test state
24
23
  // ---------------------------------------------------------------------------
25
24
 
26
- const flagsState = { flagEnabled: true, configV2Enabled: true };
25
+ const flagsState = { configV2Enabled: true };
27
26
 
28
27
  const callOrder: string[] = [];
29
28
 
@@ -55,10 +54,7 @@ mock.module("../config/skills.js", () => ({
55
54
  }));
56
55
 
57
56
  mock.module("../config/assistant-feature-flags.js", () => ({
58
- isAssistantFeatureFlagEnabled: (key: string) => {
59
- if (key === "memory-v2-enabled") return flagsState.flagEnabled;
60
- return true;
61
- },
57
+ isAssistantFeatureFlagEnabled: () => true,
62
58
  }));
63
59
 
64
60
  // Stub both `getConfig` and `loadConfig`. `loadConfig` is reached by code
@@ -220,18 +216,17 @@ const { installSkill } = await import("../daemon/handlers/skills.js");
220
216
 
221
217
  describe("v2 skill re-seed gating in skill handlers", () => {
222
218
  beforeEach(() => {
223
- flagsState.flagEnabled = true;
224
219
  flagsState.configV2Enabled = true;
225
220
  callOrder.length = 0;
226
221
  mockSeedSkillGraphNodes.mockClear();
227
222
  mockMaybeSeedMemoryV2Skills.mockClear();
228
223
  mockMaybeSeedMemoryV2Skills.mockImplementation((config) => {
229
- if (!flagsState.flagEnabled || !config.memory.v2.enabled) return;
224
+ if (!config.memory.v2.enabled) return;
230
225
  callOrder.push("v2");
231
226
  });
232
227
  });
233
228
 
234
- test("flag + config both on → maybeSeedMemoryV2Skills invoked after seedSkillGraphNodes", async () => {
229
+ test("config on → maybeSeedMemoryV2Skills invoked after seedSkillGraphNodes", async () => {
235
230
  const result = await installSkill({ slug: "bundled-skill" });
236
231
 
237
232
  expect(result.success).toBe(true);
@@ -240,17 +235,6 @@ describe("v2 skill re-seed gating in skill handlers", () => {
240
235
  expect(callOrder).toEqual(["v1", "v2"]);
241
236
  });
242
237
 
243
- test("flag off → seed mock observes the disabled flag and skips", async () => {
244
- flagsState.flagEnabled = false;
245
-
246
- const result = await installSkill({ slug: "bundled-skill" });
247
-
248
- expect(result.success).toBe(true);
249
- expect(mockSeedSkillGraphNodes).toHaveBeenCalledTimes(1);
250
- expect(mockMaybeSeedMemoryV2Skills).toHaveBeenCalledTimes(1);
251
- expect(callOrder).toEqual(["v1"]);
252
- });
253
-
254
238
  test("config.memory.v2.enabled off → seed mock observes config and skips", async () => {
255
239
  flagsState.configV2Enabled = false;
256
240