feat(email-steward): add header heuristics before sub-agent body reads - #130
feat(email-steward): add header heuristics before sub-agent body reads#130TechNickAI wants to merge 1 commit into
Conversation
Add a zero-cost triage stage that classifies bulk mail from RFC-level headers before any sub-agent is spawned to read a body. Heuristics-first is both cheaper and more accurate than sending every ambiguous email to a model: a header is a fact, a body read is an inference. List-Unsubscribe, Precedence, List-Id, campaign headers and no-reply sender patterns resolve most promotional mail outright, so the expensive path is reserved for genuinely ambiguous mail. Two safety rules are stated explicitly: - Include beats exclude, so a VIP mailing through a campaign platform is never filtered. - Fail safe: heuristics only route to existing promotional handling, never hard-delete, and a missing or malformed header is a fall-through rather than a match. Verified against a live inbox: VIP senders were correctly protected, a no-reply notification was caught with no body read, and an ambiguous account-status email correctly fell through to the normal flow. Design informed by the mailguard cascade in mypaios/mypaios (MIT).
Review triageRequired check "Pre-commit (linting)": green. Python tests green. Cursor Bugbot: no findings.
Worth fixing separately: the No code changes made in response, because there were no review findings to address. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cca758770e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | Any campaign header (see list below) | promotional | Sent by a bulk-mail platform | | ||
| | Sender localpart matches the promo pattern below | promotional | Address is not a person who reads mail | |
There was a problem hiding this comment.
Require corroboration for promotional delivery markers
For transactional mail sent through SES/Postmark/SendGrid, or account, security, and payment notices sent from a no-reply address, these checks stop at the first match and route the message to quarantine/unsubscribe without inspecting its body. These signals identify delivery infrastructure or reply behavior, not promotional intent, so a non-VIP message needing attention can be removed from the inbox; require corroborating promotional evidence or let weak matches fall through to normal triage. This AGENT is upstream-synced to live instances, so the misclassification propagates on update.
AGENTS.md reference: AGENTS.md:L46-L52
Useful? React with 👍 / 👎.
| | `Content-Type: text/calendar` or `X-Microsoft-CDO-*` | important | Real invite, never bulk | | ||
| | `List-Unsubscribe` present | promotional | Bulk sender self-identifying | |
There was a problem hiding this comment.
Map heuristic verdicts to valid structured actions
When a heuristic matches, it returns important or promotional, but neither is in the required action vocabulary, and the later instruction mentions a quarantine label or unsubscribe queue without choosing an action or confidence. The runner therefore cannot satisfy the required structured decision and confidence threshold deterministically, and different agents may archive, unsubscribe, skip, or alert the same message; define an explicit valid action and confidence—or resume normal classification—for each verdict. This ambiguity is deployed because workflow AGENT files are synchronized to live instances.
AGENTS.md reference: AGENTS.md:L46-L52
Useful? React with 👍 / 👎.
|
Superseded by TechNickAI/hermes-config#92. The header heuristic is now part of the Hermes-native email-steward skill, with account adapters, cron setup, isolated body reads, deterministic tests, and a safety correction from live transactional-email testing. |
What
Adds a header heuristics stage to the email steward that runs before any sub-agent is spawned to read an email body.
Why
The steward currently escalates ambiguous mail straight to a sub-agent body read. Most of that mail is bulk/promotional and can be classified for free from headers we already fetched.
Heuristics-first is both cheaper and more accurate than sending everything to a model, because a header is a fact while a body read is an inference. Bulk senders self-identify via RFC headers (
List-Unsubscribe,Precedence,List-Id) and campaign platforms stamp their own (X-Mailchimp,X-Sendgrid,X-HubSpot, etc.).Safety
Two rules are stated explicitly in the doc, because this stage decides things without reading content:
Only mail that survives every check is ambiguous enough to justify the expensive path.
Verification
Ran the logic against a live inbox before opening this:
importantvia include-precedence, protectednoreply@service notificationpromotional, correctly caught with no body readThat last row is the key negative test: the heuristics did not swallow the one email that genuinely warranted attention.
Credit
Design informed by the
services/mailguardcascade in mypaios/mypaios (MIT).