The conversation has shifted.
For two years, every RevOps team's question was "what tool should we add?" New sequencer. New enrichment vendor. New scoring model. New AI SDR. The stack grew. The team didn't.
In May 2026, the question changed. It's now: "what do we rip out so this thing becomes transferable again?"
Amos Bar-Joseph put it most publicly. Swan killed 27 of their AI agents in a single quarter. Pipeline doubled. Velocity picked up. The agents weren't the problem. The architecture was. They were spending more time on GTM engineering than actual GTM work. Every new workflow meant more building, maintaining, debugging.
That is the universal RevOps disease, and the cure is not "fewer tools." It is contracts.
This post walks through exactly what this means. A complete drop-in repo we use to run RevOps engines across multi-million-dollar ARR pipelines without "re-Frankensteining" your tool stack. Three contracts, five folders, and a structure that makes adding a fourth parallel system harder than retiring the first three.
What a "contract" actually is
Let's get the vocabulary right, because this is the move most teams miss.
A tool is a thing you bought. HubSpot. Apollo. Clay. n8n. Smartlead. It does work for you. It gets ripped out the moment a cheaper, faster, or better one shows up. Tools are mortal.
A contract is a fixed shape that every tool, agent, and workflow in your stack must agree to. The shape never changes. The tools behind it can.
Three examples, concrete:
"Every campaign starts from a brief YAML with a locked status." Doesn't matter if your sequencer is Instantly, Smartlead, Apollo, or something that hasn't shipped yet. They all read the same brief. You swap sequencers without touching strategy. You swap strategists without touching sequencers.
"Every agent step writes a numbered CSV." Doesn't matter if step 02 is enrichment by Apollo, by Clay, or by a Claude skill you wrote on a Tuesday. The output is always
02-enriched.csv. Step 03 reads it. Step 03 doesn't know or care who wrote step 02."Every external action goes through one dispatcher with
stdin JSON + <service> <action>." Doesn't matter if your Slack today is Slack tomorrow. The dispatcher swaps the handler. Every agent above it stays the same.
The shape never changes. The tools behind it can.
This is why contracts beat tools. Tools come and go. Contracts compound. Every campaign you run against the same brief schema makes the schema more valuable, not less. Every CSV you generate using the same numbered convention is one more piece of an audit trail that does not rot. Every external action routed through one dispatcher is one less authentication flow you have to remember.
Tools are the surface. Contracts are the substrate.
Why this matters, and why now
RevOps teams die from accretion.
You start with one tool. Six months later it's six tools, four agents, three trigger.dev workflows, and a folder called scripts/ that nobody opens. The original architect leaves. The new hire spends three weeks trying to figure out which sequencer is "the real one." A vendor gets acquired and the integration breaks. You build a workaround. The workaround becomes the third parallel system. Eventually you can't ship a campaign in under a week.
The 2026 conversation has finally surfaced this honestly. The most-shared GTM posts of the last month are all about killing things, not adding them. "We killed 27 of our AI agents." "The integration tax is dead." "Stop building workflows; build context."
Everyone has noticed the problem. Almost nobody has shipped the answer.
The answer is not fewer tools. The answer is contracts that survive every vendor swap, every team change, every "we just bought X, can you wire it in." Tools change. Vendors get bought. Workflows mutate. Contracts survive.
This week's release is the answer in repo form.
What's in the repo
The repo is a complete drop-in directory you can clone into the root of your RevOps workspace. It's not theory. It's a working scaffold.
Top-level structure:
.
├── os/ shared frameworks (ICP, TOV, brief schema)
├── engine/ shared code (conductor, dispatcher, handlers)
├── tenants/ per-revenue-motion folders (transferable units)
├── docs/ plans and references
├── _archive/ read-once graveyard (agents ignore)
└── .claude/ conductor + sub-agents + slash commands
Five folders. That's the cap. Anything outside this set requires a written argument committed to docs/plans/. This is Rule 1 of the five-rule discipline document inside the repo.
Inside that shape, three contracts.
Contract 1: Single Front Door
There is exactly ONE operator-facing agent in the repo. We call it revops-conductor. The human operator talks to the conductor. The conductor talks to everything else.
Without this, you end up with six slash commands, four specialized agents, and three ad-hoc scripts the operator picks between. Cognitive load explodes; consistency dies. With a single front door, the operator-facing reasoning lives in ONE place and stays high-quality. The conductor decides whether to run the engine binary, invoke a sub-agent for copy, or dispatch a fire-and-forget action.
The shape:
operator → revops-conductor → (engine binary | sub-agents | dispatcher)
Contract 2: Numbered-CSV Agent Chain
Every agent step in your pipeline writes a numbered CSV. 01-sourced.csv, 02-enriched.csv, 03-scored.csv, 04-personalized.csv. The number prefix forces ordering. The CSV format forces explicit columns. Step N+1 reads step N. Nothing else.
Without this, agents become opaque function calls. They take inputs from "somewhere" and write outputs to "somewhere." You cannot inspect what step 02 did wrong without re-running the whole chain. With numbered CSVs, every step is a tamper-evident artifact on disk. You can grep, diff, replay, and resume from any step.
What lives inside a run folder:
tenants/<name>/runs/<run-id>/
01-sourced.csv ← list builder writes
02-enriched.csv ← enrichment agent writes
03-scored.csv ← scoring agent writes
04-personalized.csv ← copy agent writes
meta.json ← run metadata + timing
When something goes wrong in production, you don't trace logs. You open the CSVs and see exactly which row went sideways at which step.
Contract 3: One-Contract Dispatcher
Every external action (push to Slack, write to CRM, send an email, trigger an n8n workflow) goes through one Python dispatcher. Single contract: stdin JSON + CLI <service> <action>. The dispatcher merges them, picks the handler, and calls the API.
Without this, every agent that needs to write to Slack does its own auth, error handling, retries, and dry-run logic. Six agents = six implementations of the same call. With one dispatcher, you write DRY_RUN=1 once and every handler honors it. You add observability in one place. You swap a vendor by editing one file.
Usage:
echo '{"channel":"#revops","text":"campaign launched"}' \\
| python engine/dispatch.py slack send
Adding a new service is adding one file: engine/handlers/<service>.py with a handle(action, payload, dry_run=False) function. The dispatcher picks it up automatically.
What the skill targets, and how it adapts
The repo is opinionated about shape, not tools.
Input: any RevOps workspace. The reader can be running Instantly + Apollo + HubSpot + n8n, or Smartlead + Clay + Salesforce + Zapier, or any other combination. The skill doesn't care.
Output: the same canonical five-folder structure on disk, the same conductor agent, the same brief schema, the same dispatcher contract. Your tools sit underneath the contracts as handlers and sub-agents you wire in.
How a reader tunes this for their own market:
Different sequencer? Edit
engine/handlers/<sequencer>.py. Conductor unchanged. Brief schema unchanged. Pipeline unchanged.Different CRM? Same. Replace one handler. Everything above the handler stays.
Different scoring criteria? Edit the
icpblock intenants/<name>/briefs/<brief>.yaml. The scorer reads from the brief, not from hard-coded rules. No code change.Different agent boundaries? Add a
verifier.mdagent between scorer and copy-writer. Have it write03b-verified.csv. The numbered-CSV chain extends without breaking the contract.
The contracts hold. Everything below the contracts is yours to bend.
This is the difference between an opinionated framework and a configurable framework. Most frameworks force you into their tool choices. The 3-Contract Stack forces you into one shape, and lets you pick every tool inside it.
The brief schema, in plain English
The single most-valuable file in the repo is tenants/_templates/briefs/_blank.yaml. It's the YAML that turns "we're running a campaign" from a Slack thread into a tamper-evident strategic snapshot.
The brief has a lifecycle: draft → exploring → locked → archived. You write in draft, iterate in exploring, and on commit, write lock.locked_at plus a SHA-256 content_hash over every field above the lock block. After that, the brief is append-only. You don't edit a locked brief. A correction becomes a NEW brief that inherits_from the old one.
This sounds bureaucratic until the first time a teammate asks "why did we run the campaign that way in May." The locked brief is the answer. It cannot be retroactively edited. The hypothesis, the ICP, the angle, the proof points, the sequence config, all preserved as the strategic snapshot of what you believed at that moment. Future-you doesn't trust past-you's memory. Future-you trusts the hash.
A brief covers: identity and lifecycle, the hypothesis (WHO + ANGLE + REASON + METRIC + TIMEFRAME), success criteria with explicit reply-rate and meetings targets, ICP firmographics and personas, anti-ICP rules, source policy (signal trigger or seed CSV), angle style and proof points, sequence config, and dispatch settings. The default sequencer is Instantly. The lock contract is enforced by the conductor agent, not by hope.
Why ship this as a repo, not a PDF
The reason we ship this as a repo and not a 40-page PDF is the same reason the answer is contracts and not tools.
A PDF tells you what to do. A repo is the thing you do. When you clone the 3-Contract Stack into your workspace and run /strategy-loop, you're not reading about a brief schema. You're filling one out. You're not reading about the dispatcher. You're calling it. The artifact is the proof.
This is also why the repo is gated behind a comment rather than a free download. The 30 seconds it takes to drop the comment is a filter. The people who do it are RevOps practitioners and operators who can see what's in front of them. The people who don't are the ones who would have downloaded a PDF, put it in a Drive folder, and forgotten.
How to run it
Three commands. Five minutes from clone to first brief:
# 1. Clone the repo into your RevOps workspace
git clone <repo-url> .
# 2. Spin up your first tenant
cp -r tenants/_templates tenants/my-first-revenue-motion
# 3. Edit tenants/my-first-revenue-motion/CLAUDE.md with your ICP overrides
# Then open Claude Code in your workspace and run:
/strategy-loop 2026-q3-pilot
The conductor takes it from there. It walks you through the hypothesis, the ICP, the angle, the proof points. When you're ready to lock, it confirms. After lock, it runs /pipeline against the locked brief (list-builder, enricher, scorer, copy-writer), each writing its numbered CSV. You review the 5-row sample. You approve. The dispatcher pushes to your sequencer of choice.
You now have a transferable RevOps engine. Everything is on disk. Every step is inspectable. The brief is locked. The CSVs are auditable. The handlers are swappable.
The full repo (conductor + sub-agents + dispatcher + brief schema + REPO-RULES + tenant template) is gated below.
What you get this week
The 3-Contract RevOps Stack. The complete repo, including:
revops-conductoragent file (the single front door)Four sub-agent files (list-builder, enricher, scorer, copy-writer), each writing its numbered CSV
dispatch.pyPython dispatcher plus three working handlers (Slack, Notion, generic HTTP)_blank.yamlbrief schema with full lifecycle and lock contractThree slash commands (
/strategy-loop,/pipeline,/dispatch)REPO-RULES.mdcodifying the five rules that prevent accretiontenants/_templates/(the transfer-ready per-revenue-motion folder)
Drop it into your RevOps workspace and you have a transferable engine on day one.
To get the repo, comment STACK on this week's LinkedIn post, or hit the subscribe button below if you want it in your inbox plus the rest of the GTM Architects library (playbooks, signal stacks, and new releases every Wednesday).
If you've been carrying the weight of a Frankenstein RevOps stack, this is the canonical shape that ends it.
Until next week,
The GTM Architects
