Email Channel Technical Notes
Thread splitting, participant analysis, and reply-target rules for the email channel.
This page explains the technical behavior behind the email channel.
It is the implementation-oriented companion to the product-facing Email Channel page.
Threading model
The email channel should not use senderId alone as the unit of conversation.
That would merge unrelated chains from the same sender and would make personal-memory decisions unsafe.
Instead, the runtime should derive a stable thread key from standard email headers.
Inputs
For each inbound email, the runtime should extract:
- the current
Message-ID - the
Referencesheader, if present - the
In-Reply-Toheader, if present
If the normalized API payload is missing these fields, the runtime should fall back to parsing the raw MIME message.
Thread key algorithm
- Parse
Referencesinto an ordered list of message IDs. - Parse
In-Reply-Tointo one or more parent message IDs. - Normalize all message IDs:
- trim whitespace
- lowercase
- strip surrounding angle brackets if needed
- Choose the root ID:
- if
Referencesis present, use the first message ID inReferences - else if
In-Reply-Tois present, use the first ID there - else use the current
Message-ID
- if
- Build the thread key as
email-thread:<root-id>.
That key should become the email conversation key used for runtime state.
What does not define a thread
These fields can help with diagnostics, but they should not be the primary split key:
- subject line
- sender address by itself
- participant set by itself
Subjects drift, senders reuse the same address across many unrelated chains, and participant sets can stay the same across distinct conversations.
Participant analysis
For each inbound message, the runtime should normalize addresses from:
FromReply-ToToCCBCC
Then it should:
- remove nicoolAI-owned inboxes
- deduplicate the remaining addresses
- compute the set of external participants for the thread event
This participant set drives the auth decision for the thread.
Personal eligibility rule
The rule should be strict:
- exactly one external participant: eligible for personal behavior
- more than one external participant: not eligible for personal behavior
If the sole external participant maps to a verified user email, the runtime can use that user's personal memory scope for the thread.
Otherwise it should fall back to sender-scoped behavior.
Important: this should be resolved per thread, not by globally linking email:<address> to a user.
Why the decision must be thread-scoped
The same sender can appear in:
- a direct message to nicoolAI
- a later reply-all chain with several people
- a separate conversation with the same subject prefix
If auth were linked at the sender level, a later group email could accidentally inherit personal memory from the direct thread.
Thread-scoped resolution prevents that.
Reply target rules
Outbound reply routing should be simple and deterministic:
- If
Reply-Toexists, send toReply-To. - Otherwise send to the sender in
From.
The runtime should not fabricate recipients.
Reply threading headers
Outbound replies should preserve the thread using standard email headers:
In-Reply-To: the last inbound message IDReferences: the prior thread chain plus the last inbound message ID
References is the thread ancestry list.
Example:
- original message:
<a@example> - first reply:
In-Reply-To: <a@example>,References: <a@example> - second reply:
In-Reply-To: <b@example>,References: <a@example> <b@example>
The stable thread root remains <a@example>.
Fallback behavior
If no usable message IDs are available, the runtime should fail conservatively.
A synthetic fallback key can exist for robustness, but it should be treated as a last resort because it can mis-thread unrelated emails.
The safest fallback order is:
- raw MIME parsing
- current
Message-ID - only then a synthetic key
Operational summary
The email channel should use:
- message IDs for thread identity
- participant count for personal-eligibility checks
- standard reply headers for continuity
That keeps the channel email-native while preserving the stricter trust model needed for personal memory.