đź§© Building an AI-Native Email System, One Job at a Time
What I'm learning by breaking the work inside Sock Club's sales inbox into jobs that can be measured, improved, and eventually automated.
I'm publishing this before the system is finished. This is the first entry in an ongoing series, and I want to document the decisions while they're still messy. Some numbers will change. I'll probably reverse a few decisions too.
At Sock Club, most sales work starts and ends in email.
Our team works from Front. Customers tell us what they need there. Deals move forward, designers get briefed, quotes go out, and orders get unstuck, all from the same inbox.
Every conversation asks someone on the team to do the same mental setup. They have to understand the request, pull context from a few other systems, make a call, and follow through. We repeat that process thousands of times a week, and most of the reasoning lives only in the head of the person who opened the message.
I started this project because I wanted the system to carry more of that load. The term people have started using for this kind of system is an “AI-native email system.” In practice, that means it can read a conversation, recognize the work inside it, and either handle the next step or prepare a teammate to take it from there.
The first live step is New Design Requests. Portal+ Assist turns customer context into a structured design task for a teammate to review and submit. It solves a real job today while creating a path to greater autonomy if the evidence supports it.
Why I'm careful with “AI-native”
Most AI email features summarize a thread, suggest a reply, or improve the compose box. They can save time, but the person reading the email still has to interpret the request and drive the process.
Here's the test I use: remove the AI. If the workflow still works the same way, only slower, the AI is assisting it. Remove a summary button and the inbox still functions.
If removing the AI takes away a core operating step, the system is AI-native. In this case, it would lose the ability to recognize jobs, gather context, and decide what should happen next. The team could still do the work manually, but the system would no longer function as designed.
Summarize, draft, recommend. A person still owns the consequential decision or action.
Classify, gather context, decide, execute, and measure against the business outcome.
I don't see AI-native as the destination for every job. Work with expensive or hard-to-reverse consequences may be better served by AI assistance and a human decision. Jobs with clear outcomes and easy recovery can move further toward autonomy. Some jobs may not need AI at all. The level of AI should match the consequences of getting the work wrong.
I haven't earned the label yet. That's one reason I'm writing this while I build. I want to capture how we decide when the system can act, where people should stay involved, and what we learn by watching the workflow closely.
Looking for the job inside the email
I didn't make much progress until I borrowed a page from Jobs to Be Done and stopped treating the email itself as the unit of work. The email is only the container. A single message can carry several separate jobs, each with a beginning, an end, and some way to tell whether it was done well.
When a customer writes, “Can you update the artwork and pricing?” I see a Revision Request and Quote Creation in the same message. When a reminder unsnoozes a conversation and a sales rep sends the customer a new message, that maps to a Follow-up. “Where is my order?” becomes a Tracking Update.
Reading the inbox this way gave the work names: New Design Requests, Follow-ups, Revision Requests, Quotes, Reorders, Tracking Updates, FAQs, and a handful of others that are still taking shape.
A job is a unit of work with a clear outcome. That makes it something we can measure, test, improve, and eventually automate.
One pipeline, shared by every job
Once jobs became the unit of work, a common pipeline started to take shape. Each stage has a clear responsibility, which makes it much easier to find the source of a bad decision.
- 01Inbound emailConversation enters
- 02Unified contextIntent, entities, state
- 03Identify jobsOne or many
- 04DecidePolicy + confidence
- 05ExecuteHuman or system
- 06EvaluateOutcome feeds back
Think of the Unified Context Layer as a shared case file that travels with the conversation. It holds the customer's intent, desired outcome, urgency, current state, quantities, in-hands dates, and the IDs connecting Front to HubSpot and Portal+. Every downstream job starts with the same facts instead of reconstructing the thread.
I was tempted to skip this work and automate one high-volume job first. The tradeoff became obvious once I mapped the system: without shared context, every new job would need its own version of the same brittle extraction logic. Building the common layer takes longer up front, but the improvements carry across everything downstream.
Why I started in shadow mode
The system currently runs in shadow mode. It reads real Front conversations but cannot act on them or send anything to a customer. That lets me learn from the work as it actually appears in the inbox without creating synthetic examples or putting live conversations at risk.
Each conversation moves through the n8n pipeline in stages. The Unified Context Layer creates a snapshot of the thread. A binary gate decides whether the latest message calls for action, then separate classifiers route it into one of five action categories or five no-action categories. The system also records a secondary category when needed. Every decision, extracted detail, confidence score, and unknown is logged in Supabase.
That is where the universal router currently stops. It does not identify or execute individual jobs yet. Portal+ Assist, which I cover later, is a separate, human-triggered workflow for New Design Requests. In the router, an Artwork / Design classification identifies the area of work. A later layer will determine whether the job is a New Design Request, Revision Request, or something else.
I let 100 to 200 conversations accumulate, export the rows, and give the batch to Claude with a repeatable analysis prompt. I look for overlapping categories, patterns inside Unknown, missed secondary categories, gate errors, and details pulled from the wrong part of a thread. Frequency shows where the team's workload is concentrated, while the topics inside each category begin to reveal the jobs I need to define next.
The findings go back into the pipeline. I update the categories, prompts, extraction rules, or workflow logic, then run another batch. Unknown gives uncertain conversations a safe place to land and gives me evidence for what the taxonomy needs next.
There is judgment involved, especially when deciding whether a pattern deserves its own category. Even so, this loop got the routing taxonomy to what felt like a useful first 80% much faster than trying to design it from intuition alone. More importantly, it gave me a process I can repeat.
- 01 Front conversations Real inbox data, read in place
-
02
n8n triage
Context snapshot, action gate, and high-level category router
Discovery signal Other / Unknown Uncertain work is preserved for review
- 03 Supabase log Decisions and details collect in batches of 100 to 200
- 04 Claude analysis Taxonomy gaps, missed secondary categories, gate errors, and workload patterns
- 05 System refinement Update categories, prompts, extraction rules, or workflow logic
Giving the jobs a home
Once the category router is stable, the next step is to give the jobs inside those categories a home. I'm building a job repository that tracks the high-level details I need to compare them: name, observed frequency, internal impact, external impact, priority, and current status.
Each row links to a working document with the job's definition, trigger, desired outcome, measures, and known failure modes. The details will keep evolving. The repository gives me one place to see what we know, what still needs discovery, and which jobs deserve attention first.
| Job | Frequency | Internal impact | External impact | Priority | Status |
|---|---|---|---|---|---|
| New Design RequestDetailed job doc | Measured | Low per request | Medium | P2 | Assist live |
| Follow-upsDetailed job doc | High | High | Medium | P1 | Assist |
| Revision RequestJob exercise still to do | Not yet measured | TBD | TBD | Unscored | Manual workflow |
| General Revision RequestJob exercise still to do | Not yet measured | TBD | TBD | Unscored | Manual workflow |
| Quote CreationDefinition in progress | Measuring | TBD | TBD | Unscored | Backlog |
| Tracking UpdatesDefinition in progress | Measuring | TBD | TBD | Unscored | Backlog |
| Additional jobsAdded as discovery continues | Ongoing discovery | TBD | TBD | To assess | To define |
Sanitized working view. Each job links to a deeper document covering its definition, trigger, desired outcome, measures, and failure modes.
The table helps me decide what to work on first. Frequency and pain surface opportunities, while status makes it clear what is assisted, manual, or still waiting for definition. The same logic sits behind my Workflow Friction Audit: understand and prioritize the work before choosing what to automate.
Autonomy is earned per job
Prioritizing a job tells me where the opportunity is. It does not tell me how much responsibility the system should have.
I track that separately in a job autonomy matrix. Each job has a live tier, a view of its risk and reversibility, the next behavior being tested, the evidence required before it can advance, and a list of actions that should always remain with a person.
The tiers track two handoffs: who initiates the job and who completes it. Tier 1 begins when a person asks for help. Tier 2 begins when the system recognizes the job and starts the assistance on its own. A person still controls the consequential action in both tiers.
Shadow mode sits across those tiers rather than inside them. Before a job gains more initiative or execution authority, the proposed behavior can run against real work without changing the live workflow. The broader category classifier uses shadow mode for discovery. Follow-ups can be live at Tier 1 while shadow-testing Tier 2.
- Tier 0ManualHuman initiates, prepares, and completes
- Tier 1Human-triggered assistanceHuman initiates, AI prepares, human completes
- Tier 2System-triggered assistanceAI initiates and prepares, human completes
- Tier 3Bounded autonomyAI initiates and completes within policy
| Job | Risk / reversibility | Live tier | Shadow target | Evidence required for promotion | Never autonomous actions |
|---|---|---|---|---|---|
| New Design Request | Reviewable internal draft | Tier 1 | Tier 2 · Not started | Sustained submission quality and lower rework | Customer email or creative approval |
| Follow-ups | Under review | Tier 1 | Tier 2 · Active | Define before promotion | Still being negotiated |
| Revision Request | Unassessed | Tier 0 | Not started | Complete the job exercise first | To be defined |
| General Revision Request | Unassessed | Tier 0 | Not started | Complete the job exercise first | To be defined |
| Additional jobs | Unassessed | Tier 0 | Not set | Complete the job definition first | Defined per job |
Sanitized working view. Promotion criteria and permanent human boundaries are negotiated separately for every job.
A live bridge to bounded autonomy
New Design Request makes the autonomy tiers concrete. It is live at Tier 1 and shows me what the system needs before it can take on more.
Sales works in Front, while design requests are submitted in Portal+, our internal system for this work. Portal+ Assist brings the request into the conversation so teammates no longer have to switch systems and re-enter the customer’s context.
The interface is part of the path
Portal+ Assist supports New Design Requests, Revision Requests, and General Revision Requests. New Design Request is the only AI-assisted path. The plugin prepares a structured draft; a teammate reviews, edits, and submits it. This is Tier 1: the system prepares the work, but nothing executes without approval.
Revision Requests and General Revision Requests use the same interface but remain manual because I have not completed the job exercise for either one.
The draft carries an explicit standard. I turned our Director of Design Operations’ description of the ideal new design request into the system prompt that produces it. In practice, every New Design Request is structured to give designers the best possible direction.
Working from that standard changed how I defined the job. I once thought Sales Support was simply relaying the customer’s message to Design. In practice, they add the context a designer needs to get the first pass right. The draft made missing context and rework visible in a way a process map could not.
That also changed how I measure the workflow. A fast intake that creates another design cycle only moves the cost to a different team.
The draft creates a path forward too. Its fields define the eventual API payload. Teammate edits reveal missing context, while submissions and rework show whether the job is ready for more autonomy.
At Tier 2, the Unified Context Layer recognizes the job and prepares the payload before anyone asks. A person still reviews and submits it. If the evidence supports bounded autonomy, Tier 3 would let the system complete the job on its own, from recognition through submission, within defined quality thresholds and policy checks. Customer communication and creative approval sit outside this job and remain human.
Observed workflow data from the first 500+ submissions.
Through Portal+ Assist.
Down from roughly 3–4 minutes manually, which is about a 90% reduction.
Before the customer sees something usable.
Equivalent capacity if the measured time savings hold at expected volume.
Equivalent capacity returned from New Design Requests alone.
Across approximately eight designers, creating room for work the team cannot take on today.
FTE-equivalent describes capacity. It isn't a staffing-reduction target. These projections will be updated as the reporting window grows.
The 24-second median proves the workflow is useful. The one-in-five rework signal shows it is not ready for more autonomy. The next step is improving the context Design receives so more requests succeed on the first pass.
What comes next
I'm now building three small evaluation datasets: one for the action versus no-action gate, one for the action categories, and one for the no-action categories. I test them separately so I can see which part improves when I change a model or rewrite a prompt.
LLMs are probabilistic. Unlike a deterministic rule, an LLM does not guarantee the same correct behavior every time. Its behavior can also shift when the inputs, prompts, or models change. That makes evaluations a basic practice for production AI systems. They aren't the fun part of the work, but without them, “it seems to work” becomes the release criterion.
I'm starting small. I use rows already logged in Supabase, ask senior teammates to label the correct answer, and store those reviewed examples in dedicated evaluation tables. I can then run the same examples through different models and prompts, compare the scores, and inspect the misses.
Now “done” can mean something concrete: tested against a known number of team-reviewed examples, above an agreed accuracy threshold, with the remaining errors understood. The next entry will cover how I'm building that evaluation layer and using it to decide when each part of the system is ready to move forward.