Approving a held action, end to end
Connect prepares an action, the autonomy rule for that channel says a person decides, and the action waits in Needs You with the thing it answers. A member with permission on that channel edits it or leaves it alone, then approves or rejects. Approval runs the action through the same send boundary a person's own send uses, and both the decision and its result land in the decision log.
The chain#
- Trigger — the engine finishes preparing an outbound action: a reply, an outreach message, a call.
- User or external event — none yet. The customer has written; nobody has answered.
- Authentication and workspace resolution — the deciding person's session resolves to one workspace before the queue is read at all.
- Ingest — nothing is fetched; the held action already exists as a row in the workspace.
- Canonical record — the held action carries the thread or call it belongs to, the channel, the recipient and the rule that held it.
- Reasoning — already done. What the reader sees is the finished text, not a plan to write one.
- Knowledge, memory and rules — already applied when the draft was written; a rejection does not retroactively change them.
- Autonomy and approval — this is the stage the whole flow exists for:
ask_before_sendon the applicable scope put the action here, and a person's yes is the only thing that moves it. - Action through a provider — on approval,
outbound.pyhands the action to the mailbox, the messaging provider or the carrier. - Result — the provider's own acknowledgement, not the attempt, is what makes the state *sent*.
- Relationship, timeline and memory — the sent action joins the person's timeline and the thread; the approver is recorded against it.
- Audit, usage and Needs You — the decision, the rule behind it and the outcome go to the decision log; the allowance is debited; the queue entry drains.
Stage by stage, in the screen#
| Stage | What you see | What changes | What can fail |
|---|---|---|---|
| Held | The item in Needs You, ranked against everything else waiting | Nothing outbound exists yet; the recipient has had no message | Nothing — but the customer's clock is running, and a held reply is no reply rather than a slow one |
| Opened | The original message or call above the prepared answer | Nothing | The thread has moved on since the draft was written, so the answer reads as though nobody was listening |
| Edited | Your text replacing Connect's | The stored action, not the model's output — your edit is what goes | An edit that removes something the recipient asked for; nothing re-checks the draft against the request |
| Approved | The item leaving the queue | The action is handed to the provider through the shared send boundary | The allowance is already spent, or the recipient is suppressed; the decision is recorded and the send waits or refuses |
| Acknowledged | The message on the thread with its evidence | The state becomes *sent*; usage is booked | The provider never acknowledges, and the state stays uncertain rather than quietly claiming success |
| Logged | The entry in the decision log | The approver, the rule and the outcome are stored together | Nothing — the log is written whether the action succeeded, failed or was refused |
Who may decide#
A workspace member with permission on that channel. The approval is recorded against the person who gave it, not against the workspace, because accountability that names nobody is not accountability. The Connect Assistant can approve a draft on your behalf when you ask it to — approve_draft and send_draft_now are among its tools — but its rights stay narrower than yours: it cannot quote a price and it cannot clear a do-not-contact entry.
The Owner and a customer follow the identical path here. There is no operator-only approval screen and no shortcut that skips the boundary; the operator's workspace and a customer's differ commercially, not in what may be approved.
Rejecting, and what it teaches#
Reject the item.
Result The rejection is stored against the thread and the engine does not immediately prepare the same action again.
If the reason should change future behaviour, say so as guidance on the thread or as a memory at the right tier.
Result The next draft is written with that in it. A rejection on its own is a decision about one message, not a lesson.
If nothing should ever go out on that channel for that contact, set the autonomy rule at the contact scope instead of rejecting repeatedly.
Result Connect stops preparing the work, which is cheaper for everyone than preparing it and having it refused.
Questions#
Does approving send immediately?
The send starts immediately. Whether it completes immediately depends on the provider, and the state does not become *sent* until the provider acknowledges it. Two limits can also delay it: a spent daily allowance holds the send until the allowance resets, and a suppressed recipient refuses it outright.
Can I approve something somebody else was looking at?
Yes — the queue belongs to the workspace, not to a person. The decision log records who actually approved it, so a shared queue does not blur responsibility.
What happens to an item nobody ever decides?
It stays. Nothing expires it and nothing sends it by default, which is the safe failure but not a harmless one: the recipient is still waiting. Needs You ranks by what the delay costs rather than by arrival time for exactly this reason.