Un Claude Skill qui scanne les sept derniers jours d’appels CSM, d’anomalies d’usage et de tickets de support sur l’ensemble de votre portefeuille clients, et émet un digest classé par CSM des comptes montrant une intention concrète d’expansion. Chaque compte identifié nomme le SKU de montée en gamme, les preuves verbatim qui l’étayent, et une seule action prioritaire que le CSM peut mener cette semaine. Le bundle est disponible dans apps/web/public/artifacts/expansion-signal-detection-claude/ et contient SKILL.md ainsi que trois fichiers de référence que l’équipe adapte à sa propre gamme de SKUs, ses référentiels par segment et son playbook d’actions CSM.
Quand l’utiliser
Utilisez ce skill quand votre équipe CS gère plus de comptes qu’un seul humain ne peut en scanner manuellement chaque semaine, et que vous disposez d’au moins deux sources de données croisées — typiquement des appels CSM enregistrés dans Gong plus des anomalies d’usage dans Gainsight (ou émises depuis un entrepôt de données). Le skill est conçu pour des équipes d’au moins trois CSMs sur un portefeuille d’au moins 100 comptes ; en dessous de cette échelle, un responsable CSM lisant chaque appel manuellement surpasse tout digest automatisé, car il voit un contexte que le fichier de taxonomie n’encode pas.
La bonne cadence est hebdomadaire — typiquement le lundi matin, avant la réunion de revue de comptes de l’équipe — et le bon output est un DM Slack personnel par CSM, limité à trois signaux forts. La limite est importante : dans les pilotes, un digest CSM de 10 comptes ou plus « engagés » est lu pendant deux semaines puis ignoré définitivement. Trois demandes concrètes par semaine, répétées chaque lundi, c’est la cadence que l’équipe intériorise réellement.
Quand NE PAS l’utiliser
Vous voulez des alertes en temps réel sur des événements individuels. Les notifications par événement inondent les CSMs et érodent la confiance dans le canal en deux semaines. La cadence hebdomadaire est délibérée. Si votre DRV insiste sur le temps réel, attendez-vous à ce que le digest soit mis en sourdine d’ici le T2.
Vous n’avez pas encore d’anomalies d’usage dans un flux structuré. Le skill consomme des événements d’anomalie pré-émis ; il ne les détecte pas depuis des flux d’événements bruts. Si Gainsight n’émet pas déjà des événements seat_count_spike, feature_first_use et tier_gated_feature_attempt, corrigez d’abord ce pipeline — le skill au-dessus d’un flux vide produit un digest avec des appels uniquement, ce qui effondre chaque signal vers le niveau faible.
Les CSMs ne journalisent pas leurs appels. Si moins de 60 % des comptes ont un appel journalisé dans la fenêtre glissante, la moitié conversationnelle de chaque ensemble de signaux est vide et la plupart des signaux s’effondrent vers le niveau faible. Auditez l’adoption de Gong avant de vous appuyer sur ce skill. Le skill interrompt l’exécution avec une erreur de couverture si le taux descend sous 40 % plutôt que d’émettre un digest à demi-signal.
Vous voulez créer automatiquement des CTAs Gainsight ou envoyer automatiquement des emails aux clients. Ce skill est un signal en lecture seule. L’output est conçu comme une préparation pré-réunion du CSM, pas comme un déclencheur de workflow. Câbler une couche d’action automatique en aval est le moyen le plus rapide d’envoyer à un CFO un email « nous avons remarqué que vous bénéficieriez de notre offre entreprise » la semaine où son champion vient de partir.
Vous voulez une prévision d’ARR d’expansion. L’output est un signal d’intention par compte, pas un chiffre à injecter dans une prévision financière. La prévision d’ARR d’expansion nécessite un calibrage du taux de transformation que le skill n’a pas.
Configuration
Le bundle d’artifact est disponible dans apps/web/public/artifacts/expansion-signal-detection-claude/. Téléchargez-le, modifiez les trois fichiers de référence pour correspondre à votre réalité, puis installez le Skill.
Téléchargez et décompressez le bundle. Déposez expansion-signal-detection-claude/ dans ~/.claude/skills/. La structure est SKILL.md plus references/1-expansion-signal-taxonomy.md, references/2-segment-baseline-config.md et references/3-action-library.md.
Construisez la taxonomie de signaux. Modifiez references/1-expansion-signal-taxonomy.md avec vos SKUs de montée en gamme réels et les phrases déclencheuses d’appels, types d’événements d’usage et tags de tickets de support qui correspondent à chacun. Soyez précis : pas « plus d’utilisateurs », mais « a demandé le pricing pour 50 sièges ou plus » ou « a mentionné des exigences de conformité ». La section d’exemples négatifs capture les phrases conditionnelles (« si vous preniez en charge X ») qui ressemblent à une intention mais sont en fait des signalements de lacunes fonctionnelles — gardez-la à jour, car une liste d’exemples négatifs obsolète est la cause la plus fréquente d’inondation de faux positifs.
Calibrez les référentiels par segment. Modifiez references/2-segment-baseline-config.md avec des valeurs calculées sur une fenêtre glissante de 90 jours sur votre entrepôt d’usage. Par segment, listez le delta hebdomadaire médian et la bande de bruit à deux sigmas pour chaque métrique. Le skill rejette les événements dont le delta_pct tombe dans la bande de bruit même s’ils ont dépassé le seuil de l’émetteur global — c’est ce qui empêche le bruit de décompte de sièges des PME de noyer les vraies expansions entreprise.
Remplissez la bibliothèque d’actions. Modifiez references/3-action-library.md avec une ou plusieurs actions prioritaires par SKU. Chaque entrée doit suivre la forme verbe + artefact nommé (une réunion, une personne, un document, un ticket) — le skill applique un filtre littéral de sous-chaîne sur le champ Action émis, remplaçant tout élément vague par needs human review.
Câblez les sources de données. Définissez GONG_API_KEY pour l’extraction des transcriptions, GAINSIGHT_TOKEN pour le flux d’événements d’usage et de comptes, et votre token d’API de tickets de support (Zendesk, Intercom, ou Helpscout, selon votre stack). Le skill lit des anomalies pré-calculées depuis le flux d’usage ; il n’exécute pas lui-même la détection d’anomalies.
Lancez hebdomadairement. Invoquez expansion_signal_detection(window_days=7) depuis une session Claude Code planifiée (cron ou workflow GitHub Actions workflow_dispatch sur un déclencheur hebdomadaire). L’output est un fichier Markdown par responsable CSM, posté en DM Slack plutôt qu’en message dans un canal public — l’objectif est la responsabilisation individuelle du CSM, pas un classement public que l’équipe apprend à ignorer.
Ce que le skill fait réellement
L’essentiel du travail se déroule en six étapes séquentielles documentées en détail dans SKILL.md du bundle. La structure :
Collecte de preuves par compte. Rassemblez chaque appel, événement d’usage et ticket dans la fenêtre. Supprimez les comptes sans enregistrement afin que le silence ne dilue pas la liste classée.
Filtrage par référentiel de segment. Pour chaque événement d’usage, recherchez la bande de bruit du segment dans references/2-segment-baseline-config.md et rejetez les événements dans la bande. La raison des référentiels par segment plutôt qu’un seul seuil global : un saut de 30 % des sièges d’une semaine à l’autre signifie quelque chose de différent pour une PME à 5 sièges que pour une entreprise à 500 sièges. Un seuil global unique garantit que la bande PME noie la bande entreprise.
Extraction de signaux depuis les appels et tickets. Exécutez un prompt d’extraction sur chaque transcription et ticket en utilisant les phrases déclencheuses dans references/1-expansion-signal-taxonomy.md, avec la couche d’exemples négatifs classifiant explicitement les phrases conditionnelles comme not_signal.
Classification fort/faible. Un signal est fort uniquement quand au moins une mention d’appel ET au moins un événement d’usage portent sur le même SKU dans la fenêtre. Tout le reste est faible. La raison de la division plutôt qu’un seul score-et-classement : le routage diffère. Les signaux forts justifient qu’un CSM envoie une invitation à une réunion cette semaine ; les signaux faibles justifient un regard lors de la revue de compte habituelle. Mettre des signaux faibles dans la liste classée entraîne l’apprentissage par le CSM à ignorer cette liste.
Routage et priorisation par CSM. Groupez les signaux forts par owner_email, triez par ARR décroissant puis renewal_date croissant, appliquez cap_per_csm (défaut : trois).
Correspondance d’action et émission. Recherchez chaque signal identifié dans references/3-action-library.md et attachez l’action prioritaire correspondante. Si aucune entrée ne correspond, émettez needs human review plutôt qu’en synthétiser une — les actions vagues sont le mode d’échec qui érode le plus rapidement la confiance.
Réalité des coûts
Le coût dominant en tokens est l’étape d’extraction des appels. Une exécution hebdomadaire typique pour un portefeuille de 200 comptes avec un appel CSM par compte par semaine tourne environ à :
200 transcriptions à une moyenne de 6 000 tokens chacune = 1,2M tokens d’entrée pour l’extraction.
200 résumés de corps de tickets à environ 800 tokens chacun = 0,16M tokens d’entrée.
Synthèse par compte (200 comptes, environ 2 000 tokens d’entrée + 500 de sortie chacun) = 0,4M entrée + 0,1M sortie.
Total par exécution hebdomadaire : environ 1,76M tokens d’entrée, 0,1M tokens de sortie.
Au tarif Claude Sonnet (environ 3 $ par million en entrée, 15 $ par million en sortie en 2026-T1), c’est environ 5,30 $ + 1,50 $ = moins de 7 $ par exécution hebdomadaire. Annualisé : moins de 400 $ par an pour un portefeuille de 200 comptes. À 1 000 comptes avec une couverture similaire, extrapolez linéairement jusqu’à moins de 2 000 $ par an. Le plancher de coût est l’étape d’extraction des appels ; si vos CSMs journalisent peu d’appels, la facture baisse proportionnellement et la qualité du signal aussi.
Le coût caché est la maintenance de la taxonomie. Prévoyez environ 30 minutes par trimestre pour qu’un responsable CSM modifie references/1-expansion-signal-taxonomy.md et la bibliothèque d’actions, plus une session ad hoc plus longue à chaque lancement d’un nouveau SKU. Ignorer cette maintenance rend le digest obsolète — le skill continue d’émettre un output confiant contre une gamme de SKUs qui n’existe plus.
Métriques de succès
La métrique à observer est le taux de conversion confirmé par le CSM des signaux forts vers des conversations d’expansion dans les 14 jours. Suivez-le sur une fenêtre glissante de 30 jours. Les référentiels initiaux des équipes pilotes se situent entre 25 et 40 % — soit environ un signal fort sur trois qui mène à une vraie conversation que le CSM n’aurait pas eue autrement ce mois-là. En dessous de 20 % pendant deux mois consécutifs, le seuil fort/faible est trop lâche ou la bibliothèque d’actions est trop vague ; affinez la taxonomie ou réécrivez la moitié des actions avant de continuer.
Métrique retardée : contribution à l’ARR d’expansion attribuée au digest, suivie à la clôture trimestrielle. C’est plus difficile à mesurer proprement car les conversations d’expansion ont de nombreuses causes, mais un champ d’enquête CSM sur chaque expansion gagnée (« le digest a-t-il identifié ce compte avant que vous n’engagiez la conversation ? ») est un proxy suffisant.
Alternatives
vs Gainsight Expansion Management. Le module natif de Gainsight classe les comptes sur un score composite unique et route via des CTAs. Ça fonctionne, mais c’est opaque — quand un CSM n’est pas d’accord avec le classement, il ne peut pas modifier un fichier de configuration, seulement ouvrir un ticket avec l’administrateur. Ce skill garde la logique de classement dans trois fichiers en texte brut que le responsable CSM possède et modifie directement. Choisissez Gainsight quand votre équipe CS-Ops veut un système fermé ; choisissez ce skill quand elle veut posséder les règles.
vs les QBRs CSM manuels. Un CSM senior faisant une revue personnelle Notion de son portefeuille surpasse tout digest à l’échelle de moins de 50 comptes, car il détient un contexte que la taxonomie ne peut pas encoder. À 100+ comptes par CSM, le calcul s’inverse : personne ne peut scanner autant de transcriptions hebdomadairement. Le digest est un multiplicateur de force, pas un remplacement, et la bibliothèque d’actions est intentionnellement conçue pour encourager le CSM à mener la conversation, pas le skill.
vs les tableaux de bord BI génériques. Un tableau de bord Looker de « comptes avec des pics d’usage » produit une liste chaque semaine que personne n’exploite car il n’y a pas de SKU nommé, pas de preuve verbatim d’appel, et pas d’action suivante. La valeur du digest est la fusion plus l’action, pas le classement — sans la carte SKU et la bibliothèque d’actions, vous vous retrouvez avec une version plus lente du tableau de bord.
Points de vigilance
Inondation de faux positifs. Quand le prompt d’extraction d’appels est trop lâche, la liste de signaux forts gonfle à 10 ou plus par CSM par semaine. Protection : appliquez strictement cap_per_csm, et si la liste forte d’un CSM dépasse le plafond pendant trois exécutions consécutives, ajoutez un avertissement que le seuil fort/faible est trop lâche et renvoyez vers references/1-expansion-signal-taxonomy.md pour l’affiner. Ne tronquez pas silencieusement.
Mauvaise interprétation des signaux — piège du départ du champion. Un pic d’usage juste après le départ du champion nommé est un signal de risque d’expansion, pas un signal d’intention d’expansion — le nouvel interlocuteur explore avant de décider s’il conserve le contrat. Protection : croisez chaque signal fort avec stakeholder_changes. Si un champion du compte est parti dans les 30 derniers jours, rétrogradez en faible et taguez avec champion-departure suppressed: investigate before pursuing. Le skill ne doit jamais router une demande d’expansion vers un compte qui vient de perdre son champion.
Dérive des seuils. Les phrases déclencheuses et les correspondances de SKUs deviennent obsolètes au fil des évolutions du produit. Un nouveau SKU lancé il y a deux mois a zéro entrée dans la taxonomie jusqu’à ce que quelqu’un les ajoute, et chaque signal pour lui est silencieusement mal routé. Protection : incluez le SHA-256 (7 premiers caractères) de references/1-expansion-signal-taxonomy.md dans le pied de page des diagnostics. Si le fichier n’a pas été touché depuis 90 jours, ajoutez un avertissement que la taxonomie est obsolète et renvoyez vers le fichier pour recalibration.
Mauvaise classification des mentions conditionnelles. « Nous envisagerions d’élargir si vous preniez en charge X » ressemble en apparence à une intention d’expansion mais est en fait un signalement de lacune fonctionnelle. Protection : la couche d’exemples négatifs dans l’étape d’extraction classifie explicitement les phrases conditionnelles (« si », « serions », « envisageant », « pensant à ») comme not_signal. Les diagnostics exposent la fréquence de déclenchement — si elle ne se déclenche jamais, la couche est défectueuse ; si elle se déclenche constamment, la correspondance de SKU nécessite une reformulation.
Effondrement de la spécificité des actions. Sous charge, le modèle se rabat sur des suggestions « faire un suivi sur l’opportunité ». Protection : le filtre de post-traitement à l’étape 6 rejette tout champ Action contenant des verbes vagues (follow up, reach out, touch base, align, socialize, engage) sans personne, réunion ou document nommé, en le remplaçant par needs human review. Mieux vaut le silence que le bruit.
Stack
Gong — corpus d’appels CSM et API de transcription
Gainsight — source d’anomalies d’usage et flux de comptes
Zendesk / Intercom / Helpscout — source de tickets de support pour les signaux de questions d’intégration
Claude — extraction de signaux, filtrage par référentiel de segment, classification fort/faible, correspondance d’actions
---
name: expansion-signal-detection
description: Weekly account-portfolio scan that fuses CSM-call mentions with usage anomalies, classifies expansion intent into weak vs strong signals, and emits a per-CSM ranked digest mapping each signal to a likely upsell SKU and a next-best action. Read-only — never contacts customers, never auto-creates Gainsight CTAs.
---
# Expansion-signal detection
## When to invoke
Run once a week (typically Monday morning, before the CSM team's weekly account review) to scan the trailing 7 days of CSM calls and usage events across the customer portfolio. Output is a ranked digest per CSM owner, sized for a 5-minute pre-meeting read.
Do NOT invoke this skill for:
- Auto-emailing customers, auto-creating Gainsight CTAs, or any outbound action. The skill is read-only signal — humans decide which account to actually approach.
- 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.
- Sales-call analysis (new logos, prospecting). The signal taxonomy here assumes existing customers with a baseline of usage and a named CSM. Use the AE call-coach skill instead.
- Replacing a usage-anomaly detection system. The skill consumes pre-computed anomalies; it does not detect them. If Gainsight isn't already firing usage-spike events, fix that first.
- Forecasting expansion ARR. The output is per-account intent signal, not a number a finance team should plug into a forecast.
## Inputs
- Required: `accounts` — JSON array with `id`, `name`, `arr`, `segment` (e.g. `enterprise` / `mid-market` / `smb`), `tier` (current SKU tier), `owner_email`, `renewal_date`.
- Required: `calls` — JSON array of CSM call records for the trailing window. Each record needs `account_id`, `call_id`, `occurred_at`, `transcript_url` or `transcript_text`, `attendees` (with `is_customer` flag and role/title where known).
- Required: `usage_events` — JSON array of usage anomalies emitted by Gainsight (or your usage-warehouse equivalent) for the same window. Each event needs `account_id`, `event_type` (e.g. `feature_first_use`, `seat_count_spike`, `api_call_spike`, `tier_gated_feature_attempt`), `metric_name`, `value_current`, `value_baseline`, `delta_pct`, `occurred_at`.
- Required: `support_tickets` — JSON array of recent tickets with `account_id`, `subject`, `body_summary`, `tags`, `opened_at`. Used to spot integration / capability questions tied to premium SKUs.
- Optional: `stakeholder_changes` — JSON array of org-chart events (`account_id`, `change_type` of `new_hire` / `promotion` / `departure`, `role`, `is_champion`, `occurred_at`). Used to suppress signals contaminated by champion churn (see watch-outs).
- Optional: `window_days` — lookback window. Defaults to 7. Going shorter than 7 typically yields too few signals per account to classify; going longer than 14 stale-dates the next-best action.
- Optional: `cap_per_csm` — maximum signals surfaced per CSM in the digest body. Defaults to 3. Overflow is summarized as a count.
## Reference files
Read these from `references/` before running. They encode the team's taxonomy and per-segment baselines — without them the output is generic "this account is engaged" filler.
- `references/1-expansion-signal-taxonomy.md` — the SKU-to-trigger mapping. Each upsell SKU lists the call phrases, usage patterns, and ticket topics that count as evidence, plus weak-signal vs strong-signal cutoffs.
- `references/2-segment-baseline-config.md` — per-segment baselines for usage anomalies (a 30 percent week-over-week jump means something different for an SMB on 5 seats than an enterprise on 500). The skill rejects anomalies that exceed the absolute threshold but fall inside the segment's noise band.
- `references/3-action-library.md` — the next-best-action library the skill maps signals to. Each action is a verb plus a named artifact (a meeting, a doc, a person), not a vague "follow up."
## Method
Run these six steps in order. Do not parallelize: classification depends on aggregation, routing depends on classification.
### 1. Per-account evidence collection
For each account in `accounts`, gather every record from `calls`, `usage_events`, and `support_tickets` within `window_days`. Drop accounts with zero records — silence is not a signal here, and an empty entry in the digest dilutes the ranked list. Record the count of dropped accounts for the footer so the team can see coverage.
### 2. Per-segment baseline filtering
For each `usage_event`, look up the account's `segment` in `references/2-segment-baseline-config.md` and fetch the baseline noise band (typically expressed as a two-sigma range around the segment median for that metric). Discard events whose `delta_pct` falls inside the noise band even if the absolute value crossed the emitter's threshold.
The reason for per-segment baselines (rather than a single global threshold): a 30 percent week-over-week seat jump is meaningful noise for an SMB account that adds 1-2 seats normally, and meaningful signal for an enterprise account on a flat 500-seat plan. A single global threshold guarantees the SMB band drowns out the enterprise band. Per-segment baselines are auditable — when a CSM lead disagrees with the cutoff, they edit one row in the config rather than tuning a hidden constant.
### 3. Signal extraction from calls and tickets
For each call transcript and ticket body in scope, run an extraction prompt that scans for the trigger phrases listed in `references/1-expansion-signal-taxonomy.md`. Each match is logged with the SKU it maps to, the verbatim quote, the speaker (with `is_customer` filter — coach mentions don't count), and the `call_id` or `ticket_id` it came from.
Negative-example guard: the prompt explicitly enumerates phrases that look adjacent but mean the opposite ("we're thinking about leaving," "your enterprise tier is too expensive," "we'd consider expanding if X were true" — conditional, not committed). These are classified as `not_signal` rather than dropped silently, so the diagnostics in step 6 can show how often the negative-example layer fired.
### 4. Weak-signal vs strong-signal classification
For each per-account candidate signal, classify into one of three buckets using the cutoffs in `references/1-expansion-signal-taxonomy.md`:
- **Strong** — at least one corroborating call mention plus at least one corroborating usage event for the same SKU within the window. These get routed to the per-CSM digest as ranked entries.
- **Weak** — call mention OR usage event alone, OR both but for different SKUs. These get aggregated into a per-CSM "weak signals worth a glance" footer with a count and a link, never as ranked entries.
- **Insufficient** — fewer than the cutoff above. Recorded for the diagnostics footer; not surfaced per-CSM.
The reason for weak-vs-strong split rather than a single score-and-rank: routing differs. A strong signal warrants a CSM sending a meeting invite this week. A weak signal warrants the CSM glancing during their 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`. Within each owner's list, sort by ARR descending, breaking ties by `renewal_date` ascending (closer renewals first — expansion plus a near-term renewal is more actionable than expansion in month 11 of a 24-month deal). Apply `cap_per_csm` to the strong list. If the cap drops signals, surface them only as a count in the weak-signals footer for that CSM.
### 6. Action mapping and emit
For each surfaced strong signal, look up the SKU and signal pattern in `references/3-action-library.md` and attach the matching next-best action. If no action is found, output `needs human review` rather than synthesizing one. Vague suggested actions are the failure mode that erodes trust fastest — better silence than noise.
Render to the layout in the Output format section below. Emit one file per CSM owner (not one combined file) so the digest can be delivered as a personal Slack DM rather than a public channel post that creates implicit social pressure.
## Output format
```markdown
# Expansion-signal digest — {YYYY-MM-DD} — {CSM name}
Window: trailing {window_days} days · Strong signals: {n_strong} · Weak signals: {n_weak}
## Strong signals — act this week
### 1. {Account name} — ${ARR}k ARR · renewal {renewal_date}
SKU: {target_sku}
Call evidence:
> "{verbatim quote}" — {speaker_name}, {role}, {call_date} ({call_id})
Usage evidence: {metric_name} went from {value_baseline} to {value_current} ({delta_pct} over {n} days, segment-baseline-adjusted)
Action: {verb + named artifact, from action library}
### 2. {Account name} — ...
## Weak signals — worth a glance ({n_weak})
- *{Account name}* — {SKU}: {one-line summary, e.g. "call mention only, no usage corroboration"}
- *{Account name}* — {SKU}: {one-line summary}
- (+{n_overflow} more capped from strong list — see footer)
## Diagnostics
- Accounts in scope: {n_total}
- Accounts with zero records (dropped): {n_silent}
- Negative-example matches (suppressed): {n_negative}
- Champion-departure suppressions: {n_champion_suppressed}
- Taxonomy file hash: {first_7_chars_of_sha256}
```
## Watch-outs
- **False-positive flooding.** When the call-extraction prompt is loose, it surfaces "showed interest" mentions that don't actually predict expansion, and the CSM's strong-signal list bloats to 10+ 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 `_Strong-signal threshold may be too loose — last 3 runs averaged {n} per week. Consider tightening the strong-vs-weak cutoff in references/1-expansion-signal-taxonomy.md._` warning. Do not silently truncate without flagging.
- **Signal-weighting 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 7 chars) of `references/1-expansion-signal-taxonomy.md` in the diagnostics footer. If the file hasn't been touched in 90 days, prepend `_Taxonomy last edited 90+ days ago. Time to recalibrate against the current SKU lineup._`
- **Champion-departure misclassification.** A spike in usage 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. 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 NOT route an expansion ask to an account that just lost its champion.
- **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 step 3 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.
- **CSM call-coverage gap.** If CSMs aren't actually logging calls in Gong (or the equivalent), the call half of the signal set is empty and every signal collapses to weak. Guard: at the start of every run, compute `% of accounts with at least one logged call in the window` and prepend the digest with `_CSM call coverage: {pct}% of accounts had at least one logged call. Below 60% means most signals are usage-only._` Below 40%, abort the run with a coverage-error message rather than emit a half-signal digest.
- **Action specificity collapse.** Under load, the model defaults to generic "follow up on opportunity" suggestions. Guard: post- process the Action field with a literal substring check — if the action contains `follow up`, `reach out`, `touch base`, `align`, `socialize`, `engage` without a named person, meeting, or doc, replace with `needs human review`. Action library entries that pass this filter are the only acceptable shape.
# Expansion-signal taxonomy — TEMPLATE
> Replace these mappings with your actual SKU lineup and the trigger
> phrases / usage patterns your team has observed precede an upsell.
> The skill reads this file on every run; without your real taxonomy
> the digest output is generic and CSMs ignore it within two weeks.
## Strong-signal cutoff
A signal is classified **strong** only when at least one call mention AND at least one usage-event corroboration land on the same SKU within the run window. Anything else is **weak**. Edit this cutoff only after you have three weeks of digests showing repeated cases of genuine expansion that the strong-only filter missed.
## SKU map
For each SKU, list:
- **Call triggers** — verbatim phrase patterns the extraction prompt searches transcripts for. Be specific: "asked about pricing for more than 50 seats" not "asked about pricing."
- **Usage triggers** — pre-emitted anomaly types (from your usage warehouse) that count as evidence for this SKU.
- **Ticket triggers** — support-ticket subject / tag patterns that count as evidence (typically integration questions about premium features).
- **Negative-example phrases** — phrases that look adjacent but mean the opposite. The skill classifies these as `not_signal` rather than dropping silently.
### SKU: enterprise-tier (example)
- **Call triggers**:
- "do you support SSO" / "SAML" / "SCIM"
- "compliance requirements" / "SOC 2" / "HIPAA" / "FedRAMP"
- "asked about pricing for {N}+ seats" where N is at least 2x current seat count
- "our security team needs"
- **Usage triggers**:
- `tier_gated_feature_attempt` for SSO, audit-log, or RBAC features
- `seat_count_spike` over the segment baseline (see config)
- **Ticket triggers**:
- tags include `sso`, `compliance`, `security-review`
- subject matches `audit log`, `enterprise`, `compliance`
- **Negative-example phrases**:
- "we're going to need to drop down a tier"
- "your enterprise tier is too expensive"
- "we'd consider {feature} if it were on a lower tier"
### SKU: additional-team-seats (example)
- **Call triggers**:
- "the {team_name} team is also starting to use this"
- "rolling out to {N} more people"
- "our {team} would benefit from access"
- **Usage triggers**:
- `seat_count_spike` over baseline
- `feature_first_use` from a previously-inactive department (requires department tagging in usage events)
- **Ticket triggers**:
- subject contains `add users`, `new team`, `provisioning`
- **Negative-example phrases**:
- "we're consolidating teams onto fewer seats"
- "trying to figure out who actually uses this"
### SKU: premium-feature-pack (example)
- **Call triggers**:
- "does {premium_feature} support {use_case}"
- "we're trying to do {use_case} — is that on the roadmap"
- **Usage triggers**:
- `tier_gated_feature_attempt` for premium-pack features
- `api_call_spike` on premium-only endpoints
- **Ticket triggers**:
- tags include `premium-feature`, `api-limits`, `advanced-{feature}`
- **Negative-example phrases**:
- "we tried {premium_feature} and it didn't fit our use case"
- "we're using {competitor} for {use_case} instead"
### SKU: {your_next_sku}
(Add a section per SKU. The skill only routes to SKUs listed here.)
## Conditional-mention guard
The negative-example layer specifically catches conditional expansion mentions — phrases that sound like intent but are in fact feature-gap reports. The extraction prompt classifies any match containing both an expansion-shaped verb and one of the following conditional markers as `not_signal`:
- "if you {supported, added, built, shipped}"
- "would {consider, think about, look at} {expanding, upgrading}"
- "thinking about {upgrading, expanding, the enterprise tier}"
These are valuable product-feedback signals, but they belong in a roadmap-feedback channel, not a CSM expansion digest. Route them elsewhere if you want to capture them.
## Last edited
{YYYY-MM-DD}
# Segment baseline config — TEMPLATE
> Replace these baselines with values computed from your actual usage
> warehouse. The skill rejects usage anomalies whose `delta_pct` falls
> inside the segment's noise band even when the absolute value
> crossed the emitter's threshold. Without per-segment baselines,
> SMB noise drowns out enterprise signal.
## How baselines are used
For each `usage_event` ingested, the skill:
1. Looks up `account.segment` in this file.
2. Fetches the noise band (typically two-sigma around the segment median) for the event's `metric_name`.
3. If `delta_pct` falls inside the noise band, the event is discarded as noise even if it crossed the global emitter threshold.
4. If outside the band, the event is kept as a signal candidate and proceeds to the SKU mapping in step 3 of the method.
Edit one row at a time. Watch the next two digests before editing again — baselines that move every week train the team to ignore the output.
## Per-segment baseline table
Replace these placeholder values with values from a 90-day rolling window over your actual usage data.
### Segment: enterprise (example)
Typical: 200-1000+ seats, multi-year contract, dedicated CSM.
| Metric | Median weekly delta | Noise band (2σ) | Notes |
|-----------------------------|--------------------:|-----------------|---------------------------------------------|
| `seat_count` | +0.5% | ±3% | Enterprise plans tend to be flat-by-design |
| `daily_active_users` | +1.0% | ±8% | Vacation-week dips are normal |
| `api_calls` | +2.0% | ±15% | Spiky on integration release days |
| `tier_gated_feature_attempts` | 0 | ±0 (any > 0 is signal) | Crossing into a tier-gate is signal regardless of band |
### Segment: mid-market (example)
Typical: 50-200 seats, annual contract, shared CSM coverage.
| Metric | Median weekly delta | Noise band (2σ) | Notes |
|-----------------------------|--------------------:|-----------------|---------------------------------------------|
| `seat_count` | +1.5% | ±7% | Quarterly rollouts can produce one-off jumps |
| `daily_active_users` | +2.0% | ±12% | |
| `api_calls` | +3.5% | ±20% | |
| `tier_gated_feature_attempts` | 0 | ±0 (any > 0 is signal) | |
### Segment: smb (example)
Typical: 1-50 seats, monthly or annual contract, pooled CSM coverage.
| Metric | Median weekly delta | Noise band (2σ) | Notes |
|-----------------------------|--------------------:|-----------------|---------------------------------------------|
| `seat_count` | +5.0% | ±25% | Adding 1-2 seats is week-on-week normal |
| `daily_active_users` | +6.0% | ±30% | Highly variable |
| `api_calls` | +8.0% | ±40% | Often noisy due to integration tinkering |
| `tier_gated_feature_attempts` | 0 | ±0 (any > 0 is signal) | |
### Segment: {your_next_segment}
(Add a section per segment in your customer base.)
## Recompute cadence
Recompute the medians and noise bands from your usage warehouse on a quarterly basis. Append to the calibration log below so the next person editing this file can see why the numbers are what they are.
## Calibration log
Format: `YYYY-MM-DD — change — reason`.
- {YYYY-MM-DD} — initial baselines — placeholder, replace with values computed from a 90-day rolling window
## Last edited
{YYYY-MM-DD}
# Action library — TEMPLATE
> Replace these actions with the next-best actions your CSM team
> actually runs. The skill maps each strong signal to one entry in
> this library; entries that are vague ("follow up", "engage
> stakeholder") are rejected by the post-process filter described in
> the SKILL.md watch-outs section.
## Action shape
Every entry MUST follow the shape:
```
verb + named artifact (a meeting, a person, a doc, or a ticket)
```
Acceptable:
- "Send the SSO setup checklist to the security contact and propose a 30-min walkthrough this week."
- "Forward the Q3 roadmap deck to the new VP of Eng and ask for a 15-min reaction call."
- "Open a Gainsight CTA tagged `enterprise-tier-evaluation` and ping the renewal owner in the linked thread."
Not acceptable:
- "Follow up on the opportunity" (no named artifact)
- "Reach out about expansion" (no verb-and-artifact)
- "Engage the buying committee" (vague)
The skill enforces this with a literal substring check on the emitted Action field. Anything not from this library — or matching the vague-language denylist — is replaced with `needs human review`.
## SKU: enterprise-tier
| Trigger pattern | Next-best action |
|----------------------------------------------|------------------|
| Call mention of SSO/SAML/SCIM + tier-gated attempt | "Send the SSO setup checklist {link} to the security contact and propose a 30-min walkthrough this week." |
| Compliance language + ticket tagged `compliance` | "Forward the SOC 2 report {link} and the compliance one-pager {link} to the named compliance contact within 48 hours." |
| Seat-count spike at 2x baseline + pricing call mention | "Schedule a 30-min commercial conversation with the EB this week. Bring the enterprise-tier pricing sheet {link}." |
## SKU: additional-team-seats
| Trigger pattern | Next-best action |
|----------------------------------------------|------------------|
| Call mention of new team + seat-count spike | "Open a provisioning thread with the named admin and offer a 15-min onboarding for the new team this week." |
| `feature_first_use` from new department | "Send the {department} onboarding playbook {link} to the named admin and CC the new department's manager." |
## SKU: premium-feature-pack
| Trigger pattern | Next-best action |
|----------------------------------------------|------------------|
| Use-case question + tier-gated attempt | "Send the premium-feature one-pager {link} and book a 30-min product walkthrough with the asking persona this week." |
| `api_call_spike` on premium endpoints | "Open a Gainsight CTA tagged `premium-pack-evaluation` and ping the technical evaluator in the linked thread." |
## SKU: {your_next_sku}
(Add a section per SKU. Every SKU listed in the taxonomy file MUST have at least one matching trigger-action row here, or the skill will emit `needs human review` for every signal that maps to it.)
## Vague-language denylist
The post-process filter rejects any Action field containing the following substrings without an accompanying named artifact:
- `follow up`
- `reach out`
- `touch base`
- `align`
- `socialize`
- `engage`
- `circle back`
- `loop in`
- `start a conversation`
If a legitimate action needs one of these verbs, write the action with a named artifact attached (e.g. "Loop in the Solutions Engineer {name} on the next call to demo {feature}.").
## Last edited
{YYYY-MM-DD}