Executing phone follow-ups
A follow-up on the phone channel is executed by a drain in the runner: when one comes due, it places the call through the same outbound path any other call uses. The gates are the ordinary ones — memory blocks, consent, autonomy, budget, the line's hours — plus two the drain adds: a voice worker that is not ready, and a cut-off once a follow-up is a day late.
What happens when a call-back comes due#
The drain picks up follow-ups whose due time has passed on the
phonechannel.Result Nothing is placed early. A call-back promised for tomorrow morning is not made tonight because the queue happened to be quiet.
The call is placed through
comms_providers.dispatch_callwith aplacer— the same call that the Assistant, a person or the engine would make.Result There is one outbound path, so every rule written once applies everywhere. A follow-up cannot route around consent by being a follow-up.
The line rings the person, the conversation happens, and the call ends like any other.
Result A summary, an outcome, facts, a lead and possibly another follow-up come out of it. A call-back that produces a second call-back is ordinary business, not a loop.
The follow-up is closed against the call that fulfilled it.
Result The commitment and the evidence it was kept sit together, which is what makes the queue trustworthy enough to work from.
The gates, in the order they refuse#
| Gate | Refusal | Retried? |
|---|---|---|
| A memory block or do-not-contact on the person | The call is not placed | No — the block is the answer |
| Consent for this channel | The call is not placed | No |
| The autonomy rule for the phone channel | Held for a person to approve, or not made at all | Not by the drain — a person decides |
budget_refusal before an outbound | The call is not placed | When budget is available again |
| The line's hours, or the line switched off | The call is not placed now | Yes, when the line is open |
No voice worker ready (not_ready) | Refused before a Call row exists | Yes — this is the case the drain retries |
A malformed model id (bad_model) | Refused before a Call row exists | No — retrying a bad configuration only rings the owner again |
The distinction in the last two rows is the useful one. not_ready is a statement about this moment — a worker is deploying, the fleet is saturated — and the right response is to try again shortly. bad_model is a statement about the configuration, and trying again changes nothing; one Lab call rang the owner and then died with a session error because a model id pointed somewhere that could not serve it.
Why "not ready" is refused before a row exists#
ring refuses when no worker has checked in for 90 seconds, and refuses when every live worker reports a one-minute load per core over 0.85 — the same threshold the worker itself gives its dispatcher, so admission control and the gate agree rather than arguing.
Refusing *before* a Call row is created is what makes the retry clean. There is no half-created call to reconcile, no row that has to be swept later, and nothing that shows up in the call list as an attempt that never rang. The follow-up simply stays due.
The point at which a late call-back is abandoned#
A phone follow-up that is more than 24 hours late is not placed. That number is a judgement about customers, not about queues: somebody promised a call back this afternoon, and a phone ringing at this time tomorrow is not the promise being kept late, it is a different and worse experience. The commitment stays visible so a person can decide what to do about it.
The practical consequence is that a fleet outage lasting a day does not resolve itself into a burst of stale calls when it ends. That failure mode — every customer who was owed a call yesterday rung at once, out of context — is the one the cut-off exists to prevent.
Questions#
The follow-up is overdue and no call was made. Where do I look first?
At the line before the queue. Most non-placements are the line being closed or switched off, the fleet having no ready worker, or the budget being spent — all of which are visible on the Phone screen's health signals rather than on the follow-up itself.
Can a call-back be placed outside business hours?
Not by the drain. The line's hours gate an automated outbound the same way they gate answering an inbound. If a commitment genuinely needs a call outside hours, a person places it from the browser line, where the same may_place_call check runs with a person behind it.
What happens to a follow-up that is refused for budget?
It stays due and is attempted again while it is still inside the 24-hour window. The refusal is recorded, so a queue that stalls on budget looks like a budget problem rather than an unexplained silence.