# Ingesting a burst of mail, end to end

A burst is taken in as bounded passes rather than one enormous read, oldest message first, each becoming a canonical record before the read position moves past it. The daily allowance decides how much is processed today and holds the rest. Ingest and sending are separate gates, so several hundred arriving messages never become several hundred replies leaving at once.

- **Status:** Available
- **Audience:** both
- **Channels:** email
- **In the app:** #/inbox, #/needs-you
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/workflows/burst-ingest/

## The flow, stage by stage

1. Trigger — a sync pass finds far more waiting than a normal pass would.
2. External event — a newsletter blast, a form that fired repeatedly, a mailbox reconnected after a long silence, or a genuine spike in customer mail.
3. Authentication and workspace resolution — the mailbox's workspace is entered once, and every read and write in the pass happens inside it.
4. Ingest — messages are taken in bounded batches, oldest first, so the read position always trails work that is finished.
5. Canonical record — each message is matched to an existing thread or starts one, and the person it came from is resolved as it lands.
6. Classification and reasoning — triage runs per message; the engine picks its next piece of work by priority rather than by arrival order.
7. Knowledge, memory and rules — read per thread when a reply is considered, not once per message during ingest.
8. Autonomy and approval — applied at the point of sending, per channel and per mailbox, and entirely separate from how fast mail came in.
9. Action through a provider — reads during ingest; sends only for the threads that pass every gate.
10. Result — a filled Conversations list, a much shorter list of things actually answered, and a held remainder if the allowance was reached.
11. Relationship, timeline and memory — each message attaches to its person and appears on the timeline dated when it was received.
12. Audit, usage and Needs You — processed mail is metered, refusals are recorded as decisions, and anything a person must see is queued.

Nothing in that chain is special-cased for volume. A burst is the ordinary path run many times with the ordinary limits still in force, which is the reason it behaves predictably rather than dramatically.

## Four things bound the damage

| Bound | Effect on a burst |
|---|---|
| Bounded batches | The mailbox is read in passes rather than in one read that could exhaust memory or time out against the provider |
| Oldest first | A long thread is rebuilt in the order it happened, so triage sees the question before the chaser |
| The daily allowance | How much mail is processed today; the rest is held, and the read position does not move past it |
| Autonomy at the send gate | Whether anything leaves at all — a workspace in `ask_before_send` produces a queue for a person, not a wave of mail |

Priority is what makes the queue useful rather than merely long. The engine reads a thread's priority when it chooses what to work on, so raising one changes what happens next rather than re-sorting a screen. In a burst that is the difference between the important thread being answered first and being answered five hundredth.

## What waits, and what waiting looks like

- **Held mail.** Messages above the read position that the allowance would not cover. They are not dropped and not marked as seen; they arrive when the allowance resets.
- **Held replies.** Drafts written but not sent, because the autonomy rule for that mailbox says a person decides. The recipient sees nothing at all while one waits.
- **Nothing skipped.** No part of the burst is discarded to catch up. That is the trade the refusal makes: a visible backlog instead of quiet loss.

> **Note** A burst is one of the few times a workspace sees its own allowance clearly. The refusal is shown in Needs You with its cause, so the question a person is left with is *do we want a larger allowance* rather than *why did the mailbox stop*.

## Failure modes

**The provider rate-limits the reads** — The pass shortens and resumes rather than failing the mailbox. The read position stays with what was recorded.
**The burst is one sender repeating** — Blocking that sender is a memory directive tagged per channel, which holds across channels and future conversations rather than filtering one thread.
**A thread appears twice** — Identity, not volume. Two mailbox rows for one real inbox is the cause worth checking first.
**The backlog never shrinks** — One message at the head of the queue may be unrecordable, holding everything behind it. An allowance backlog shrinks at each reset; an obstruction does not.
**Replies go out faster than expected** — The workspace is autonomous on that channel. Autonomy, not ingest, is the setting to change.

## What to do while it drains

1. Raise the priority on the few threads that genuinely cannot wait.
   - Result: The engine picks work by priority, so the correction changes the order in which mail is actually handled.
2. Leave the rest alone for one allowance cycle.
   - Result: You learn whether the backlog is a limit or an obstruction, which is the one diagnostic that separates them.
3. If the burst is unwanted mail from one source, record a block against that contact rather than deleting threads.
   - Result: The block is durable and channel-aware; deleting threads is a tidy-up that the next message undoes.
4. Check the Needs You queue before assuming a fault.
   - Result: A refusal names its cause. A mailbox with no entry and no new mail is a different problem from one that is openly holding work.

## Questions

### Will Connect reply to hundreds of messages at once?

Ingest and sending are separate gates. How quickly mail comes in has no bearing on how much goes out: the autonomy rule for the mailbox decides that, and a workspace that asks before sending gets a queue for a person rather than a wave of outbound mail.

### Is old mail processed before new mail?

Ingest is oldest first, so threads are rebuilt in the order they happened. What the engine then works on is chosen by priority rather than by age, which is why correcting a priority is worth doing during a backlog.

### What happens to the mail the allowance would not cover?

It waits above the read position, untouched. Nothing is marked as seen and nothing is discarded; the refusal appears in Needs You, and ingest continues from the same place when the allowance resets.

## Related

- [Large batches and bursts](https://connectbyjbrh.com/docs/email/burst-handling/)
- [The daily email allowance](https://connectbyjbrh.com/docs/email/daily-allowance/)
- [Hitting the daily allowance, end to end](https://connectbyjbrh.com/docs/workflows/quota-refusal/)
- [Triage and priority](https://connectbyjbrh.com/docs/email/triage/)
- [Why only one loop may think](https://connectbyjbrh.com/research/single-thinker/)

## What this page is based on

- CHANNELS.md §1 — health, sync, the cursor and blocking
- GENERAL.md §3 and §5 — canonical triage fields, autonomy and Needs You
- `backend/app/tenant_inbox.py`, `metering.py`, `runner.py`
- Connect capability registry (docs-source/facts.py) — `daily_quota_refusal`
