Connect by JBRH Open Connect

An email follow-up, end to end

A follow-up is a dated commitment with a reason attached to a person. When it falls due, the drain writes the message and puts it through the same gates as any other outbound email: compliance, autonomy, allowance, then outbound.py. The commitment is one record with one outcome, which is what stops a retry sending it twice.

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

From commitment to sent message#

  1. Trigger — the commitment falls due. It exists because somebody promised something, or because Connect recorded a promise made in a reply.
  2. User or external event — nothing external happens here; the reason for the message is already a record, which is what makes it defensible later.
  3. Authentication and workspace resolution — the drain runs inside the owning workspace before any mailbox, rule or allowance is read.
  4. Ingest — the person, the thread it belongs to and the reason for the commitment are loaded together.
  5. Canonical record — the row is the unit of work; the message that goes out is written against it, not instead of it.
  6. Reasoning — the message is written for this commitment, in the context of the conversation that produced it.
  7. Knowledge, memory and rules — memory resolves narrowest-first; a block:email directive on the contact stops it here rather than at the provider.
  8. Autonomy and approval — the mailbox's mode decides. ask_before_send turns a due chase into a Needs You item rather than a sent message.
  9. Action through a provider — outbound.py, the same boundary a person's own send uses, with suppression and the daily allowance checked inside it.
  10. Result — sent with provider evidence, held, refused, or left *uncertain*; the outcome is written against that row.
  11. Relationship, timeline and memory — the message joins the person's timeline, and a new commitment made in it becomes the next follow-up.
  12. Audit, usage and Needs You — the send is metered, the decision — including a refusal — is recorded, and anything a person must decide is queued.

Where a follow-up comes from#

Follow-ups are not a mail feature; they are the workspace's commitment queue, and email is one of the channels they run on. The others are WhatsApp, SMS, phone, any, and task. A task follow-up is work for a person: no drain ever sends it, and it shows on the follow-ups screen as something for a person to do.

Two sources produce most email follow-ups. One is explicit — somebody, or the Assistant through create_followup, writes the commitment down with a date and a reason. The other is a promise made inside a reply, which becomes a dated row rather than a sentence nobody tracks. The reason field matters more than it looks: it is what the message is written from when the date arrives, and it is what a person reads to decide whether the commitment is still worth keeping.

The gates, in the order they are asked#

GateWhat you seeWhat changesWhat can fail
ComplianceThe chase closes without sendingA recorded refusal against the rowNothing silently: suppression, unsubscribe, complaints and do-not-contact are checked in one place, and the Assistant cannot clear a do-not-contact entry
DirectivesIt stops before a message is writtenA refusal, with the blocking memory namedA block set for one channel being read as a block on all of them — it is per channel by design
AutonomyAn item in Needs You instead of a sent messageA held message ranked into the queueA due commitment quietly turning into an approval nobody works
AllowanceThe message waits rather than failingNothing is consumed and nothing is lostAssuming a held one was sent, because the row is no longer listed as due
SendA message on the thread with its stateAn outbound record with provider evidenceA provider rejection, or an acknowledgement that never arrives — which is *uncertain*, not failed

Why a retry cannot send it twice#

Idempotency here rests on the record rather than on the message. One commitment is one row with one outcome, and the outcome is written against that row: a drain that runs again finds work that already has an answer and leaves it alone. That is why the commitment, not the email, is the unit of work.

The subtle case is an uncertain send. Because Connect refuses to guess either way, an uncertain outcome is not retried as though it had failed — re-sending on a maybe is exactly how somebody receives the same chase twice, and the follow-up screen shows the state rather than resolving it for you.

What happens next#

  • A reply to the follow-up arrives as ordinary inbound mail and is handled by the reply path, not the outreach path — the two are never merged, and their gates are different.
  • A commitment made inside the follow-up becomes the next dated row, so a chain of chases is a chain of records rather than a habit.
  • Nothing further happens on a closed row. Completing one is a decision and is recorded as one.
  • Where the reply changes the commercial picture, the thread can become an opportunity: from an email to an opportunity.

Questions#

Does a follow-up send itself if I have never approved anything?

Only where autonomy for that scope allows it. Under ask_before_send a due follow-up becomes an approval; under draft_only the message is prepared and not queued at all; under off nothing is written.

What happens to a follow-up when the allowance is spent?

It waits. The work is held rather than dropped, exactly as an inbound refusal holds mail, and it goes out when the allowance resets — see hitting the daily allowance.

Can the Assistant create and close follow-ups?

Yes — create_followup, complete_followup and list_followups are among its tools. Its rights stay narrower than a person's: it cannot clear a do-not-contact entry, so it cannot make an unsendable follow-up sendable.