Office hours: Build your self-driving GTM engine·Oct 29, 9:00am PT, onlineRegister→
Cargo
  • PrimitivesData ModelsYour companies, contacts and deals, merged from every sourceContextWhat your team knows, as files every agent readsTerritoriesWho sells where, defined onceMailboxesMailboxes in your reps' names, warmed up and kept under limitsToolsThe actions your agents, plays and reps callAgentsAI that researches, decides and writes, reading your contextPlaysWorkflows that run on a trigger or a schedule, with retriesAppsInternal apps for your reps, hosted on Cargo
    Add-onsChrome ExtensionSell faster, right in your browserButtonTrigger AI agents inside your CRMFormTurn any tool into an embeddable formSlackTag Cargo in Slack. It does the GTM workGitHubPlan on every pull request, deploy on merge
    MoreProjectsDefine your entire GTM in codeCLIUse Cargo from your terminalMCPUse Cargo from Claude and ChatGPTDeveloper resourcesCargo API docs, OpenAPI spec, auth docs, webhooks, MCP serverAPI ReferenceExplore the Cargo APIDocumentationLearn how to use CargoIntegrationsConnected to your entire GTM stack
  • VeriffHow Veriff replaced MuleSoft with Cargo under NetSuite, Stripe and SalesforceAugmentHow Augment Code routes developer sign-ups to reps in under an hourWeights & BiasesHow Weights & Biases ships a new purchase signal in 2 days on CargoSee all
  • Pricing
  • Cookbooks
  • Blog
Sign in
Blog

Cross-Platform Revenue Logic: Where GTM Rules Should Live

27 Sept9min read
AurelienAurelien

Ask four people in a revenue team what makes an account qualified and you will get four answers, all of them correct, because all four are implemented. There is a lead score in the marketing platform, a qualification field in the CRM set by a workflow, a is_qualified column in a warehouse model, and a saved view the SDR team actually works from. Each was built by someone solving a real problem. Together they are a company that cannot say what it believes.

This is why revenue logic scatters across platforms, which parts genuinely belong in which tool, and what it takes to define a rule once and have every system execute the same one.

The same rule, written four times #

Scattering is not carelessness. It is the predictable result of every tool in the stack being able to hold logic, and each being the closest tool at the moment a decision was needed.

Marketing needed to stop sending to non-fits, so the rule went into the marketing platform, where it could read form fields. Sales needed routing to respect segment, so a version went into the CRM, where it could read the owner. Analytics needed consistent reporting, so a cleaner version went into dbt, where it could read everything but could not act. The SDR team found all three wrong in some edge case and built a filtered view.

Nothing here is a mistake in isolation. The compound cost arrives later:

  • Changes apply unevenly. The ICP narrows. Three of the four definitions get updated, and the one that does not is the one feeding outbound.
  • Reporting and operations disagree by construction. The dashboard counts qualified accounts with the warehouse rule. The reps work the CRM rule. The gap is real and no reconciliation will close it, because they are different rules.
  • Nobody can safely delete anything. Each implementation might be the one something depends on, so all four persist, and the fifth gets added next quarter.
  • The logic is unreadable. No document describes qualification. Answering the question means reading a dbt model, a Salesforce Flow, a HubSpot workflow and a view definition.

Why it happens, in one sentence #

Every tool in a GTM stack is a system of action that also offers a place to write rules, and a rule written next to the action is always the cheapest thing to write and the most expensive thing to own.

That is not an argument against those features. It is an argument for deciding, deliberately, which rules are allowed to live there.

One definition, many executors #

The usable shape is not “centralise everything”. It is a split between the decision and the act on it.

A decision is a judgement about a record. Is this account a fit. What tier. Which motion. Which rep. Is this account at risk. Decisions should have exactly one definition, live outside every system of action, and be expressed in a form that can be reviewed before it takes effect.

An act is what a system does about the decision. Update the field, enrol in the sequence, post to the channel, create the task, push the audience. Acts belong in the tools built for them, and duplicating them is fine because they do not disagree with each other, they just happen.

Applied to qualification: one definition of qualified, computed once, written to the CRM as a field, pushed to the marketing platform as a list membership, used as a segment for the sequencer, and materialised in the warehouse for reporting. Four systems, four acts, one rule. The four can now never disagree, because three of them are reading a result rather than recomputing it.

The test for whether you have this is a question, not an audit: change the rule in one place and see how many systems are wrong the next morning.

What stays in each tool #

Centralising decisions does not empty the rest of the stack. A reasonable division:

LayerKeepsGives up
CRMOwnership, stages, the record of what happened, validation on user inputComputed qualification, scoring, routing that needs outside data
Marketing platformSend mechanics, consent, unsubscribe, deliverabilityThe definition of who is a fit
WarehouseHistorical models, aggregation, analysisBeing the only place an operational rule is written
Sequencer and channelsDelivery, throttling, reply handlingAudience definitions
The decision layerFit, tier, motion, routing, risk, and the trace behind eachExecuting anything itself

The CRM row is the one that causes arguments, so it is worth being precise: this is not “take logic out of Salesforce”. Stage transitions, validation rules and ownership belong there, because they are about the record’s own lifecycle and the people editing it. What leaves is the logic that needs facts the CRM does not hold. Alternatives to CRM-native lead routing works through that boundary for assignment specifically.

Defining the rule once #

Concretely, one definition means the rule is a file: type-checked, diffed before it deploys, reviewed by a person, and versioned so the question “what did this say in March” has an answer.

typescript
import { definePlay, defineSegment, type SegmentSpec } from "@cargo-ai/cdk";

// The one definition of "qualified", in one file.
const qualified: SegmentSpec["filter"] = {
  conjonction: "and",
  groups: [
    {
      conjonction: "and",
      conditions: [
        {
          kind: "number",
          columnSlug: "employee_count",
          operator: "greaterThan",
          value: 50,
        },
        {
          kind: "string",
          columnSlug: "industry",
          operator: "is",
          values: ["software", "fintech"],
        },
        { kind: "string", columnSlug: "icp_exclusion", operator: "isNull" },
      ],
    },
  ],
};

export const qualifiedAccounts = defineSegment("qualified-accounts", {
  model: accounts,
  filter: qualified,
});

export const activateQualified = definePlay("activate-qualified", {
  model: accounts,
  filter: qualified,
  changeKinds: ["added", "updated"],
  workflow: activationWorkflow,
  isEnabled: true,
});

The segment is the definition. The play is one executor of it, firing when a record enters or changes, and its workflow does the writing: the CRM field, the Slack post, the sequence enrolment. Adding a fifth destination adds a step to the workflow. It does not add a fifth definition.

Two properties are what make this different from moving the mess to a new tool. The rule is readable by a person who did not write it, because it is one expression rather than a graph of UI nodes. And a change to it is a diff, reviewed before it takes effect, which is the property no admin console offers. That argument in full is GTM as code; the wider layer it sits in is revenue orchestration.

Getting there without a rewrite #

Nobody can pause go-to-market to reorganise it. The migration that works is narrow and boring.

Pick one decision, not a layer. Qualification, or tiering, or routing. One. The rule that causes the most arguments is the right one, because it is the one where a single answer is visibly worth something.

Write down the versions that exist today, including the informal ones. Usually four to six. Most teams have never seen them side by side, and the list is itself the argument for doing the work.

Agree on one, in the open. This step is political, not technical, and it is where the project actually succeeds or stalls. If the four definitions cannot be collapsed into one, that disagreement was always there and was being settled by whichever tool ran last.

Compute it in one place and write it out. Keep the old implementations running in parallel for a cycle and compare. The differences are the edge cases the original authors knew about and nobody wrote down.

Delete the old ones. This is the step that gets skipped, and skipping it means you added a fifth definition. A migration that does not end in deletions did not happen.

Frequently asked questions #

Split it. Decisions about a record (fit, tier, motion, owner, risk) should have exactly one definition, held outside the systems that act on them. Acts (update a field, enrol a sequence, post a message, push an audience) belong in the tools built for them, and duplicating those is harmless because acts cannot contradict each other. The rule of thumb is that anything you could argue about belongs in one place.

Because every tool in the stack offers somewhere to write rules, and the rule written next to the action is always the cheapest to create. Marketing writes it where it can read form fields, sales where it can read the owner, analytics where it can read everything. Each is locally correct. The cost only appears when the definition changes and three of the four get updated.

Only the computed part. Stage transitions, ownership, validation on what a user types and the record of what happened belong in the CRM, because they are about the record’s own lifecycle. What leaves is logic that depends on facts the CRM does not hold, such as product usage, a warehouse score, enrichment results or a rep’s current capacity.

Compute once, distribute the result. One definition produces a value; every other system receives it rather than recomputing it. The check is to change the rule in one place and count how many systems are wrong the next day. If the answer is more than zero, you have copies rather than distribution.

The one that causes the most arguments, usually qualification or tiering. Start by listing every version of it that exists today, including saved views and informal filters. Most teams find four to six and have never seen them side by side, and that list does more to justify the work than any architecture diagram.

~/run-it-on-cargo/

Build this workflow instead of reading about it.

Cargo is the GTM infrastructure your coding agent builds on: enrichment, scoring, routing and outreach, defined in code and run in production.

Start building
AurelienAurelienSept 27, 2026
On this page
  • The same rule, written four times
  • Why it happens, in one sentence
  • One definition, many executors
  • What stays in each tool
  • Defining the rule once
  • Getting there without a rewrite
  • Frequently asked questions

Stay Informed with our
weekly Newsletter

Related articlesSee all articles
GTM Engineering
CI/CD for Go-to-Market: What It Means and How to Set It Up

CI/CD for GTM means every change to enrichment, scoring, routing and sequences ships as a pull request that is planned, checked, approved, deployed on merge, logged and reversible. What each software CI/CD step becomes for go-to-market, and how to set it up on Cargo.

AurelienAurelien·Nov 3, 2026
GTM Engineering
Require Approval Before a High-Impact Go-to-Market Change Goes Live

How Cargo holds a go-to-market pull request that would send or spend more than set limits until a reviewer adds the cargo:approve-impact label: the thresholds, what counts as high impact, who should approve, and what the gate does not catch.

AurelienAurelien·Nov 3, 2026
GTM Engineering
Test a Go-to-Market Change Before It Reaches Production

How to test a change to enrichment, scoring, routing or outreach before it runs on every lead: check the project offline, dry run an action, read the plan on the pull request, ship the play switched off and pilot it on 50 records, evaluate agents, and use a second workspace as staging.

AurelienAurelien·Nov 3, 2026

Build the self-driving GTM engine

Your coding agents build it on Cargo.Or our team builds, operates and improves it with you.

Start building
Cargo
Backed byY CombinatorSOC 2 Type IICertified
LinkedinX

Product

Data ModelsContextTerritoriesMailboxesToolsAI AgentsPlaysAppsIntegrationsPricing

Add-ons

Chrome extensionButtonFormSlackGitHub

Build

DocsDeveloper resourcesCargo API docsCargo OpenAPI specCargo auth docsCargo webhooksCargo MCP serverProjectsClaude CodeCodexCursorAll coding agents

Resources

ReportsBlogCustomer storiesCookbooksEnrichmentRoutingSignalsScoringCRM hygieneAd audiencesGTM skillsGTM EngineeringGlossaryCompareCargo x ClayCargo x WorkatoCargo x n8nCargo x DeeplineCargo x DefaultCargo x LeanDataCargo x UnifyCargo x ValleyCargo x Gojiberry

Company

ManifestoCommunityEventsJobsPartners DirectoryPartner Program

Legal

SecurityTerms of servicePrivacy PolicyRefundsDPASupport
© 2026 Cargo
 ////////    ///////    ////////     ////////    ///////
///         ///   ///   ///   ///   ///         ///   ///
///         ///   ///   ///   ///   ///         ///   ///
///         /////////   ////////    ///  ////   ///   ///
///         ///   ///   /// ///     ///   ///   ///   ///
///         ///   ///   ///  ///    ///   ///   ///   ///
 ////////   ///   ///   ///   ///    ///////     ///////

$ npm install -g @cargo-ai/cli