{"id":"1676fb7c-1ffa-45f6-9dfe-6a129d33fca4","slug":"revops-3-contracts","kind":"skill","name":"revops-3-contracts","summary":"Drop-in RevOps engine for Claude Code teams: three discipline-imposing contracts (single front door, numbered-CSV agent chain, one-contract dispatcher) that make a RevOps stack transferable.","owner":"tga-cheetung","repoUrl":"https://github.com/tga-cheetung/revops-3-contracts","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-05-14T23:08:10.000Z","addedAt":"2026-10-21T10:11:56.685Z","logoUrl":"https://avatars.githubusercontent.com/u/250624307?u=6b1d6cc7464936a232cf374d3272adad8da368f4&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","files-documents","communication"],"tags":["ai-agents","claude-code","gtm-engineering","outbound","revops"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T04:03:08.636Z","sample":false,"url":"https://conduits.dev/tools/revops-3-contracts","language":"Python","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# The 3-Contract RevOps Stack\n\nA complete, drop-in RevOps engine for Claude Code teams running multi-million-dollar ARR pipelines.\n\nBuilt on three discipline-imposing contracts that make it impossible to add a fourth parallel system. Tools change. Vendors get bought. Workflows mutate. **Contracts survive** — because a contract is a fixed shape that every tool, agent, and workflow must agree to, not a tool that gets ripped and replaced.\n\nIf you've ever inherited a RevOps stack and thought \"I cannot transfer this — there's no canonical shape,\" this repo is the canonical shape.\n\n---\n\n## What a contract is (and why it beats tools)\n\nA **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.\n\nA **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.\n\nThree examples to make this concrete:\n\n1. **The contract \"every campaign starts from a brief YAML with a locked status.\"** Doesn't matter if your sequencer is Instantly, Smartlead, Apollo, or something that doesn't exist yet — they all read the same brief. Swap sequencers without touching strategy. Swap strategists without touching sequencers.\n2. **The contract \"every agent step writes a numbered CSV.\"** Doesn't matter if step 02 is enrichment by Apollo, Clay, or a custom script — the output is `02-enriched.csv`. Step 03 reads it. Step 03 doesn't know or care who wrote step 02.\n3. **The contract \"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.\n\n**Why this matters:** RevOps teams die from accretion. Every tool added is a new shape, a new auth flow, a new error path, a new thing to break the day someone leaves. Contracts are the only thing that survive the next vendor swap, the next team change, the next \"we just bought X, can you wire it in.\" Tools come and go. Contracts compound.\n\nThis repo gives you three contracts. Everything else is replaceable.\n\n---\n\n## Repo structure\n\n```\n.\n├── os/                      ← shared frameworks (ICP, TOV, brief schema)\n├── engine/                  ← shared code (dispatcher, handlers)\n│   ├── dispatch.py\n│   └── handlers/\n│       ├── slack.py\n│       ├── notion.py\n│       └── http.py\n├── tenants/                 ← per-revenue-motion (one folder per ICP / product / segment)\n│   └── _templates/\n│       ├── CLAUDE.md\n│       ├── briefs/\n│       │   └── _blank.yaml\n│       └── RUNBOOK.md\n├── .claude/\n│   ├── agents/\n│   │   ├── revops-conductor.md\n│   │   ├── list-builder.md\n│   │   ├── enricher.md\n│   │   ├── scorer.md\n│   │   └── copy-writer.md\n│   └── commands/\n│       ├── strategy-loop.md\n│       ├── pipeline.md\n│       └── dispatch.md\n└── docs/\n    └── REPO-RULES.md\n```\n\nFive folders. That's the cap. Anything outside this set requires a written argument committed to `docs/plans/`.\n\n---\n\n## The three contracts\n\n### Contract 1 — Single Front Door\n\nThere is exactly ONE operator-facing agent. Call it `revops-conductor`. The human operator talks to the conductor. The conductor talks to everything else.\n\n```\noperator → revops-conductor → (engine binary | sub-agents | dispatcher)\n```\n\nSee [`.claude/agents/revops-conductor.md`](.claude/agents/revops-conductor.md).\n\n### Contract 2 — Numbered-CSV Agent Chain\n\nEvery agent step writes a numbered CSV. `01-sourced.csv`, `02-enriched.csv`, `03-scored.csv`, `04-personalized.csv`. The number prefix forces ordering. Step N+1 reads step N — nothing else.\n\n```\ntenants/<name>/runs/<run-id>/\n  01-sourced.csv      ← list builder writes\n  02-enriched.csv     ← enrichment agent writes\n  03-scored.csv       ← scoring agent writes\n  04-personalized.csv ← copy agent writes\n  meta.json           ← run metadata\n```\n\nSee the four sub-agent files under [`.claude/agents/`](.claude/agents/).\n\n### Contract 3 — One-Contract Dispatcher\n\nEvery external action goes through one Python dispatcher with a single contract: `stdin JSON + CLI <service> <action>`.\n\n```bash\necho '{\"channel\":\"#revops\",\"text\":\"campaign launched\"}' \\\n  | python engine/dispatch.py slack send\n```\n\nSee [`engine/dispatch.py`](engine/dispatch.py) and the example handlers under [`engine/handlers/`](engine/handlers/).\n\n---\n\n## Install (5 minutes)\n\n```bash\n# 1. Clone this repo at the root of your RevOps workspace\ngit clone https://github.com/tga-cheetung/revops-3-contracts.git .\n\n# 2. Spin up your first tenant\ncp -r tenants/_templates tenants/my-first-revenue-motion\n\n# 3. Edit tenants/my-first-revenue-motion/CLAUDE.md with your ICP overrides\n#    Then open Claude Code in your workspace and run:\n/strategy-loop 2026-q3-pilot\n```\n\nThe conductor takes it from there.\n\n---\n\n## Configuration\n\nSet in `tenants/<name>/.env`:\n\n| Variable | Used by | Purpose |\n|---|---|---|\n| `INSTANTLY_API_KEY` (or your sequencer of choice) | sequencer handler | Sending |\n| `APOLLO_API_KEY` (or your sourcing tool of choice) | list-builder | Sourcing |\n| `SLACK_WEBHOOK_URL` | `engine/handlers/slack.py` | Notifications |\n| `NOTION_API_KEY` | `engine/handlers/notion.py` | Archive strategic decisions |\n| `DRY_RUN` (1 or unset) | every handler | Safety |\n\n---\n\n## Tuning the repo for your stack\n\nThe repo is opinionated about **shape**, not **tools**. Edit these to fit your environment:\n\n- **Want a different sequencer?** Replace the sequencer handler. Conductor doesn't change.\n- **Want a different CRM?** Replace the relevant handler. Conductor doesn't change.\n- **Want different scoring criteria?** Edit `tenants/<name>/briefs/<brief>.yaml` `icp` block. Scorer reads it. Scorer doesn't change.\n- **Want different agent boundaries?** Add a `verifier.md` agent between scorer and copy-writer; have it write `03b-verified.csv`. The chain extends without breaking the contract.\n\nThe contracts hold. Everything below the contracts is yours to bend.\n\n---\n\n## Deploy when\n\n- You're inheriting (or rebuilding) a RevOps stack and want a canonical shape before adding tools\n- You're scaling from one revenue motion to multiple and need each motion to look the same\n- You're handing a RevOps engine off to a colleague, an acquirer, or a buyer and need it to be transferable\n- You've felt the \"we have 12 agents and 6 trigger.dev workflows and nobody can find anything\" pain\n- You're using Claude Code (or any operator-agent pattern) and want to stop the proliferation of parallel skill files\n\n## What this is NOT\n\n- Not a sequencer (use Instantly / Smartlead / Apollo / etc. as your handler)\n- Not a CRM (use HubSpot / Salesforce / Attio / etc. as your handler)\n- Not a workflow engine (use n8n / trigger.dev / Vercel cron / launchd as your scheduler)\n- Not opinionated about *which* tools you use — opinionated about the *shape* every tool plugs into\n\nThis is the **discipline layer** that sits on top of whatever stack you already have.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n---\n\n*Created by [The GTM Architects](https://www.thegtmarchitects.com), 2026. Built for B2B software and services teams running multi-million-dollar ARR pipelines who want their RevOps engine to be transferable, inspectable, and free of accretion.*\n"}