0101 — Tour-day arrival updates reach the leasing team on every channel; voice transfers the live call

Context

On 2026-07-17, prospect Daniel Yagow called Camellia Apartments a few minutes before his 1:00 PM tour and said "I'm here to look at an apartment… I'm a few minutes early" (conv_voice_026faf88-77ee-473f-8ad9-5be96f5a4e8b). Clara gave him the buzz code and directions, the call ended resolved — and nobody on the leasing team was told a prospect was standing at the door.

Two structural gaps caused this:

  1. The tour-day update path is text-only. leasing.notify_leasing_team (src/lib/tools/leasing.ts) exists precisely for this — its enum includes arriving_early and arrived, and its description says it is "the only way the team hears about it in real time." But its voice binding is deliberately empty (channels: ['text'], agents: []), on the assumption that "the voice Leasing specialist transfers a live caller instead."
  2. That transfer assumption never fires for arrivals. The Leasing voice specialist does carry the ElevenLabs transfer_to_number system tool (conference transfer to pm_phone_number, agents/clara/lib/voice-agents/leasing.config.json), but its only condition is "The caller asks for a human or the issue is beyond any sibling's scope." An arrival/running-late/at-the-door update satisfies neither — Clara self-serves the access answer and the call ends with the team unaware.

Net effect: on text channels the team gets a real-time email for tour-day updates; on voice — the channel a prospect standing at the door is most likely to use — they get nothing.

A secondary observation from the same call (out of scope here, tracked separately): the topic classifier filed the call as resident_inquiry/access because the taxonomy has no tour-arrival category.

Decision

Tour-day time-sensitive updates from a prospect with a scheduled tour must reach the leasing team on every channel. The channel-appropriate mechanism differs:

Concretely:

  1. Widen the transfer_to_number condition on the Leasing voice specialist (and the triage/unknown-caller specialists that can field a prospect before hand-off) to include: a caller with a scheduled tour reporting a tour-day logistics update — arrived / at the door, arriving early, on the way, running late, can't find the office, wants to nudge the time.
  2. Prompt guidance: Clara may still answer the access question (buzz code, directions) first — self-serving the door is good — but she must then transfer so a human greets the prospect. Announce the transfer with the standard connect line ("Let me connect you with someone on the team." — owner ruling 2026-08-15, voice-agents/human-transfer-connect.ts).
  3. Fallback when the transfer doesn't complete (no answer / caller hangs up): the call-ended pipeline already detects whether a transfer_to_number system tool-call completed (src/app/api/voice/call-ended/route.ts, emergency-relay gate pattern). Reuse that detection to send the existing notify_leasing_team email post-call, so a failed transfer degrades to today's text-channel behavior instead of silence.

A future reader can test code against this decision: any channel where a prospect can say "I'm here for my tour" and the leasing team is not synchronously alerted (voice: transfer; text: email; any: fallback email on failure) violates this ADR.

Consequences

Alternatives considered