@vellumai/assistant 0.3.27 → 0.4.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 (247) hide show
  1. package/ARCHITECTURE.md +81 -4
  2. package/Dockerfile +2 -2
  3. package/bun.lock +4 -1
  4. package/docs/trusted-contact-access.md +9 -2
  5. package/package.json +6 -3
  6. package/scripts/ipc/generate-swift.ts +9 -5
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +80 -0
  8. package/src/__tests__/agent-loop-thinking.test.ts +1 -1
  9. package/src/__tests__/agent-loop.test.ts +119 -0
  10. package/src/__tests__/approval-routes-http.test.ts +13 -5
  11. package/src/__tests__/asset-materialize-tool.test.ts +2 -0
  12. package/src/__tests__/asset-search-tool.test.ts +2 -0
  13. package/src/__tests__/assistant-events-sse-hardening.test.ts +4 -2
  14. package/src/__tests__/attachments-store.test.ts +2 -0
  15. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  16. package/src/__tests__/bundled-asset.test.ts +107 -0
  17. package/src/__tests__/call-controller.test.ts +30 -29
  18. package/src/__tests__/call-routes-http.test.ts +34 -32
  19. package/src/__tests__/call-start-guardian-guard.test.ts +2 -0
  20. package/src/__tests__/canonical-guardian-store.test.ts +636 -0
  21. package/src/__tests__/channel-approval-routes.test.ts +174 -1
  22. package/src/__tests__/channel-invite-transport.test.ts +6 -6
  23. package/src/__tests__/channel-reply-delivery.test.ts +19 -0
  24. package/src/__tests__/channel-retry-sweep.test.ts +130 -0
  25. package/src/__tests__/clarification-resolver.test.ts +2 -0
  26. package/src/__tests__/claude-code-skill-regression.test.ts +2 -0
  27. package/src/__tests__/claude-code-tool-profiles.test.ts +2 -0
  28. package/src/__tests__/commit-message-enrichment-service.test.ts +9 -1
  29. package/src/__tests__/computer-use-session-lifecycle.test.ts +2 -0
  30. package/src/__tests__/computer-use-session-working-dir.test.ts +1 -0
  31. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -0
  32. package/src/__tests__/config-schema.test.ts +5 -5
  33. package/src/__tests__/config-watcher.test.ts +3 -1
  34. package/src/__tests__/connection-policy.test.ts +14 -5
  35. package/src/__tests__/contacts-tools.test.ts +3 -1
  36. package/src/__tests__/contradiction-checker.test.ts +2 -0
  37. package/src/__tests__/conversation-pairing.test.ts +10 -0
  38. package/src/__tests__/conversation-routes.test.ts +1 -1
  39. package/src/__tests__/credential-security-invariants.test.ts +16 -6
  40. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  41. package/src/__tests__/credential-vault.test.ts +5 -4
  42. package/src/__tests__/daemon-lifecycle.test.ts +9 -0
  43. package/src/__tests__/daemon-server-session-init.test.ts +27 -0
  44. package/src/__tests__/elevenlabs-config.test.ts +2 -0
  45. package/src/__tests__/emit-signal-routing-intent.test.ts +43 -1
  46. package/src/__tests__/encrypted-store.test.ts +10 -5
  47. package/src/__tests__/followup-tools.test.ts +3 -1
  48. package/src/__tests__/gateway-only-enforcement.test.ts +21 -21
  49. package/src/__tests__/gmail-integration.test.ts +0 -1
  50. package/src/__tests__/guardian-actions-endpoint.test.ts +205 -345
  51. package/src/__tests__/guardian-control-plane-policy.test.ts +19 -19
  52. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +599 -0
  53. package/src/__tests__/guardian-dispatch.test.ts +21 -19
  54. package/src/__tests__/guardian-grant-minting.test.ts +68 -1
  55. package/src/__tests__/guardian-outbound-http.test.ts +12 -9
  56. package/src/__tests__/guardian-routing-invariants.test.ts +1092 -0
  57. package/src/__tests__/handle-user-message-secret-resume.test.ts +1 -0
  58. package/src/__tests__/handlers-slack-config.test.ts +3 -1
  59. package/src/__tests__/handlers-telegram-config.test.ts +3 -1
  60. package/src/__tests__/handlers-twilio-config.test.ts +3 -1
  61. package/src/__tests__/handlers-twitter-config.test.ts +3 -1
  62. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +318 -0
  63. package/src/__tests__/heartbeat-service.test.ts +20 -0
  64. package/src/__tests__/inbound-invite-redemption.test.ts +33 -0
  65. package/src/__tests__/ingress-reconcile.test.ts +3 -1
  66. package/src/__tests__/ingress-routes-http.test.ts +231 -4
  67. package/src/__tests__/intent-routing.test.ts +2 -0
  68. package/src/__tests__/ipc-snapshot.test.ts +13 -0
  69. package/src/__tests__/mcp-cli.test.ts +77 -0
  70. package/src/__tests__/media-generate-image.test.ts +21 -0
  71. package/src/__tests__/media-reuse-story.e2e.test.ts +2 -0
  72. package/src/__tests__/memory-regressions.test.ts +20 -20
  73. package/src/__tests__/non-member-access-request.test.ts +212 -36
  74. package/src/__tests__/notification-decision-fallback.test.ts +63 -3
  75. package/src/__tests__/notification-decision-strategy.test.ts +78 -0
  76. package/src/__tests__/notification-guardian-path.test.ts +15 -15
  77. package/src/__tests__/oauth-connect-handler.test.ts +3 -1
  78. package/src/__tests__/oauth2-gateway-transport.test.ts +2 -0
  79. package/src/__tests__/onboarding-starter-tasks.test.ts +4 -4
  80. package/src/__tests__/onboarding-template-contract.test.ts +116 -21
  81. package/src/__tests__/pairing-routes.test.ts +171 -0
  82. package/src/__tests__/playbook-execution.test.ts +3 -1
  83. package/src/__tests__/playbook-tools.test.ts +3 -1
  84. package/src/__tests__/provider-error-scenarios.test.ts +59 -8
  85. package/src/__tests__/proxy-approval-callback.test.ts +2 -0
  86. package/src/__tests__/recording-handler.test.ts +11 -0
  87. package/src/__tests__/recording-intent-handler.test.ts +15 -0
  88. package/src/__tests__/recording-state-machine.test.ts +13 -2
  89. package/src/__tests__/registry.test.ts +7 -3
  90. package/src/__tests__/relay-server.test.ts +148 -28
  91. package/src/__tests__/runtime-attachment-metadata.test.ts +4 -2
  92. package/src/__tests__/runtime-events-sse-parity.test.ts +21 -0
  93. package/src/__tests__/runtime-events-sse.test.ts +4 -2
  94. package/src/__tests__/sandbox-diagnostics.test.ts +2 -0
  95. package/src/__tests__/schedule-tools.test.ts +3 -1
  96. package/src/__tests__/secret-scanner-executor.test.ts +59 -0
  97. package/src/__tests__/secret-scanner.test.ts +8 -0
  98. package/src/__tests__/send-endpoint-busy.test.ts +4 -0
  99. package/src/__tests__/sensitive-output-placeholders.test.ts +208 -0
  100. package/src/__tests__/session-abort-tool-results.test.ts +23 -0
  101. package/src/__tests__/session-agent-loop.test.ts +16 -0
  102. package/src/__tests__/session-conflict-gate.test.ts +21 -0
  103. package/src/__tests__/session-load-history-repair.test.ts +27 -17
  104. package/src/__tests__/session-pre-run-repair.test.ts +23 -0
  105. package/src/__tests__/session-profile-injection.test.ts +21 -0
  106. package/src/__tests__/session-provider-retry-repair.test.ts +20 -0
  107. package/src/__tests__/session-queue.test.ts +23 -0
  108. package/src/__tests__/session-runtime-assembly.test.ts +126 -59
  109. package/src/__tests__/session-skill-tools.test.ts +27 -5
  110. package/src/__tests__/session-slash-known.test.ts +23 -0
  111. package/src/__tests__/session-slash-queue.test.ts +23 -0
  112. package/src/__tests__/session-slash-unknown.test.ts +23 -0
  113. package/src/__tests__/session-workspace-cache-state.test.ts +7 -0
  114. package/src/__tests__/session-workspace-injection.test.ts +21 -0
  115. package/src/__tests__/session-workspace-tool-tracking.test.ts +21 -0
  116. package/src/__tests__/shell-credential-ref.test.ts +2 -0
  117. package/src/__tests__/skill-feature-flags-integration.test.ts +6 -6
  118. package/src/__tests__/skill-load-feature-flag.test.ts +5 -4
  119. package/src/__tests__/skill-projection-feature-flag.test.ts +22 -0
  120. package/src/__tests__/skills.test.ts +8 -4
  121. package/src/__tests__/slack-channel-config.test.ts +3 -1
  122. package/src/__tests__/subagent-tools.test.ts +19 -0
  123. package/src/__tests__/swarm-recursion.test.ts +2 -0
  124. package/src/__tests__/swarm-session-integration.test.ts +2 -0
  125. package/src/__tests__/swarm-tool.test.ts +2 -0
  126. package/src/__tests__/system-prompt.test.ts +3 -1
  127. package/src/__tests__/task-compiler.test.ts +3 -1
  128. package/src/__tests__/task-management-tools.test.ts +3 -1
  129. package/src/__tests__/task-tools.test.ts +3 -1
  130. package/src/__tests__/terminal-sandbox.test.ts +13 -12
  131. package/src/__tests__/terminal-tools.test.ts +2 -0
  132. package/src/__tests__/tool-approval-handler.test.ts +15 -15
  133. package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -0
  134. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -0
  135. package/src/__tests__/tool-grant-request-escalation.test.ts +497 -0
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +48 -0
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +22 -19
  138. package/src/__tests__/trusted-contact-verification.test.ts +91 -0
  139. package/src/__tests__/twilio-routes-elevenlabs.test.ts +2 -0
  140. package/src/__tests__/twitter-auth-handler.test.ts +3 -1
  141. package/src/__tests__/twitter-cli-routing.test.ts +3 -1
  142. package/src/__tests__/view-image-tool.test.ts +3 -1
  143. package/src/__tests__/voice-invite-redemption.test.ts +329 -0
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -5
  145. package/src/__tests__/voice-session-bridge.test.ts +10 -10
  146. package/src/__tests__/work-item-output.test.ts +3 -1
  147. package/src/__tests__/workspace-lifecycle.test.ts +13 -2
  148. package/src/agent/loop.ts +46 -3
  149. package/src/approvals/guardian-decision-primitive.ts +285 -0
  150. package/src/approvals/guardian-request-resolvers.ts +539 -0
  151. package/src/calls/call-controller.ts +26 -23
  152. package/src/calls/guardian-action-sweep.ts +10 -2
  153. package/src/calls/guardian-dispatch.ts +46 -40
  154. package/src/calls/relay-server.ts +358 -24
  155. package/src/calls/types.ts +1 -1
  156. package/src/calls/voice-session-bridge.ts +3 -3
  157. package/src/cli.ts +12 -0
  158. package/src/config/agent-schema.ts +14 -3
  159. package/src/config/calls-schema.ts +6 -6
  160. package/src/config/core-schema.ts +3 -3
  161. package/src/config/feature-flag-registry.json +8 -0
  162. package/src/config/mcp-schema.ts +1 -1
  163. package/src/config/memory-schema.ts +27 -19
  164. package/src/config/schema.ts +21 -21
  165. package/src/config/skills-schema.ts +7 -7
  166. package/src/config/system-prompt.ts +2 -1
  167. package/src/config/templates/BOOTSTRAP.md +47 -31
  168. package/src/config/templates/USER.md +5 -0
  169. package/src/config/update-bulletin-template-path.ts +4 -1
  170. package/src/config/vellum-skills/trusted-contacts/SKILL.md +149 -21
  171. package/src/daemon/handlers/config-inbox.ts +4 -4
  172. package/src/daemon/handlers/guardian-actions.ts +45 -66
  173. package/src/daemon/handlers/sessions.ts +148 -4
  174. package/src/daemon/ipc-contract/guardian-actions.ts +7 -0
  175. package/src/daemon/ipc-contract/messages.ts +16 -0
  176. package/src/daemon/ipc-contract-inventory.json +1 -0
  177. package/src/daemon/lifecycle.ts +22 -16
  178. package/src/daemon/pairing-store.ts +86 -3
  179. package/src/daemon/server.ts +18 -0
  180. package/src/daemon/session-agent-loop-handlers.ts +5 -4
  181. package/src/daemon/session-agent-loop.ts +33 -6
  182. package/src/daemon/session-lifecycle.ts +25 -17
  183. package/src/daemon/session-memory.ts +2 -2
  184. package/src/daemon/session-process.ts +68 -326
  185. package/src/daemon/session-runtime-assembly.ts +119 -25
  186. package/src/daemon/session-tool-setup.ts +3 -2
  187. package/src/daemon/session.ts +4 -3
  188. package/src/home-base/prebuilt/seed.ts +2 -1
  189. package/src/hooks/templates.ts +2 -1
  190. package/src/memory/canonical-guardian-store.ts +586 -0
  191. package/src/memory/channel-guardian-store.ts +2 -0
  192. package/src/memory/conversation-crud.ts +7 -7
  193. package/src/memory/db-init.ts +20 -0
  194. package/src/memory/embedding-local.ts +257 -39
  195. package/src/memory/embedding-runtime-manager.ts +471 -0
  196. package/src/memory/guardian-action-store.ts +7 -60
  197. package/src/memory/guardian-approvals.ts +9 -4
  198. package/src/memory/guardian-bindings.ts +25 -1
  199. package/src/memory/indexer.ts +3 -3
  200. package/src/memory/ingress-invite-store.ts +45 -0
  201. package/src/memory/job-handlers/backfill.ts +16 -9
  202. package/src/memory/migrations/036-normalize-phone-identities.ts +289 -0
  203. package/src/memory/migrations/037-voice-invite-columns.ts +16 -0
  204. package/src/memory/migrations/118-reminder-routing-intent.ts +3 -3
  205. package/src/memory/migrations/121-canonical-guardian-requests.ts +59 -0
  206. package/src/memory/migrations/122-canonical-guardian-requester-chat-id.ts +15 -0
  207. package/src/memory/migrations/123-canonical-guardian-deliveries-destination-index.ts +15 -0
  208. package/src/memory/migrations/index.ts +5 -0
  209. package/src/memory/migrations/registry.ts +5 -0
  210. package/src/memory/qdrant-client.ts +31 -22
  211. package/src/memory/schema-migration.ts +1 -0
  212. package/src/memory/schema.ts +56 -0
  213. package/src/notifications/copy-composer.ts +31 -4
  214. package/src/notifications/decision-engine.ts +57 -0
  215. package/src/permissions/defaults.ts +2 -0
  216. package/src/runtime/access-request-helper.ts +173 -0
  217. package/src/runtime/actor-trust-resolver.ts +221 -0
  218. package/src/runtime/channel-guardian-service.ts +12 -4
  219. package/src/runtime/channel-invite-transports/voice.ts +58 -0
  220. package/src/runtime/channel-retry-sweep.ts +18 -6
  221. package/src/runtime/guardian-context-resolver.ts +38 -71
  222. package/src/runtime/guardian-decision-types.ts +6 -0
  223. package/src/runtime/guardian-reply-router.ts +717 -0
  224. package/src/runtime/http-server.ts +8 -0
  225. package/src/runtime/ingress-service.ts +80 -3
  226. package/src/runtime/invite-redemption-service.ts +141 -2
  227. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +116 -0
  228. package/src/runtime/routes/channel-route-shared.ts +1 -1
  229. package/src/runtime/routes/channel-routes.ts +1 -1
  230. package/src/runtime/routes/conversation-routes.ts +20 -2
  231. package/src/runtime/routes/guardian-action-routes.ts +100 -109
  232. package/src/runtime/routes/guardian-approval-interception.ts +17 -6
  233. package/src/runtime/routes/inbound-message-handler.ts +205 -529
  234. package/src/runtime/routes/ingress-routes.ts +52 -4
  235. package/src/runtime/routes/pairing-routes.ts +3 -0
  236. package/src/runtime/tool-grant-request-helper.ts +195 -0
  237. package/src/tools/executor.ts +13 -1
  238. package/src/tools/guardian-control-plane-policy.ts +2 -2
  239. package/src/tools/sensitive-output-placeholders.ts +203 -0
  240. package/src/tools/tool-approval-handler.ts +53 -10
  241. package/src/tools/types.ts +13 -2
  242. package/src/util/bundled-asset.ts +31 -0
  243. package/src/util/canonicalize-identity.ts +52 -0
  244. package/src/util/logger.ts +20 -8
  245. package/src/util/platform.ts +10 -0
  246. package/src/util/voice-code.ts +29 -0
  247. package/src/daemon/guardian-invite-intent.ts +0 -124
@@ -380,7 +380,7 @@ describe('enforceGuardianOnlyPolicy', () => {
380
380
  test('non-guardian actor denied for guardian endpoint', () => {
381
381
  const result = enforceGuardianOnlyPolicy('bash', {
382
382
  command: 'curl http://localhost:3000/v1/integrations/guardian/outbound/start',
383
- }, 'non-guardian');
383
+ }, 'trusted_contact');
384
384
  expect(result.denied).toBe(true);
385
385
  expect(result.reason).toContain('restricted to guardian users');
386
386
  });
@@ -388,7 +388,7 @@ describe('enforceGuardianOnlyPolicy', () => {
388
388
  test('unverified_channel actor denied for guardian endpoint', () => {
389
389
  const result = enforceGuardianOnlyPolicy('network_request', {
390
390
  url: 'https://api.example.com/v1/integrations/guardian/challenge',
391
- }, 'unverified_channel');
391
+ }, 'unknown');
392
392
  expect(result.denied).toBe(true);
393
393
  expect(result.reason).toContain('restricted to guardian users');
394
394
  });
@@ -419,14 +419,14 @@ describe('enforceGuardianOnlyPolicy', () => {
419
419
  test('non-guardian actor is NOT denied for unrelated endpoint', () => {
420
420
  const result = enforceGuardianOnlyPolicy('bash', {
421
421
  command: 'curl http://localhost:3000/v1/messages',
422
- }, 'non-guardian');
422
+ }, 'trusted_contact');
423
423
  expect(result.denied).toBe(false);
424
424
  });
425
425
 
426
426
  test('non-guardian actor is NOT denied for unrelated tool', () => {
427
427
  const result = enforceGuardianOnlyPolicy('file_read', {
428
428
  path: 'README.md',
429
- }, 'non-guardian');
429
+ }, 'trusted_contact');
430
430
  expect(result.denied).toBe(false);
431
431
  });
432
432
  });
@@ -445,7 +445,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
445
445
  const result = await executor.execute(
446
446
  'bash',
447
447
  { command: 'curl -X POST http://localhost:3000/v1/integrations/guardian/outbound/start' },
448
- makeContext({ guardianActorRole: 'non-guardian' }),
448
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
449
449
  );
450
450
  expect(result.isError).toBe(true);
451
451
  expect(result.content).toContain('restricted to guardian users');
@@ -456,7 +456,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
456
456
  const result = await executor.execute(
457
457
  'network_request',
458
458
  { url: 'https://api.example.com/v1/integrations/guardian/challenge' },
459
- makeContext({ guardianActorRole: 'unverified_channel' }),
459
+ makeContext({ guardianTrustClass: 'unknown' }),
460
460
  );
461
461
  expect(result.isError).toBe(true);
462
462
  expect(result.content).toContain('restricted to guardian users');
@@ -467,18 +467,18 @@ describe('ToolExecutor guardian-only policy gate', () => {
467
467
  const result = await executor.execute(
468
468
  'bash',
469
469
  { command: 'curl -X POST http://localhost:3000/v1/integrations/guardian/outbound/start' },
470
- makeContext({ guardianActorRole: 'guardian' }),
470
+ makeContext({ guardianTrustClass: 'guardian' }),
471
471
  );
472
472
  expect(result.isError).toBe(false);
473
473
  expect(result.content).toBe('ok');
474
474
  });
475
475
 
476
- test('undefined guardianActorRole is NOT blocked from guardian endpoint', async () => {
476
+ test('undefined guardianTrustClass is NOT blocked from guardian endpoint', async () => {
477
477
  const executor = new ToolExecutor(makePrompter());
478
478
  const result = await executor.execute(
479
479
  'bash',
480
480
  { command: 'curl http://localhost:3000/v1/integrations/guardian/status' },
481
- makeContext(), // no guardianActorRole set
481
+ makeContext(), // no guardianTrustClass set
482
482
  );
483
483
  expect(result.isError).toBe(false);
484
484
  expect(result.content).toBe('ok');
@@ -489,7 +489,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
489
489
  const result = await executor.execute(
490
490
  'bash',
491
491
  { command: 'curl http://localhost:3000/v1/messages' },
492
- makeContext({ guardianActorRole: 'non-guardian' }),
492
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
493
493
  );
494
494
  expect(result.isError).toBe(true);
495
495
  expect(result.content).toContain('requires guardian approval');
@@ -500,7 +500,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
500
500
  const result = await executor.execute(
501
501
  'file_read',
502
502
  { path: 'README.md' },
503
- makeContext({ guardianActorRole: 'non-guardian' }),
503
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
504
504
  );
505
505
  expect(result.isError).toBe(false);
506
506
  expect(result.content).toBe('ok');
@@ -513,7 +513,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
513
513
  'bash',
514
514
  { command: 'curl http://localhost:3000/v1/integrations/guardian/outbound/cancel' },
515
515
  makeContext({
516
- guardianActorRole: 'non-guardian',
516
+ guardianTrustClass: 'trusted_contact',
517
517
  onToolLifecycleEvent: (event: ToolLifecycleEvent) => {
518
518
  if (event.type === 'permission_denied') {
519
519
  capturedEvent = event as ToolPermissionDeniedEvent;
@@ -531,7 +531,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
531
531
  const result = await executor.execute(
532
532
  'web_fetch',
533
533
  { url: 'http://localhost:3000/v1/integrations/guardian/outbound/resend' },
534
- makeContext({ guardianActorRole: 'non-guardian' }),
534
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
535
535
  );
536
536
  expect(result.isError).toBe(true);
537
537
  expect(result.content).toContain('restricted to guardian users');
@@ -542,7 +542,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
542
542
  const result = await executor.execute(
543
543
  'browser_navigate',
544
544
  { url: 'http://localhost:3000/v1/integrations/guardian/status' },
545
- makeContext({ guardianActorRole: 'non-guardian' }),
545
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
546
546
  );
547
547
  expect(result.isError).toBe(true);
548
548
  expect(result.content).toContain('restricted to guardian users');
@@ -553,7 +553,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
553
553
  const result = await executor.execute(
554
554
  'host_bash',
555
555
  { command: 'curl -X POST https://internal:8080/v1/integrations/guardian/challenge' },
556
- makeContext({ guardianActorRole: 'non-guardian' }),
556
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
557
557
  );
558
558
  expect(result.isError).toBe(true);
559
559
  expect(result.content).toContain('restricted to guardian users');
@@ -573,7 +573,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
573
573
  const result = await executor.execute(
574
574
  'network_request',
575
575
  { url: `https://api.example.com${path}` },
576
- makeContext({ guardianActorRole: 'non-guardian' }),
576
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
577
577
  );
578
578
  expect(result.isError).toBe(true);
579
579
  expect(result.content).toContain('restricted to guardian users');
@@ -585,7 +585,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
585
585
  const result = await executor.execute(
586
586
  'host_file_read',
587
587
  { path: '/Users/noaflaherty/.ssh/config' },
588
- makeContext({ guardianActorRole: 'non-guardian' }),
588
+ makeContext({ guardianTrustClass: 'trusted_contact' }),
589
589
  );
590
590
  expect(result.isError).toBe(true);
591
591
  expect(result.content).toContain('requires guardian approval');
@@ -596,7 +596,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
596
596
  const result = await executor.execute(
597
597
  'reminder_create',
598
598
  { fire_at: '2026-02-27T12:00:00-05:00', label: 'test', message: 'hello' },
599
- makeContext({ guardianActorRole: 'unverified_channel' }),
599
+ makeContext({ guardianTrustClass: 'unknown' }),
600
600
  );
601
601
  expect(result.isError).toBe(true);
602
602
  expect(result.content).toContain('verified channel identity');
@@ -607,7 +607,7 @@ describe('ToolExecutor guardian-only policy gate', () => {
607
607
  const result = await executor.execute(
608
608
  'reminder_create',
609
609
  { fire_at: '2026-02-27T12:00:00-05:00', label: 'test', message: 'hello' },
610
- makeContext({ guardianActorRole: 'guardian' }),
610
+ makeContext({ guardianTrustClass: 'guardian' }),
611
611
  );
612
612
  expect(result.isError).toBe(false);
613
613
  expect(result.content).toBe('ok');