Connect by JBRH Open Connect

Executing a follow-up, end to end

A row falls due, the drain takes it — two per tick on the phone channel — and runs it through the same gates as any outbound action on that channel. One of three outcomes is written back: placed, awaiting approval, or refused with a reason. More than twenty-four hours late and it is closed as missed: instead of rung.

Status
Available What this means
Audience
both
Channels
phone
In the app
#/follow-ups, #/needs-you, #/calls
Last verified
Product version
6.3.2

The thirteen stages#

  1. TRIGGER — the row's due time passes. Nothing external happens; time is the trigger, which is what makes this flow different from every other one in this section.
  2. USER / EXTERNAL EVENT — none at the start. The customer has done nothing; they are simply waiting for something they were promised.
  3. AUTH / WORKSPACE RESOLUTION — the row belongs to exactly one workspace, and the drain acts within it. There is no cross-workspace queue and no privileged operator pass through this path.
  4. INGEST / REQUEST — runner.chase_phone picks up due phone rows on the engine's tick, two per tick, so a batch of call-backs is worked through over several passes rather than seizing every line at once.
  5. CANONICAL RECORD — the row resolves to its Person and to a reachable identity: a number for a call, a mailbox or handle for a message. A row whose person has no usable identity cannot be executed.
  6. CLASSIFICATION / RESEARCH / REASONING — the channel decides the action. task rows are never picked up at all; nothing drains them, at any tick.
  7. KNOWLEDGE + MEMORY + RULES — what the action will say is grounded the same way any outbound message is. On a call, safe_sales still refuses a commercial term Knowledge does not support, follow-up or not.
  8. AUTONOMY / APPROVAL — the channel's autonomy rule decides whether the action may leave. A held attempt is recorded as awaiting approval <id> and joins Needs You, ranked with everything else waiting on a person.
  9. ACTION / PROVIDER — a permitted phone row goes through voice_engine.place_call, with the same gates as any outbound call: suppression and do-not-contact, line readiness, and what the workspace's allowances permit. A line that is not ready is retried in an hour.
  10. RESULT — one of three strings against the row: call placed <id>, awaiting approval <id>, or refused: <reason>. A placed call becomes an ordinary call with its own transcript, summary and cost.
  11. RELATIONSHIP / TIMELINE / MEMORY — the attempt appears on the person's timeline, and a successful action stops the commitment being owed. Anything durable learned on the resulting call can be remembered against that contact.
  12. AUDIT / USAGE / NEEDS YOU — the attempt is recorded with its outcome and its reason, usage is metered against the workspace, and anything held sits in front of a person while the clock keeps running on it.
  13. NEXT — the row is completed, retried, or — past twenty-four hours late on the phone channel — closed as missed: and never rung, because a very late call-back is worse than none.

Stage by stage#

StageWhat you seeWhat changesWhat can fail
DueThe row goes overdueNothing yetNothing — a minute between due and picked up is the tick, not a fault
Pick-upTwo rows moving per tickThe rows being attemptedA long queue means later rows wait, and ageing rows can pass the cut-off
IdentityNothingNothingA person with no reachable identity on that channel
AutonomyAn item in Needs YouThe row shows awaiting approvalNobody works the queue, and the held row ages towards missed:
GatesA refusal with its reasonThe refusal on the rowSuppression, an unready line, or an exhausted allowance
ActionA call in progressA call record with its own idThe call itself fails; that is the call's own failure path, not the follow-up's
OutcomeOne of three stringsThe row's recorded resultReading awaiting approval as refused, and fixing the wrong thing
LatenessA closed row reading missed:The row closesNothing was rung, deliberately

Reading the outcome correctly#

call placed <id>
The commitment to ring was kept. Follow the id for what was said; the follow-up's part is done.
awaiting approval <id>
Nothing has been dialled. A person must decide, and the row keeps ageing while they do.
refused: <reason>
A gate decided. Some reasons clear themselves — an allowance resets, a line recovers — and some are the correct permanent answer, such as a do-not-contact entry.
missed:
The twenty-four-hour cut-off. Nobody abandoned this; the clock ran out, and the row still says what was promised.

What this flow will not do#

  • It will not ring somebody who has asked not to be rung. A scheduled action is still an action, and suppression applies unchanged.
  • It will not execute a task row. Nothing drains that channel, so the wait is the whole answer.
  • It will not retry forever. A specific case — an unready line — is retried in an hour. Everything else is recorded and left for a person.
  • It will not ring a very late row. Past twenty-four hours the call is not made at all, which is the deliberate outcome rather than a failure to reach the customer.

Questions#

Why is a follow-up subject to the same gates as an ordinary call?

Because it is an ordinary call. Placing it through voice_engine.place_call rather than through a private path is what guarantees a scheduled action cannot bypass suppression, allowances or the line's health.

Can the drain be made faster than two rows per tick?

The rate is a property of the drain rather than a per-workspace setting, and it exists to stop a queue of due rows seizing every line at once. A queue consistently outrunning it is a signal about how many call-backs are being promised.

What happens to the row while an approval is waiting?

It stays open, still owed, and still ageing against its due time — including against the twenty-four-hour phone cut-off. Approvals are not a pause on the clock.