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 test is New Design Requests, where a teammate can turn a customer conversation into a reviewed design task in a median of 24 seconds.
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.
What New Design Requests taught me
New Design Request is the first job I moved into a live, job-specific workflow. It gave me a concrete place to test what AI assistance should look like inside the work rather than beside it.
The sales team spends most of its day in Front, but many of the internal actions required to move a deal forward happen somewhere else. A teammate has to leave the conversation, open another system, and re-enter context that already exists in the email thread. The cost is larger than the extra clicks. Manual transcription introduces errors, handoffs slow execution, and important context gets thinner each time the work changes hands.
The job I wanted to improve was straightforward: help a teammate move from customer intent to design task delivery with less context switching, manual transcription, and coordination overhead.
Portal+ is the internal system where the team creates and submits work such as design requests. Portal+ Assist is the Front plugin I built around this job. It brings a defined set of Portal+ workflows into the place where the customer context already lives.
Useful artifacts before autonomy
Portal+ Assist supports New Design Requests, Revision Requests, and General Revision Requests. New Design Request is currently the only AI-assisted path. For that workflow, the plugin interprets the conversation and prepares a structured design task draft. A teammate reviews the information, makes any necessary changes, and decides whether to submit it. Nothing executes without explicit approval.
Revision Requests and General Revision Requests use the same plugin, but those workflows are manual. I have not completed the job exercise for either one yet, so I am not treating them as AI-assisted simply because they share an interface with the New Design Request flow.
Creating the draft inside Front keeps the context attached to the work, reduces transcription between systems, and leaves submission with the teammate who owns the request.
The New Design Request path is currently Tier 1 because a teammate initiates the assistance. Tier 2 would begin when the system recognizes the job and prepares the draft before someone has to ask for it. A person would still review and submit the task.
Once the team started using the workflow, I saw effects I had not planned for. The structured draft exposed missing context, made rework easier to see, and created a new measurement point. I could feed those outcomes back into the job definition and context layer. I would not have found those effects in a process map. They surfaced when the workflow met real work.
Before I sat with designers, I would have described the job as relaying the customer's message to Design. Watching the work changed that definition. Sales Support also has to add the context a designer needs to produce something useful on the first pass.
That changed how I measure the workflow. Submission speed is useful, but a fast intake that creates another design cycle only moves the cost to a different team.
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.
At this point, the one-in-five rework signal interests me more than shaving another few seconds from the form. That number points me toward the next piece of work: 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.