Your CRM stores rows. Claude Code needs state.
Last month I watched a founder ask Claude Code to "review the pipeline and tell me what's at risk." He pasted in a CRM export, hit enter, and got back a clean, confident, completely wrong answer. It called a dead deal healthy because the export didn't carry the last-activity date. It missed two stalled accounts entirely. It counted one company twice because the same logo lived in both HubSpot and the sequencer under slightly different names.
The model wasn't broken. The setup was. He'd handed an LLM a photograph of his revenue at one frozen second and asked it to reason like something that had been watching the whole movie.
This is the single most common way teams wire Claude Code into revenue operations, and it's the reason so many "AI RevOps" experiments produce a smarter-sounding version of the wrong answer. The fix isn't a better prompt. It's giving the model something it doesn't have by default: memory.
This week's release is a production CLAUDE.md that does exactly that. I call the thing it builds the Revenue Memory Layer. Here's what it is, why the obvious approach fails, and how to point it at your own stack.
The problem: a model with no continuity

Revenue workflows run on what engineers call system state. Not "what does this record say right now," but the full condition of your GTM data across every tool at a moment in time. Is this contact already in an active sequence? Has this account gone quiet for fourteen days? Did marketing touch this deal before sales claimed it as sourced?
None of that lives in a single export. It lives in the relationship between records, across systems, over time. When you drop a flat CSV into a context window, you strip all of it out. The model sees rows. It cannot see state. So it does the only thing it can: it guesses, fluently.
A model handed a raw export re-meets your pipeline cold every single session. It has no idea what changed since Monday because it was never shown Monday. That's the gap. And no amount of prompt engineering closes it, because the missing thing isn't instruction, it's data the model was never given.
The fix: separate state from judgment

The CLAUDE.md enforces one rule above everything else:
Deterministic code computes state. The model interprets state. Never ask the model to be the source of truth for a number it could instead read.
That sentence is the whole architecture. Two jobs, kept strictly apart.
Job one is maintaining state, and it belongs to code, not the model. A scheduled refresh pulls from your CRM and sequencer, normalizes every system's field names into one schema, dedupes the same account showing up in two places, and computes the stateful facts the model must never invent: days since last activity per deal, sequence status per contact, how long an account has been quiet, whether marketing or sales touched a deal first. Then it writes a clean snapshot to disk and logs what changed since the last run.
Job two is judgment, and that's where the model earns its keep. It reads the snapshot and does what models are genuinely good at: synthesis, prioritization, drafting, explaining the "why" behind a number. When it needs a fact, it reads it from the memory layer instead of recomputing it from raw rows. When it can't find a fact, it says "not in current state" rather than estimating.
The layer is the boundary between those two jobs. Code owns the truth. The model owns the interpretation. They never blur, which is exactly why the output stops hallucinating.
How the memory actually works

The refresh is the part that turns a cache into a memory. Every run, before it overwrites the current state, it saves a dated snapshot and diffs against the previous one. New deals, stage moves, deals that crossed a stall threshold since yesterday: all of it gets recorded in a plain-language changelog.
That diff is what lets you ask "which deals slipped since last week and why" and get a deterministic answer instead of an impression. The model isn't reconstructing history from memory it doesn't have. It's reading a record that code wrote down. Run it for a week and it feels like a sharper export. Run it for a month and it catches an account that went quiet twelve days ago, because the layer has been watching that account the entire time you weren't.
On top of the state, the file ships five workflows you run immediately:
/leakscores the four highest-prevalence revenue leaks, each computed from state, not vibes: slow lead response, no follow-up, unqualified volume, and stalled deals. For each one it gives you the count, the specific records by ID, and a dollar-impact estimate, then ranks them so you fix the expensive leak first. Across the public B2B SaaS audits I trust, the median annual pipeline impact of these leaks lands around $1.6M, and most companies have more than one running at once./stallflags every active deal matching a stall pattern you define, with the relevant state fact and one recommended next action./reportgenerates a weekly pipeline report with week-over-week movement pulled straight from the diff, plus an attribution reconciliation that lines up marketing-sourced versus sales-sourced pipeline against actual close dates./routeproposes lead assignments with a fit score and a one-line rationale, formatted for Slack.
Every figure in every output traces back to a file in the memory layer. If a number can be read, the model reads it. That's the rule, enforced.
Tuning it for your own signals

The part that makes this yours is three config files, and you edit those, not the prompts.
icp.yaml holds your fit criteria and the score floor below which a lead counts as unqualified volume. That one file drives both the unqualified-volume leak detection and the routing logic. stall-patterns.yaml is your definition of a stalled deal. The defaults are common patterns, things like "single-threaded past week three" or "no champion activity in ten days," but the real win is replacing them with the patterns your own lost deals actually showed. Go pull your last ten closed-lost opportunities, find what they had in common, and encode that. routing.yaml is your rep map and assignment rules.
Then you point the adapters at your systems. The CRM adapter handles HubSpot or Salesforce, the sequencer defaults to Instantly, and the one spot you'll spend real time is mapping your field names into the internal schema, because every CRM names things differently and your instance has custom fields nobody else has.
The reframe worth internalizing: you're not editing a prompt to change behavior. You're editing rules that code enforces and the model reads as intent. Change the config, and every workflow's behavior changes with it. That's the difference between a system you can trust and a prompt you have to babysit.
Running it
Setup is about an hour. Drop the file in a fresh project as CLAUDE.md alongside the memory/, config/, scripts/, and reports/ folders. Install Claude Code, set your CRM and sequencer keys, and run the first refresh by hand to seed the layer. Then schedule it. A single cron line running the refresh daily at 6am is plenty for a team that reads its pipeline once a day. Open Claude Code in the project and run /report.
One honest limitation: this is not a real-time event processor. If you need sub-minute triggers, that's a job for n8n or Make. The memory layer is for logic, analysis, and the batch operations that run on a cadence, which is most of what RevOps actually is. And if your CRM data is a mess, the refresh will faithfully snapshot the mess. Foundations first. The layer makes a clean operation sharper; it doesn't rescue a dirty one.
Why this is the part that compounds
Here's what I keep coming back to. The agent was never the hard part. Everybody has the agent now. What almost nobody builds is the layer of state underneath it, the thing that gives the model continuity between sessions and across systems.
A model pointed at a raw export is a press release: confident, fluent, and built on a single frozen frame. A model pointed at a memory layer that's been accumulating state on a schedule is leverage. It knows what changed, it cites the record, and it gets sharper every week instead of starting over every session.
Build the state first. Then point the agent at it. That order is the whole game.
One more thing, because I'd rather be useful than precious about it. If reading all of that landed as "this is a lot of wiring to own," you're not wrong, and you don't have to build it from scratch. A friend of mine, Ben Reed, runs RevyOps, which ships this deterministic state-and-sync layer as a product out of the gate: no scripts to maintain, the same idea of a reliable layer under your GTM data that an agent can safely run on top of. They've got a free way to start, so you can try the concept before you commit to building your own. The CLAUDE.md in this release and a tool like RevyOps are solving the same problem from two ends. Get the deterministic layer in place first, however you get there, then let the agent run on top of it.
The full CLAUDE.md, with all five workflows, the config templates, and the setup, is in the library. Grab it, drop it in a project, and give your pipeline a memory.
Until next week,
The GTM Architects
