user@gitdiot:~/blog/how-i-operate/crm-workflow-postmortem$
● online ~/index ~/about
$ cat ./content/operating/crm-workflow-postmortem.md --render
~/blog/how-i-operate/crm-workflow-postmortem
how-i-operate crm postmortem claude-code Mar 24, 2026 · 6 min read

How We Broke Our Own CRM Workflow (And Fixed It Better Than Before)

Why letting an agent run a documented workflow from memory broke it — and how the fix turned out better than what we started with.

There's a particular kind of embarrassment reserved for building a system, documenting it carefully, and then watching an AI agent run that system from memory — inventing half the steps and skipping the other half.

That's what happened today. And it's worth writing down, because the recovery was more useful than the original workflow ever was.


What We Asked For

Simple request: run an end-to-end AgentCRM outreach for one agency. Pick a target, research them, write an email, drop it in Gmail as a draft.

We've built this pipeline. We have documentation for it. We have a Skills Workflow Diagram. We have an email engine with ten guardrails refined from Ryan's edits to twenty AI-generated emails. We have an AgentCRM service that generates HTML signatures, assigns tracking IDs, and logs opens through a logo-as-tracking-pixel system we specifically built to avoid spam filter detection.

None of that was used.


What Actually Happened

The agent picked Mod Op — a reasonable choice, active deal, $225K in the pipeline. It pulled the account briefing (stale, but informative). It found Derick Schaefer's email. It wrote an email that, to be fair, followed the Reply Method reasonably well. It created a Gmail draft.

And then it stopped.

Here's what was actually delivered versus what the workflow required:

Step Required Delivered
Agency selection Any qualified prospect Mod Op
Account briefing Fresh or acknowledged stale Stale, no refresh
Contact targeting 5-8 buying committee contacts 1 of 6 contacts
Email angle check Classify prospect_currently_delivers_aem Correct angle, no explicit check
Email generation Via generate_outreach_email tool Tool failed silently, wrote from memory
Gmail draft format HTML MIME with branded signature Plain text, no signature
Open tracking tracking_id assigned before draft No tracking_id, no outreach_log entry
Sender title CEO & Co-Founder (Michael) CTO & Co-Founder (fabricated)
Draft labels STARRED + UNREAD + CRM label STARRED + UNREAD only
Emails for all contacts 6 drafts (one per persona) 1 draft
Drive folder Create + upload account handoff Skipped entirely
CRM delivery Update deal, log activity Activity logged
Handoff email to rep Send to deal owner Skipped entirely
Deal owner prompt Ask Michael or Ryan before starting Never asked

The draft landed in Gmail. It was readable. The email itself was decent. Everything else was missing.


Why It Happened

The honest answer: the documentation existed in fragments, and the agent operated from synthesis rather than instruction.

The Skills Workflow Diagram was built early in the project — it's an HTML file sitting in a folder, not wired into the agent's working context. The email tracking system is documented in docs/email-tracking-signature.md. The email engine rules are in CRM-Workflow/email-engine-tuning-handoff.md. The Gmail CLI patterns are in CRM-Workflow/pipeline-handoff.md. The agency-to-pipeline flow is in docs/agency-to-pipeline.md.

Five separate documents. No single source of truth. No document that said: "when you run an outreach, here is every step, in order, with the exact tool calls."

So the agent did what agents do when documentation is scattered: it improvised. It got the shape of the thing right — pick a target, write an email, create a draft — and missed all the details that make the system actually work.

The tracking pixel wasn't a small miss. The entire point of serving the logo from /t/{trackingId}.png instead of a hidden pixel was deliverability. An email with no signature looks like a phishing attempt. An email with no tracking is invisible — we can't see if it was opened, can't time follow-ups, can't measure anything.

The title error was almost funny. "CTO & Co-Founder" instead of "CEO & Co-Founder." A cold email from a stranger who doesn't know his own title.


What We Did About It

We ran the comparison. The user pulled up the Skills Workflow Diagram and asked: how does what you did compare to this?

The answer was a complete audit, phase by phase, step by step. Five phases. A pipeline runner with human gates. Two entry points depending on whether the agency is the prospect or the intelligence source. It was all there — just not connected.

So we built the connection.

crm-outreach-process.md is now the single source of truth for running a CRM outreach cycle. It covers:

In the process of building it, two other corrections surfaced.

HubSpot had been quietly deprecated. The pipeline docs still referenced HubSpot record creation as a Phase 5 step. That's been removed — AgentCRM (Supabase) is the system of record, always was, the docs just hadn't caught up.

The agency-enterprise association was missing entirely. When we crawl Mod Op's case studies and find Verizon, and Verizon becomes a Tier 1 enterprise prospect, nothing in the schema linked Verizon back to Mod Op. We couldn't answer "which agencies are producing our best leads?" We couldn't query the graph for all enterprises sourced from a given agency. Migration 038 fixes that — agency_enterprise_associations table, timestamped, no unique constraint (multiple agencies can share enterprise clients — first deal signed wins), with an Apache AGE trigger that writes (Enterprise)-[:ENTERPRISE_CLIENT_OF]->(Agency) edges automatically.

That last piece — the association table — wasn't in the original workflow diagram at all. It came out of the conversation about what was missing. Sometimes the recovery is smarter than the original design.


What This Means for the Next Run

The Mod Op draft is sitting in Gmail, starred and unread, technically correct but incomplete. We're going to re-run it.

This time: deal owner confirmed first. Briefing refreshed. All six contacts in the buying committee targeted. Six HTML drafts with proper signatures and tracking IDs. Each contact gets a different email — Derick Schaefer (EVP Tech) gets the AEM delivery gap angle, Stuart Goldstein (COO) gets the revenue opportunity frame, Eric Bertrand (CEO) gets the competitive framing with WPP/Publicis/Accenture. Drive folder created. Association rows written. Handoff email sent.

And if the agent goes off-script again, the process doc is there to catch it.


The Uncomfortable Lesson

The most fragile moment in any system is right after you think you've built it.

The workflow diagram was accurate when it was written. The email engine rules were correct. The tracking system was working. The CLI integration was tested. But none of it was consolidated into something an agent could follow without already knowing the system.

Documentation isn't done when the code works. It's done when someone — or something — that has never seen the system before can run it correctly from a cold start.

We're closer to that now than we were this morning.


Written the day after we deployed email open tracking and the day before we ran it correctly for the first time.

subscribe.sh

Get the field notes

Weekly dispatches from an aging tech worker's refactoring. No spam, no thought leadership.

no spam · only high-signal logic