Skip to content

feat(voice): emit callback handoff notification on guardian-wait timeout#10930

Merged
noanflaherty merged 2 commits into
mainfrom
safe-do/callback-handoff-notification
Mar 1, 2026
Merged

feat(voice): emit callback handoff notification on guardian-wait timeout#10930
noanflaherty merged 2 commits into
mainfrom
safe-do/callback-handoff-notification

Conversation

@noanflaherty
Copy link
Copy Markdown
Contributor

@noanflaherty noanflaherty commented Mar 1, 2026

Summary

  • When a caller opts into callback during guardian-wait and the wait times out or the call disconnects, a notification is now emitted to the guardian so the callback intent is not silently dropped
  • Adds emitAccessRequestCallbackHandoff() helper with idempotency guard (in-memory flag + deterministic dedupeKey) to prevent duplicate notifications from timeout + transport-close race
  • Includes trusted-contact member reference in the notification payload when the caller maps to an existing member record
  • Adds deterministic fallback copy template for the new ingress.access_request.callback_handoff source event
  • Notification-only handoff — no auto-callback execution, no schema migration, no new persistence beyond normal notification/event behavior

Test plan

  • Relay-server tests: callback opt-in + timeout emits handoff notification
  • Relay-server tests: no callback opt-in + timeout does NOT emit handoff
  • Relay-server tests: callback opt-in + transport close emits handoff
  • Relay-server tests: timeout then transport-close race emits only one handoff (idempotency)
  • Relay-server tests: payload includes requesterMemberId when member exists
  • Relay-server tests: payload omits member reference when no member exists
  • Copy-composer tests: renders caller identity (name + phone, phone only, name only, unknown)
  • Copy-composer tests: includes request code when present
  • Copy-composer tests: includes trusted-contact member reference when present
  • Copy-composer tests: telegram/sms channels get deliveryText fallback

Original prompt

/Users/noaflaherty/Repos/vellum-ai/vellum-assistant/.private/plans/voice-access-request-callback-handoff-notification-one-pr-plan-2026-03-01.md

🤖 Generated with Claude Code


Open with Devin

… callback during guardian wait

When a caller explicitly opts into callback during guardian-wait and the wait
ends without resolution (timeout or transport close), emit a notification signal
to the guardian so the callback intent is not silently dropped.

- Add emitAccessRequestCallbackHandoff() helper with idempotency guard
- Trigger from handleAccessRequestTimeout() and handleTransportClosed()
- Include trusted-contact member reference when resolvable
- Add ingress.access_request.callback_handoff fallback copy template
- Add relay-server tests for timeout/close/idempotency/member-ref coverage
- Add copy-composer tests for new notification template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@noanflaherty
Copy link
Copy Markdown
Contributor Author

@codex review

@noanflaherty
Copy link
Copy Markdown
Contributor Author

@devin review

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

…iteria

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@noanflaherty
Copy link
Copy Markdown
Contributor Author

@codex review this PR again — the previous issues have been fixed in commit 7d6fdd8

@noanflaherty
Copy link
Copy Markdown
Contributor Author

@devin review this PR again — the previous issues have been fixed in commit 7d6fdd8

@noanflaherty noanflaherty merged commit e954aaf into main Mar 1, 2026
1 check passed
@noanflaherty noanflaherty deleted the safe-do/callback-handoff-notification branch March 1, 2026 01:42
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@noanflaherty
Copy link
Copy Markdown
Contributor Author

The Codex P1 feedback about restricting callback handoff member mapping to trusted contacts was already addressed in the merged code. The emitAccessRequestCallbackHandoff method gates requesterMemberId on member.status === 'active' && member.policy === 'allow' (line 1452), which ensures only trusted contacts are identified — revoked/pending/denied members correctly leave requesterMemberId as null. No follow-up PR needed.

tkheyfets pushed a commit that referenced this pull request Mar 2, 2026
…out (#10930)

* feat(voice): emit callback handoff notification when caller opts into callback during guardian wait

When a caller explicitly opts into callback during guardian-wait and the wait
ends without resolution (timeout or transport close), emit a notification signal
to the guardian so the callback intent is not silently dropped.

- Add emitAccessRequestCallbackHandoff() helper with idempotency guard
- Trigger from handleAccessRequestTimeout() and handleTransportClosed()
- Include trusted-contact member reference when resolvable
- Add ingress.access_request.callback_handoff fallback copy template
- Add relay-server tests for timeout/close/idempotency/member-ref coverage
- Add copy-composer tests for new notification template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: gate callback handoff requesterMemberId on active+allow trust criteria

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant