Your GTM belongs in gitRegister
Cookbooks
CRM

Expansion signals

Every week the customers coming up on renewal are judged for an expansion moment (purchase cadence and last price from won deals, and dated outside events such as funding, hiring or a new leader); the signal and reason are written onto the account and posted as one digest for the customer team.

Installation
Set up the expansion-signals cookbook in this project. 1. If the Cargo CLI is not installed yet, follow every step in https://api.getcargo.io/INSTALL.md 2. From the Cargo project, run: cargo-ai cdk add cookbook/expansion-signals 3. Then follow .claude/skills/expansion-signals/SKILL.md. Stop for my approval before any paid call, and stop at "cargo-ai project plan" before deploying anything.
Paste it into Claude Code, Cursor, Codex, Gemini CLI, Devin or Replicas.

Say this to your agent

Every Monday, flag which customers near renewal are ready to expand and post the digest to #cs-weekly.

Illustrative output #

Fictional records, to show the shape of what comes back.

text
:seedling: *Expansion signals, week of 2026-10-05*
_6 accounts in their renewal window: 1 at risk, 2 ready to expand._

*Tailspin Logistics* (tailspin.example) · at_risk · New CDO joined Sep 22 from a
  competitor's customer; renewed every 12 months, last at 24,000. Play: executive
  check-in. Sources: tailspin.example/news/new-cdo · owner 4411
*Fabrikam* (fabrikam.example) · expansion · Raised a Series B on Sep 9 and posted
  four data-engineer roles; renewed every 12 months, last at 38,000. Play: annual
  prepay offer. Sources: fabrikam.example/press/series-b · owner 4402
*Northwind Traders* (northwind.example) · expansion · Hired a Head of Compliance on
  Sep 30. Play: governance add-on demo. Sources: northwind.example/team · owner 4402
*Contoso* (contoso.example) · repeat_purchase · Ordered every 6 months, last at
  9,500 on Apr 2. Play: renewal call at the last price. · owner 4419
*Litware* (litware.example) · renewal · No outside event. · owner 4411

Six won deals entered their renewal window this week, so six accounts carry a signal and a reason; a seventh account had already renewed early and was written none.

What you will be asked #

InputWhy
channelId on the digestAskedThe digest names customers and their renewal risk. Locked so it never lands in a customer shared channel.

Done when #

  • node --import tsx evals/contract.mjs passes
  • cargo-ai cdk plan reports the gtm_accounts, gtm_opportunities and expansion_digests models, the two agents, the play, two connectors and three folders, with the play disabled and no CRM connector
  • seeded accounts and won deals, with two deals inside the window, produced two analyst runs and two accounts carrying a signal, a reason and a stamp; every event named in a reason has a dated source in it
  • an account whose newer win already renewed it (closed more than two months after the trigger) was written none with that reason, and an account with a second win within two months of the trigger was judged on its whole purchase history instead
  • a second play execution the same week judged neither deal again
  • the digest posted once in the locked channel, listed exactly the accounts stamped that week with a signal other than none, and a re-run that week posted nothing
  • no deal or contact record changed

What it costs #

The model writes are native and the research is web search inside the analyst, at most three per account. Immediately before the plan, read the live price of the one connector action:

  • cargo-ai orchestration action list postMessage --kind connector --integration-slug slack

Say it out loud. The recurring cost is one analyst run per won deal entering its window each week, plus one digest run, billed as LLM tokens through the Anthropic connector. It scales with how many customers are near renewal, not with the size of the book. Count the window before enabling: a SELECT count(*) over gtm_opportunities with is_won true and close_date ten to twelve months back.

Every Monday the customers coming up on renewal are judged for an expansion moment, the judgment is written onto the account, and one digest lands in Slack for the customer team. The worked example runs on Cargo’s native accounts and deals models, so it deploys with no CRM connector; HubSpot, Salesforce and Attio are the crm-backed variation in SKILL.md.

What it does #

  • A weekly play picks up each won deal whose close date entered the ten-to-twelve-month window. A deal enters once, so each renewal is judged once.
  • An agent judges the account from its won deals in SQL (a newer win, the cadence, the last price), your expansion plays in the workspace context, and dated public events: renewal, expansion, repeat_purchase, at_risk or none, with a reason, a play and its sources.
  • The play writes expansion_signal, expansion_reason and expansion_signal_at onto the account record by id, and nothing else.
  • A digest agent posts one Slack message that afternoon, at-risk first, and records the week in a ledger so a re-run posts nothing.

What’s inside #

Adds 11 resources.

FileResourceRole
infra/models/gtm-accounts.tsdefineModel (native account)the customer book, plus the three expansion columns
infra/models/gtm-opportunities.tsdefineModel (native deal)every deal; the play’s model and the purchase history
infra/models/expansion-digests.tsdefineModel (native custom)the digest ledger: one row per week posted
infra/plays/flag-expansion.tsdefinePlay + defineWorkflowwho is judged, the judgment, the one account write
infra/agents/analyst.tsdefineAgentthe judgment, as JSON, read-only
infra/agents/digest.tsdefineAgentthe weekly Slack post, channel locked
infra/connectors/slack.tsdefineConnector (slack)the digest’s post path
infra/connectors/anthropic.tsdefineConnector (anthropic)the model both agents run on
infra/folders/index.tsdefineFolder ×3where the models, agents and play are filed
references/expansion-plays.md(not a resource)the example to copy into context/expansion-plays.md

Why native models in the example #

Fewest dependencies: the example deploys with a Slack and an Anthropic connector and nothing else. The judgment does not care where the deals come from. A team whose deals live in a CRM swaps the two models for connector-backed ones and the write for the CRM’s updateRecords on the record id; the play, the analyst and the digest stay as they are.

Why a play writes and the agent does not #

The agent hands back a judgment; the play persists it on the account by id. That keeps the write in one reviewable place, limited to three columns, and makes a missing signal mean one thing: the run failed.

Placeholders (edit before deploy) #

  1. The renewal window in infra/plays/flag-expansion.ts, if contracts are not annual.
  2. channelId in infra/agents/digest.ts.
  3. languageModel on both agents.
  4. context/expansion-plays.md in your project, from references/expansion-plays.md.

What it does not do #

It does not change a deal, a contact or an owner, contact a customer, or post anywhere but the locked channel.

Give your agents a runtime

Bring the agents you have.Start free, deploy in one command.