@vellumai/assistant 0.10.0 → 0.10.1-dev.202606240317.ea25efe
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.
- package/ARCHITECTURE.md +36 -37
- package/bun.lock +3 -0
- package/docs/workflows.md +12 -7
- package/eslint-rules/cli-no-daemon-internals.js +12 -0
- package/node_modules/@slack/types/LICENSE +23 -0
- package/node_modules/@slack/types/README.md +32 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +953 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +474 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +237 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts +88 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js.map +1 -0
- package/node_modules/@slack/types/dist/calls.d.ts +26 -0
- package/node_modules/@slack/types/dist/calls.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/calls.js +6 -0
- package/node_modules/@slack/types/dist/calls.js.map +1 -0
- package/node_modules/@slack/types/dist/chunk.d.ts +52 -0
- package/node_modules/@slack/types/dist/chunk.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/chunk.js +3 -0
- package/node_modules/@slack/types/dist/chunk.js.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts +12 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js +3 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts +6 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js +3 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js.map +1 -0
- package/node_modules/@slack/types/dist/dialog.d.ts +36 -0
- package/node_modules/@slack/types/dist/dialog.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/dialog.js +3 -0
- package/node_modules/@slack/types/dist/dialog.js.map +1 -0
- package/node_modules/@slack/types/dist/events/app.d.ts +204 -0
- package/node_modules/@slack/types/dist/events/app.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/app.js +3 -0
- package/node_modules/@slack/types/dist/events/app.js.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts +29 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.js +3 -0
- package/node_modules/@slack/types/dist/events/assistant.js.map +1 -0
- package/node_modules/@slack/types/dist/events/call.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/call.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/call.js +3 -0
- package/node_modules/@slack/types/dist/events/call.js.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts +85 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.js +3 -0
- package/node_modules/@slack/types/dist/events/channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts +24 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.js +3 -0
- package/node_modules/@slack/types/dist/events/dnd.js.map +1 -0
- package/node_modules/@slack/types/dist/events/email.d.ts +6 -0
- package/node_modules/@slack/types/dist/events/email.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/email.js +3 -0
- package/node_modules/@slack/types/dist/events/email.js.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts +11 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.js +3 -0
- package/node_modules/@slack/types/dist/events/emoji.js.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts +21 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js +3 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js.map +1 -0
- package/node_modules/@slack/types/dist/events/file.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/file.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/file.js +4 -0
- package/node_modules/@slack/types/dist/events/file.js.map +1 -0
- package/node_modules/@slack/types/dist/events/function.d.ts +33 -0
- package/node_modules/@slack/types/dist/events/function.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/function.js +3 -0
- package/node_modules/@slack/types/dist/events/function.js.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts +9 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js +3 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js.map +1 -0
- package/node_modules/@slack/types/dist/events/group.d.ts +55 -0
- package/node_modules/@slack/types/dist/events/group.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/group.js +3 -0
- package/node_modules/@slack/types/dist/events/group.js.map +1 -0
- package/node_modules/@slack/types/dist/events/im.d.ts +26 -0
- package/node_modules/@slack/types/dist/events/im.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/im.js +3 -0
- package/node_modules/@slack/types/dist/events/im.js.map +1 -0
- package/node_modules/@slack/types/dist/events/index.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/index.js +43 -0
- package/node_modules/@slack/types/dist/events/index.js.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts +20 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.js +3 -0
- package/node_modules/@slack/types/dist/events/invite.js.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts +16 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.js +3 -0
- package/node_modules/@slack/types/dist/events/link-shared.js.map +1 -0
- package/node_modules/@slack/types/dist/events/member.d.ts +19 -0
- package/node_modules/@slack/types/dist/events/member.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/member.js +3 -0
- package/node_modules/@slack/types/dist/events/member.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts +38 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js +3 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message.d.ts +306 -0
- package/node_modules/@slack/types/dist/events/message.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message.js +3 -0
- package/node_modules/@slack/types/dist/events/message.js.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.js +3 -0
- package/node_modules/@slack/types/dist/events/pin.js.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts +23 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.js +3 -0
- package/node_modules/@slack/types/dist/events/reaction.js.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts +134 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js +3 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/star.d.ts +13 -0
- package/node_modules/@slack/types/dist/events/star.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/star.js +3 -0
- package/node_modules/@slack/types/dist/events/star.js.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts +82 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js +3 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts +66 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.js +3 -0
- package/node_modules/@slack/types/dist/events/subteam.js.map +1 -0
- package/node_modules/@slack/types/dist/events/team.d.ts +99 -0
- package/node_modules/@slack/types/dist/events/team.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/team.js +3 -0
- package/node_modules/@slack/types/dist/events/team.js.map +1 -0
- package/node_modules/@slack/types/dist/events/token.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/token.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/token.js +3 -0
- package/node_modules/@slack/types/dist/events/token.js.map +1 -0
- package/node_modules/@slack/types/dist/events/user.d.ts +313 -0
- package/node_modules/@slack/types/dist/events/user.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/user.js +3 -0
- package/node_modules/@slack/types/dist/events/user.js.map +1 -0
- package/node_modules/@slack/types/dist/index.d.ts +12 -0
- package/node_modules/@slack/types/dist/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/index.js +28 -0
- package/node_modules/@slack/types/dist/index.js.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts +171 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.js +3 -0
- package/node_modules/@slack/types/dist/message-attachments.js.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts +281 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.js +27 -0
- package/node_modules/@slack/types/dist/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/views.d.ts +71 -0
- package/node_modules/@slack/types/dist/views.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/views.js +3 -0
- package/node_modules/@slack/types/dist/views.js.map +1 -0
- package/node_modules/@slack/types/package.json +47 -0
- package/node_modules/@vellumai/gateway-client/bun.lock +3 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +69 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +96 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +28 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +4 -2
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +3 -2
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +95 -0
- package/openapi.yaml +458 -18
- package/package.json +2 -1
- package/scripts/memory-inspect.ts +24 -14
- package/scripts/test.sh +36 -15
- package/src/__tests__/access-request-seed-content-blocks.test.ts +83 -103
- package/src/__tests__/activation-early-marking.test.ts +1 -1
- package/src/__tests__/actor-token-service.test.ts +39 -17
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +1 -40
- package/src/__tests__/agent-loop-compaction-events.test.ts +0 -1
- package/src/__tests__/agent-loop-compaction-strip.test.ts +0 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +0 -1
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +0 -1
- package/src/__tests__/agent-loop.test.ts +3 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/anthropic-provider.test.ts +210 -9
- package/src/__tests__/app-builder-skill-instructions.test.ts +47 -5
- package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -1
- package/src/__tests__/app-source-watcher.test.ts +30 -10
- package/src/__tests__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +151 -0
- package/src/__tests__/approval-primitive.test.ts +1 -1
- package/src/__tests__/approval-routes-http.test.ts +1 -1
- package/src/__tests__/assistant-attachments.test.ts +155 -0
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +2 -4
- package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-shed.test.ts +1 -1
- package/src/__tests__/attachment-upload-trusted-source.test.ts +13 -8
- package/src/__tests__/attachments-store.test.ts +1 -1
- package/src/__tests__/audit-log-rotation.test.ts +50 -54
- package/src/__tests__/auth-fallback-events-store.test.ts +1 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +9 -14
- package/src/__tests__/background-shell-bash.test.ts +4 -1
- package/src/__tests__/background-shell-host-bash.test.ts +17 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-controller.test.ts +20 -1
- package/src/__tests__/call-conversation-messages.test.ts +1 -1
- package/src/__tests__/call-domain.test.ts +1 -1
- package/src/__tests__/call-pointer-messages.test.ts +3 -4
- package/src/__tests__/call-recovery.test.ts +1 -1
- package/src/__tests__/call-routes-http.test.ts +1 -1
- package/src/__tests__/call-store.test.ts +1 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/canonical-guardian-store.test.ts +24 -1
- package/src/__tests__/card-surface-data.test.ts +60 -0
- package/src/__tests__/channel-approval-routes.test.ts +73 -1119
- package/src/__tests__/channel-delivery-store.test.ts +1 -1
- package/src/__tests__/channel-guardian.test.ts +291 -641
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +1 -2
- package/src/__tests__/channel-retry-sweep.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +6 -0
- package/src/__tests__/compaction-trail-store.test.ts +6 -5
- package/src/__tests__/compaction.benchmark.test.ts +0 -1
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +188 -52
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -2
- package/src/__tests__/contact-store-user-file.test.ts +2 -2
- package/src/__tests__/contacts-relay-reads.test.ts +409 -0
- package/src/__tests__/contacts-tools.test.ts +4 -4
- package/src/__tests__/contacts-write.test.ts +1 -2
- package/src/__tests__/context-search-conversations-source.test.ts +1 -1
- package/src/__tests__/context-window-manager-compact-retry.test.ts +6 -2
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +6 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop.test.ts +7 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -5
- package/src/__tests__/conversation-attention-store.test.ts +1 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -2
- package/src/__tests__/conversation-clear-safety.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +12 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +1 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +10 -8
- package/src/__tests__/conversation-fork-retrospective.test.ts +250 -0
- package/src/__tests__/conversation-fork-route.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-list.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +117 -0
- package/src/__tests__/conversation-list-source.test.ts +3 -3
- package/src/__tests__/conversation-process-callsite.test.ts +6 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +95 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +12 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +12 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +115 -12
- package/src/__tests__/conversation-slash-queue.test.ts +6 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +6 -0
- package/src/__tests__/conversation-starter-routes.test.ts +5 -5
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +4 -4
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +352 -0
- package/src/__tests__/conversation-sync-tags.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-wipe.test.ts +9 -8
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/conversations-import-system-filter.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +17 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-acp-history.test.ts +2 -2
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +5 -7
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -7
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +5 -10
- package/src/__tests__/db-migration-rollback.test.ts +129 -39
- package/src/__tests__/db-proxy-transaction.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -11
- package/src/__tests__/db-test-helpers.ts +36 -19
- package/src/__tests__/delete-propagation.test.ts +1 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +28 -8
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/disk-pressure-tools.test.ts +41 -1
- package/src/__tests__/dm-backfill.test.ts +1 -1
- package/src/__tests__/drop-capability-card-state-migration.test.ts +0 -8
- package/src/__tests__/dynamic-page-surface.test.ts +0 -94
- package/src/__tests__/edit-propagation.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +93 -5
- package/src/__tests__/empty-response-hook.test.ts +42 -0
- package/src/__tests__/events-client-registration.test.ts +1 -1
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/followup-tools.test.ts +1 -1
- package/src/__tests__/gemini-count-tokens.test.ts +70 -0
- package/src/__tests__/guardian-action-sweep.test.ts +9 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +76 -11
- package/src/__tests__/guardian-card-withdrawal.test.ts +1 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +96 -2
- package/src/__tests__/guardian-outbound-http.test.ts +20 -12
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +1 -2
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +2 -2
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +6 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +92 -0
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-conversation-lineage.test.ts +1 -1
- package/src/__tests__/http-user-message-parity.test.ts +165 -8
- package/src/__tests__/image-recovery-hook.test.ts +1 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +1 -2
- package/src/__tests__/inbound-trust-verdict.test.ts +254 -0
- package/src/__tests__/inference-profile-reaper.test.ts +1 -1
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +11 -6
- package/src/__tests__/internal-telemetry-routes.test.ts +1 -1
- package/src/__tests__/invite-redemption-service.test.ts +244 -43
- package/src/__tests__/invite-routes-http.test.ts +35 -186
- package/src/__tests__/invite-service-ipc.test.ts +287 -0
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +5 -5
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +9 -12
- package/src/__tests__/list-messages-attachments.test.ts +42 -1
- package/src/__tests__/list-messages-client-message-id.test.ts +1 -1
- package/src/__tests__/list-messages-hidden-metadata.test.ts +1 -1
- package/src/__tests__/list-messages-page-latest.test.ts +1 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +1 -1
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-context-route-provider.test.ts +69 -4
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -5
- package/src/__tests__/llm-request-log-call-site.test.ts +6 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +27 -13
- package/src/__tests__/llm-resolver.test.ts +205 -5
- package/src/__tests__/llm-usage-store.test.ts +65 -1
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/log-export-workspace.test.ts +3 -3
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +5 -5
- package/src/__tests__/memory-recall-log-store.test.ts +1 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +3 -4
- package/src/__tests__/messages-after-tiebreaker.test.ts +1 -1
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +375 -0
- package/src/__tests__/non-member-access-request.test.ts +190 -19
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +4 -0
- package/src/__tests__/notification-guardian-path.test.ts +20 -1
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +1 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +1 -1
- package/src/__tests__/persist-unsendable-image.test.ts +1 -1
- package/src/__tests__/persona-resolver.test.ts +39 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/playbook-execution.test.ts +1 -1
- package/src/__tests__/playbook-tools.test.ts +1 -1
- package/src/__tests__/plugin-api-model-profiles.test.ts +74 -21
- package/src/__tests__/plugin-bootstrap.test.ts +78 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +25 -5
- package/src/__tests__/provider-usage-tracking.test.ts +40 -1
- package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/registry.test.ts +3 -0
- package/src/__tests__/relay-server.test.ts +1026 -73
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -1
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +7 -9
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-retry.test.ts +1 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/schedule-tools.test.ts +1 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
- package/src/__tests__/scheduler-recurrence.test.ts +1 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +1 -1
- package/src/__tests__/scheduler-wake.test.ts +2 -1
- package/src/__tests__/scoped-approval-grants.test.ts +1 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -5
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +0 -8
- package/src/__tests__/secret-ingress-http.test.ts +12 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +31 -9
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +40 -1
- package/src/__tests__/settings-routes.test.ts +11 -10
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +48 -5
- package/src/__tests__/slack-messaging-token-resolution.test.ts +13 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -1
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +102 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +44 -13
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -73
- package/src/__tests__/subagent-tools.test.ts +1 -31
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
- package/src/__tests__/task-compiler.test.ts +1 -1
- package/src/__tests__/task-management-tools.test.ts +1 -1
- package/src/__tests__/task-memory-cleanup.test.ts +9 -6
- package/src/__tests__/task-scheduler.test.ts +1 -1
- package/src/__tests__/thread-backfill.test.ts +1 -1
- package/src/__tests__/tool-approval-handler.test.ts +1 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +37 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +73 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +34 -34
- package/src/__tests__/trusted-contact-multichannel.test.ts +1 -2
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/turn-boundary-resolution.test.ts +3 -3
- package/src/__tests__/turn-events-store.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +98 -3
- package/src/__tests__/usage-cache-backfill-migration.test.ts +20 -10
- package/src/__tests__/usage-routes.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +34 -29
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/voice-invite-redemption.test.ts +134 -36
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
- package/src/__tests__/voice-session-bridge.test.ts +1 -1
- package/src/__tests__/workspace-git-service.test.ts +114 -1
- package/src/__tests__/workspace-heartbeat-service.test.ts +45 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +88 -18
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +6 -6
- package/src/__tests__/workspace-migration-109-swap-quality-profile-to-glm-5p2.test.ts +281 -0
- package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +167 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +55 -0
- package/src/__tests__/workspace-tool-loader.test.ts +3 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -1
- package/src/a2a/__tests__/task-store.test.ts +1 -1
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +22 -11
- package/src/acp/__tests__/session-manager-startup.test.ts +1 -1
- package/src/acp/__tests__/session-manager.test.ts +72 -1
- package/src/acp/index.ts +10 -0
- package/src/acp/session-manager.ts +35 -0
- package/src/agent/loop-exclusive-tool.test.ts +150 -0
- package/src/agent/loop.ts +101 -27
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/events/ui-surface-show.ts +8 -3
- package/src/api/index.ts +7 -6
- package/src/api/responses/conversation-message.ts +4 -0
- package/src/api/responses/llm-request-log-entry.ts +25 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/api/surfaces.ts +33 -0
- package/src/approvals/AGENTS.md +1 -2
- package/src/approvals/guardian-decision-primitive.ts +13 -210
- package/src/approvals/guardian-request-resolvers.ts +104 -58
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/inbound-trust-reader.test.ts +110 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +349 -65
- package/src/calls/guardian-dispatch.ts +10 -8
- package/src/calls/inbound-trust-reader.ts +56 -0
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-server.ts +231 -72
- package/src/calls/relay-setup-router.ts +57 -13
- package/src/calls/relay-verification.ts +7 -7
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +13 -3
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/contacts.ts +6 -24
- package/src/cli/commands/db/__tests__/repair.test.ts +15 -6
- package/src/cli/commands/db/__tests__/status.test.ts +7 -3
- package/src/cli/commands/db/status.ts +212 -33
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +6 -1
- package/src/cli/commands/memory/__tests__/worker.test.ts +302 -0
- package/src/cli/commands/memory/index.ts +4 -0
- package/src/cli/commands/memory/memory-retrospective.ts +129 -0
- package/src/cli/commands/memory/memory-v3.ts +176 -4
- package/src/cli/commands/memory/worker.ts +175 -0
- package/src/cli/commands/plugins.ts +343 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +158 -0
- package/src/cli/lib/install-from-github.ts +47 -6
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -0
- package/src/cli/lib/toggle-plugin.ts +146 -0
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +15 -33
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +3 -8
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +64 -37
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +1 -1
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +14 -72
- package/src/config/bundled-skills/app-builder/references/examples/README.md +1 -2
- package/src/config/bundled-skills/contacts/SKILL.md +7 -12
- package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
- package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
- package/src/config/bundled-skills/workflows/SKILL.md +4 -3
- package/src/config/call-site-defaults.ts +11 -2
- package/src/config/feature-flag-registry.json +0 -8
- package/src/config/llm-resolver.ts +151 -14
- package/src/config/loader.ts +36 -5
- package/src/config/profile-dispatchability.ts +11 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +17 -3
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +32 -0
- package/src/config/seed-inference-profiles.ts +147 -50
- package/src/config/skills.ts +27 -5
- package/src/config/sync-gated-profiles.ts +13 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/contact-store.ts +21 -0
- package/src/contacts/contacts-write.ts +3 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/contacts/member-status.ts +9 -0
- package/src/credential-health/credential-health-service.ts +1 -5
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
- package/src/daemon/app-source-watcher.ts +31 -18
- package/src/daemon/assistant-attachments.ts +94 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +3 -0
- package/src/daemon/conversation-agent-loop.ts +18 -36
- package/src/daemon/conversation-process.ts +35 -16
- package/src/daemon/conversation-runtime-assembly.ts +91 -66
- package/src/daemon/conversation-surfaces.ts +273 -18
- package/src/daemon/conversation-tool-setup.ts +24 -64
- package/src/daemon/conversation.ts +149 -53
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.test.ts +85 -0
- package/src/daemon/event-loop-watchdog.ts +133 -0
- package/src/daemon/external-plugins-bootstrap.ts +26 -80
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -1
- package/src/daemon/handlers/config-channels.ts +41 -27
- package/src/daemon/handlers/conversations.ts +84 -0
- package/src/daemon/handlers/shared.ts +7 -0
- package/src/daemon/lifecycle.ts +44 -5
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/message-types/inbox.ts +0 -6
- package/src/daemon/message-types/messages.ts +0 -4
- package/src/daemon/message-types/surfaces.ts +12 -11
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +7 -5
- package/src/daemon/trust-context.ts +6 -0
- package/src/daemon/wake-conversation-ops.ts +70 -0
- package/src/daemon/workspace-tools-watcher.ts +7 -3
- package/src/documents/document-comments-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
- package/src/heartbeat/heartbeat-service.ts +3 -4
- package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +73 -2
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/__tests__/watcher-ipc.test.ts +59 -39
- package/src/ipc/assistant-server.ts +10 -2
- package/src/ipc/gateway-client.ts +2 -1
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +58 -0
- package/src/ipc/routes/invite-ipc-routes.ts +66 -0
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
- package/src/memory/__tests__/activation-session-store.test.ts +1 -1
- package/src/memory/__tests__/auto-analysis-guard.test.ts +1 -1
- package/src/memory/__tests__/conversation-group-migration.test.ts +1 -1
- package/src/memory/__tests__/conversation-queries.test.ts +1 -1
- package/src/memory/__tests__/db-async-query.test.ts +1 -1
- package/src/memory/__tests__/db-logs-attach.test.ts +110 -0
- package/src/memory/__tests__/db-maintenance.test.ts +28 -36
- package/src/memory/__tests__/db-memory-attach.test.ts +113 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +1 -1
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -1
- package/src/memory/__tests__/fork-message-copy.test.ts +232 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +3 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +5 -5
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +8 -6
- package/src/memory/__tests__/memory-retrospective-job.test.ts +30 -37
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +69 -66
- package/src/memory/__tests__/memory-retrospective-state.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +1 -1
- package/src/memory/__tests__/onboarding-events-store.test.ts +1 -1
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/table-relocation.test.ts +129 -0
- package/src/memory/conversation-crud.ts +461 -152
- package/src/memory/db-async-query.ts +89 -5
- package/src/memory/db-connection.ts +101 -18
- package/src/memory/db-init.ts +409 -234
- package/src/memory/db-maintenance.ts +43 -38
- package/src/memory/db-singleton.ts +45 -19
- package/src/memory/embedding-gemini.test.ts +3 -1
- package/src/memory/embedding-gemini.ts +18 -2
- package/src/memory/fork-message-copy.ts +170 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +92 -0
- package/src/memory/graph/bootstrap.test.ts +6 -3
- package/src/memory/graph/retriever.test.ts +12 -12
- package/src/memory/graph/store.test.ts +15 -25
- package/src/memory/graph/store.ts +23 -14
- package/src/memory/graph/tool-handlers.ts +34 -5
- package/src/memory/graph/tools.ts +5 -2
- package/src/memory/indexer.ts +21 -9
- package/src/memory/job-handlers/cleanup.ts +10 -3
- package/src/memory/job-handlers/embedding.test.ts +4 -4
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +4 -4
- package/src/memory/jobs/embed-pkb-file.test.ts +7 -7
- package/src/memory/jobs-store.ts +36 -24
- package/src/memory/llm-request-log-store.ts +51 -19
- package/src/memory/llm-usage-store.ts +79 -21
- package/src/memory/memory-retrospective-job.ts +27 -19
- package/src/memory/memory-retrospective-startup-cleanup.ts +10 -2
- package/src/memory/migrations/{100-core-tables.ts → 000-core-tables.ts} +6 -10
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +13 -3
- package/src/memory/migrations/104-core-indexes.ts +1 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +189 -196
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +98 -105
- package/src/memory/migrations/134-contacts-notes-column.ts +66 -69
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +19 -22
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +241 -219
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +204 -209
- package/src/memory/migrations/141-rename-verification-table.ts +45 -48
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +16 -23
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +23 -30
- package/src/memory/migrations/144-rename-voice-to-phone.ts +133 -136
- package/src/memory/migrations/145-drop-accounts-table.ts +4 -7
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +79 -82
- package/src/memory/migrations/148-drop-reminders-table.ts +3 -6
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +71 -78
- package/src/memory/migrations/157-invite-contact-id.ts +73 -76
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +44 -58
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +36 -43
- package/src/memory/migrations/174-rename-thread-starters-table.ts +30 -37
- package/src/memory/migrations/176-drop-capability-card-state.ts +17 -22
- package/src/memory/migrations/177-create-trace-events-table.ts +23 -28
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +36 -43
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +14 -21
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +17 -24
- package/src/memory/migrations/192-contacts-user-file-column.ts +6 -9
- package/src/memory/migrations/193-add-source-type-columns.ts +33 -36
- package/src/memory/migrations/194-memory-recall-logs.ts +34 -39
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +59 -66
- package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +41 -48
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +11 -18
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +76 -83
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +135 -68
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +6 -11
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +4 -9
- package/src/memory/migrations/217-conversation-host-access.ts +13 -18
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +86 -93
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +41 -48
- package/src/memory/migrations/230-acp-session-history.ts +23 -28
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +58 -62
- package/src/memory/migrations/232-activation-state.ts +11 -16
- package/src/memory/migrations/233-document-conversations.ts +20 -25
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +26 -31
- package/src/memory/migrations/235-slack-compaction-watermark.ts +5 -10
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +6 -11
- package/src/memory/migrations/237-heartbeat-runs.ts +22 -27
- package/src/memory/migrations/239-trace-events-created-at-index.ts +4 -9
- package/src/memory/migrations/242-message-bookmarks.ts +17 -22
- package/src/memory/migrations/245-memory-retrospective-state.ts +8 -13
- package/src/memory/migrations/249-normalize-slack-external-content.ts +37 -41
- package/src/memory/migrations/251-a2a-tasks.ts +27 -32
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +12 -17
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +10 -15
- package/src/memory/migrations/256-memory-v2-injection-events.ts +70 -74
- package/src/memory/migrations/259-conversation-cleaned-at.ts +4 -9
- package/src/memory/migrations/260-rename-cleaned-at.ts +11 -16
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +3 -8
- package/src/memory/migrations/262-memory-v3-coactivation.ts +21 -26
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +14 -19
- package/src/memory/migrations/270-schedule-description.ts +7 -12
- package/src/memory/migrations/272-acp-session-history-cwd.ts +8 -13
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +8 -13
- package/src/memory/migrations/297-move-llm-request-logs-to-logs-db.ts +111 -0
- package/src/memory/migrations/298-move-memory-jobs-to-memory-db.ts +128 -0
- package/src/memory/migrations/299-canonical-guardian-deliveries-conversation-index.ts +19 -0
- package/src/memory/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +108 -0
- package/src/memory/migrations/__tests__/136-drop-assistant-id-columns.test.ts +82 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +224 -0
- package/src/memory/migrations/__tests__/297-move-llm-request-logs.test.ts +180 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +333 -7
- package/src/memory/migrations/helpers/relocation.ts +227 -0
- package/src/memory/migrations/registry.ts +63 -0
- package/src/memory/migrations/run-migrations.ts +187 -16
- package/src/memory/migrations/schema-introspection.ts +14 -0
- package/src/memory/migrations/validate-migration-state.ts +50 -145
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/raw-query.ts +47 -2
- package/src/memory/skill-loaded-events-store.test.ts +1 -1
- package/src/memory/task-memory-cleanup.ts +62 -41
- package/src/memory/tool-executed-events-store.test.ts +1 -1
- package/src/memory/turn-trace-store.test.ts +1 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +16 -15
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +2 -2
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +38 -0
- package/src/memory/v3-eval/__tests__/eval-tally.test.ts +139 -0
- package/src/memory/v3-eval/eval-packets.ts +197 -12
- package/src/memory/v3-eval/eval-tally.ts +234 -0
- package/src/memory/worker-control.ts +118 -0
- package/src/memory/worker-process.ts +72 -0
- package/src/messaging/provider.ts +10 -0
- package/src/messaging/providers/gmail/adapter.ts +1 -0
- package/src/messaging/providers/gmail/client.ts +13 -0
- package/src/messaging/providers/index.ts +1 -1
- package/src/messaging/providers/slack/send.test.ts +87 -39
- package/src/messaging/providers/slack/send.ts +84 -105
- package/src/notifications/README.md +9 -5
- package/src/notifications/__tests__/broadcaster.test.ts +16 -8
- package/src/notifications/__tests__/connected-channels.test.ts +114 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +256 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +43 -1
- package/src/notifications/adapters/slack.ts +12 -10
- package/src/notifications/approval-card-builder.ts +81 -20
- package/src/notifications/approval-card-data.ts +8 -5
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/canonical-delivery-recorder.ts +7 -5
- package/src/notifications/conversation-candidates.ts +24 -59
- package/src/notifications/copy-composer.ts +48 -68
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +68 -24
- package/src/notifications/deterministic-checks.ts +19 -16
- package/src/notifications/emit-signal.ts +68 -15
- package/src/notifications/trusted-contact-payloads.ts +70 -0
- package/src/oauth/byo-connection.test.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +174 -6
- package/src/oauth/connection-resolver.ts +132 -5
- package/src/oauth/oauth-store.ts +16 -3
- package/src/oauth/scope-utils.ts +39 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +9 -4
- package/src/plugin-api/model-profiles.test.ts +123 -0
- package/src/plugin-api/model-profiles.ts +5 -1
- package/src/plugin-api/vision-support.test.ts +173 -0
- package/src/plugin-api/vision-support.ts +113 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +90 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +106 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +60 -0
- package/src/plugins/defaults/advisor/consult.ts +65 -6
- package/src/plugins/defaults/advisor/context-pack.ts +288 -0
- package/src/plugins/defaults/advisor/steering.ts +14 -2
- package/src/plugins/defaults/advisor/tools/advisor.ts +32 -5
- package/src/plugins/defaults/compaction/window-manager.ts +45 -64
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +13 -4
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +441 -0
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +57 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +61 -0
- package/src/plugins/defaults/image-fallback/package.json +14 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +108 -0
- package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
- package/src/plugins/defaults/image-fallback/src/image-persist.ts +56 -0
- package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
- package/src/plugins/defaults/index.ts +27 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +14 -1
- package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +134 -5
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +246 -19
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +8 -1
- package/src/plugins/external-plugin-loader.ts +47 -6
- package/src/plugins/mtime-cache.ts +772 -0
- package/src/plugins/pipeline.ts +7 -2
- package/src/plugins/registry.ts +16 -5
- package/src/plugins/user-loader.ts +22 -76
- package/src/prompts/persona-resolver.ts +29 -11
- package/src/prompts/system-prompt.ts +1 -1
- package/src/prompts/templates/system-sections.ts +4 -4
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
- package/src/providers/anthropic/client.ts +290 -185
- package/src/providers/call-site-routing.ts +14 -0
- package/src/providers/gemini/client.ts +43 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +6 -1
- package/src/providers/model-catalog.ts +53 -0
- package/src/providers/openai/responses-provider.ts +5 -0
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-send-message.ts +4 -0
- package/src/providers/ratelimit.ts +13 -0
- package/src/providers/retry.ts +14 -0
- package/src/providers/together/client.ts +35 -0
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +11 -0
- package/src/runtime/AGENTS.md +9 -1
- package/src/runtime/__tests__/agent-wake.test.ts +259 -4
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +181 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +64 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +164 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +39 -10
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +670 -0
- package/src/runtime/access-request-helper.ts +19 -39
- package/src/runtime/actor-trust-resolver.ts +8 -16
- package/src/runtime/agent-wake.ts +183 -60
- package/src/runtime/anchored-guardian.test.ts +156 -0
- package/src/runtime/anchored-guardian.ts +135 -0
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-reply-delivery.ts +6 -3
- package/src/runtime/channel-verification-service.ts +24 -0
- package/src/runtime/guardian-decision-types.ts +3 -22
- package/src/runtime/guardian-vellum-migration.ts +66 -7
- package/src/runtime/http-server.ts +1 -15
- package/src/runtime/invite-redemption-service.ts +155 -6
- package/src/runtime/invite-service.ts +113 -62
- package/src/runtime/local-actor-identity.ts +76 -11
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +277 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +140 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +26 -7
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +164 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +8 -8
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +1 -3
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +240 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +4 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +143 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +163 -0
- package/src/runtime/routes/acp-routes-list.test.ts +4 -0
- package/src/runtime/routes/acp-routes.test.ts +5 -6
- package/src/runtime/routes/attachment-routes.ts +21 -17
- package/src/runtime/routes/browser-routes.ts +19 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -9
- package/src/runtime/routes/channel-verification-routes.ts +13 -2
- package/src/runtime/routes/contact-routes.ts +275 -164
- package/src/runtime/routes/conversation-query-routes.ts +15 -5
- package/src/runtime/routes/conversation-routes.ts +80 -66
- package/src/runtime/routes/conversation-starter-routes.ts +7 -8
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/guardian-approval-interception.ts +13 -274
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/inbound-message-handler.ts +21 -16
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +376 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +86 -64
- package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +16 -4
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/llm-context-normalization.ts +71 -0
- package/src/runtime/routes/log-export-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +38 -15
- package/src/runtime/routes/memory-eval-routes.ts +92 -0
- package/src/runtime/routes/memory-item-routes.test.ts +12 -11
- package/src/runtime/routes/migration-routes.ts +51 -40
- package/src/runtime/routes/plugins-routes.ts +164 -8
- package/src/runtime/routes/schedule-routes.ts +1 -0
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +39 -51
- package/src/runtime/routes/usage-routes.ts +3 -0
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/slack-block-formatting.ts +46 -48
- package/src/runtime/trust-verdict-consumer.ts +210 -0
- package/src/schedule/scheduler.ts +6 -9
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/manager.ts +9 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +89 -52
- package/src/tools/ask-question/ask-question-tool.ts +27 -73
- package/src/tools/browser/__tests__/browser-status.test.ts +20 -0
- package/src/tools/browser/browser-execution.ts +16 -4
- package/src/tools/document/document-comment-tool.test.ts +1 -1
- package/src/tools/executor.ts +15 -3
- package/src/tools/host-terminal/host-shell.ts +28 -9
- package/src/tools/memory/register.test.ts +32 -0
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +4 -10
- package/src/tools/terminal/shell.ts +16 -5
- package/src/tools/tool-defaults.ts +2 -0
- package/src/tools/types.ts +18 -2
- package/src/tools/ui-surface/definitions.ts +0 -43
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/log-redact.ts +2 -4
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/memory-db-path.ts +23 -0
- package/src/util/platform.ts +5 -0
- package/src/watcher/providers/gmail.ts +7 -2
- package/src/workflows/engine-integration.test.ts +1 -1
- package/src/workflows/engine.test.ts +1 -1
- package/src/workflows/engine.ts +22 -0
- package/src/workflows/fanout-load.test.ts +1 -1
- package/src/workflows/journal-store.test.ts +1 -1
- package/src/workflows/leaf-runner.test.ts +40 -1
- package/src/workflows/leaf-runner.ts +26 -1
- package/src/workspace/git-service.ts +144 -29
- package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +121 -0
- package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +82 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/migrations/runner.ts +32 -2
- package/src/__tests__/access-request-decision.test.ts +0 -375
- package/src/__tests__/guardian-grant-minting.test.ts +0 -607
- package/src/__tests__/plugin-source-watcher.test.ts +0 -302
- package/src/api/events/turn-profile-auto-routed.ts +0 -28
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +0 -107
- package/src/daemon/plugin-source-watcher.ts +0 -278
- package/src/daemon/switch-inference-profile-tool.ts +0 -62
- package/src/memory/guardian-approvals.ts +0 -361
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +0 -66
- package/src/memory/migrations/038-actor-token-records.ts +0 -45
- package/src/memory/migrations/039-actor-refresh-token-records.ts +0 -57
- package/src/memory/migrations/103-complex-migrations.ts +0 -23
- package/src/memory/migrations/113-late-migrations.ts +0 -30
- package/src/memory/migrations/index.ts +0 -301
- package/src/runtime/routes/access-request-decision.ts +0 -297
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -963
- package/src/runtime/routes/channel-guardian-routes.ts +0 -19
- package/src/runtime/routes/guardian-expiry-sweep.ts +0 -132
|
@@ -63,6 +63,52 @@ mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
|
63
63
|
},
|
|
64
64
|
}));
|
|
65
65
|
|
|
66
|
+
// Gateway relay mock — the revoke path relays the ACL downgrade over IPC and
|
|
67
|
+
// validates the response; return a well-formed mark_channel_revoked result.
|
|
68
|
+
mock.module("../ipc/gateway-client.js", () => ({
|
|
69
|
+
ipcCallPersistent: async (
|
|
70
|
+
_method: string,
|
|
71
|
+
params?: Record<string, unknown>,
|
|
72
|
+
) => ({
|
|
73
|
+
ok: true,
|
|
74
|
+
didWrite: true,
|
|
75
|
+
channel: {
|
|
76
|
+
id: (params?.contactChannelId as string) ?? "ch1",
|
|
77
|
+
contactId: "c1",
|
|
78
|
+
type: "phone",
|
|
79
|
+
address: "addr",
|
|
80
|
+
status: "revoked",
|
|
81
|
+
revokedReason: (params?.reason as string) ?? null,
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
// Guardian-delivery reader mock — the inbound challenge guard reads guardian
|
|
87
|
+
// existence from the gateway. Derive the list from the local binding state so
|
|
88
|
+
// the gateway-backed presence guard mirrors the DB the rest of the test sets up.
|
|
89
|
+
const resolveGuardianList = async (input?: { channelTypes?: string[] }) => {
|
|
90
|
+
const { findGuardianForChannel } = await import(
|
|
91
|
+
"../contacts/contact-store.js"
|
|
92
|
+
);
|
|
93
|
+
const channels = input?.channelTypes ?? [];
|
|
94
|
+
return channels
|
|
95
|
+
.map((channelType) => {
|
|
96
|
+
const found = findGuardianForChannel(channelType);
|
|
97
|
+
return found ? { channelType, status: "active" } : null;
|
|
98
|
+
})
|
|
99
|
+
.filter((g): g is { channelType: string; status: string } => g !== null);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
mock.module("../contacts/guardian-delivery-reader.js", () => ({
|
|
103
|
+
getGuardianDelivery: resolveGuardianList,
|
|
104
|
+
getGuardianDeliveryFresh: resolveGuardianList,
|
|
105
|
+
guardianForChannel: (
|
|
106
|
+
list: Array<{ channelType: string; status: string }>,
|
|
107
|
+
channelType: string,
|
|
108
|
+
) =>
|
|
109
|
+
list.find((g) => g.channelType === channelType && g.status === "active"),
|
|
110
|
+
}));
|
|
111
|
+
|
|
66
112
|
import { handleChannelVerificationSession } from "../daemon/handlers/config-channels.js";
|
|
67
113
|
import type {
|
|
68
114
|
ChannelVerificationSessionRequest,
|
|
@@ -84,12 +130,6 @@ import {
|
|
|
84
130
|
import { getDb } from "../memory/db-connection.js";
|
|
85
131
|
import { initializeDb } from "../memory/db-init.js";
|
|
86
132
|
import { upsertBinding as upsertExternalBinding } from "../memory/external-conversation-store.js";
|
|
87
|
-
import {
|
|
88
|
-
createApprovalRequest,
|
|
89
|
-
getPendingApprovalByGuardianChat,
|
|
90
|
-
getPendingApprovalForRequest,
|
|
91
|
-
updateApprovalDecision,
|
|
92
|
-
} from "../memory/guardian-approvals.js";
|
|
93
133
|
import {
|
|
94
134
|
getRateLimit,
|
|
95
135
|
recordInvalidAttempt,
|
|
@@ -133,7 +173,6 @@ afterAll(() => {
|
|
|
133
173
|
function resetTables(): void {
|
|
134
174
|
const db = getDb();
|
|
135
175
|
db.run("DELETE FROM channel_verification_sessions");
|
|
136
|
-
db.run("DELETE FROM channel_guardian_approval_requests");
|
|
137
176
|
db.run("DELETE FROM channel_guardian_rate_limits");
|
|
138
177
|
db.run("DELETE FROM contact_channels");
|
|
139
178
|
db.run("DELETE FROM contacts");
|
|
@@ -564,251 +603,6 @@ describe("guardian identity check", () => {
|
|
|
564
603
|
// 5. Approval Request CRUD (Store)
|
|
565
604
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
566
605
|
|
|
567
|
-
describe("guardian approval request CRUD", () => {
|
|
568
|
-
beforeEach(() => {
|
|
569
|
-
resetTables();
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
test("createApprovalRequest creates a pending request", () => {
|
|
573
|
-
const request = createApprovalRequest({
|
|
574
|
-
runId: "run-1",
|
|
575
|
-
requestId: "req-1",
|
|
576
|
-
conversationId: "conv-1",
|
|
577
|
-
channel: "telegram",
|
|
578
|
-
requesterExternalUserId: "user-99",
|
|
579
|
-
requesterChatId: "chat-99",
|
|
580
|
-
guardianExternalUserId: "user-42",
|
|
581
|
-
guardianChatId: "chat-42",
|
|
582
|
-
toolName: "shell",
|
|
583
|
-
riskLevel: "high",
|
|
584
|
-
reason: "Executing rm command",
|
|
585
|
-
expiresAt: Date.now() + 300_000,
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
expect(request.id).toBeDefined();
|
|
589
|
-
expect(request.runId).toBe("run-1");
|
|
590
|
-
expect(request.requestId).toBe("req-1");
|
|
591
|
-
expect(request.status).toBe("pending");
|
|
592
|
-
expect(request.toolName).toBe("shell");
|
|
593
|
-
expect(request.riskLevel).toBe("high");
|
|
594
|
-
expect(request.reason).toBe("Executing rm command");
|
|
595
|
-
expect(request.decidedByExternalUserId).toBeNull();
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
test("getPendingApprovalForRequest returns the pending request", () => {
|
|
599
|
-
createApprovalRequest({
|
|
600
|
-
runId: "run-1",
|
|
601
|
-
requestId: "req-1",
|
|
602
|
-
conversationId: "conv-1",
|
|
603
|
-
channel: "telegram",
|
|
604
|
-
requesterExternalUserId: "user-99",
|
|
605
|
-
requesterChatId: "chat-99",
|
|
606
|
-
guardianExternalUserId: "user-42",
|
|
607
|
-
guardianChatId: "chat-42",
|
|
608
|
-
toolName: "shell",
|
|
609
|
-
expiresAt: Date.now() + 300_000,
|
|
610
|
-
});
|
|
611
|
-
|
|
612
|
-
const found = getPendingApprovalForRequest("req-1");
|
|
613
|
-
expect(found).not.toBeNull();
|
|
614
|
-
expect(found!.requestId).toBe("req-1");
|
|
615
|
-
expect(found!.status).toBe("pending");
|
|
616
|
-
});
|
|
617
|
-
|
|
618
|
-
test("getPendingApprovalForRequest returns null when no pending request exists", () => {
|
|
619
|
-
const found = getPendingApprovalForRequest("req-nonexistent");
|
|
620
|
-
expect(found).toBeNull();
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
test("getPendingApprovalByGuardianChat returns pending request for guardian chat", () => {
|
|
624
|
-
createApprovalRequest({
|
|
625
|
-
runId: "run-1",
|
|
626
|
-
requestId: "req-1",
|
|
627
|
-
conversationId: "conv-1",
|
|
628
|
-
channel: "telegram",
|
|
629
|
-
requesterExternalUserId: "user-99",
|
|
630
|
-
requesterChatId: "chat-99",
|
|
631
|
-
guardianExternalUserId: "user-42",
|
|
632
|
-
guardianChatId: "chat-42",
|
|
633
|
-
toolName: "shell",
|
|
634
|
-
expiresAt: Date.now() + 300_000,
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
const found = getPendingApprovalByGuardianChat("telegram", "chat-42");
|
|
638
|
-
expect(found).not.toBeNull();
|
|
639
|
-
expect(found!.guardianChatId).toBe("chat-42");
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
test("getPendingApprovalByGuardianChat returns null for wrong channel", () => {
|
|
643
|
-
createApprovalRequest({
|
|
644
|
-
runId: "run-1",
|
|
645
|
-
requestId: "req-1",
|
|
646
|
-
conversationId: "conv-1",
|
|
647
|
-
channel: "telegram",
|
|
648
|
-
requesterExternalUserId: "user-99",
|
|
649
|
-
requesterChatId: "chat-99",
|
|
650
|
-
guardianExternalUserId: "user-42",
|
|
651
|
-
guardianChatId: "chat-42",
|
|
652
|
-
toolName: "shell",
|
|
653
|
-
expiresAt: Date.now() + 300_000,
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
const found = getPendingApprovalByGuardianChat("slack", "chat-42");
|
|
657
|
-
expect(found).toBeNull();
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
test("updateApprovalDecision updates status to approved", () => {
|
|
661
|
-
const request = createApprovalRequest({
|
|
662
|
-
runId: "run-1",
|
|
663
|
-
requestId: "req-1",
|
|
664
|
-
conversationId: "conv-1",
|
|
665
|
-
channel: "telegram",
|
|
666
|
-
requesterExternalUserId: "user-99",
|
|
667
|
-
requesterChatId: "chat-99",
|
|
668
|
-
guardianExternalUserId: "user-42",
|
|
669
|
-
guardianChatId: "chat-42",
|
|
670
|
-
toolName: "shell",
|
|
671
|
-
expiresAt: Date.now() + 300_000,
|
|
672
|
-
});
|
|
673
|
-
|
|
674
|
-
updateApprovalDecision(request.id, {
|
|
675
|
-
status: "approved",
|
|
676
|
-
decidedByExternalUserId: "user-42",
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
// After approval, getPendingApprovalForRequest should return null
|
|
680
|
-
const found = getPendingApprovalForRequest("req-1");
|
|
681
|
-
expect(found).toBeNull();
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
test("updateApprovalDecision updates status to denied", () => {
|
|
685
|
-
const request = createApprovalRequest({
|
|
686
|
-
runId: "run-1",
|
|
687
|
-
requestId: "req-1",
|
|
688
|
-
conversationId: "conv-1",
|
|
689
|
-
channel: "telegram",
|
|
690
|
-
requesterExternalUserId: "user-99",
|
|
691
|
-
requesterChatId: "chat-99",
|
|
692
|
-
guardianExternalUserId: "user-42",
|
|
693
|
-
guardianChatId: "chat-42",
|
|
694
|
-
toolName: "shell",
|
|
695
|
-
expiresAt: Date.now() + 300_000,
|
|
696
|
-
});
|
|
697
|
-
|
|
698
|
-
updateApprovalDecision(request.id, {
|
|
699
|
-
status: "denied",
|
|
700
|
-
decidedByExternalUserId: "user-42",
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
const found = getPendingApprovalForRequest("req-1");
|
|
704
|
-
expect(found).toBeNull();
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
test("multiple approval requests for different runs are independent", () => {
|
|
708
|
-
createApprovalRequest({
|
|
709
|
-
runId: "run-1",
|
|
710
|
-
requestId: "req-1",
|
|
711
|
-
conversationId: "conv-1",
|
|
712
|
-
channel: "telegram",
|
|
713
|
-
requesterExternalUserId: "user-99",
|
|
714
|
-
requesterChatId: "chat-99",
|
|
715
|
-
guardianExternalUserId: "user-42",
|
|
716
|
-
guardianChatId: "chat-42",
|
|
717
|
-
toolName: "shell",
|
|
718
|
-
expiresAt: Date.now() + 300_000,
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
createApprovalRequest({
|
|
722
|
-
runId: "run-2",
|
|
723
|
-
requestId: "req-2",
|
|
724
|
-
conversationId: "conv-2",
|
|
725
|
-
channel: "telegram",
|
|
726
|
-
requesterExternalUserId: "user-88",
|
|
727
|
-
requesterChatId: "chat-88",
|
|
728
|
-
guardianExternalUserId: "user-42",
|
|
729
|
-
guardianChatId: "chat-42",
|
|
730
|
-
toolName: "browser",
|
|
731
|
-
expiresAt: Date.now() + 300_000,
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
const found1 = getPendingApprovalForRequest("req-1");
|
|
735
|
-
const found2 = getPendingApprovalForRequest("req-2");
|
|
736
|
-
expect(found1).not.toBeNull();
|
|
737
|
-
expect(found2).not.toBeNull();
|
|
738
|
-
expect(found1!.toolName).toBe("shell");
|
|
739
|
-
expect(found2!.toolName).toBe("browser");
|
|
740
|
-
});
|
|
741
|
-
|
|
742
|
-
test("createApprovalRequest works for voice channel", () => {
|
|
743
|
-
const request = createApprovalRequest({
|
|
744
|
-
runId: "run-voice-1",
|
|
745
|
-
requestId: "req-voice-1",
|
|
746
|
-
conversationId: "conv-voice-1",
|
|
747
|
-
channel: "phone",
|
|
748
|
-
requesterExternalUserId: "phone-user-99",
|
|
749
|
-
requesterChatId: "voice-chat-99",
|
|
750
|
-
guardianExternalUserId: "phone-user-42",
|
|
751
|
-
guardianChatId: "voice-chat-42",
|
|
752
|
-
toolName: "shell",
|
|
753
|
-
expiresAt: Date.now() + 300_000,
|
|
754
|
-
});
|
|
755
|
-
|
|
756
|
-
expect(request.id).toBeDefined();
|
|
757
|
-
expect(request.runId).toBe("run-voice-1");
|
|
758
|
-
expect(request.requestId).toBe("req-voice-1");
|
|
759
|
-
expect(request.channel).toBe("phone");
|
|
760
|
-
expect(request.status).toBe("pending");
|
|
761
|
-
|
|
762
|
-
const found = getPendingApprovalForRequest("req-voice-1");
|
|
763
|
-
expect(found).not.toBeNull();
|
|
764
|
-
expect(found!.channel).toBe("phone");
|
|
765
|
-
});
|
|
766
|
-
|
|
767
|
-
test("getPendingApprovalByGuardianChat works for voice channel", () => {
|
|
768
|
-
createApprovalRequest({
|
|
769
|
-
runId: "run-voice-2",
|
|
770
|
-
requestId: "req-voice-2",
|
|
771
|
-
conversationId: "conv-voice-2",
|
|
772
|
-
channel: "phone",
|
|
773
|
-
requesterExternalUserId: "phone-user-99",
|
|
774
|
-
requesterChatId: "voice-chat-99",
|
|
775
|
-
guardianExternalUserId: "phone-user-42",
|
|
776
|
-
guardianChatId: "voice-chat-42",
|
|
777
|
-
toolName: "shell",
|
|
778
|
-
expiresAt: Date.now() + 300_000,
|
|
779
|
-
});
|
|
780
|
-
|
|
781
|
-
const found = getPendingApprovalByGuardianChat("phone", "voice-chat-42");
|
|
782
|
-
expect(found).not.toBeNull();
|
|
783
|
-
expect(found!.channel).toBe("phone");
|
|
784
|
-
|
|
785
|
-
// Should not find it under a different channel
|
|
786
|
-
const notFound = getPendingApprovalByGuardianChat(
|
|
787
|
-
"telegram",
|
|
788
|
-
"voice-chat-42",
|
|
789
|
-
);
|
|
790
|
-
expect(notFound).toBeNull();
|
|
791
|
-
});
|
|
792
|
-
|
|
793
|
-
test("createApprovalRequest with optional fields omitted defaults to null", () => {
|
|
794
|
-
const request = createApprovalRequest({
|
|
795
|
-
runId: "run-1",
|
|
796
|
-
requestId: "req-1",
|
|
797
|
-
conversationId: "conv-1",
|
|
798
|
-
channel: "telegram",
|
|
799
|
-
requesterExternalUserId: "user-99",
|
|
800
|
-
requesterChatId: "chat-99",
|
|
801
|
-
guardianExternalUserId: "user-42",
|
|
802
|
-
guardianChatId: "chat-42",
|
|
803
|
-
toolName: "shell",
|
|
804
|
-
expiresAt: Date.now() + 300_000,
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
expect(request.riskLevel).toBeNull();
|
|
808
|
-
expect(request.reason).toBeNull();
|
|
809
|
-
});
|
|
810
|
-
});
|
|
811
|
-
|
|
812
606
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
813
607
|
// 6. Verification Rate Limiting (Store)
|
|
814
608
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -1204,64 +998,6 @@ describe("channel-scoped guardian resolution", () => {
|
|
|
1204
998
|
// 9. Assistant-scoped approval request lookups
|
|
1205
999
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
1206
1000
|
|
|
1207
|
-
describe("assistant-scoped approval request lookups", () => {
|
|
1208
|
-
beforeEach(() => {
|
|
1209
|
-
resetTables();
|
|
1210
|
-
});
|
|
1211
|
-
|
|
1212
|
-
test("createApprovalRequest no longer exposes assistantId on the returned interface", () => {
|
|
1213
|
-
const req = createApprovalRequest({
|
|
1214
|
-
runId: "run-1",
|
|
1215
|
-
requestId: "req-1",
|
|
1216
|
-
conversationId: "conv-1",
|
|
1217
|
-
channel: "telegram",
|
|
1218
|
-
requesterExternalUserId: "user-99",
|
|
1219
|
-
requesterChatId: "chat-99",
|
|
1220
|
-
guardianExternalUserId: "user-42",
|
|
1221
|
-
guardianChatId: "chat-42",
|
|
1222
|
-
toolName: "shell",
|
|
1223
|
-
expiresAt: Date.now() + 300_000,
|
|
1224
|
-
});
|
|
1225
|
-
// assistantId is no longer on the public interface
|
|
1226
|
-
expect(req.id).toBeDefined();
|
|
1227
|
-
expect(req.toolName).toBe("shell");
|
|
1228
|
-
});
|
|
1229
|
-
|
|
1230
|
-
test("approval requests from different conversations are independent", () => {
|
|
1231
|
-
createApprovalRequest({
|
|
1232
|
-
runId: "run-A",
|
|
1233
|
-
requestId: "req-A",
|
|
1234
|
-
conversationId: "conv-A",
|
|
1235
|
-
channel: "telegram",
|
|
1236
|
-
requesterExternalUserId: "user-99",
|
|
1237
|
-
requesterChatId: "chat-99",
|
|
1238
|
-
guardianExternalUserId: "user-42",
|
|
1239
|
-
guardianChatId: "chat-42",
|
|
1240
|
-
toolName: "shell",
|
|
1241
|
-
expiresAt: Date.now() + 300_000,
|
|
1242
|
-
});
|
|
1243
|
-
createApprovalRequest({
|
|
1244
|
-
runId: "run-B",
|
|
1245
|
-
requestId: "req-B",
|
|
1246
|
-
conversationId: "conv-B",
|
|
1247
|
-
channel: "telegram",
|
|
1248
|
-
requesterExternalUserId: "user-88",
|
|
1249
|
-
requesterChatId: "chat-88",
|
|
1250
|
-
guardianExternalUserId: "user-42",
|
|
1251
|
-
guardianChatId: "chat-42",
|
|
1252
|
-
toolName: "browser",
|
|
1253
|
-
expiresAt: Date.now() + 300_000,
|
|
1254
|
-
});
|
|
1255
|
-
|
|
1256
|
-
const foundA = getPendingApprovalForRequest("req-A");
|
|
1257
|
-
const foundB = getPendingApprovalForRequest("req-B");
|
|
1258
|
-
expect(foundA).not.toBeNull();
|
|
1259
|
-
expect(foundB).not.toBeNull();
|
|
1260
|
-
expect(foundA!.toolName).toBe("shell");
|
|
1261
|
-
expect(foundB!.toolName).toBe("browser");
|
|
1262
|
-
});
|
|
1263
|
-
});
|
|
1264
|
-
|
|
1265
1001
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
1266
1002
|
// 10. HTTP handler — channel-aware guardian status response
|
|
1267
1003
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -2588,24 +2324,20 @@ describe("outbound voice verification", () => {
|
|
|
2588
2324
|
test("resend_outbound before cooldown is rejected", async () => {
|
|
2589
2325
|
// Start an outbound session first
|
|
2590
2326
|
broadcastedMessages.length = 0;
|
|
2591
|
-
await handleChannelVerificationSession(
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
},
|
|
2598
|
-
);
|
|
2327
|
+
await handleChannelVerificationSession({
|
|
2328
|
+
type: "channel_verification_session",
|
|
2329
|
+
action: "create_session",
|
|
2330
|
+
channel: "phone",
|
|
2331
|
+
destination: "+15551234567",
|
|
2332
|
+
});
|
|
2599
2333
|
|
|
2600
2334
|
// Immediately try to resend (before cooldown)
|
|
2601
2335
|
const { lastResponse } = createResponseReader();
|
|
2602
|
-
await handleChannelVerificationSession(
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
},
|
|
2608
|
-
);
|
|
2336
|
+
await handleChannelVerificationSession({
|
|
2337
|
+
type: "channel_verification_session",
|
|
2338
|
+
action: "resend_session",
|
|
2339
|
+
channel: "phone",
|
|
2340
|
+
});
|
|
2609
2341
|
|
|
2610
2342
|
const resp = lastResponse();
|
|
2611
2343
|
expect(resp).not.toBeNull();
|
|
@@ -2616,14 +2348,12 @@ describe("outbound voice verification", () => {
|
|
|
2616
2348
|
test("resend_outbound after cooldown succeeds and increments sendCount", async () => {
|
|
2617
2349
|
// Start an outbound session
|
|
2618
2350
|
const { lastResponse: startResp } = createResponseReader();
|
|
2619
|
-
await handleChannelVerificationSession(
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
},
|
|
2626
|
-
);
|
|
2351
|
+
await handleChannelVerificationSession({
|
|
2352
|
+
type: "channel_verification_session",
|
|
2353
|
+
action: "create_session",
|
|
2354
|
+
channel: "phone",
|
|
2355
|
+
destination: "+15551234567",
|
|
2356
|
+
});
|
|
2627
2357
|
|
|
2628
2358
|
const startResponse = startResp();
|
|
2629
2359
|
expect(startResponse!.success).toBe(true);
|
|
@@ -2640,13 +2370,11 @@ describe("outbound voice verification", () => {
|
|
|
2640
2370
|
|
|
2641
2371
|
// Now resend should succeed
|
|
2642
2372
|
const { lastResponse } = createResponseReader();
|
|
2643
|
-
await handleChannelVerificationSession(
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
},
|
|
2649
|
-
);
|
|
2373
|
+
await handleChannelVerificationSession({
|
|
2374
|
+
type: "channel_verification_session",
|
|
2375
|
+
action: "resend_session",
|
|
2376
|
+
channel: "phone",
|
|
2377
|
+
});
|
|
2650
2378
|
|
|
2651
2379
|
const resp = lastResponse();
|
|
2652
2380
|
expect(resp).not.toBeNull();
|
|
@@ -2658,14 +2386,12 @@ describe("outbound voice verification", () => {
|
|
|
2658
2386
|
test("resend_outbound exceeding max sends is rejected", async () => {
|
|
2659
2387
|
// Start an outbound session
|
|
2660
2388
|
broadcastedMessages.length = 0;
|
|
2661
|
-
await handleChannelVerificationSession(
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
},
|
|
2668
|
-
);
|
|
2389
|
+
await handleChannelVerificationSession({
|
|
2390
|
+
type: "channel_verification_session",
|
|
2391
|
+
action: "create_session",
|
|
2392
|
+
channel: "phone",
|
|
2393
|
+
destination: "+15551234567",
|
|
2394
|
+
});
|
|
2669
2395
|
|
|
2670
2396
|
// Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
|
|
2671
2397
|
const session = serviceFindActiveSession("phone");
|
|
@@ -2679,13 +2405,11 @@ describe("outbound voice verification", () => {
|
|
|
2679
2405
|
|
|
2680
2406
|
// Resend should be rejected due to max sends
|
|
2681
2407
|
const { lastResponse } = createResponseReader();
|
|
2682
|
-
await handleChannelVerificationSession(
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
},
|
|
2688
|
-
);
|
|
2408
|
+
await handleChannelVerificationSession({
|
|
2409
|
+
type: "channel_verification_session",
|
|
2410
|
+
action: "resend_session",
|
|
2411
|
+
channel: "phone",
|
|
2412
|
+
});
|
|
2689
2413
|
|
|
2690
2414
|
const resp = lastResponse();
|
|
2691
2415
|
expect(resp).not.toBeNull();
|
|
@@ -2696,14 +2420,12 @@ describe("outbound voice verification", () => {
|
|
|
2696
2420
|
test("cancel_outbound revokes active session", async () => {
|
|
2697
2421
|
// Start an outbound session
|
|
2698
2422
|
broadcastedMessages.length = 0;
|
|
2699
|
-
await handleChannelVerificationSession(
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
},
|
|
2706
|
-
);
|
|
2423
|
+
await handleChannelVerificationSession({
|
|
2424
|
+
type: "channel_verification_session",
|
|
2425
|
+
action: "create_session",
|
|
2426
|
+
channel: "phone",
|
|
2427
|
+
destination: "+15551234567",
|
|
2428
|
+
});
|
|
2707
2429
|
|
|
2708
2430
|
// Verify session exists
|
|
2709
2431
|
const sessionBefore = serviceFindActiveSession("phone");
|
|
@@ -2711,13 +2433,11 @@ describe("outbound voice verification", () => {
|
|
|
2711
2433
|
|
|
2712
2434
|
// Cancel it
|
|
2713
2435
|
const { lastResponse } = createResponseReader();
|
|
2714
|
-
await handleChannelVerificationSession(
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
},
|
|
2720
|
-
);
|
|
2436
|
+
await handleChannelVerificationSession({
|
|
2437
|
+
type: "channel_verification_session",
|
|
2438
|
+
action: "cancel_session",
|
|
2439
|
+
channel: "phone",
|
|
2440
|
+
});
|
|
2721
2441
|
|
|
2722
2442
|
const resp = lastResponse();
|
|
2723
2443
|
expect(resp).not.toBeNull();
|
|
@@ -2780,14 +2500,12 @@ describe("outbound voice verification", () => {
|
|
|
2780
2500
|
|
|
2781
2501
|
test("start_outbound succeeds for email channel", async () => {
|
|
2782
2502
|
const { lastResponse } = createResponseReader();
|
|
2783
|
-
await handleChannelVerificationSession(
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
},
|
|
2790
|
-
);
|
|
2503
|
+
await handleChannelVerificationSession({
|
|
2504
|
+
type: "channel_verification_session",
|
|
2505
|
+
action: "create_session",
|
|
2506
|
+
channel: "email",
|
|
2507
|
+
destination: "user@example.com",
|
|
2508
|
+
});
|
|
2791
2509
|
|
|
2792
2510
|
const resp = lastResponse();
|
|
2793
2511
|
expect(resp).not.toBeNull();
|
|
@@ -2797,14 +2515,12 @@ describe("outbound voice verification", () => {
|
|
|
2797
2515
|
|
|
2798
2516
|
test("create_session without destination falls through to inbound challenge", async () => {
|
|
2799
2517
|
const { lastResponse } = createResponseReader();
|
|
2800
|
-
await handleChannelVerificationSession(
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
},
|
|
2807
|
-
);
|
|
2518
|
+
await handleChannelVerificationSession({
|
|
2519
|
+
type: "channel_verification_session",
|
|
2520
|
+
action: "create_session",
|
|
2521
|
+
channel: "phone",
|
|
2522
|
+
// no destination — unified create_session creates an inbound challenge
|
|
2523
|
+
});
|
|
2808
2524
|
|
|
2809
2525
|
const resp = lastResponse();
|
|
2810
2526
|
expect(resp).not.toBeNull();
|
|
@@ -2814,14 +2530,12 @@ describe("outbound voice verification", () => {
|
|
|
2814
2530
|
|
|
2815
2531
|
test("start_outbound rejects unparseable phone number", async () => {
|
|
2816
2532
|
const { lastResponse } = createResponseReader();
|
|
2817
|
-
await handleChannelVerificationSession(
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
},
|
|
2824
|
-
);
|
|
2533
|
+
await handleChannelVerificationSession({
|
|
2534
|
+
type: "channel_verification_session",
|
|
2535
|
+
action: "create_session",
|
|
2536
|
+
channel: "phone",
|
|
2537
|
+
destination: "not-a-phone",
|
|
2538
|
+
});
|
|
2825
2539
|
|
|
2826
2540
|
const resp = lastResponse();
|
|
2827
2541
|
expect(resp).not.toBeNull();
|
|
@@ -2831,14 +2545,12 @@ describe("outbound voice verification", () => {
|
|
|
2831
2545
|
|
|
2832
2546
|
test("start_outbound normalizes formatted phone number for voice", async () => {
|
|
2833
2547
|
const { lastResponse } = createResponseReader();
|
|
2834
|
-
await handleChannelVerificationSession(
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
},
|
|
2841
|
-
);
|
|
2548
|
+
await handleChannelVerificationSession({
|
|
2549
|
+
type: "channel_verification_session",
|
|
2550
|
+
action: "create_session",
|
|
2551
|
+
channel: "phone",
|
|
2552
|
+
destination: "(555) 123-4567",
|
|
2553
|
+
});
|
|
2842
2554
|
|
|
2843
2555
|
const resp = lastResponse();
|
|
2844
2556
|
expect(resp).not.toBeNull();
|
|
@@ -2863,13 +2575,11 @@ describe("outbound voice verification", () => {
|
|
|
2863
2575
|
|
|
2864
2576
|
test("cancel_session succeeds even when no active session (idempotent)", async () => {
|
|
2865
2577
|
const { lastResponse } = createResponseReader();
|
|
2866
|
-
await handleChannelVerificationSession(
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
},
|
|
2872
|
-
);
|
|
2578
|
+
await handleChannelVerificationSession({
|
|
2579
|
+
type: "channel_verification_session",
|
|
2580
|
+
action: "cancel_session",
|
|
2581
|
+
channel: "phone",
|
|
2582
|
+
});
|
|
2873
2583
|
|
|
2874
2584
|
const resp = lastResponse();
|
|
2875
2585
|
expect(resp).not.toBeNull();
|
|
@@ -2888,14 +2598,12 @@ describe("outbound Telegram verification", () => {
|
|
|
2888
2598
|
|
|
2889
2599
|
test("start_outbound for telegram with handle returns deep link URL, no outbound message", async () => {
|
|
2890
2600
|
const { lastResponse } = createResponseReader();
|
|
2891
|
-
await handleChannelVerificationSession(
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
},
|
|
2898
|
-
);
|
|
2601
|
+
await handleChannelVerificationSession({
|
|
2602
|
+
type: "channel_verification_session",
|
|
2603
|
+
action: "create_session",
|
|
2604
|
+
channel: "telegram",
|
|
2605
|
+
destination: "@someuser",
|
|
2606
|
+
});
|
|
2899
2607
|
|
|
2900
2608
|
const resp = lastResponse();
|
|
2901
2609
|
expect(resp).not.toBeNull();
|
|
@@ -2921,14 +2629,12 @@ describe("outbound Telegram verification", () => {
|
|
|
2921
2629
|
|
|
2922
2630
|
test("start_outbound for telegram with handle (no @ prefix) returns deep link", async () => {
|
|
2923
2631
|
const { lastResponse } = createResponseReader();
|
|
2924
|
-
await handleChannelVerificationSession(
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
},
|
|
2931
|
-
);
|
|
2632
|
+
await handleChannelVerificationSession({
|
|
2633
|
+
type: "channel_verification_session",
|
|
2634
|
+
action: "create_session",
|
|
2635
|
+
channel: "telegram",
|
|
2636
|
+
destination: "someuser",
|
|
2637
|
+
});
|
|
2932
2638
|
|
|
2933
2639
|
const resp = lastResponse();
|
|
2934
2640
|
expect(resp).not.toBeNull();
|
|
@@ -2941,14 +2647,12 @@ describe("outbound Telegram verification", () => {
|
|
|
2941
2647
|
|
|
2942
2648
|
test("start_outbound for telegram with known chat ID sends message, no deep link", async () => {
|
|
2943
2649
|
const { lastResponse } = createResponseReader();
|
|
2944
|
-
await handleChannelVerificationSession(
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
},
|
|
2951
|
-
);
|
|
2650
|
+
await handleChannelVerificationSession({
|
|
2651
|
+
type: "channel_verification_session",
|
|
2652
|
+
action: "create_session",
|
|
2653
|
+
channel: "telegram",
|
|
2654
|
+
destination: "123456789",
|
|
2655
|
+
});
|
|
2952
2656
|
|
|
2953
2657
|
const resp = lastResponse();
|
|
2954
2658
|
expect(resp).not.toBeNull();
|
|
@@ -2980,14 +2684,12 @@ describe("outbound Telegram verification", () => {
|
|
|
2980
2684
|
mockBotUsername = undefined;
|
|
2981
2685
|
|
|
2982
2686
|
const { lastResponse } = createResponseReader();
|
|
2983
|
-
await handleChannelVerificationSession(
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
},
|
|
2990
|
-
);
|
|
2687
|
+
await handleChannelVerificationSession({
|
|
2688
|
+
type: "channel_verification_session",
|
|
2689
|
+
action: "create_session",
|
|
2690
|
+
channel: "telegram",
|
|
2691
|
+
destination: "@someuser",
|
|
2692
|
+
});
|
|
2991
2693
|
|
|
2992
2694
|
const resp = lastResponse();
|
|
2993
2695
|
expect(resp).not.toBeNull();
|
|
@@ -3004,15 +2706,13 @@ describe("outbound Telegram verification", () => {
|
|
|
3004
2706
|
});
|
|
3005
2707
|
|
|
3006
2708
|
const { lastResponse } = createResponseReader();
|
|
3007
|
-
await handleChannelVerificationSession(
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
},
|
|
3015
|
-
);
|
|
2709
|
+
await handleChannelVerificationSession({
|
|
2710
|
+
type: "channel_verification_session",
|
|
2711
|
+
action: "create_session",
|
|
2712
|
+
channel: "telegram",
|
|
2713
|
+
destination: "@newuser",
|
|
2714
|
+
rebind: false,
|
|
2715
|
+
});
|
|
3016
2716
|
|
|
3017
2717
|
const resp = lastResponse();
|
|
3018
2718
|
expect(resp).not.toBeNull();
|
|
@@ -3166,14 +2866,12 @@ describe("outbound Telegram verification", () => {
|
|
|
3166
2866
|
test("resend_outbound for telegram works with known chat ID", async () => {
|
|
3167
2867
|
// Start an outbound session with a known chat ID
|
|
3168
2868
|
broadcastedMessages.length = 0;
|
|
3169
|
-
await handleChannelVerificationSession(
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
},
|
|
3176
|
-
);
|
|
2869
|
+
await handleChannelVerificationSession({
|
|
2870
|
+
type: "channel_verification_session",
|
|
2871
|
+
action: "create_session",
|
|
2872
|
+
channel: "telegram",
|
|
2873
|
+
destination: "123456789",
|
|
2874
|
+
});
|
|
3177
2875
|
|
|
3178
2876
|
// Fast-forward the cooldown
|
|
3179
2877
|
const session = serviceFindActiveSession("telegram");
|
|
@@ -3186,13 +2884,11 @@ describe("outbound Telegram verification", () => {
|
|
|
3186
2884
|
);
|
|
3187
2885
|
|
|
3188
2886
|
const { lastResponse } = createResponseReader();
|
|
3189
|
-
await handleChannelVerificationSession(
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
},
|
|
3195
|
-
);
|
|
2887
|
+
await handleChannelVerificationSession({
|
|
2888
|
+
type: "channel_verification_session",
|
|
2889
|
+
action: "resend_session",
|
|
2890
|
+
channel: "telegram",
|
|
2891
|
+
});
|
|
3196
2892
|
|
|
3197
2893
|
const resp = lastResponse();
|
|
3198
2894
|
expect(resp).not.toBeNull();
|
|
@@ -3208,23 +2904,19 @@ describe("outbound Telegram verification", () => {
|
|
|
3208
2904
|
test("resend_outbound for pending_bootstrap session is rejected", async () => {
|
|
3209
2905
|
// Start an outbound session with a handle (pending_bootstrap)
|
|
3210
2906
|
broadcastedMessages.length = 0;
|
|
3211
|
-
await handleChannelVerificationSession(
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
},
|
|
3218
|
-
);
|
|
2907
|
+
await handleChannelVerificationSession({
|
|
2908
|
+
type: "channel_verification_session",
|
|
2909
|
+
action: "create_session",
|
|
2910
|
+
channel: "telegram",
|
|
2911
|
+
destination: "@someuser",
|
|
2912
|
+
});
|
|
3219
2913
|
|
|
3220
2914
|
const { lastResponse } = createResponseReader();
|
|
3221
|
-
await handleChannelVerificationSession(
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
},
|
|
3227
|
-
);
|
|
2915
|
+
await handleChannelVerificationSession({
|
|
2916
|
+
type: "channel_verification_session",
|
|
2917
|
+
action: "resend_session",
|
|
2918
|
+
channel: "telegram",
|
|
2919
|
+
});
|
|
3228
2920
|
|
|
3229
2921
|
const resp = lastResponse();
|
|
3230
2922
|
expect(resp).not.toBeNull();
|
|
@@ -3235,26 +2927,22 @@ describe("outbound Telegram verification", () => {
|
|
|
3235
2927
|
test("cancel_outbound for telegram revokes session", async () => {
|
|
3236
2928
|
// Start an outbound session
|
|
3237
2929
|
broadcastedMessages.length = 0;
|
|
3238
|
-
await handleChannelVerificationSession(
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
},
|
|
3245
|
-
);
|
|
2930
|
+
await handleChannelVerificationSession({
|
|
2931
|
+
type: "channel_verification_session",
|
|
2932
|
+
action: "create_session",
|
|
2933
|
+
channel: "telegram",
|
|
2934
|
+
destination: "123456789",
|
|
2935
|
+
});
|
|
3246
2936
|
|
|
3247
2937
|
const session = serviceFindActiveSession("telegram");
|
|
3248
2938
|
expect(session).not.toBeNull();
|
|
3249
2939
|
|
|
3250
2940
|
const { lastResponse } = createResponseReader();
|
|
3251
|
-
await handleChannelVerificationSession(
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
},
|
|
3257
|
-
);
|
|
2941
|
+
await handleChannelVerificationSession({
|
|
2942
|
+
type: "channel_verification_session",
|
|
2943
|
+
action: "cancel_session",
|
|
2944
|
+
channel: "telegram",
|
|
2945
|
+
});
|
|
3258
2946
|
|
|
3259
2947
|
const resp = lastResponse();
|
|
3260
2948
|
expect(resp).not.toBeNull();
|
|
@@ -3295,13 +2983,11 @@ describe("outbound Telegram verification", () => {
|
|
|
3295
2983
|
|
|
3296
2984
|
test("create_session for telegram without destination falls through to inbound challenge", async () => {
|
|
3297
2985
|
const { lastResponse } = createResponseReader();
|
|
3298
|
-
await handleChannelVerificationSession(
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
},
|
|
3304
|
-
);
|
|
2986
|
+
await handleChannelVerificationSession({
|
|
2987
|
+
type: "channel_verification_session",
|
|
2988
|
+
action: "create_session",
|
|
2989
|
+
channel: "telegram",
|
|
2990
|
+
});
|
|
3305
2991
|
|
|
3306
2992
|
const resp = lastResponse();
|
|
3307
2993
|
expect(resp).not.toBeNull();
|
|
@@ -3312,14 +2998,12 @@ describe("outbound Telegram verification", () => {
|
|
|
3312
2998
|
test("rate limits apply to telegram outbound (per-session send cap)", async () => {
|
|
3313
2999
|
// Start an outbound session with a known chat ID
|
|
3314
3000
|
broadcastedMessages.length = 0;
|
|
3315
|
-
await handleChannelVerificationSession(
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
},
|
|
3322
|
-
);
|
|
3001
|
+
await handleChannelVerificationSession({
|
|
3002
|
+
type: "channel_verification_session",
|
|
3003
|
+
action: "create_session",
|
|
3004
|
+
channel: "telegram",
|
|
3005
|
+
destination: "123456789",
|
|
3006
|
+
});
|
|
3323
3007
|
|
|
3324
3008
|
// Set the send count to MAX_SENDS_PER_SESSION and nextResendAt to the past
|
|
3325
3009
|
const session = serviceFindActiveSession("telegram");
|
|
@@ -3333,13 +3017,11 @@ describe("outbound Telegram verification", () => {
|
|
|
3333
3017
|
|
|
3334
3018
|
// Resend should be rejected due to max sends
|
|
3335
3019
|
const { lastResponse } = createResponseReader();
|
|
3336
|
-
await handleChannelVerificationSession(
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
},
|
|
3342
|
-
);
|
|
3020
|
+
await handleChannelVerificationSession({
|
|
3021
|
+
type: "channel_verification_session",
|
|
3022
|
+
action: "resend_session",
|
|
3023
|
+
channel: "telegram",
|
|
3024
|
+
});
|
|
3343
3025
|
|
|
3344
3026
|
const resp = lastResponse();
|
|
3345
3027
|
expect(resp).not.toBeNull();
|
|
@@ -3350,24 +3032,20 @@ describe("outbound Telegram verification", () => {
|
|
|
3350
3032
|
test("rate limits apply to telegram outbound (cooldown)", async () => {
|
|
3351
3033
|
// Start an outbound session with a known chat ID
|
|
3352
3034
|
broadcastedMessages.length = 0;
|
|
3353
|
-
await handleChannelVerificationSession(
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
},
|
|
3360
|
-
);
|
|
3035
|
+
await handleChannelVerificationSession({
|
|
3036
|
+
type: "channel_verification_session",
|
|
3037
|
+
action: "create_session",
|
|
3038
|
+
channel: "telegram",
|
|
3039
|
+
destination: "123456789",
|
|
3040
|
+
});
|
|
3361
3041
|
|
|
3362
3042
|
// Immediately try to resend (before cooldown)
|
|
3363
3043
|
const { lastResponse } = createResponseReader();
|
|
3364
|
-
await handleChannelVerificationSession(
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
},
|
|
3370
|
-
);
|
|
3044
|
+
await handleChannelVerificationSession({
|
|
3045
|
+
type: "channel_verification_session",
|
|
3046
|
+
action: "resend_session",
|
|
3047
|
+
channel: "telegram",
|
|
3048
|
+
});
|
|
3371
3049
|
|
|
3372
3050
|
const resp = lastResponse();
|
|
3373
3051
|
expect(resp).not.toBeNull();
|
|
@@ -3387,14 +3065,12 @@ describe("outbound voice verification", () => {
|
|
|
3387
3065
|
|
|
3388
3066
|
test("start_outbound for voice creates session with 6-digit code and initiates call", async () => {
|
|
3389
3067
|
const { lastResponse } = createResponseReader();
|
|
3390
|
-
await handleChannelVerificationSession(
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
},
|
|
3397
|
-
);
|
|
3068
|
+
await handleChannelVerificationSession({
|
|
3069
|
+
type: "channel_verification_session",
|
|
3070
|
+
action: "create_session",
|
|
3071
|
+
channel: "phone",
|
|
3072
|
+
destination: "+15551234567",
|
|
3073
|
+
});
|
|
3398
3074
|
|
|
3399
3075
|
const resp = lastResponse();
|
|
3400
3076
|
expect(resp).not.toBeNull();
|
|
@@ -3427,14 +3103,12 @@ describe("outbound voice verification", () => {
|
|
|
3427
3103
|
|
|
3428
3104
|
test("start_outbound for voice rejects unparseable phone number", async () => {
|
|
3429
3105
|
const { lastResponse } = createResponseReader();
|
|
3430
|
-
await handleChannelVerificationSession(
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
},
|
|
3437
|
-
);
|
|
3106
|
+
await handleChannelVerificationSession({
|
|
3107
|
+
type: "channel_verification_session",
|
|
3108
|
+
action: "create_session",
|
|
3109
|
+
channel: "phone",
|
|
3110
|
+
destination: "not-a-phone",
|
|
3111
|
+
});
|
|
3438
3112
|
|
|
3439
3113
|
const resp = lastResponse();
|
|
3440
3114
|
expect(resp).not.toBeNull();
|
|
@@ -3444,14 +3118,12 @@ describe("outbound voice verification", () => {
|
|
|
3444
3118
|
|
|
3445
3119
|
test("start_outbound for voice normalizes formatted phone number", async () => {
|
|
3446
3120
|
const { lastResponse } = createResponseReader();
|
|
3447
|
-
await handleChannelVerificationSession(
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
},
|
|
3454
|
-
);
|
|
3121
|
+
await handleChannelVerificationSession({
|
|
3122
|
+
type: "channel_verification_session",
|
|
3123
|
+
action: "create_session",
|
|
3124
|
+
channel: "phone",
|
|
3125
|
+
destination: "555-123-4567",
|
|
3126
|
+
});
|
|
3455
3127
|
|
|
3456
3128
|
const resp = lastResponse();
|
|
3457
3129
|
expect(resp).not.toBeNull();
|
|
@@ -3485,15 +3157,13 @@ describe("outbound voice verification", () => {
|
|
|
3485
3157
|
});
|
|
3486
3158
|
|
|
3487
3159
|
const { lastResponse } = createResponseReader();
|
|
3488
|
-
await handleChannelVerificationSession(
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
},
|
|
3496
|
-
);
|
|
3160
|
+
await handleChannelVerificationSession({
|
|
3161
|
+
type: "channel_verification_session",
|
|
3162
|
+
action: "create_session",
|
|
3163
|
+
channel: "phone",
|
|
3164
|
+
destination: "+15559876543",
|
|
3165
|
+
rebind: false,
|
|
3166
|
+
});
|
|
3497
3167
|
|
|
3498
3168
|
const resp = lastResponse();
|
|
3499
3169
|
expect(resp).not.toBeNull();
|
|
@@ -3504,24 +3174,20 @@ describe("outbound voice verification", () => {
|
|
|
3504
3174
|
test("resend_outbound for voice initiates a new call with cooldown check", async () => {
|
|
3505
3175
|
// Start an outbound session first
|
|
3506
3176
|
broadcastedMessages.length = 0;
|
|
3507
|
-
await handleChannelVerificationSession(
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
},
|
|
3514
|
-
);
|
|
3177
|
+
await handleChannelVerificationSession({
|
|
3178
|
+
type: "channel_verification_session",
|
|
3179
|
+
action: "create_session",
|
|
3180
|
+
channel: "phone",
|
|
3181
|
+
destination: "+15551234567",
|
|
3182
|
+
});
|
|
3515
3183
|
|
|
3516
3184
|
// Immediately try to resend (before cooldown)
|
|
3517
3185
|
const { lastResponse } = createResponseReader();
|
|
3518
|
-
await handleChannelVerificationSession(
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
},
|
|
3524
|
-
);
|
|
3186
|
+
await handleChannelVerificationSession({
|
|
3187
|
+
type: "channel_verification_session",
|
|
3188
|
+
action: "resend_session",
|
|
3189
|
+
channel: "phone",
|
|
3190
|
+
});
|
|
3525
3191
|
|
|
3526
3192
|
const resp = lastResponse();
|
|
3527
3193
|
expect(resp).not.toBeNull();
|
|
@@ -3532,24 +3198,20 @@ describe("outbound voice verification", () => {
|
|
|
3532
3198
|
test("cancel_outbound for voice cancels session", async () => {
|
|
3533
3199
|
// Start an outbound session first
|
|
3534
3200
|
broadcastedMessages.length = 0;
|
|
3535
|
-
await handleChannelVerificationSession(
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
},
|
|
3542
|
-
);
|
|
3201
|
+
await handleChannelVerificationSession({
|
|
3202
|
+
type: "channel_verification_session",
|
|
3203
|
+
action: "create_session",
|
|
3204
|
+
channel: "phone",
|
|
3205
|
+
destination: "+15551234567",
|
|
3206
|
+
});
|
|
3543
3207
|
|
|
3544
3208
|
// Cancel the session
|
|
3545
3209
|
const { lastResponse } = createResponseReader();
|
|
3546
|
-
await handleChannelVerificationSession(
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
},
|
|
3552
|
-
);
|
|
3210
|
+
await handleChannelVerificationSession({
|
|
3211
|
+
type: "channel_verification_session",
|
|
3212
|
+
action: "cancel_session",
|
|
3213
|
+
channel: "phone",
|
|
3214
|
+
});
|
|
3553
3215
|
|
|
3554
3216
|
const resp = lastResponse();
|
|
3555
3217
|
expect(resp).not.toBeNull();
|
|
@@ -3583,14 +3245,12 @@ describe("outbound voice verification", () => {
|
|
|
3583
3245
|
}
|
|
3584
3246
|
|
|
3585
3247
|
const { lastResponse } = createResponseReader();
|
|
3586
|
-
await handleChannelVerificationSession(
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
},
|
|
3593
|
-
);
|
|
3248
|
+
await handleChannelVerificationSession({
|
|
3249
|
+
type: "channel_verification_session",
|
|
3250
|
+
action: "create_session",
|
|
3251
|
+
channel: "phone",
|
|
3252
|
+
destination: "+15551234567",
|
|
3253
|
+
});
|
|
3594
3254
|
|
|
3595
3255
|
const resp = lastResponse();
|
|
3596
3256
|
expect(resp).not.toBeNull();
|
|
@@ -3600,13 +3260,11 @@ describe("outbound voice verification", () => {
|
|
|
3600
3260
|
|
|
3601
3261
|
test("create_session for voice without destination falls through to inbound challenge", async () => {
|
|
3602
3262
|
const { lastResponse } = createResponseReader();
|
|
3603
|
-
await handleChannelVerificationSession(
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
},
|
|
3609
|
-
);
|
|
3263
|
+
await handleChannelVerificationSession({
|
|
3264
|
+
type: "channel_verification_session",
|
|
3265
|
+
action: "create_session",
|
|
3266
|
+
channel: "phone",
|
|
3267
|
+
});
|
|
3610
3268
|
|
|
3611
3269
|
const resp = lastResponse();
|
|
3612
3270
|
expect(resp).not.toBeNull();
|
|
@@ -3634,14 +3292,12 @@ describe("M1–M4 hardening coverage", () => {
|
|
|
3634
3292
|
|
|
3635
3293
|
test("start_outbound for voice response includes secret", async () => {
|
|
3636
3294
|
const { lastResponse } = createResponseReader();
|
|
3637
|
-
await handleChannelVerificationSession(
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
},
|
|
3644
|
-
);
|
|
3295
|
+
await handleChannelVerificationSession({
|
|
3296
|
+
type: "channel_verification_session",
|
|
3297
|
+
action: "create_session",
|
|
3298
|
+
channel: "phone",
|
|
3299
|
+
destination: "+15551234567",
|
|
3300
|
+
});
|
|
3645
3301
|
|
|
3646
3302
|
const resp = lastResponse();
|
|
3647
3303
|
expect(resp).not.toBeNull();
|
|
@@ -3656,14 +3312,12 @@ describe("M1–M4 hardening coverage", () => {
|
|
|
3656
3312
|
test("resend_outbound for voice response includes secret", async () => {
|
|
3657
3313
|
// Start a session first
|
|
3658
3314
|
broadcastedMessages.length = 0;
|
|
3659
|
-
await handleChannelVerificationSession(
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
},
|
|
3666
|
-
);
|
|
3315
|
+
await handleChannelVerificationSession({
|
|
3316
|
+
type: "channel_verification_session",
|
|
3317
|
+
action: "create_session",
|
|
3318
|
+
channel: "phone",
|
|
3319
|
+
destination: "+15551234567",
|
|
3320
|
+
});
|
|
3667
3321
|
|
|
3668
3322
|
// Move past cooldown
|
|
3669
3323
|
const session = serviceFindActiveSession("phone");
|
|
@@ -3677,13 +3331,11 @@ describe("M1–M4 hardening coverage", () => {
|
|
|
3677
3331
|
|
|
3678
3332
|
// Resend
|
|
3679
3333
|
const { lastResponse } = createResponseReader();
|
|
3680
|
-
await handleChannelVerificationSession(
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
},
|
|
3686
|
-
);
|
|
3334
|
+
await handleChannelVerificationSession({
|
|
3335
|
+
type: "channel_verification_session",
|
|
3336
|
+
action: "resend_session",
|
|
3337
|
+
channel: "phone",
|
|
3338
|
+
});
|
|
3687
3339
|
|
|
3688
3340
|
const resp = lastResponse();
|
|
3689
3341
|
expect(resp).not.toBeNull();
|
|
@@ -3697,14 +3349,12 @@ describe("M1–M4 hardening coverage", () => {
|
|
|
3697
3349
|
|
|
3698
3350
|
test("start_outbound for Telegram bootstrap (handle) does NOT return secret", async () => {
|
|
3699
3351
|
const { lastResponse } = createResponseReader();
|
|
3700
|
-
await handleChannelVerificationSession(
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
},
|
|
3707
|
-
);
|
|
3352
|
+
await handleChannelVerificationSession({
|
|
3353
|
+
type: "channel_verification_session",
|
|
3354
|
+
action: "create_session",
|
|
3355
|
+
channel: "telegram",
|
|
3356
|
+
destination: "@someuser",
|
|
3357
|
+
});
|
|
3708
3358
|
|
|
3709
3359
|
const resp = lastResponse();
|
|
3710
3360
|
expect(resp).not.toBeNull();
|