# 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.

- **Status:** Available
- **Audience:** both
- **In the app:** #/approvals, #/needs-you, #/autonomy-audit
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/workflows/approval-decision/

## The chain

1. Trigger — the engine finishes preparing an outbound action: a reply, an outreach message, a call.
2. User or external event — none yet. The customer has written; nobody has answered.
3. Authentication and workspace resolution — the deciding person's session resolves to one workspace before the queue is read at all.
4. Ingest — nothing is fetched; the held action already exists as a row in the workspace.
5. Canonical record — the held action carries the thread or call it belongs to, the channel, the recipient and the rule that held it.
6. Reasoning — already done. What the reader sees is the finished text, not a plan to write one.
7. Knowledge, memory and rules — already applied when the draft was written; a rejection does not retroactively change them.
8. Autonomy and approval — this is the stage the whole flow exists for: `ask_before_send` on the applicable scope put the action here, and a person's yes is the only thing that moves it.
9. Action through a provider — on approval, `outbound.py` hands the action to the mailbox, the messaging provider or the carrier.
10. Result — the provider's own acknowledgement, not the attempt, is what makes the state *sent*.
11. Relationship, timeline and memory — the sent action joins the person's timeline and the thread; the approver is recorded against it.
12. 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.

> **Note** Stage eight is a decision, not a formality, which is why a rejection is written to the decision log in the same shape as an approval. A refusal is a decision about your business, and the log answers 'who said no, and why' months later.

## 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](/docs/account/owner-vs-tenant/) differ commercially, not in what may be approved.

## Rejecting, and what it teaches

1. Reject the item.
   - Result: The rejection is stored against the thread and the engine does not immediately prepare the same action again.
2. 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.
3. 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.

> **Careful** Approving an item does not approve the rule that held it. The next action on that channel is held in exactly the same way. If you find yourself approving everything unchanged, the rule is the thing to change — see [changing what Connect may do](/docs/workflows/autonomy-change/).

## 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](/docs/autonomy/needs-you/) ranks by what the delay costs rather than by arrival time for exactly this reason.

## Related

- [Approvals](https://connectbyjbrh.com/docs/autonomy/approvals/)
- [Editing before approving](https://connectbyjbrh.com/docs/autonomy/editing-before-approval/)
- [Rejecting an action](https://connectbyjbrh.com/docs/autonomy/rejecting/)
- [Needs You](https://connectbyjbrh.com/docs/autonomy/needs-you/)
- [Proof that a message was sent](https://connectbyjbrh.com/docs/email/send-evidence/)
- [The approval is not in the queue](https://connectbyjbrh.com/docs/troubleshooting/approval-not-appearing/)
- [Human approval without blocking low-risk work](https://connectbyjbrh.com/research/approval-without-blocking/)

## What this page is based on

- Connect source pack §5 — autonomy, approvals and Needs You (`docs-source/sources/GENERAL.md`)
- Connect source pack §8 — the Assistant's rights are narrower than a person's
- Connect capability registry (`docs-source/facts.py`) — `approvals`, `held_draft_approval`, `send_evidence`, `audit_trail`
