ooligo
claude-skill

Detect expansion signals in CSM calls and usage

Difficulty
intermediate
Setup time
45min
For
revops · csm
RevOps

Stack

A Claude Skill that scans the trailing seven days of CSM calls, usage anomalies, and support tickets across your customer portfolio and emits a per-CSM ranked digest of accounts showing concrete expansion intent. Each surfaced account names the upsell SKU, the verbatim evidence that supports it, and a single next-best action the CSM can take this week. The bundle ships at apps/web/public/artifacts/expansion-signal-detection-claude/ and contains SKILL.md plus three reference files the team edits to match its own SKU lineup, segment baselines, and CSM action playbook.

When to use

Use this skill when your CS team owns more accounts than any single human can manually scan every week, and you have at least two overlapping data sources to fuse — typically Gong-recorded CSM calls plus Gainsight (or warehouse-emitted) usage anomalies. The skill is designed for teams of three or more CSMs across a portfolio of at least 100 accounts; below that scale, a CSM lead reading every call manually outperforms any automated digest, because the human sees context the taxonomy file does not encode.

The right cadence is weekly — typically Monday morning, before the team’s account-review meeting — and the right output is a personal Slack DM per CSM, capped at three strong signals each. The cap matters: in pilots, a CSM digest of 10 or more “engaged accounts” gets read for two weeks and then ignored permanently. Three concrete asks per week, repeated every Monday, is the cadence the team actually internalizes.

When NOT to use

  • You want real-time alerting on individual events. Per-event pings flood CSMs and erode trust in the channel within two weeks. The weekly cadence is deliberate. If your CRO insists on real-time, expect the digest to be muted by Q2.
  • You don’t already have usage anomalies in a structured feed. The skill consumes pre-emitted anomaly events; it does not detect them from raw event streams. If Gainsight isn’t already firing seat_count_spike, feature_first_use, and tier_gated_feature_attempt events, fix that pipeline first — the skill on top of an empty feed produces a digest with calls only, which collapses every signal to weak.
  • CSMs aren’t logging calls. If under 60 percent of accounts have a logged call in the trailing window, the conversation half of every signal set is empty and most signals collapse to weak. Audit Gong adoption before relying on this. The skill aborts the run with a coverage error if the rate drops under 40 percent rather than emit a half-signal digest.
  • You want to auto-create Gainsight CTAs or auto-email customers. This skill is read-only signal. The output is designed to be a CSM’s pre-meeting prep, not a workflow trigger. Wiring an auto-action layer downstream is the fastest way to send a CFO a “we noticed you’d benefit from our enterprise tier” email the week after their champion just left.
  • You want an expansion-ARR forecast. The output is per-account intent signal, not a number to plug into a finance forecast. Expansion-ARR forecasting requires close-rate calibration the skill does not have.

Setup

The artifact bundle ships at apps/web/public/artifacts/expansion-signal-detection-claude/. Download it, edit the three reference files to match your reality, then install the Skill.

  1. Download and unpack the bundle. Drop expansion-signal-detection-claude/ into ~/.claude/skills/. The layout is SKILL.md plus references/1-expansion-signal-taxonomy.md, references/2-segment-baseline-config.md, and references/3-action-library.md.
  2. Build the signal taxonomy. Edit references/1-expansion-signal-taxonomy.md with your actual upsell SKUs and the call-trigger phrases, usage-event types, and support-ticket tags that map to each. Be specific: not “more users,” but “asked about pricing for 50 or more seats” or “mentioned compliance requirements.” The negative-example section catches conditional phrases (“if you supported X”) that read as intent but are in fact feature-gap reports — keep it tuned, because a stale negative-example list is the most common cause of false-positive flooding.
  3. Calibrate the segment baselines. Edit references/2-segment-baseline-config.md with values computed from a 90-day rolling window over your usage warehouse. Per segment, list the median weekly delta and the two-sigma noise band for each metric. The skill rejects events whose delta_pct falls inside the noise band even when they crossed the global emitter threshold — this is what stops SMB seat-count noise from drowning out genuine enterprise expansion.
  4. Populate the action library. Edit references/3-action-library.md with one or more next-best actions per SKU. Every entry must follow the shape verb plus named artifact (a meeting, a person, a doc, a ticket) — the skill enforces this with a literal substring filter on the emitted Action field, replacing anything vague with needs human review.
  5. Wire the data sources. Set GONG_API_KEY for transcript pull, GAINSIGHT_TOKEN for the usage-event and account feed, and your support-ticket API token (Zendesk, Intercom, or Helpscout, per your stack). The skill reads pre-computed anomalies from the usage feed; it does not run anomaly detection itself.
  6. Run weekly. Invoke expansion_signal_detection(window_days=7) from a scheduled Claude Code session (cron or GitHub Actions workflow_dispatch on a weekly trigger). Output is one Markdown file per CSM owner, posted as a Slack DM rather than a public channel post — the goal is per-CSM accountability, not a public leaderboard the team learns to scroll past.

What the skill actually does

The body of work is six sequential steps documented in detail in the bundle’s SKILL.md. The shape:

  1. Per-account evidence collection. Gather every call, usage event, and ticket in the window. Drop accounts with zero records so silence doesn’t dilute the ranked list.
  2. Per-segment baseline filtering. For each usage event, look up the segment’s noise band in references/2-segment-baseline-config.md and discard events inside the band. The reason for per-segment baselines rather than a single global threshold: a 30 percent week-over-week seat jump means something different for a 5-seat SMB than a 500-seat enterprise. A single global threshold guarantees the SMB band drowns out the enterprise band.
  3. Signal extraction from calls and tickets. Run an extraction prompt against each transcript and ticket using the trigger phrases in references/1-expansion-signal-taxonomy.md, with the negative-example layer explicitly classifying conditional phrases as not_signal.
  4. Strong-vs-weak classification. A signal is strong only when at least one call mention AND at least one usage event land on the same SKU within the window. Anything else is weak. The reason for the split rather than a single score-and-rank: routing differs. Strong signals warrant a CSM sending a meeting invite this week; weak signals warrant a glance during normal account review. Putting weak signals in the ranked list trains the CSM to ignore the ranked list.
  5. Per-CSM routing and prioritization. Group strong signals by owner_email, sort by ARR descending then renewal_date ascending, apply cap_per_csm (default three).
  6. Action mapping and emit. Look up each surfaced signal in references/3-action-library.md and attach the matching next-best action. If no entry matches, output needs human review rather than synthesizing one — vague actions are the failure mode that erodes trust fastest.

Cost reality

The dominant token cost is the call-extraction step. A typical weekly run for a 200-account portfolio with one CSM call per account per week runs roughly:

  • 200 transcripts at an average of 6,000 tokens each = 1.2M input tokens for extraction.
  • 200 ticket-body summaries at roughly 800 tokens each = 0.16M input tokens.
  • Per-account synthesis (200 accounts, around 2,000 input + 500 output tokens each) = 0.4M input + 0.1M output.
  • Total per weekly run: roughly 1.76M input tokens, 0.1M output tokens.

At Claude Sonnet pricing (around $3 per million input, $15 per million output as of 2026-Q1), that’s about $5.30 + $1.50 = under $7 per weekly run. Annualized: under $400 per year per 200-account portfolio. At a 1,000-account portfolio with similar call coverage, scale linearly to under $2,000 per year. The cost floor is the call-extraction step; if your CSMs log few calls the bill drops proportionally and so does the signal quality.

The hidden cost is taxonomy maintenance. Expect a CSM lead to spend roughly 30 minutes per quarter editing references/1-expansion-signal-taxonomy.md and the action library, and a longer ad-hoc session whenever a new SKU launches. Skipping this maintenance is what makes the digest go stale — the skill keeps emitting confident output against a SKU lineup that no longer exists.

Success metric

The metric to watch is CSM-confirmed conversion rate of strong signals to expansion conversations within 14 days. Track it on a trailing-30-day window. Early baselines from pilot teams land in the 25-40 percent range — meaning roughly one in three strong signals leads to a real conversation the CSM would not otherwise have had that month. Below 20 percent for two consecutive months means the strong-vs-weak cutoff is too loose or the action library is too vague; tighten the taxonomy or rewrite half the actions before continuing.

Lagging metric: expansion-ARR contribution attributed to the digest, tracked at quarterly close. This is harder to measure cleanly because expansion conversations have many causes, but a CSM-survey field on every won expansion (“did the digest surface this account before you opened the conversation?”) is a good enough proxy.

vs alternatives

  • vs. Gainsight Expansion Management. Gainsight’s native module ranks accounts on a single composite score and routes via CTAs. It works, but it is opaque — when a CSM disagrees with the ranking they cannot edit a config file, only file a ticket with the admin. This skill keeps the ranking logic in three plain-text files the CSM lead owns and edits directly. Pick Gainsight when your CS-Ops team wants a closed system; pick this when they want the team to own the rules.
  • vs. manual CSM-driven QBRs. A senior CSM running a personal Notion review of their book of business outperforms any digest at the under-50-account scale because they hold context the taxonomy cannot encode. At 100+ accounts per CSM the math flips: nobody can scan that many transcripts weekly. The digest is a force multiplier, not a replacement, and the action library is intentionally shaped to encourage the CSM to do the conversation, not the skill.
  • vs. generic BI dashboards. A Looker dashboard of “accounts with usage spikes” produces a list every week that nobody acts on because there’s no named SKU, no verbatim call evidence, and no next action. The digest’s value is the fusion plus the action, not the ranking — without the SKU map and action library, you end up with a slower version of the dashboard.

Watch-outs

  • False-positive flooding. When the call-extraction prompt is loose, the strong-signal list bloats to 10 or more per CSM per week. Guard: enforce cap_per_csm strictly, and if any single CSM’s strong list exceeds the cap on three consecutive runs, prepend a warning that the strong-vs-weak cutoff is too loose and link to references/1-expansion-signal-taxonomy.md for tightening. Do not silently truncate.
  • Signal misinterpretation — champion-departure trap. A usage spike right after the named champion leaves is an expansion-risk signal, not an expansion-intent signal — the new owner is exploring before deciding whether to keep the contract at all. Guard: cross-reference every strong signal against stakeholder_changes. If a champion on the account departed within the trailing 30 days, downgrade to weak and tag with champion-departure suppressed: investigate before pursuing. The skill must never route an expansion ask to an account that just lost its champion.
  • Threshold drift. Trigger phrases and SKU mappings go stale as the product changes. A new SKU that launched two months ago has zero entries in the taxonomy until someone adds them, and every signal for it is silently mis-routed. Guard: include the SHA-256 (first seven chars) of references/1-expansion-signal-taxonomy.md in the diagnostics footer. If the file hasn’t been touched in 90 days, prepend a warning that the taxonomy is stale and link to the file for recalibration.
  • Conditional-mention misclassification. “We’d consider expanding if you supported X” reads as expansion intent on its face but is in fact a feature-gap report. Guard: the negative- example layer in the extraction step explicitly classifies conditional phrases (“if,” “would,” “considering,” “thinking about”) as not_signal. Diagnostics expose how often this fires — if it never fires the layer is broken; if it fires constantly the SKU mapping needs rephrasing.
  • Action specificity collapse. Under load, the model defaults to “follow up on the opportunity” suggestions. Guard: the post- process filter in step 6 rejects any Action field containing vague verbs (follow up, reach out, touch base, align, socialize, engage) without a named person, meeting, or doc, replacing it with needs human review. Better silence than noise.

Stack

  • Gong — CSM call corpus and transcript API
  • Gainsight — usage-anomaly source and account feed
  • Zendesk / Intercom / Helpscout — support-ticket source for integration-question signals
  • Claude — signal extraction, segment-baseline filtering, strong-vs-weak classification, action mapping

Files in this artifact

Download all (.zip)