@vellumai/assistant 0.5.16 → 0.6.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 (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  mock.module("../util/logger.js", () => ({
4
4
  getLogger: () =>
@@ -22,7 +22,7 @@ mock.module("../tools/registry.js", () => ({
22
22
 
23
23
  import type { Database } from "bun:sqlite";
24
24
 
25
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
25
+ import { getDb, initializeDb } from "../memory/db.js";
26
26
  import { renderTemplate } from "../tasks/task-runner.js";
27
27
  import {
28
28
  createTask,
@@ -58,10 +58,6 @@ import {
58
58
 
59
59
  initializeDb();
60
60
 
61
- afterAll(() => {
62
- resetDb();
63
- });
64
-
65
61
  const ctx: ToolContext = {
66
62
  workingDir: "/tmp",
67
63
  conversationId: "test-conversation",
@@ -1,12 +1,4 @@
1
- import {
2
- afterAll,
3
- beforeAll,
4
- beforeEach,
5
- describe,
6
- expect,
7
- mock,
8
- test,
9
- } from "bun:test";
1
+ import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
10
2
 
11
3
  import { eq } from "drizzle-orm";
12
4
 
@@ -47,14 +39,13 @@ mock.module("../config/loader.js", () => ({
47
39
  invalidateConfigCache: () => {},
48
40
  }));
49
41
 
50
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
42
+ import { getDb, initializeDb } from "../memory/db.js";
51
43
  import { enqueueMemoryJob } from "../memory/jobs-store.js";
52
44
  import {
53
45
  conversations,
54
46
  cronJobs,
55
47
  cronRuns,
56
- memoryItems,
57
- memoryItemSources,
48
+ memoryGraphNodes,
58
49
  memoryJobs,
59
50
  messages,
60
51
  taskRuns,
@@ -65,6 +56,9 @@ import {
65
56
  isConversationFailed,
66
57
  } from "../memory/task-memory-cleanup.js";
67
58
 
59
+ const DEFAULT_EMOTIONAL_CHARGE =
60
+ '{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}';
61
+
68
62
  describe("invalidateAssistantInferredItemsForConversation", () => {
69
63
  const now = 1_701_100_000_000;
70
64
  const convId = "conv-task-cleanup";
@@ -76,8 +70,7 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
76
70
 
77
71
  beforeEach(() => {
78
72
  const db = getDb();
79
- db.run("DELETE FROM memory_item_sources");
80
- db.run("DELETE FROM memory_items");
73
+ db.run("DELETE FROM memory_graph_nodes");
81
74
  db.run("DELETE FROM memory_jobs");
82
75
  db.run("DELETE FROM messages");
83
76
  db.run("DELETE FROM cron_runs");
@@ -87,10 +80,6 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
87
80
  db.run("DELETE FROM conversations");
88
81
  });
89
82
 
90
- afterAll(() => {
91
- resetDb();
92
- });
93
-
94
83
  function seedConversations() {
95
84
  const db = getDb();
96
85
  for (const id of [convId, otherConvId]) {
@@ -140,165 +129,161 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
140
129
  .run();
141
130
  }
142
131
 
143
- function seedMemoryItems() {
132
+ function seedMemoryGraphNodes() {
144
133
  const db = getDb();
145
- db.insert(memoryItems)
134
+ db.insert(memoryGraphNodes)
146
135
  .values([
147
136
  {
148
137
  id: "item-assistant-inferred",
149
- kind: "fact",
150
- subject: "DMV appointment",
151
- statement: "Booked a DMV appointment at 9 AM.",
152
- status: "active",
138
+ content: "DMV appointment\nBooked a DMV appointment at 9 AM.",
139
+ type: "semantic",
140
+ created: now + 10,
141
+ lastAccessed: now + 10,
142
+ lastConsolidated: now + 10,
143
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
144
+ fidelity: "vivid",
153
145
  confidence: 0.8,
154
- importance: 0.7,
155
- fingerprint: "fp-assistant-inferred",
156
- verificationState: "assistant_inferred",
157
- sourceType: "extraction",
158
- sourceMessageRole: "assistant",
146
+ significance: 0.7,
147
+ stability: 14,
148
+ reinforcementCount: 0,
149
+ lastReinforced: now + 10,
150
+ sourceConversations: JSON.stringify([convId]),
151
+ sourceType: "inferred",
152
+ narrativeRole: null,
153
+ partOfStory: null,
159
154
  scopeId: "default",
160
- firstSeenAt: now + 10,
161
- lastSeenAt: now + 10,
162
155
  },
163
156
  {
164
157
  id: "item-user-reported",
165
- kind: "preference",
166
- subject: "notification pref",
167
- statement: "User prefers email notifications.",
168
- status: "active",
158
+ content: "notification pref\nUser prefers email notifications.",
159
+ type: "semantic",
160
+ created: now + 20,
161
+ lastAccessed: now + 20,
162
+ lastConsolidated: now + 20,
163
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
164
+ fidelity: "vivid",
169
165
  confidence: 0.9,
170
- importance: 0.8,
171
- fingerprint: "fp-user-reported",
172
- verificationState: "user_reported",
173
- sourceType: "extraction",
174
- sourceMessageRole: "user",
166
+ significance: 0.8,
167
+ stability: 14,
168
+ reinforcementCount: 0,
169
+ lastReinforced: now + 20,
170
+ sourceConversations: JSON.stringify([convId]),
171
+ sourceType: "direct",
172
+ narrativeRole: null,
173
+ partOfStory: null,
175
174
  scopeId: "default",
176
- firstSeenAt: now + 20,
177
- lastSeenAt: now + 20,
178
175
  },
179
176
  {
180
177
  id: "item-other-conv",
181
- kind: "fact",
182
- subject: "weather check",
183
- statement: "Checked weather for tomorrow.",
184
- status: "active",
178
+ content: "weather check\nChecked weather for tomorrow.",
179
+ type: "semantic",
180
+ created: now + 30,
181
+ lastAccessed: now + 30,
182
+ lastConsolidated: now + 30,
183
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
184
+ fidelity: "vivid",
185
185
  confidence: 0.7,
186
- importance: 0.5,
187
- fingerprint: "fp-other-conv",
188
- verificationState: "assistant_inferred",
189
- sourceType: "extraction",
190
- sourceMessageRole: "assistant",
186
+ significance: 0.5,
187
+ stability: 14,
188
+ reinforcementCount: 0,
189
+ lastReinforced: now + 30,
190
+ sourceConversations: JSON.stringify([otherConvId]),
191
+ sourceType: "inferred",
192
+ narrativeRole: null,
193
+ partOfStory: null,
191
194
  scopeId: "default",
192
- firstSeenAt: now + 30,
193
- lastSeenAt: now + 30,
194
195
  },
195
196
  {
196
- id: "item-already-superseded",
197
- kind: "fact",
198
- subject: "old claim",
199
- statement: "Old assistant claim already superseded.",
200
- status: "superseded",
197
+ id: "item-already-gone",
198
+ content: "old claim\nOld assistant claim already gone.",
199
+ type: "semantic",
200
+ created: now + 5,
201
+ lastAccessed: now + 5,
202
+ lastConsolidated: now + 5,
203
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
204
+ fidelity: "gone",
201
205
  confidence: 0.6,
202
- importance: 0.4,
203
- fingerprint: "fp-already-superseded",
204
- verificationState: "assistant_inferred",
205
- sourceType: "extraction",
206
- sourceMessageRole: "assistant",
206
+ significance: 0.4,
207
+ stability: 14,
208
+ reinforcementCount: 0,
209
+ lastReinforced: now + 5,
210
+ sourceConversations: JSON.stringify([convId]),
211
+ sourceType: "inferred",
212
+ narrativeRole: null,
213
+ partOfStory: null,
207
214
  scopeId: "default",
208
- firstSeenAt: now + 5,
209
- lastSeenAt: now + 5,
210
- },
211
- ])
212
- .run();
213
-
214
- db.insert(memoryItemSources)
215
- .values([
216
- {
217
- memoryItemId: "item-assistant-inferred",
218
- messageId: "msg-task-1",
219
- evidence: "booking claim",
220
- createdAt: now + 10,
221
- },
222
- {
223
- memoryItemId: "item-user-reported",
224
- messageId: "msg-task-2",
225
- evidence: "user stated",
226
- createdAt: now + 20,
227
- },
228
- {
229
- memoryItemId: "item-other-conv",
230
- messageId: "msg-other",
231
- evidence: "weather",
232
- createdAt: now + 30,
233
- },
234
- {
235
- memoryItemId: "item-already-superseded",
236
- messageId: "msg-task-1",
237
- evidence: "old claim",
238
- createdAt: now + 5,
239
215
  },
240
216
  ])
241
217
  .run();
242
218
  }
243
219
 
244
- test("only invalidates assistant_inferred items, not user_reported", () => {
220
+ test("only invalidates inferred items, not direct (user-reported)", () => {
245
221
  seedConversations();
246
222
  seedMessages();
247
- seedMemoryItems();
223
+ seedMemoryGraphNodes();
248
224
 
249
225
  const affected = invalidateAssistantInferredItemsForConversation(convId);
250
226
 
251
227
  expect(affected).toBe(1);
252
228
 
253
229
  const db = getDb();
254
- const assistantItem = db
230
+ const inferredItem = db
255
231
  .select()
256
- .from(memoryItems)
257
- .where(eq(memoryItems.id, "item-assistant-inferred"))
232
+ .from(memoryGraphNodes)
233
+ .where(eq(memoryGraphNodes.id, "item-assistant-inferred"))
258
234
  .get();
259
- expect(assistantItem?.status).toBe("invalidated");
260
- expect(assistantItem?.invalidAt).not.toBeNull();
235
+ expect(inferredItem?.fidelity).toBe("gone");
261
236
 
262
- const userItem = db
237
+ const directItem = db
263
238
  .select()
264
- .from(memoryItems)
265
- .where(eq(memoryItems.id, "item-user-reported"))
239
+ .from(memoryGraphNodes)
240
+ .where(eq(memoryGraphNodes.id, "item-user-reported"))
266
241
  .get();
267
- expect(userItem?.status).toBe("active");
268
- expect(userItem?.invalidAt).toBeNull();
242
+ expect(directItem?.fidelity).toBe("vivid");
269
243
  });
270
244
 
271
245
  test("does not affect items from other conversations", () => {
272
246
  seedConversations();
273
247
  seedMessages();
274
- seedMemoryItems();
248
+ seedMemoryGraphNodes();
275
249
 
276
250
  invalidateAssistantInferredItemsForConversation(convId);
277
251
 
278
252
  const db = getDb();
279
253
  const otherItem = db
280
254
  .select()
281
- .from(memoryItems)
282
- .where(eq(memoryItems.id, "item-other-conv"))
255
+ .from(memoryGraphNodes)
256
+ .where(eq(memoryGraphNodes.id, "item-other-conv"))
283
257
  .get();
284
- expect(otherItem?.status).toBe("active");
285
- expect(otherItem?.invalidAt).toBeNull();
258
+ expect(otherItem?.fidelity).toBe("vivid");
286
259
  });
287
260
 
288
261
  test("does not invalidate items also sourced from another conversation", () => {
289
262
  seedConversations();
290
263
  seedMessages();
291
- seedMemoryItems();
292
264
 
293
- // Add a second source from the other conversation to the assistant-inferred item.
294
- // This simulates deduplication: the same fact was extracted from both conversations.
265
+ // Insert a node sourced from both conversations (corroboration).
295
266
  const db = getDb();
296
- db.insert(memoryItemSources)
267
+ db.insert(memoryGraphNodes)
297
268
  .values({
298
- memoryItemId: "item-assistant-inferred",
299
- messageId: "msg-other",
300
- evidence: "corroborating source from other conversation",
301
- createdAt: now + 40,
269
+ id: "item-corroborated",
270
+ content: "DMV appointment\nBooked a DMV appointment at 9 AM.",
271
+ type: "semantic",
272
+ created: now + 10,
273
+ lastAccessed: now + 10,
274
+ lastConsolidated: now + 10,
275
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
276
+ fidelity: "vivid",
277
+ confidence: 0.8,
278
+ significance: 0.7,
279
+ stability: 14,
280
+ reinforcementCount: 0,
281
+ lastReinforced: now + 10,
282
+ sourceConversations: JSON.stringify([convId, otherConvId]),
283
+ sourceType: "inferred",
284
+ narrativeRole: null,
285
+ partOfStory: null,
286
+ scopeId: "default",
302
287
  })
303
288
  .run();
304
289
 
@@ -309,33 +294,32 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
309
294
 
310
295
  const item = db
311
296
  .select()
312
- .from(memoryItems)
313
- .where(eq(memoryItems.id, "item-assistant-inferred"))
297
+ .from(memoryGraphNodes)
298
+ .where(eq(memoryGraphNodes.id, "item-corroborated"))
314
299
  .get();
315
- expect(item?.status).toBe("active");
316
- expect(item?.invalidAt).toBeNull();
300
+ expect(item?.fidelity).toBe("vivid");
317
301
  });
318
302
 
319
- test("does not affect already-superseded items", () => {
303
+ test("does not affect already-gone items", () => {
320
304
  seedConversations();
321
305
  seedMessages();
322
- seedMemoryItems();
306
+ seedMemoryGraphNodes();
323
307
 
324
308
  invalidateAssistantInferredItemsForConversation(convId);
325
309
 
326
310
  const db = getDb();
327
- const supersededItem = db
311
+ const goneItem = db
328
312
  .select()
329
- .from(memoryItems)
330
- .where(eq(memoryItems.id, "item-already-superseded"))
313
+ .from(memoryGraphNodes)
314
+ .where(eq(memoryGraphNodes.id, "item-already-gone"))
331
315
  .get();
332
- expect(supersededItem?.status).toBe("superseded");
316
+ expect(goneItem?.fidelity).toBe("gone");
333
317
  });
334
318
 
335
319
  test("returns 0 when no matching items exist", () => {
336
320
  seedConversations();
337
321
  seedMessages();
338
- // No memory items seeded
322
+ // No memory graph nodes seeded
339
323
 
340
324
  const affected = invalidateAssistantInferredItemsForConversation(convId);
341
325
  expect(affected).toBe(0);
@@ -344,7 +328,7 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
344
328
  test("returns 0 for unknown conversation", () => {
345
329
  seedConversations();
346
330
  seedMessages();
347
- seedMemoryItems();
331
+ seedMemoryGraphNodes();
348
332
 
349
333
  const affected =
350
334
  invalidateAssistantInferredItemsForConversation("conv-nonexistent");
@@ -424,54 +408,40 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
424
408
  ])
425
409
  .run();
426
410
 
427
- // A memory item sourced from both conversations
428
- db.insert(memoryItems)
411
+ // A memory node sourced from both failed conversations
412
+ db.insert(memoryGraphNodes)
429
413
  .values({
430
414
  id: "item-cross-sourced",
431
- kind: "fact",
432
- subject: "cross-sourced claim",
433
- statement: "Claim from two failed tasks.",
434
- status: "active",
415
+ content: "cross-sourced claim\nClaim from two failed tasks.",
416
+ type: "semantic",
417
+ created: now + 10,
418
+ lastAccessed: now + 20,
419
+ lastConsolidated: now + 10,
420
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
421
+ fidelity: "vivid",
435
422
  confidence: 0.8,
436
- importance: 0.7,
437
- fingerprint: "fp-cross-sourced",
438
- verificationState: "assistant_inferred",
439
- sourceType: "extraction",
440
- sourceMessageRole: "assistant",
423
+ significance: 0.7,
424
+ stability: 14,
425
+ reinforcementCount: 0,
426
+ lastReinforced: now + 10,
427
+ sourceConversations: JSON.stringify([convA, convB]),
428
+ sourceType: "inferred",
429
+ narrativeRole: null,
430
+ partOfStory: null,
441
431
  scopeId: "default",
442
- firstSeenAt: now + 10,
443
- lastSeenAt: now + 20,
444
432
  })
445
433
  .run();
446
434
 
447
- db.insert(memoryItemSources)
448
- .values([
449
- {
450
- memoryItemId: "item-cross-sourced",
451
- messageId: "msg-a",
452
- evidence: "claim from A",
453
- createdAt: now + 10,
454
- },
455
- {
456
- memoryItemId: "item-cross-sourced",
457
- messageId: "msg-b",
458
- evidence: "claim from B",
459
- createdAt: now + 20,
460
- },
461
- ])
462
- .run();
463
-
464
435
  // Invalidating for convA should succeed because convB is also from a failed task
465
436
  const affected = invalidateAssistantInferredItemsForConversation(convA);
466
437
  expect(affected).toBe(1);
467
438
 
468
439
  const item = db
469
440
  .select()
470
- .from(memoryItems)
471
- .where(eq(memoryItems.id, "item-cross-sourced"))
441
+ .from(memoryGraphNodes)
442
+ .where(eq(memoryGraphNodes.id, "item-cross-sourced"))
472
443
  .get();
473
- expect(item?.status).toBe("invalidated");
474
- expect(item?.invalidAt).not.toBeNull();
444
+ expect(item?.fidelity).toBe("gone");
475
445
  });
476
446
 
477
447
  test("invalidates items when corroborating conversation is from a failed schedule run", () => {
@@ -550,51 +520,38 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
550
520
  ])
551
521
  .run();
552
522
 
553
- db.insert(memoryItems)
523
+ db.insert(memoryGraphNodes)
554
524
  .values({
555
525
  id: "item-cross-sched",
556
- kind: "fact",
557
- subject: "cross-sourced schedule claim",
558
- statement: "Claim from two failed schedules.",
559
- status: "active",
526
+ content: "cross-sourced schedule claim\nClaim from two failed schedules.",
527
+ type: "semantic",
528
+ created: now + 10,
529
+ lastAccessed: now + 20,
530
+ lastConsolidated: now + 10,
531
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
532
+ fidelity: "vivid",
560
533
  confidence: 0.8,
561
- importance: 0.7,
562
- fingerprint: "fp-cross-sched",
563
- verificationState: "assistant_inferred",
564
- sourceType: "extraction",
565
- sourceMessageRole: "assistant",
534
+ significance: 0.7,
535
+ stability: 14,
536
+ reinforcementCount: 0,
537
+ lastReinforced: now + 10,
538
+ sourceConversations: JSON.stringify([convA, convB]),
539
+ sourceType: "inferred",
540
+ narrativeRole: null,
541
+ partOfStory: null,
566
542
  scopeId: "default",
567
- firstSeenAt: now + 10,
568
- lastSeenAt: now + 20,
569
543
  })
570
544
  .run();
571
545
 
572
- db.insert(memoryItemSources)
573
- .values([
574
- {
575
- memoryItemId: "item-cross-sched",
576
- messageId: "msg-sched-a",
577
- evidence: "claim from A",
578
- createdAt: now + 10,
579
- },
580
- {
581
- memoryItemId: "item-cross-sched",
582
- messageId: "msg-sched-b",
583
- evidence: "claim from B",
584
- createdAt: now + 20,
585
- },
586
- ])
587
- .run();
588
-
589
546
  const affected = invalidateAssistantInferredItemsForConversation(convA);
590
547
  expect(affected).toBe(1);
591
548
 
592
549
  const item = db
593
550
  .select()
594
- .from(memoryItems)
595
- .where(eq(memoryItems.id, "item-cross-sched"))
551
+ .from(memoryGraphNodes)
552
+ .where(eq(memoryGraphNodes.id, "item-cross-sched"))
596
553
  .get();
597
- expect(item?.status).toBe("invalidated");
554
+ expect(item?.fidelity).toBe("gone");
598
555
  });
599
556
 
600
557
  test("preserves items when corroborating conversation is from a successful task run", () => {
@@ -668,42 +625,29 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
668
625
  ])
669
626
  .run();
670
627
 
671
- db.insert(memoryItems)
628
+ db.insert(memoryGraphNodes)
672
629
  .values({
673
630
  id: "item-with-good-corroboration",
674
- kind: "fact",
675
- subject: "corroborated claim",
676
- statement: "Claim corroborated by successful task.",
677
- status: "active",
631
+ content: "corroborated claim\nClaim corroborated by successful task.",
632
+ type: "semantic",
633
+ created: now + 10,
634
+ lastAccessed: now + 20,
635
+ lastConsolidated: now + 10,
636
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
637
+ fidelity: "vivid",
678
638
  confidence: 0.8,
679
- importance: 0.7,
680
- fingerprint: "fp-good-corroboration",
681
- verificationState: "assistant_inferred",
682
- sourceType: "extraction",
683
- sourceMessageRole: "assistant",
639
+ significance: 0.7,
640
+ stability: 14,
641
+ reinforcementCount: 0,
642
+ lastReinforced: now + 10,
643
+ sourceConversations: JSON.stringify([convFailed, convSuccess]),
644
+ sourceType: "inferred",
645
+ narrativeRole: null,
646
+ partOfStory: null,
684
647
  scopeId: "default",
685
- firstSeenAt: now + 10,
686
- lastSeenAt: now + 20,
687
648
  })
688
649
  .run();
689
650
 
690
- db.insert(memoryItemSources)
691
- .values([
692
- {
693
- memoryItemId: "item-with-good-corroboration",
694
- messageId: "msg-failed",
695
- evidence: "claim from failed",
696
- createdAt: now + 10,
697
- },
698
- {
699
- memoryItemId: "item-with-good-corroboration",
700
- messageId: "msg-success",
701
- evidence: "claim from success",
702
- createdAt: now + 20,
703
- },
704
- ])
705
- .run();
706
-
707
651
  // The successful task run corroborates the claim, so it should NOT be invalidated
708
652
  const affected =
709
653
  invalidateAssistantInferredItemsForConversation(convFailed);
@@ -711,10 +655,10 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
711
655
 
712
656
  const item = db
713
657
  .select()
714
- .from(memoryItems)
715
- .where(eq(memoryItems.id, "item-with-good-corroboration"))
658
+ .from(memoryGraphNodes)
659
+ .where(eq(memoryGraphNodes.id, "item-with-good-corroboration"))
716
660
  .get();
717
- expect(item?.status).toBe("active");
661
+ expect(item?.fidelity).toBe("vivid");
718
662
  });
719
663
 
720
664
  test("isConversationFailed derives state from durable task_runs/cron_runs", () => {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  mock.module("../util/logger.js", () => ({
4
4
  getLogger: () =>
@@ -7,17 +7,13 @@ mock.module("../util/logger.js", () => ({
7
7
  }),
8
8
  }));
9
9
 
10
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
10
+ import { getDb, initializeDb } from "../memory/db.js";
11
11
  import { getTaskRunRules } from "../tasks/ephemeral-permissions.js";
12
12
  import { renderTemplate, runTask } from "../tasks/task-runner.js";
13
13
  import { createTask } from "../tasks/task-store.js";
14
14
 
15
15
  initializeDb();
16
16
 
17
- afterAll(() => {
18
- resetDb();
19
- });
20
-
21
17
  // ── renderTemplate ──────────────────────────────────────────────────
22
18
 
23
19
  describe("renderTemplate", () => {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  mock.module("../util/logger.js", () => ({
4
4
  getLogger: () =>
@@ -7,7 +7,7 @@ mock.module("../util/logger.js", () => ({
7
7
  }),
8
8
  }));
9
9
 
10
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
10
+ import { getDb, initializeDb } from "../memory/db.js";
11
11
  import {
12
12
  createSchedule,
13
13
  getSchedule,
@@ -33,10 +33,6 @@ function forceScheduleDue(scheduleId: string): void {
33
33
  ]);
34
34
  }
35
35
 
36
- afterAll(() => {
37
- resetDb();
38
- });
39
-
40
36
  // ── scheduleTask helper ─────────────────────────────────────────────
41
37
 
42
38
  describe("scheduleTask", () => {