GTM Operations
Skip Phase 0 and You Pay 3x in Rework
The best RevOps builds start with zero code. Here is the discovery artifact that kills the rebuild, and the scoping doc I fill before I touch a field.
· 13 min read
I shipped a lead-routing build in two weeks and felt fast. Sales lead handed me the rules on a Friday, I wrote the flow, tested it against a handful of records, and it went live the next sprint. It got rebuilt twice. The first rebuild took three weeks because “inbound lead” meant one thing to marketing and another to the SDR manager, and my routing split them the wrong way. The second took four weeks because nobody told me partner-sourced leads had their own owner logic that lived in a spreadsheet. Nine weeks of build time for something a three-week build should have covered. I paid 3x because I skipped the part with no code in it.
That part has a name. Phase 0 is the scoping pass you run before you build anything, and its only deliverable is a document. No flow, no field, no query in production. Just the discovery artifact that says exactly what you are building, for whom, against which definitions, and what “done” looks like. It feels like the phase you can cut when the ask seems obvious. It is the phase that decides whether you build once or three times.
Watch the bill compound as you scroll. Skipping the scope doc does not erase the cost; it defers it, and the deferred cost grows with every phase it hides in. The curve below is the routing build: near-zero the Friday I skipped scoping, then a step up at v1, then a steeper climb through each rebuild as the wrong definition surfaces later and later. The scoping build later in this piece is the flat line that never leaves the bottom.
The rebuild loop is a scoping bill you pay later
Skipping Phase 0 does not save the time. It moves the time to a worse place. When you build against an assumed scope, the gaps do not show up in your test org. They show up in production, in front of the people who depend on the workflow, after the old process is already torn out. Now you are debugging live, re-interviewing the stakeholders you should have talked to first, and rebuilding against a scope you are learning one angry Slack message at a time.
Here is the shape of it. The build that skips scoping does not go in a straight line. It loops.
The routing project is the loop on top. Two weeks to v1, then back to build twice. The straight line on the bottom is what four days of scoping buys: one build that survives contact with production.
The math of the rebuild
Put real weeks on it. My routing build ran the loop; a scoped version would have run the line. Same feature, same person, two very different bills.
View as table
| Item | Value |
|---|---|
| Scoping | 0 wk |
| Build v1 | 2 wk |
| Rebuild 1 | 3 wk |
| Rebuild 2 | 4 wk |
Nine weeks looped. Three point eight weeks scoped. The 3x is not a scare number I reached for; it is nine divided by three, the build I should have run. The four days of Phase 0 was the cheapest four days in the whole project, and it was the part that felt skippable on that Friday.
Why the rework is invisible until it is expensive
Bad scope hides inside good-looking data. A routing rule that fires on the wrong definition still fires. A flow that assigns the wrong owner still assigns. The build looks like it works because it does work, against the wrong specification. The cost surfaces later as records in the wrong hands, SLAs missed on leads that routed to a rep who does not cover them, and a slow erosion of trust in the system.
That erosion compounds with the data underneath. B2B contact data decays at roughly 30% per year (ZoomInfo), so a routing model scoped against today’s owners and territories is already drifting the day it ships. Gartner pegs the average cost of poor data quality near $15M per year per company. A build scoped against assumptions instead of a profiled current state does not only risk a rebuild; it pours effort into a model that was wrong about the data on day one. Phase 0 is where you catch both, before the flow is live and the old process is gone.
The Phase 0 scoping doc, as an actual artifact
The deliverable is a document, so here is the document. I keep it as a short YAML file in the project repo, because it forces every field to be filled and it diffs cleanly when scope changes. This is the artifact I would have written for the routing build:
project: inbound-lead-routing
owner: vinay
status: phase-0-scoping # no build until this reads "approved"
problem:
# the failure in one sentence, in the stakeholder's words
statement: >
Inbound leads sit unassigned for hours and partner-sourced
leads route to the wrong SDR, so speed-to-lead misses SLA.
evidence:
- "median time-to-first-owner: 4.2 hrs (query below)"
- "partner leads mis-routed: 31 of last 90 (spreadsheet audit)"
definitions: # the words people will argue about later
inbound_lead: "Lead where LeadSource in (Web, Content, Event)"
partner_lead: "Lead with Partner_Account__c populated"
# marketing and the SDR manager MUST agree on these two lines
in_scope_owner_pool: "Active SDRs in the routing group only"
current_state:
lead_sources_live: 11 # from profiling query, not memory
records_with_partner_owner: 214
systems_touched: [Salesforce, Marketo, partner spreadsheet]
target_state:
rule_order: [partner, geo, round-robin]
sla_minutes: 15
fallback_owner: "SDR queue, not a person"
out_of_scope: # the line that stops the rebuild
- "Outbound-sourced leads (owned at creation)"
- "Re-routing on owner deactivation (separate project)"
done_means:
- "95% of inbound leads owned within 15 min for 2 weeks"
- "0 partner leads in a non-partner SDR queue"
signoff: # freeze the scope here
marketing_ops: pending
sdr_manager: pending
partner_lead: pending
The two blocks that save the rebuild are definitions and out_of_scope. Every rebuild I have paid for traces back to a word two people defined differently, or a case I assumed was out of scope that the stakeholder assumed was in. Writing partner_lead down as Lead with Partner_Account__c populated and getting the partner lead to sign it is a fifteen-minute conversation in Phase 0 that replaces a four-week rebuild in Phase 3.
Profile the current state before you believe it
Half of Phase 0 is interviews. The other half is refusing to take the interviews at face value. People describe the workflow they think they run, not the one the data shows. So before you write the target state, you profile the current state with queries. For the routing build, the profiling that would have caught the partner-lead gap is one SOQL query:
SELECT LeadSource, COUNT(Id) leads,
COUNT(Partner_Account__c) partner_tagged
FROM Lead
WHERE IsConverted = false
AND CreatedDate = LAST_N_DAYS:90
GROUP BY LeadSource
ORDER BY COUNT(Id) DESC
Run that and the eleven live lead sources show up next to the count of partner-tagged records, and the “leads have one owner path” assumption dies on the spot. The number goes straight into the current_state block of the scope doc. Now the doc carries measured facts, not remembered ones, and the build is scoped against reality.
The Phase 0 discovery run
This is the sequence I run now on every build before I open a flow or write a field. It ends with a signed scope doc and nothing in production. Four days, in this order.
- 1
Interview the humans who touch the workflow, one at a time
Talk to every role that creates, owns, or hands off the record, separately. Marketing, the SDR manager, and the partner lead do not describe the same process, and interviewing them together buries the disagreement. Write down where their stories differ; that gap is your scope risk.
- 2
Profile the current state with queries, not memory
Run the SOQL that counts what exists: lead sources, records already carrying a partner owner, systems in the path. People describe the workflow they intend, not the one the data shows. Put the measured numbers in the current_state block.
- 3
Write the definitions everyone will argue about later
Pin down the two or three terms that mean different things to different teams. Inbound lead. Partner lead. The owner pool. Write each as a literal rule (a field, a picklist value) and get the humans who disagree to agree on the line before you encode it.
- 4
Draw the target-state wiring and mark what is out of scope
Rule order, SLA, fallback owner, and the explicit out-of-scope list. The out-of-scope block stops the rebuild, because it converts "I assumed that was included" into a line someone signed off on refusing.
- 5
Get sign-off, then freeze the scope
Three names on the doc: the roles that own the definitions. Once signed, the scope is frozen for the build. New requirements are welcome; they are a new version of the doc, not a silent expansion of the current build.
Nothing in that sequence is a flow or a field. That is the point. Phase 0 produces a document and a shared understanding, and the build that follows it goes in a straight line.
Ship-first versus scope-first, side by side
The instinct to skip scoping comes from wanting to look fast. Scope-first looks slower for the first week and is finished sooner overall. Here is the honest comparison from the routing build.
| Ship-first (what I did) | Scope-first (what I do now) | |
|---|---|---|
| Week 1 | Flow half built, feels fast | Interviews and profiling, nothing in prod |
| Definitions | Assumed, encoded differently per system | Written, signed by the roles that disagree |
| Out-of-scope cases | Discovered in production, angrily | Listed and signed off before building |
| Total build time | 9 weeks across two rebuilds | 3.8 weeks, one build |
| Trust in the system after | Eroded, reps route around it | Intact, the workflow stays shipped |
When to run the full four days, and when not
Phase 0 scales to the build. A single-field default or a report tweak does not need a signed YAML doc; the scope fits in the ticket. The full discovery run earns its cost when the build changes ownership, crosses systems, or encodes a definition two teams hold differently. Those are the builds that get rebuilt, and they are the ones worth scoping. The routing build hit all three triggers and I ran none of the discovery, which is why it looped.
| Build type | Phase 0 depth | Why |
|---|---|---|
| Single field, report filter, default value | Scope in the ticket | One owner, one definition, no handoff |
| New automation on an existing object | Half-day: definitions + profiling query | Definition drift is the main risk |
| Anything that changes owner, stage, or responsibility | Full four-day run + signed doc | Revenue leaks anywhere a record changes hands |
| Cross-system build (Salesforce plus Marketo, CPQ, spreadsheets) | Full run, extended interviews | Each system encodes its own definition |
The second table is the stake in benchmark terms, so the cost of skipping is not only my one project:
| What Phase 0 protects | Benchmark | Source |
|---|---|---|
| Data the build depends on | Contact data decays ~30% per year | ZoomInfo |
| Cost of building on bad data | ~$15M/yr average per company | Gartner |
| Where the leaks hide | Any point a record, owner, or stage changes | first-person, from the routing rebuild |
The scope doc is the cheapest artifact you will ship
I stopped measuring a project by how fast the first version shipped. I measure it by whether it shipped once. The routing build taught me that “fast” and “finished” are not the same thing, and the gap between them is exactly the size of the scope I skipped. Governing which builds even earn a slot is its own discipline; if you are drowning in half-finished automations, tool sprawl and the governance that ends it is the companion problem, and the data governance guide covers the definitions layer the scope doc depends on.
The next build on your list, the one that changes an owner or crosses a system: do not open the flow. Open a file, write the problem in the stakeholder’s words, run the one profiling query that tells you what exists, pin the two definitions people will argue about, and get three names on it. Four days. Then build once.
Keep reading
One email. Every week.
One email a week: an operating problem I solved or botched, with the model, the numbers, and what I would change. No roundups, no theory, unsubscribe whenever it stops being useful.
The newsletter opens soon.
Connect a provider in src/config.ts