@vellumai/assistant 0.8.12 → 0.9.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 (442) hide show
  1. package/AGENTS.md +0 -14
  2. package/ARCHITECTURE.md +45 -45
  3. package/README.md +1 -1
  4. package/bun.lock +200 -154
  5. package/docs/architecture/integrations.md +3 -3
  6. package/docs/architecture/memory.md +2 -2
  7. package/docs/architecture/security.md +10 -10
  8. package/docs/runbook-trusted-contacts.md +12 -12
  9. package/docs/skills.md +6 -6
  10. package/docs/workflows-testing.md +221 -0
  11. package/docs/workflows.md +510 -0
  12. package/examples/plugins/echo/README.md +5 -5
  13. package/knip.json +2 -0
  14. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +105 -0
  15. package/node_modules/@vellumai/gateway-client/src/index.ts +12 -0
  16. package/openapi.yaml +7197 -5708
  17. package/package.json +8 -4
  18. package/scripts/generate-openapi.ts +66 -114
  19. package/src/__tests__/access-request-seed-content-blocks.test.ts +213 -0
  20. package/src/__tests__/adaptive-thinking-repair.test.ts +32 -3
  21. package/src/__tests__/agent-loop-output-hooks.test.ts +183 -0
  22. package/src/__tests__/agent-loop-regrowth-guard.test.ts +506 -0
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
  24. package/src/__tests__/agent-wake-override-profile.test.ts +77 -0
  25. package/src/__tests__/app-compiler.test.ts +7 -1
  26. package/src/__tests__/app-dir-path-guard.test.ts +27 -3
  27. package/src/__tests__/app-executors.test.ts +43 -0
  28. package/src/__tests__/approval-cascade.test.ts +0 -5
  29. package/src/__tests__/approval-routes-http.test.ts +91 -0
  30. package/src/__tests__/assistant-stream-state.test.ts +107 -0
  31. package/src/__tests__/browser-fill-credential.test.ts +3 -3
  32. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +1 -1
  33. package/src/__tests__/compaction-events.test.ts +63 -7
  34. package/src/__tests__/compaction-trail-store.test.ts +74 -1
  35. package/src/__tests__/compaction.benchmark.test.ts +63 -41
  36. package/src/__tests__/compactor-low-watermark-cut.test.ts +349 -0
  37. package/src/__tests__/context-window-manager-compact-retry.test.ts +64 -0
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
  39. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -5
  40. package/src/__tests__/conversation-history-web-search.test.ts +7 -0
  41. package/src/__tests__/conversation-process-callsite.test.ts +0 -5
  42. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
  43. package/src/__tests__/conversation-queue.test.ts +0 -5
  44. package/src/__tests__/conversation-slash-queue.test.ts +0 -5
  45. package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
  46. package/src/__tests__/conversation-speed-override.test.ts +0 -5
  47. package/src/__tests__/conversation-surfaces-data-persist.test.ts +97 -0
  48. package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
  49. package/src/__tests__/conversation-usage.test.ts +2 -0
  50. package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
  51. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
  52. package/src/__tests__/credential-broker-browser-fill.test.ts +2 -2
  53. package/src/__tests__/credential-broker-server-use.test.ts +2 -2
  54. package/src/__tests__/credential-broker.test.ts +1 -1
  55. package/src/__tests__/credential-prompt-route.test.ts +417 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault.test.ts +37 -0
  58. package/src/__tests__/db-schedule-syntax-migration.test.ts +24 -0
  59. package/src/__tests__/dynamic-page-surface.test.ts +219 -0
  60. package/src/__tests__/empty-state-greeting-cache.test.ts +94 -0
  61. package/src/__tests__/gateway-flag-listener.test.ts +24 -7
  62. package/src/__tests__/guardian-action-sweep.test.ts +56 -219
  63. package/src/__tests__/guardian-routing-invariants.test.ts +138 -0
  64. package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
  65. package/src/__tests__/list-messages-hidden-metadata.test.ts +99 -0
  66. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +87 -1
  67. package/src/__tests__/llm-resolver.test.ts +115 -0
  68. package/src/__tests__/managed-profile-guard.test.ts +6 -5
  69. package/src/__tests__/max-tokens-continue-hook.test.ts +184 -0
  70. package/src/__tests__/media-generate-image.test.ts +20 -9
  71. package/src/__tests__/mock-gateway-ipc.ts +23 -0
  72. package/src/__tests__/model-intents.test.ts +1 -1
  73. package/src/__tests__/normalize-onboarding.test.ts +26 -0
  74. package/src/__tests__/notification-decision-strategy.test.ts +4 -2
  75. package/src/__tests__/notification-telegram-adapter.test.ts +21 -3
  76. package/src/__tests__/pending-interactions-resolved-event.test.ts +62 -0
  77. package/src/__tests__/post-turn-tool-result-truncation.test.ts +72 -18
  78. package/src/__tests__/require-fresh-approval.test.ts +425 -1
  79. package/src/__tests__/resolve-app-id.test.ts +56 -0
  80. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -0
  81. package/src/__tests__/schedule-routes-workflow-validation.test.ts +408 -0
  82. package/src/__tests__/schedule-routes.test.ts +257 -4
  83. package/src/__tests__/schedule-store.test.ts +60 -0
  84. package/src/__tests__/schedule-tools.test.ts +247 -2
  85. package/src/__tests__/skill-execute-input.test.ts +85 -0
  86. package/src/__tests__/skill-secret-handling-guard.test.ts +21 -20
  87. package/src/__tests__/skills.test.ts +3 -3
  88. package/src/__tests__/slack-app-setup-skill-regression.test.ts +1 -1
  89. package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
  90. package/src/__tests__/subagent-tool-gate-mode.test.ts +547 -0
  91. package/src/__tests__/system-prompt.test.ts +1 -1
  92. package/src/__tests__/task-progress-nudge-hook.test.ts +372 -0
  93. package/src/__tests__/task-scheduler.test.ts +299 -0
  94. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +209 -0
  95. package/src/__tests__/tool-result-spool.test.ts +3 -1
  96. package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +181 -0
  97. package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +174 -0
  98. package/src/agent/compaction-circuit.ts +11 -0
  99. package/src/agent/loop.ts +181 -12
  100. package/src/api/constants/call-sites.ts +12 -0
  101. package/src/api/events/assistant-thinking-delta.ts +10 -0
  102. package/src/api/events/usage-update.ts +7 -0
  103. package/src/api/index.ts +4 -1
  104. package/src/api/responses/memory-v3-selection-log.ts +18 -11
  105. package/src/approvals/approval-primitive.ts +2 -2
  106. package/src/background-wake/background-wake-routes.test.ts +5 -2
  107. package/src/bundler/compiler-tools.ts +1 -1
  108. package/src/bundler/package-resolver.ts +0 -1
  109. package/src/calls/call-domain.ts +1 -1
  110. package/src/calls/guardian-action-sweep.ts +16 -93
  111. package/src/cli/AGENTS.md +4 -0
  112. package/src/cli/commands/__tests__/schedules.test.ts +430 -1
  113. package/src/cli/commands/credentials.ts +28 -24
  114. package/src/cli/commands/image-generation.ts +23 -9
  115. package/src/cli/commands/notifications.ts +1 -1
  116. package/src/cli/commands/plugins.ts +89 -46
  117. package/src/cli/commands/schedules.ts +384 -11
  118. package/src/cli/lib/__tests__/inspect-plugin.test.ts +69 -5
  119. package/src/cli/lib/__tests__/install-from-github.test.ts +15 -0
  120. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +81 -4
  121. package/src/cli/lib/inspect-plugin.ts +62 -1
  122. package/src/cli/lib/install-from-github.ts +52 -5
  123. package/src/cli/lib/upgrade-plugin.ts +18 -0
  124. package/src/config/__tests__/workflows-schema.test.ts +60 -0
  125. package/src/config/bundled-skills/acp/SKILL.md +2 -2
  126. package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
  127. package/src/config/bundled-skills/app-builder/tools/app-create.ts +6 -1
  128. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +7 -1
  129. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +7 -1
  130. package/src/config/bundled-skills/app-builder/tools/app-update.ts +10 -1
  131. package/src/config/bundled-skills/image-studio/SKILL.md +66 -19
  132. package/src/config/bundled-skills/image-studio/TOOLS.json +1 -6
  133. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +22 -3
  134. package/src/config/bundled-skills/personal-page/SKILL.md +57 -0
  135. package/src/config/bundled-skills/personal-page/TOOLS.json +27 -0
  136. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +17 -0
  137. package/src/config/bundled-skills/schedule/SKILL.md +7 -2
  138. package/src/config/bundled-skills/schedule/TOOLS.json +48 -4
  139. package/src/config/bundled-skills/workflows/SKILL.md +214 -0
  140. package/src/config/bundled-skills/workflows/TOOLS.json +84 -0
  141. package/src/config/bundled-skills/workflows/tools/manage-workflows.ts +12 -0
  142. package/src/config/bundled-skills/workflows/tools/run-workflow.ts +12 -0
  143. package/src/config/bundled-tool-registry.ts +14 -2
  144. package/src/config/call-site-defaults.ts +5 -0
  145. package/src/config/feature-flag-registry.json +12 -4
  146. package/src/config/llm-context-resolution.ts +8 -0
  147. package/src/config/llm-resolver.ts +30 -0
  148. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +22 -0
  149. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +16 -0
  150. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +77 -0
  151. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +57 -0
  152. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +28 -0
  153. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +234 -0
  154. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +48 -0
  155. package/src/config/preloaded-apps/personal-page/src/components/media.ts +16 -0
  156. package/src/config/preloaded-apps/personal-page/src/index.html +20 -0
  157. package/src/config/preloaded-apps/personal-page/src/main.tsx +7 -0
  158. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +82 -0
  159. package/src/config/preloaded-apps/personal-page/src/styles.css +759 -0
  160. package/src/config/schema.ts +2 -0
  161. package/src/config/schemas/call-site-catalog.ts +7 -0
  162. package/src/config/schemas/heartbeat.ts +4 -1
  163. package/src/config/schemas/llm.ts +33 -26
  164. package/src/config/schemas/memory-retrospective.ts +19 -0
  165. package/src/config/schemas/platform.ts +8 -0
  166. package/src/config/schemas/services.ts +5 -2
  167. package/src/config/schemas/workflows.ts +42 -0
  168. package/src/config/skills.ts +3 -3
  169. package/src/context/compactor.ts +273 -39
  170. package/src/context/post-turn-tool-result-truncation.ts +23 -6
  171. package/src/context/tool-result-spool.ts +12 -17
  172. package/src/credential-execution/executable-discovery.ts +1 -1
  173. package/src/credential-execution/process-manager.ts +37 -3
  174. package/src/credential-execution/prompted-credential.ts +205 -0
  175. package/src/daemon/conversation-agent-loop-handlers.ts +14 -0
  176. package/src/daemon/conversation-process.ts +11 -2
  177. package/src/daemon/conversation-surfaces.ts +167 -3
  178. package/src/daemon/conversation-tool-setup.ts +103 -26
  179. package/src/daemon/conversation-usage.ts +2 -0
  180. package/src/daemon/conversation.ts +115 -11
  181. package/src/daemon/handlers/shared.ts +26 -14
  182. package/src/daemon/host-cu-proxy.ts +15 -12
  183. package/src/daemon/host-file-proxy.ts +15 -12
  184. package/src/daemon/host-transfer-proxy.ts +30 -24
  185. package/src/daemon/lifecycle.ts +40 -3
  186. package/src/daemon/message-protocol.ts +3 -0
  187. package/src/daemon/message-types/messages.ts +2 -10
  188. package/src/daemon/message-types/workflows.ts +49 -0
  189. package/src/daemon/parse-actual-tokens-from-error.test.ts +62 -1
  190. package/src/daemon/parse-actual-tokens-from-error.ts +43 -4
  191. package/src/daemon/process-message.ts +6 -0
  192. package/src/daemon/tool-setup-types.ts +57 -0
  193. package/src/daemon/wake-conversation-ops.ts +18 -0
  194. package/src/heartbeat/heartbeat-run-store.ts +8 -2
  195. package/src/home/feed-types.ts +1 -1
  196. package/src/ipc/gateway-flag-listener.ts +28 -6
  197. package/src/mcp/mcp-auth-state.ts +8 -20
  198. package/src/media/__tests__/image-models.test.ts +57 -0
  199. package/src/media/image-models.ts +66 -0
  200. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +38 -0
  201. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +12 -2
  202. package/src/memory/__tests__/memory-retrospective-job.test.ts +911 -34
  203. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +227 -5
  204. package/src/memory/__tests__/memory-retrospective-state.test.ts +195 -0
  205. package/src/memory/__tests__/preloaded-apps.test.ts +85 -0
  206. package/src/memory/auto-analysis-enqueue.ts +14 -1
  207. package/src/memory/compaction-log-store-clickhouse.ts +6 -4
  208. package/src/memory/conversation-crud.ts +9 -2
  209. package/src/memory/conversation-disk-view.ts +1 -1
  210. package/src/memory/conversation-queries.ts +22 -7
  211. package/src/memory/db-init.ts +20 -0
  212. package/src/memory/db-maintenance.ts +16 -0
  213. package/src/memory/embedding-runtime-manager.ts +1 -1
  214. package/src/memory/llm-request-log-source-clickhouse.ts +112 -14
  215. package/src/memory/llm-request-log-source-local.ts +19 -1
  216. package/src/memory/llm-request-log-source.ts +35 -6
  217. package/src/memory/llm-request-log-store.ts +90 -2
  218. package/src/memory/memory-retrospective-constants.ts +9 -0
  219. package/src/memory/memory-retrospective-enqueue.ts +3 -6
  220. package/src/memory/memory-retrospective-fork-boundary.ts +94 -0
  221. package/src/memory/memory-retrospective-job.ts +500 -208
  222. package/src/memory/memory-retrospective-startup-cleanup.ts +97 -19
  223. package/src/memory/memory-retrospective-state.ts +85 -2
  224. package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +40 -0
  225. package/src/memory/migrations/282-schedule-inference-profile.test.ts +77 -0
  226. package/src/memory/migrations/282-schedule-inference-profile.ts +26 -0
  227. package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +102 -0
  228. package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.ts +53 -0
  229. package/src/memory/migrations/284-workflow-runs.ts +51 -0
  230. package/src/memory/migrations/285-schedule-workflow-mode.ts +26 -0
  231. package/src/memory/migrations/286-workflow-run-trust.ts +27 -0
  232. package/src/memory/migrations/287-conversation-origin-channel-index.ts +15 -0
  233. package/src/memory/migrations/288-backfill-origin-channel-from-bindings.ts +43 -0
  234. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +115 -0
  235. package/src/memory/migrations/290-schedule-capabilities.test.ts +77 -0
  236. package/src/memory/migrations/290-schedule-capabilities.ts +25 -0
  237. package/src/memory/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +96 -0
  238. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +571 -0
  239. package/src/memory/migrations/index.ts +10 -0
  240. package/src/memory/preloaded-apps.ts +116 -0
  241. package/src/memory/schema/infrastructure.ts +4 -0
  242. package/src/memory/schema/memory-core.ts +4 -0
  243. package/src/memory/v2/__tests__/concept-page-frontmatter-schema.test.ts +45 -0
  244. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +11 -7
  245. package/src/memory/v2/__tests__/page-store.test.ts +13 -2
  246. package/src/memory/v2/__tests__/qdrant.test.ts +24 -0
  247. package/src/memory/v2/frontmatter-sweep.ts +7 -6
  248. package/src/memory/v2/page-store.ts +4 -3
  249. package/src/memory/v2/qdrant.ts +42 -3
  250. package/src/memory/v2/types.ts +16 -10
  251. package/src/messaging/draft-store.ts +1 -1
  252. package/src/notifications/access-request-copy.ts +200 -113
  253. package/src/notifications/adapters/slack.ts +250 -111
  254. package/src/notifications/adapters/telegram.ts +7 -44
  255. package/src/notifications/approval-card-builder.ts +93 -0
  256. package/src/notifications/broadcaster.ts +74 -0
  257. package/src/notifications/conversation-pairing.ts +8 -6
  258. package/src/notifications/copy-composer.ts +32 -26
  259. package/src/notifications/decision-engine.ts +59 -7
  260. package/src/notifications/guardian-question-mode.ts +145 -155
  261. package/src/notifications/home-feed-side-effect.ts +28 -11
  262. package/src/notifications/notification-utils.ts +66 -0
  263. package/src/notifications/signal.ts +6 -0
  264. package/src/notifications/tool-approval-copy.ts +142 -0
  265. package/src/notifications/types.ts +19 -0
  266. package/src/permissions/threshold.ts +11 -0
  267. package/src/plugin-api/types.ts +16 -4
  268. package/src/plugins/defaults/compaction/window-manager.ts +44 -0
  269. package/src/plugins/defaults/index.ts +46 -0
  270. package/src/plugins/defaults/max-tokens-continue/continue-state-store.ts +53 -0
  271. package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +80 -0
  272. package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +20 -0
  273. package/src/plugins/defaults/max-tokens-continue/package.json +14 -0
  274. package/src/plugins/defaults/memory-retrieval/hooks/__tests__/user-prompt-submit.test.ts +37 -0
  275. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +29 -1
  276. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +8 -3
  277. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +4 -2
  278. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +28 -18
  279. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +67 -0
  280. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +122 -22
  281. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +2 -0
  282. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +63 -1
  283. package/src/plugins/defaults/memory-v3-shadow/injector.ts +61 -18
  284. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +1 -1
  285. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +39 -10
  286. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +34 -1
  287. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +112 -47
  288. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +78 -15
  289. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +206 -0
  290. package/src/plugins/defaults/task-progress-nudge/package.json +15 -0
  291. package/src/prompts/__tests__/system-prompt.test.ts +100 -1
  292. package/src/prompts/__tests__/task-progress-hint-section.test.ts +5 -7
  293. package/src/prompts/normalize-onboarding.ts +2 -0
  294. package/src/prompts/persona-resolver.ts +3 -0
  295. package/src/prompts/system-prompt.ts +51 -2
  296. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +3 -1
  297. package/src/prompts/templates/system-sections.ts +8 -3
  298. package/src/providers/call-site-routing.ts +6 -3
  299. package/src/providers/fireworks/client.ts +3 -0
  300. package/src/providers/inference/auth.ts +52 -46
  301. package/src/providers/model-intents.ts +2 -2
  302. package/src/providers/openai/__tests__/coerce-object-args.test.ts +105 -0
  303. package/src/providers/openai/chat-completions-provider.ts +47 -9
  304. package/src/providers/openai/coerce-object-args.ts +104 -0
  305. package/src/providers/retry.ts +8 -5
  306. package/src/providers/types.ts +10 -0
  307. package/src/runtime/__tests__/agent-wake.test.ts +629 -7
  308. package/src/runtime/access-request-helper.ts +16 -9
  309. package/src/runtime/agent-wake.ts +302 -51
  310. package/src/runtime/assistant-stream-state.ts +141 -8
  311. package/src/runtime/background-job-runner.ts +9 -0
  312. package/src/runtime/channel-approval-types.ts +1 -0
  313. package/src/runtime/channel-invite-transports/telegram.ts +6 -5
  314. package/src/runtime/channel-invite-transports/voice.ts +2 -2
  315. package/src/runtime/channel-invite-types.ts +4 -2
  316. package/src/runtime/channel-retry-sweep.ts +19 -41
  317. package/src/runtime/finalize-event-delivery.ts +72 -0
  318. package/src/runtime/guardian-action-message-composer.ts +0 -54
  319. package/src/runtime/http-server.ts +6 -14
  320. package/src/runtime/http-types.ts +0 -1
  321. package/src/runtime/message-composer-types.ts +0 -9
  322. package/src/runtime/middleware/__tests__/rate-limiter.test.ts +63 -0
  323. package/src/runtime/middleware/auth.ts +27 -3
  324. package/src/runtime/middleware/rate-limiter.ts +28 -1
  325. package/src/runtime/migrations/vbundle-builder.ts +6 -5
  326. package/src/runtime/pending-interactions.ts +20 -1
  327. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +232 -173
  328. package/src/runtime/routes/__tests__/plugins-routes.test.ts +18 -0
  329. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +436 -0
  330. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +11 -0
  331. package/src/runtime/routes/approval-routes.ts +35 -8
  332. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -1
  333. package/src/runtime/routes/btw-routes.ts +37 -1
  334. package/src/runtime/routes/channel-delivery-routes.ts +11 -7
  335. package/src/runtime/routes/channel-route-definitions.ts +3 -0
  336. package/src/runtime/routes/channel-route-shared.ts +3 -1
  337. package/src/runtime/routes/consolidation-routes.ts +17 -13
  338. package/src/runtime/routes/conversation-compaction-routes.ts +159 -119
  339. package/src/runtime/routes/conversation-list-routes.ts +41 -4
  340. package/src/runtime/routes/conversation-query-routes.ts +196 -11
  341. package/src/runtime/routes/conversation-routes.ts +15 -1
  342. package/src/runtime/routes/credential-prompt-routes.ts +39 -17
  343. package/src/runtime/routes/empty-state-greeting-cache.ts +65 -0
  344. package/src/runtime/routes/heartbeat-routes.ts +18 -13
  345. package/src/runtime/routes/image-generation-routes.ts +20 -2
  346. package/src/runtime/routes/inbound-message-handler.ts +13 -12
  347. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +32 -31
  348. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +7 -5
  349. package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -21
  350. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  351. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +6 -15
  352. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
  353. package/src/runtime/routes/index.ts +6 -0
  354. package/src/runtime/routes/log-export/AGENTS.md +1 -1
  355. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  356. package/src/runtime/routes/migration-routes.ts +5 -9
  357. package/src/runtime/routes/plugins-routes.ts +26 -0
  358. package/src/runtime/routes/ps-routes.ts +10 -8
  359. package/src/runtime/routes/retrospective-routes.ts +235 -0
  360. package/src/runtime/routes/runs-pagination.ts +75 -0
  361. package/src/runtime/routes/schedule-routes.ts +367 -59
  362. package/src/runtime/routes/sounds-config-routes.ts +239 -0
  363. package/src/runtime/routes/surface-action-routes.ts +84 -4
  364. package/src/runtime/routes/workflow-routes.test.ts +372 -0
  365. package/src/runtime/routes/workflow-routes.ts +363 -0
  366. package/src/runtime/routes/workspace-routes.test.ts +61 -1
  367. package/src/runtime/routes/workspace-routes.ts +26 -1
  368. package/src/runtime/services/__tests__/analyze-conversation.test.ts +38 -0
  369. package/src/runtime/services/analyze-conversation.ts +26 -13
  370. package/src/schedule/inference-profile.ts +28 -0
  371. package/src/schedule/schedule-store.ts +152 -4
  372. package/src/schedule/scheduler-types.ts +6 -0
  373. package/src/schedule/scheduler.ts +96 -0
  374. package/src/security/secret-allowlist.ts +1 -1
  375. package/src/skills/path-classifier.ts +1 -1
  376. package/src/tools/apps/executors.ts +23 -0
  377. package/src/tools/apps/resolve-app-id.ts +42 -0
  378. package/src/tools/browser/browser-execution.ts +9 -11
  379. package/src/tools/credentials/broker.ts +4 -4
  380. package/src/tools/credentials/vault.ts +26 -137
  381. package/src/tools/executor.ts +69 -0
  382. package/src/tools/flag-gated-tools.test.ts +76 -0
  383. package/src/tools/permission-checker.ts +8 -1
  384. package/src/tools/registry.ts +51 -0
  385. package/src/tools/schedule/create.ts +77 -1
  386. package/src/tools/schedule/list.ts +1 -0
  387. package/src/tools/schedule/update.ts +73 -1
  388. package/src/tools/skills/execute.ts +56 -0
  389. package/src/tools/terminal/shell.ts +1 -1
  390. package/src/tools/ui-surface/definitions.ts +91 -2
  391. package/src/tools/workflows/manage-workflows.ts +183 -0
  392. package/src/tools/workflows/run-workflow.test.ts +442 -0
  393. package/src/tools/workflows/run-workflow.ts +88 -0
  394. package/src/types/onboarding-context.ts +2 -0
  395. package/src/usage/attribution.ts +24 -0
  396. package/src/util/canonicalize-identity.ts +12 -3
  397. package/src/util/platform.ts +17 -17
  398. package/src/watcher/__tests__/engine.test.ts +24 -0
  399. package/src/watcher/__tests__/telemetry.test.ts +135 -0
  400. package/src/watcher/engine.ts +7 -0
  401. package/src/watcher/telemetry.ts +74 -0
  402. package/src/workflows/capabilities.test.ts +365 -0
  403. package/src/workflows/capabilities.ts +359 -0
  404. package/src/workflows/deterministic-stringify.ts +27 -0
  405. package/src/workflows/engine-integration.test.ts +656 -0
  406. package/src/workflows/engine.test.ts +1144 -0
  407. package/src/workflows/engine.ts +1078 -0
  408. package/src/workflows/fanout-load.test.ts +168 -0
  409. package/src/workflows/journal-store.test.ts +369 -0
  410. package/src/workflows/journal-store.ts +470 -0
  411. package/src/workflows/leaf-runner.test.ts +704 -0
  412. package/src/workflows/leaf-runner.ts +589 -0
  413. package/src/workflows/library.test.ts +134 -0
  414. package/src/workflows/library.ts +124 -0
  415. package/src/workflows/run-manager.test.ts +711 -0
  416. package/src/workflows/run-manager.ts +593 -0
  417. package/src/workflows/sandbox-escape.test.ts +339 -0
  418. package/src/workflows/sandbox.test.ts +251 -0
  419. package/src/workflows/sandbox.ts +447 -0
  420. package/src/workspace/adaptive-thinking-repair.ts +33 -11
  421. package/src/workspace/migrations/021-move-signals-to-workspace.ts +1 -1
  422. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +1 -1
  423. package/src/workspace/migrations/026-backfill-install-meta.ts +1 -1
  424. package/src/workspace/migrations/030-seed-pkb-autoinject.ts +2 -1
  425. package/src/workspace/migrations/031-drop-user-md.ts +1 -4
  426. package/src/workspace/migrations/048-remove-workspace-hooks.ts +1 -1
  427. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +5 -2
  428. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +1 -1
  429. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +8 -2
  430. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +41 -14
  431. package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +69 -0
  432. package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +83 -0
  433. package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +133 -0
  434. package/src/workspace/migrations/registry.ts +6 -0
  435. package/src/workspace/migrations/runner.ts +1 -1
  436. package/tsconfig.json +1 -1
  437. package/src/__tests__/guardian-action-copy-generator.test.ts +0 -200
  438. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -579
  439. package/src/__tests__/guardian-action-store.test.ts +0 -106
  440. package/src/daemon/guardian-action-generators.ts +0 -71
  441. package/src/memory/guardian-action-store.ts +0 -484
  442. package/src/runtime/guardian-action-grant-minter.ts +0 -150
@@ -486,14 +486,14 @@ The proxy subsystem is fully wired, including credential injection. The session
486
486
 
487
487
  ## Conversation Disk View — Filesystem-Based Conversation Access
488
488
 
489
- The conversation disk view projects conversation metadata, messages, and attachments to a browsable filesystem layout under `~/.vellum/workspace/conversations/`. This enables the assistant to search, read, and manipulate conversation data (including media attachments) using standard file tools (`read_file`, `glob`, `grep`) rather than dedicated asset search tools.
489
+ The conversation disk view projects conversation metadata, messages, and attachments to a browsable filesystem layout under `$VELLUM_WORKSPACE_DIR/conversations/`. This enables the assistant to search, read, and manipulate conversation data (including media attachments) using standard file tools (`read_file`, `glob`, `grep`) rather than dedicated asset search tools.
490
490
 
491
491
  ### Directory Layout
492
492
 
493
493
  Each conversation is projected to a directory named `{isoDate}_{id}`:
494
494
 
495
495
  ```
496
- ~/.vellum/workspace/conversations/
496
+ $VELLUM_WORKSPACE_DIR/conversations/
497
497
  2025-01-15T10-30-00.000Z_abc123/
498
498
  meta.json # Conversation metadata (id, title, type, channel, timestamps)
499
499
  messages.jsonl # Flattened message log (one JSON object per line)
@@ -506,7 +506,7 @@ Each conversation is projected to a directory named `{isoDate}_{id}`:
506
506
 
507
507
  The disk view is updated at the daemon level, not automatically by the DB CRUD layer. Conversation creation, metadata updates, and deletion are synced from `conversation-crud.ts`, but message sync (`syncMessageToDisk`) is only called from daemon-level code paths (e.g. `conversation-messaging.ts`) — not from the CRUD `addMessage()` function. This means `messages.jsonl` reflects messages processed through the daemon's messaging pipeline, not every message write. All disk writes are best-effort; failures are logged but never thrown, so the disk view cannot break DB operations.
508
508
 
509
- > **Privacy note:** Conversation disk-view files live under `~/.vellum/workspace/conversations/`. Workspace files are not included in diagnostic log exports ("Send logs to Vellum"). For conversation-scoped exports, conversation data is included as structured JSON tables (e.g. `messages.json`, `llm-request-logs.json`), not as a raw database dump.
509
+ > **Privacy note:** Conversation disk-view files live under `$VELLUM_WORKSPACE_DIR/conversations/`. Workspace files are not included in diagnostic log exports ("Send logs to Vellum"). For conversation-scoped exports, conversation data is included as structured JSON tables (e.g. `messages.json`, `llm-request-logs.json`), not as a raw database dump.
510
510
 
511
511
  ```mermaid
512
512
  sequenceDiagram
@@ -445,7 +445,7 @@ graph TB
445
445
 
446
446
  ### Key design decisions
447
447
 
448
- - **Scope**: Sandbox workspace only (`~/.vellum/workspace`). Non-recursive — only top-level directories.
448
+ - **Scope**: Sandbox workspace only (`$VELLUM_WORKSPACE_DIR`). Non-recursive — only top-level directories.
449
449
  - **Bounded**: Maximum 120 directory entries (`MAX_TOP_LEVEL_ENTRIES`). Excess is truncated with a note.
450
450
  - **Prepend, not append**: The workspace block is prepended to the user message content so that Anthropic cache breakpoints continue to land on the trailing user text block, preserving prompt cache efficiency.
451
451
  - **Persists in history**: The injected `<workspace>` block persists in conversation history, giving the model workspace grounding across turns. Legacy `<workspace_top_level>` blocks from pre-change history are stripped for backward compatibility.
@@ -512,7 +512,7 @@ graph TB
512
512
 
513
513
  ## Workspace Git Tracking — Change Management
514
514
 
515
- The workspace sandbox (`~/.vellum/workspace`) is automatically tracked by a per-workspace git repository. Every file change made by the assistant is captured in structured commits, providing a full audit trail and natural undo/history exploration via standard git commands.
515
+ The workspace sandbox (`$VELLUM_WORKSPACE_DIR`) is automatically tracked by a per-workspace git repository. Every file change made by the assistant is captured in structured commits, providing a full audit trail and natural undo/history exploration via standard git commands.
516
516
 
517
517
  ### Architecture overview
518
518
 
@@ -94,13 +94,13 @@ When `autoApproveUpTo` is `"none"`, `skill_load` without a matching rule is alwa
94
94
 
95
95
  Skills that use existing system tools (`bash`, `file_read`, `web_fetch`, etc.) **do not expand the assistant's capability surface**. The assistant already has access to these tools based on its trust rules; a skill that teaches `curl https://api.example.com/v1/endpoint -d "..."` presents identical risk to a user asking the assistant to run that same command directly. The risk is governed entirely by the bash risk classifier and the user's `autoApproveUpTo` threshold — the same path as any other bash invocation.
96
96
 
97
- The threat vectors that skills *do* introduce are:
97
+ The threat vectors that skills _do_ introduce are:
98
98
 
99
- | Threat | Mitigation |
100
- |---|---|
99
+ | Threat | Mitigation |
100
+ | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
101
101
  | **Skill source file mutations** — editing a skill's own source files could inject behavior on next load | `isSkillSourcePath()` escalates `file_write`/`file_edit` targeting skill roots to **High**, requiring explicit approval |
102
- | **New skill-origin tools** — tools registered and invoked through the skill IPC contract | Skill-origin tools with no matching trust rule are always **prompted**, regardless of their risk level |
103
- | **Credential storage** — a skill collecting and storing an API key | Mediated by the `credential_store` approval flow |
102
+ | **New skill-origin tools** — tools registered and invoked through the skill IPC contract | Skill-origin tools with no matching trust rule are always **prompted**, regardless of their risk level |
103
+ | **Credential storage** — a skill collecting and storing an API key | Mediated by the secure credential prompt flow (`assistant credentials prompt`) |
104
104
 
105
105
  What skills do **not** introduce:
106
106
 
@@ -278,11 +278,11 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
278
278
 
279
279
  ### Storage Layout
280
280
 
281
- | Component | Location | What it stores |
282
- | ------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
283
- | Secret values | CES credential store or encrypted file store | Encrypted credential values keyed as `credential/{service}/{field}`. Stored via CES RPC (primary), CES HTTP (containerized), or encrypted file store (fallback). |
284
- | Credential metadata | `~/.vellum/workspace/data/credentials/metadata.json` | Service, field, label, policy (allowedTools, allowedDomains), timestamps |
285
- | Config | `~/.vellum/workspace/config.*` | `secretDetection` settings: enabled, blockIngress, allowOneTimeSend |
281
+ | Component | Location | What it stores |
282
+ | ------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
283
+ | Secret values | CES credential store or encrypted file store | Encrypted credential values keyed as `credential/{service}/{field}`. Stored via CES RPC (primary), CES HTTP (containerized), or encrypted file store (fallback). |
284
+ | Credential metadata | `$VELLUM_WORKSPACE_DIR/data/credentials/metadata.json` | Service, field, label, policy (allowedTools, allowedDomains), timestamps |
285
+ | Config | `$VELLUM_WORKSPACE_DIR/config.*` | `secretDetection` settings: enabled, blockIngress, allowOneTimeSend |
286
286
 
287
287
  ### Key Files
288
288
 
@@ -90,7 +90,7 @@ Access requests are stored in the `channel_guardian_approval_requests` table. Us
90
90
  ### Via SQLite CLI
91
91
 
92
92
  ```bash
93
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
93
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
94
94
  "SELECT id, channel, requester_external_user_id, requester_chat_id, \
95
95
  guardian_external_user_id, status, tool_name, created_at, expires_at \
96
96
  FROM channel_guardian_approval_requests \
@@ -101,7 +101,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
101
101
  ### Check all access requests (including resolved)
102
102
 
103
103
  ```bash
104
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
104
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
105
105
  "SELECT id, channel, requester_external_user_id, status, \
106
106
  decided_by_external_user_id, created_at \
107
107
  FROM channel_guardian_approval_requests \
@@ -114,7 +114,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
114
114
  Verification challenges are stored in `channel_verification_sessions`. Active sessions have `status = 'awaiting_response'` and `expires_at > now`.
115
115
 
116
116
  ```bash
117
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
117
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
118
118
  "SELECT id, channel, status, identity_binding_status, \
119
119
  expected_external_user_id, expected_chat_id, expected_phone_e164, \
120
120
  expires_at, created_at \
@@ -158,7 +158,7 @@ curl -s -X PATCH "$BASE/v1/contact-channels/$CHANNEL_ID" \
158
158
  If the HTTP API is unavailable:
159
159
 
160
160
  ```bash
161
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
161
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
162
162
  "UPDATE contact_channels \
163
163
  SET status = 'revoked', revoked_reason = 'Emergency operator revocation', \
164
164
  updated_at = $(date +%s)000 \
@@ -172,7 +172,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
172
172
  If a user is getting "invalid or expired code" errors, they may be rate-limited:
173
173
 
174
174
  ```bash
175
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
175
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
176
176
  "SELECT * FROM channel_guardian_rate_limits \
177
177
  WHERE external_user_id = 'TARGET_USER_ID' \
178
178
  OR chat_id = 'TARGET_CHAT_ID' \
@@ -182,7 +182,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
182
182
  ### Reset rate limits for a user
183
183
 
184
184
  ```bash
185
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
185
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
186
186
  "DELETE FROM channel_guardian_rate_limits \
187
187
  WHERE external_user_id = 'TARGET_USER_ID' AND channel = 'telegram';"
188
188
  ```
@@ -190,7 +190,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
190
190
  ### Check verification challenge state
191
191
 
192
192
  ```bash
193
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
193
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
194
194
  "SELECT id, channel, status, identity_binding_status, \
195
195
  expected_external_user_id, expected_chat_id, expected_phone_e164, \
196
196
  expires_at, consumed_by_external_user_id \
@@ -215,7 +215,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
215
215
  ### Check if the access request notification was delivered
216
216
 
217
217
  ```bash
218
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
218
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
219
219
  "SELECT ne.id, ne.source_event_name, ne.dedupe_key, ne.created_at, \
220
220
  nd.channel, nd.status, nd.confidence \
221
221
  FROM notification_events ne \
@@ -227,7 +227,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
227
227
  ### Check delivery records
228
228
 
229
229
  ```bash
230
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
230
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
231
231
  "SELECT ndel.id, ndel.channel, ndel.status, ndel.error_message, \
232
232
  ndel.created_at, ne.source_event_name \
233
233
  FROM notification_deliveries ndel \
@@ -239,7 +239,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
239
239
  ### Check lifecycle signals
240
240
 
241
241
  ```bash
242
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
242
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
243
243
  "SELECT source_event_name, source_channel, dedupe_key, created_at \
244
244
  FROM notification_events \
245
245
  WHERE source_event_name LIKE 'ingress.trusted_contact.%' \
@@ -295,7 +295,7 @@ curl -s -X POST "$BASE/v1/contacts" \
295
295
  Expired sessions are already invisible to the verification flow (filtered by `expires_at`), but you can clean them up:
296
296
 
297
297
  ```bash
298
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
298
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
299
299
  "DELETE FROM channel_verification_sessions \
300
300
  WHERE expires_at < $(date +%s)000 \
301
301
  AND status IN ('awaiting_response', 'pending_bootstrap');"
@@ -306,7 +306,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
306
306
  The `sweepExpiredGuardianApprovals()` timer handles this automatically every 60 seconds, but manual cleanup:
307
307
 
308
308
  ```bash
309
- sqlite3 ~/.vellum/workspace/data/db/assistant.db \
309
+ sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
310
310
  "UPDATE channel_guardian_approval_requests \
311
311
  SET status = 'expired' \
312
312
  WHERE status = 'pending' AND expires_at < $(date +%s)000;"
package/docs/skills.md CHANGED
@@ -6,7 +6,7 @@ This document describes the security model for the Vellum Assistant skill system
6
6
 
7
7
  Skills extend the assistant's capabilities by providing instructions (via `SKILL.md`) and optional custom tools (via `TOOLS.json`). Skills can be **bundled** (shipped with the application), **managed** (user-installed via `scaffold_managed_skill`), **workspace** (project-local), or **extra** (additional directories configured by the user).
8
8
 
9
- For managed skills, the installed source of truth is a valid directory at `~/.vellum/workspace/skills/<id>/` containing a top-level `SKILL.md` with standardized frontmatter. The assistant parses that frontmatter at startup and when skill directories change, then seeds Memory V2 skill entries under `skills/<id>` so the assistant can discover available skills from memory. The legacy `SKILLS.md` index is removed by workspace migration and is no longer created by install or scaffold paths.
9
+ For managed skills, the installed source of truth is a valid directory at `$VELLUM_WORKSPACE_DIR/skills/<id>/` containing a top-level `SKILL.md` with standardized frontmatter. The assistant parses that frontmatter at startup and when skill directories change, then seeds Memory V2 skill entries under `skills/<id>` so the assistant can discover available skills from memory. The legacy `SKILLS.md` index is removed by workspace migration and is no longer created by install or scaffold paths.
10
10
 
11
11
  Because skills can introduce arbitrary tool behavior, they are subject to stricter permission defaults than core tools.
12
12
 
@@ -70,7 +70,7 @@ Version-specific rules are more secure but require re-approval after every skill
70
70
 
71
71
  Writing to skill source files is treated as a **high-risk** operation by the risk classifier. The `isSkillSourcePath()` function detects whether a file path falls under any known skill directory:
72
72
 
73
- - **Managed skills**: `~/.vellum/workspace/skills/`
73
+ - **Managed skills**: `$VELLUM_WORKSPACE_DIR/skills/`
74
74
  - **Bundled skills**: The application's built-in `bundled-skills/` directory
75
75
  - **Workspace skills**: Project-local skill directories
76
76
  - **Extra skills**: Additional roots configured by the user
@@ -116,10 +116,10 @@ Acceptance is idempotent and recorded in `trust.json`. The bundle does not inclu
116
116
 
117
117
  Tools can execute in two contexts:
118
118
 
119
- | Target | Description |
120
- | --------- | -------------------------------------------------------------------------------------- |
121
- | `sandbox` | Isolated execution within `~/.vellum/workspace` (Docker container or OS-level sandbox) |
122
- | `host` | Direct execution on the host machine |
119
+ | Target | Description |
120
+ | --------- | ---------------------------------------------------------------------------------------- |
121
+ | `sandbox` | Isolated execution within `$VELLUM_WORKSPACE_DIR` (Docker container or OS-level sandbox) |
122
+ | `host` | Direct execution on the host machine |
123
123
 
124
124
  Trust rules can include an `executionTarget` field to bind the rule to a specific context. A rule without `executionTarget` matches both sandbox and host invocations.
125
125
 
@@ -0,0 +1,221 @@
1
+ # Workflows — Manual e2e / Live-Verification Runbook
2
+
3
+ This runbook covers the parts of the workflow engine that automated tests do not:
4
+ real provider calls, real journaled resume across a restart, capability
5
+ containment under a live model, flag-off inertness, and persona-leaf voice. Unit
6
+ and integration coverage lives under `assistant/src/workflows/*.test.ts` and
7
+ `assistant/src/__tests__/`; this is the human-in-the-loop pass that runs **last**,
8
+ on throwaway instances first, and only touches a real inbox or a production
9
+ instance at the very end.
10
+
11
+ Work through the steps in order. The `workflows` flag is **off by default**, so
12
+ every step that exercises the engine first enables it on a throwaway instance.
13
+
14
+ > **Safety rule:** Nothing in this runbook touches a real inbox, a real workspace,
15
+ > or a production instance until every throwaway-instance step has passed. The
16
+ > production/persona instance is the **last** step.
17
+
18
+ ---
19
+
20
+ ## 1. Hatch a throwaway instance and enable the flag
21
+
22
+ Hatch a disposable Docker instance built from local source:
23
+
24
+ ```
25
+ vellum hatch --remote docker --source .
26
+ ```
27
+
28
+ Note the instance name it prints (e.g. `vellum-<adjective>-<animal>`). Use it as
29
+ `--assistant <name>` for everything below, or set it active.
30
+
31
+ Enable the `workflows` flag via that instance's feature-flag override file. The
32
+ override lives in the instance's `protected/feature-flags.json` (overrides here
33
+ win over the registry default — see the feature-flag-overrides gotcha):
34
+
35
+ ```jsonc
36
+ // .../<instance>/protected/feature-flags.json
37
+ { "workflows": true }
38
+ ```
39
+
40
+ Restart the instance so it re-reads the override, then confirm it is up:
41
+
42
+ ```
43
+ vellum ps
44
+ ```
45
+
46
+ Sanity-check that the surface is now live: `vellum workflows runs --assistant <name>`
47
+ should return an (empty) table rather than a 404.
48
+
49
+ ---
50
+
51
+ ## 2. Synthetic-corpus run (no Gmail/Slack dependency)
52
+
53
+ Drive a `run_workflow` over a **fixture item list passed as `args`** — no external
54
+ integration. Ask the assistant (via `vellum events`-visible conversation, the app,
55
+ or a CLI message) to run a small workflow such as the triage example from
56
+ [`workflows.md`](./workflows.md), passing a dozen synthetic items in `args.items`.
57
+
58
+ Watch the run:
59
+
60
+ ```
61
+ vellum workflows runs --assistant <name> # find the runId
62
+ vellum workflows show <run-id> --assistant <name> # status + agent/token counts
63
+ vellum events --assistant <name> # workflow_progress / workflow_completed
64
+ ```
65
+
66
+ Confirm:
67
+
68
+ - The run reaches `completed`.
69
+ - `agentsSpawned` matches the number of leaves the script should have launched.
70
+ - A completion summary is injected back into the originating conversation.
71
+
72
+ ---
73
+
74
+ ## 3. Inspect the evidence
75
+
76
+ Query the instance's database directly (the live DB is under the instance's
77
+ `workspace/data/db/assistant.db`).
78
+
79
+ **Leaf cost attribution** — confirm leaves ran on the cost-optimized model and
80
+ tally spend:
81
+
82
+ ```sql
83
+ SELECT model, COUNT(*) AS calls,
84
+ SUM(input_tokens) AS in_tok,
85
+ SUM(output_tokens) AS out_tok,
86
+ SUM(estimated_cost_usd) AS usd
87
+ FROM llm_usage_events
88
+ WHERE call_site = 'workflowLeaf'
89
+ GROUP BY model;
90
+ ```
91
+
92
+ **Request shape** — confirm the schema path forced a tool and used a cheap model;
93
+ for persona leaves, confirm identity + memory were injected:
94
+
95
+ ```sql
96
+ SELECT id, created_at
97
+ FROM llm_request_logs
98
+ ORDER BY created_at DESC
99
+ LIMIT 20;
100
+ ```
101
+
102
+ Inspect a few `request_payload` bodies:
103
+
104
+ - A **schema** leaf request carries `tool_choice` forcing the synthetic
105
+ `emit_result` tool and a cheap model id.
106
+ - A **persona** leaf request's system prompt carries the assistant identity and a
107
+ `<memory>` block; an **anonymous** leaf's does not.
108
+
109
+ ---
110
+
111
+ ## 4. Restart-resume (journal replay)
112
+
113
+ Start a **long** synthetic run (enough leaves that it is still in flight for a few
114
+ seconds). While it is running, restart the assistant with **SIGTERM**:
115
+
116
+ > **Never SIGKILL the assistant.** SIGKILL leaves WAL pages unmerged and forces a
117
+ > costly recovery on the next start (and can corrupt an in-flight run). Use a
118
+ > graceful stop / `vellum sleep` / SIGTERM with grace.
119
+
120
+ After restart, the run that was in flight when the process stopped is no longer
121
+ `running` — at startup the assistant reconciles every orphaned `running` row to
122
+ `interrupted` (status only; the accounting counters are preserved). Resume is
123
+ **not automatic**. Confirm the run shows up as interrupted, then trigger an
124
+ explicit resume:
125
+
126
+ ```bash
127
+ # The crashed run is now interrupted, not running.
128
+ vellum workflows runs --status interrupted
129
+
130
+ # Trigger the resume (or: manage_workflows with action="resume" from chat).
131
+ vellum workflows resume <run-id>
132
+ ```
133
+
134
+ Resuming re-invokes the engine with the **same `runId`**, so the completed prefix
135
+ replays from the journal. Assert:
136
+
137
+ - Resuming does **not** double the `agentsSpawned` count or the
138
+ `llm_usage_events` rows for `call_site = 'workflowLeaf'` — the completed prefix
139
+ replays from the journal rather than re-spawning leaves. The agent count
140
+ **carries** across the restart (it seeds from the persisted run row) instead of
141
+ resetting to zero.
142
+ - Only leaves that had not completed before the restart produce new usage rows.
143
+ - The run transitions `interrupted` → `running` → a terminal status.
144
+
145
+ ```sql
146
+ -- Before and after the resume, this count should not grow for already-done leaves.
147
+ SELECT COUNT(*) FROM llm_usage_events WHERE call_site = 'workflowLeaf';
148
+
149
+ -- The journal holds one row per completed (run_id, seq); resuming does not duplicate them.
150
+ SELECT run_id, COUNT(*) FROM workflow_journal GROUP BY run_id;
151
+ ```
152
+
153
+ ---
154
+
155
+ ## 5. Capability containment
156
+
157
+ Author a workflow whose leaf tries to use a **side-effecting tool that is absent
158
+ from its manifest** (e.g. a leaf prompt that pushes the model toward `file_write`
159
+ or a send tool, with `capabilities.tools` left empty). Run it and confirm:
160
+
161
+ - The forbidden tool invocation is **hard-denied** inside the leaf — it never
162
+ executes. The leaf gets an error result, not a permission prompt (there are no
163
+ per-call prompts inside a run).
164
+ - Declaring a **forbidden** tool (`subagent_spawn`, `run_workflow`,
165
+ `manage_workflows`, `manage_secure_command_tool`) in `capabilities.tools` fails
166
+ the run synchronously at start — `run_workflow` returns an error and **no**
167
+ `running` row is created.
168
+
169
+ ---
170
+
171
+ ## 6. Flag-off inertness
172
+
173
+ On a **default** instance (no `workflows` override, or set back to `false` and
174
+ restart), confirm the whole surface is gone:
175
+
176
+ - `run_workflow` and `manage_workflows` are **absent** from the tool set (the
177
+ assistant cannot call them).
178
+ - The routes 404:
179
+
180
+ ```
181
+ vellum workflows runs --assistant <default-instance> # request fails (404)
182
+ ```
183
+
184
+ - A scheduler `workflow`-mode job is **rejected** (the engine gate throws before
185
+ any run is launched).
186
+
187
+ ---
188
+
189
+ ## 7. Real-data smoke (throwaway TEST account)
190
+
191
+ Only after steps 1–6 pass: run the full path against a **throwaway TEST Google or
192
+ Slack account** with about a dozen messages — never a real account. Drive the
193
+ end-to-end flow:
194
+
195
+ 1. The assistant enumerates the relevant skill (e.g. `gmail`).
196
+ 2. It authors and launches a `run_workflow` over the real messages.
197
+ 3. Leaves synthesize results.
198
+ 4. Any side-effecting action (label, draft, reply) goes through the declared
199
+ capability manifest and the normal audited-action path.
200
+
201
+ Confirm the run completes, the evidence queries from step 3 look right against
202
+ real content, and every side effect was one the manifest declared.
203
+
204
+ ---
205
+
206
+ ## 8. Production / persona instance — LAST
207
+
208
+ Flip the `workflows` flag on a real (e.g. persona) instance **only after** the
209
+ throwaway instances above pass, and only after the instance is on current code:
210
+
211
+ 1. `git pull` and **restart** the instance so it runs the merged code (a restart
212
+ alone re-runs stale code — see the deploy gotcha).
213
+ 2. Enable the flag and restart.
214
+ 3. Start with the **smallest real slice** — a few items, dry-run actions where the
215
+ tool supports it — before any larger or side-effecting run.
216
+ 4. **Human-eval the persona-leaf voice**: read a persona leaf's output and confirm
217
+ it reads as the assistant, not as a generic worker.
218
+
219
+ Stop and reassess if any run's `agentsSpawned` approaches `maxAgentsPerRun`, if
220
+ spend (step 3 query) is higher than expected, or if any side effect was not one
221
+ the manifest declared.