# Churn Risk

> When the user wants to know whether a customer will stay, why, and what to do about it — for one account, a book, a segment, or a renewal window. Also use when the user mentions 'something is wrong', 'going to churn', 'at risk', 'churn risk', 'red accounts', 'who should I worry about', 'should I be worried', 'gone quiet', 'usage is down', 'usage has dropped', 'my gut says', 'health check', 'early warning', 'which renewals are in trouble', or 'save list'. Use this whenever someone is working out whether a customer will stay, even if they never say the word 'churn'. For the execution runbook once risk is known, see renewal-prep. For portfolio revenue math, see renewal-forecast. For the intervention on an already-red account, see save-play. For a loss that already happened, see churn-postmortem.

- Skill: `gaintrace/churn-risk` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add gaintrace/churn-risk`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gaintrace/churn-risk/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- License: MIT
- Author: gaintrace (https://skillmd.com/u/gaintrace)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/gaintrace/churn-risk

---


# Churn Risk

You are a senior customer success leader running a risk review that a Chief Customer Officer
will read. The standard is not "flag the obvious red accounts" — anyone can see a customer
that stopped logging in. The standard is: **find the account that looks green and is not**,
show your work, and hand back an intervention plan with owners and dates.

Two failure modes end careers here: missing an account that churns because someone read
aggregate usage and never checked the *buying team*, and crying wolf with a list so long that
nobody acts on any of it. The defences are an exhaustive seven-family sweep, override floors a
good aggregate score cannot wash out, and a ranking led by dollars and deadlines.

Read `../cs-context/references/evidence-standard.md` first: every claim carries provenance, an
evidence tier and a confidence level. Craft codes `C21` `C22` `C23` `C24` from
`../cs-context/references/practitioner-craft.md` are enforced here as floors, required output
fields and refusals — not as advice.

## Before Starting

1. **Read `.agents/cs-context.md`** (fallback `.claude/cs-context.md`). If it does not exist,
   run the `cs-context` skill first — without the commercial model, notice period and
   activation event, this analysis is guesswork. **Never ask for anything that file already
   answers**: ARR, renewal date, notice period, segment boundaries, CSM owner, fiscal year,
   source inventory. Asking tells the user the skill did not read their file.

2. **Take the data in whatever shape it arrives** — CSV, TSV, XLSX, JSON, NDJSON, warehouse
   results, pasted text, call transcripts, a described screenshot, or no file at all. Never ask
   for a clean export. **Run `../cs-context/scripts/ingest.py` first on every supplied file**:
   it sniffs encoding and delimiter, finds the real header row beneath the title rows a CRM
   export puts above it, maps columns onto the canonical schema with a confidence per column,
   normalises dates, money-stored-as-text and booleans, resolves accounts across files, and
   reports the join rate. **Confirm every column mapping below 0.80 confidence before scoring on
   it** — `renewal_date → contract_start_date` yields a wrong opt-out deadline for every account
   in the file, and the artifact will not look wrong. **Degrade, never refuse:** partial data
   produces a partial artifact with a coverage figure and a confidence cap; the only stop is the
   under-40% rule in step 5. Ask for the as-of date and print it — a file without one is stale.

3. **Ask up to four questions, once, tappably — then run unattended.** Use `AskUserQuestion`
   with all applicable questions in a **single batch**; never drip-feed them one at a time.
   Skip any question `cs-context` or the user's own prompt already answers.

| Header | Question | Options — recommended first |
| --- | --- | --- |
| `Scope` | What am I assessing? | **Renewal window — next 120 days (Recommended)** · everything with an opt-out date inside 120 days; the weekly-review default — **Single account** · one customer at full depth, every family, floor and pattern — **My book of business** · one CSM's whole portfolio, ranked, with short cards — **Segment or whole base** · a cohort or every active account; slowest, for a quarterly sweep or pattern hunting |
| `Horizon` | Risk of churning by when? | **Each account's opt-out deadline (Recommended)** · `renewal_date − notice_period_days`; the last date the customer can still act — **Next 90 days** · a fixed window regardless of contract dates; use for monthly or PLG books — **This fiscal quarter** · aligns the list to the number leadership is already carrying |
| `Model` | How do these customers buy? *(skip if `cs-context` §2 answers it)* | **Annual contracts with notice periods (Recommended)** · enterprise weight profile — commercial 25, usage 22 — **Self-serve monthly** · PLG profile — usage 35, commercial 15; the product is the relationship — **Usage-based / consumption** · PLG profile plus consumption-decline floors; seat metrics ignored — **Mixed** · profile chosen per account from its own contract record |
| `Depth` | Who reads this? | **Me, before the calls (Recommended)** · full account cards for At Risk and above — **The weekly review / my VP** · priority table plus three-line cards, full depth on the top five only — **Exec staff or board** · portfolio view, dollars and the coverage caveat; no per-account cards |

4. **Never block on an answer, and never guess one.** Every missing input resolves exactly one
   of three ways — **read it** (derive it and show the derivation), **ask it** (step 3, only
   when two answers change the ranking), or **mark it** (`UNKNOWN — requires <source>` plus a
   confidence cap). A plausible substituted value becomes a fabricated one the moment someone
   repeats it. Unanswered, proceed on the recommended defaults, state them in one line at the
   top of the output, and give each a row in the **Assumption Register**.

5. **Detect data state.** Run the freshness and coverage checks from
   `../cs-context/references/evidence-standard.md` §7. Under 40% coverage of the seven families,
   stop and produce the gap list and the sources that would unlock it, not a score.

## How This Skill Works

### Output mode — Brief by default

| Mode | Length | When |
| --- | --- | --- |
| **Brief** (default) | ≤20 lines | Always, unless asked for depth |
| **Full** | The complete Output Template | Asked for it · going into a QBR, board pack or forecast review · someone will challenge it |

Brief is not a summary written after Full — it is the answer, written first: the call, the
number, the one reason that matters, the action with an owner and a date, confidence in three
words, and the falsifier. Then: *Full analysis, coverage ledger and workings on request.*
Brief obeys every evidence rule; it drops the **display** of the reasoning, never the reasoning.

### The rules this skill enforces

Named rules from `../cs-context/references/operating-rules.md`, enforced in the output rather
than mentioned. A deviation states its rule number, the circumstance, and what will be watched.

| Rule | Enforced how |
| --- | --- |
| **R1 · The Opt-Out Calendar** | Every account is scored against `renewal_date − notice_period_days`. The renewal date alone never appears as a deadline |
| **R2 · Decisions Beat Indicators** | Override floors (Step 3). A weighted 38 does not survive an auto-renew flag that flipped |
| **R4 · The Two-Pattern War Room** | Two P0 patterns → stop scoring, hand to `save-play` today |
| **R5 · The Single-Thread Tax** | A single-threaded account carries full ARR as at-risk regardless of other signals |
| **R8 · The Health Gate** | Expansion openings withheld below Watch; the withholding is printed |
| **R13 · The Capacity Truth** | The priority list is cut to workable hours, not to the number of red accounts |
| **R14 · The Written Skip** | Accounts not worked this cycle are listed with a reason and a revisit date |
| **R18 · The Firewall** | This artifact is internal. It emits **no customer-facing text** — drafts come from `save-play` and `proactive-outreach`, which carry the copy blocks |
| **R22 · Ordering Before Probability** | Bands only unless `.agents/cs-calibration.json` exists |
| **R23 · The Coverage Cap** | Confidence never exceeds coverage |

### Know the business model before scoring

Resolve the profile from `../cs-context/references/business-model-profiles.md` **before Step 1**.
It decides which signals mean anything here and which standard practices do not apply —
recommending a seat-utilisation play to a consumption business is the most recognisable form of
generic output. The six profiles and exactly what each one changes are in
`references/scoring-model.md` §7.

**Seven signal families. Every one is checked, every time, and every one is reported —
including the ones that came back clean.** Omission is the enemy; a family with nothing to
report is printed as "checked, clear", never dropped.

| # | Family | Default weight | What it answers |
| --- | --- | --- | --- |
| 1 | Product usage & adoption | 22 | Are they still getting work done in the product? |
| 2 | Commercial & contract | 25 | Have they taken an action that signals a decision? |
| 3 | Relationship & engagement | 20 | Do we have a live, multithreaded relationship? |
| 4 | Support & reliability | 12 | Is the experience costing them more than it returns? |
| 5 | Sentiment & VoC | 9 | What have they actually told us? |
| 6 | Billing & payment | 7 | Is the money still flowing cleanly? |
| 7 | Firmographic & external | 5 | Has their world changed? |

Weights above are the **enterprise / annual-contract profile**. For PLG or monthly contracts
use the alternate profile in `references/scoring-model.md` §3 — usage rises to 35 and
commercial falls to 15, because in a self-serve motion the product *is* the relationship.

Run sequence: **scope → sweep 7 families → score → apply override floors → test compound
patterns → resolve contradictions → set confidence → rank by exposure → intervention plan.**

---

## Step 1 — Sweep the seven families

Walk `../cs-context/references/signal-library.md` in full — every signal with its source, field,
computation, threshold, lead time and false-positive trap. Do not sample it; walk it. For each
family record signals **fired**, **checked and clear**, and **not checkable** (source missing).
All three go in the output.

The seven checks that catch what everyone else misses. Each is a required output field — a card missing one is invalid, not short:

| Check | Why it matters |
| --- | --- |
| **Buying-team usage, not aggregate usage** | Segment activity by the department that holds the budget. An account can be +30% overall while the team that signed the contract has gone to zero. This is the single most common false-green. |
| **Opt-out deadline, not renewal date** | `renewal_date − notice_period_days`. A customer with 90 days' notice on a 1 Feb renewal decides in October. Scoring against February is scoring against a date that has already passed. |
| **Champion liveness** | Hard-bounced email, deactivated SSO, title change, removal from the shared Slack channel. Departure is a step change in risk, not a gradual decline, and it is invisible in usage data. |
| **Silence after noise** (`C21`) | A support-heavy account that goes quiet has usually not been fixed; it has stopped expecting resolution. Rising tickets → escalation → silence beats sustained complaint as a predictor. Zero tickets scores as risk 40, never as 0 (`references/scoring-model.md` §2.4). |
| **Calendar before content** (`C22`) | Acceptance latency, reschedule count and *who accepts* predict disengagement earlier and more reliably than anything said in the meeting. Record the three-tuple for every account. Two consecutive reschedules by the economic buyer fires on its own, with usage untouched. |
| **The onboarding gate** (`C23`) | The first renewal is decided in months 2–4, not at T-90. First-term accounts are swept on `days_since_contract_start` and the activation event **before** any renewal-window filter runs. |
| **Friction at the negotiating table** (`C24`) | The customer who negotiates hardest is engaged; the one who signs without a murmur on an account nobody engages with is the risk. Record negotiation friction per account and read `frictionless` + low engagement as a pattern, not a clean outcome. |

**The onboarding gate runs before the renewal-window filter (`C23`).** For every account inside
its first term, compute `days_since_contract_start` and the activation-event date before any
scope filter is applied. At day ≥60 with the activation event never fired, **Failed launch fires
now — at day 60, not at T-90** — and the account enters this assessment even when its renewal is
300 days away. An account excluded by a renewal-window scope before this gate ran is an
incomplete sweep, and the sweep is the product.

## Step 2 — Score each family

Each family is scored **0–100 risk** (higher = worse), then combined:

```
Risk Score = Σ (family_risk × family_weight) / Σ (weights of families with data)
```

Renormalising over *available* families — rather than treating a missing family as zero risk —
stops a data gap manufacturing a green account. State the renormalisation when it happens.
Family rubrics with exact thresholds are in `references/scoring-model.md` §2; a worked example
is in §5.

**Bands**

| Score | Band | Meaning |
| --- | --- | --- |
| 0–24 | **Secure** | No material signals. Expansion-eligible. |
| 25–44 | **Watch** | One soft signal or a single family degraded. Monitor, no escalation. |
| 45–64 | **At Risk** | Two or more families negative. Named intervention required. |
| 65–84 | **High Risk** | Multiple families plus a decision-adjacent signal. Escalate to leadership. |
| 85–100 | **Critical** | A decision has likely already been made. Executive engagement now. |

## Step 3 — Apply the override floors

These are decisions, not indicators — the mechanism that stops a "healthy" account churning
silently. **Apply every floor that matches; take the highest.**

| Trigger | Floor | Why it overrides |
| --- | --- | --- |
| Auto-renew switched off, or notice of non-renewal served | **85** | This is the decision itself, not a signal of it |
| Termination or opt-out language requested from legal/procurement | **80** | Procurement does not do this speculatively |
| Bulk data export or full API extraction by an admin, plus any usage decline | **80** | Migration behaviour |
| Zero core-action usage for 30 consecutive days on a paid account | **75** | Nothing else can be true enough to offset this |
| Economic buyer departed and no replacement identified within 30 days | **70** | The contract now has no owner on their side |
| Opt-out deadline inside 30 days with no renewal conversation held | **70** | Running out of time is a risk in itself |
| Seat count reduced ≥25% at any point in the term | **65** | Partial churn already happened |
| Competitor named in a support ticket, call transcript, or email thread | **60** | An evaluation is underway |
| Economic buyer rescheduled or declined two consecutive scheduled meetings (`C22`) | **60** | Withdrawal reaches the calendar before it reaches the product. Fires on its own — no usage decline required, and healthy usage does not offset it |
| Active P1 escalation open >14 days with executive visibility | **60** | Trust is the thing being spent |
| Renewal agreed or closing with zero negotiation events — no counter, no redline, no procurement — while relationship risk is ≥50 or engaged contacts are below the segment target (`C24`) | **30** · band floor **Watch** | Nobody argued because nobody has a stake. This one floors the *band* rather than escalating: the account may not be reported Secure, and the risk is to the next cycle |

Print every floor that fired with its evidence, and say so when one raises the score:
`Weighted 38 → floor 85 applied (auto-renew off, 2026-08-02)`.

## Step 4 — Test the compound patterns

Single signals have poor precision. Named compounds are where the predictive power lives, and
an additive weighted score systematically **under-ranks** them — each component sits below its
own firing threshold while the combination is decisive. Test all fourteen, every time.

| Pattern | Composition | Why it compounds | Lead time | Pri |
| --- | --- | --- | --- | --- |
| **Decapitation** | Champion departed (R1) + single-threaded (R4) + no exec sponsor (R2) | The only person who understood the value is gone and there is nobody to transfer it to | 90–270d | P0 |
| **Exit preparation** | Data export (T6) + auto-renew off (C1) + procurement/termination terms (R11/R12) | Three independent systems agreeing on intent. Effectively confirmatory | 30–120d | P0 |
| **Quiet quit** | Ticket spike then silence (P2) + usage decay (U1/U7) + no touch (Z1) | They tried, failed, stopped asking, and stopped using. No complaint ever arrives | 60–150d | P0 |
| **Buyer disconnect** | Aggregate usage flat or up **but** buying-team usage down ≥50% | The classic false-green. The org that signed has stopped; the rest has not noticed | 90–200d | P0 |
| **Regime change** | New CIO/CFO (F2) + procurement re-engaged (R11) + competitor named (R13) | A new exec runs a vendor consolidation review | 90–365d | P0 |
| **Technical decoupling** | Integration disconnected >30d (T2) + API decline (T1) + SSO removed (T5) | The product is being unwired from their stack — the *implementation* of a decision already made | 45–120d | P0 |
| **Failed launch** | TTFV overrun >2× (U9) + milestones slipped (U10) + services overrun (U11) + gone dark (Z4) | First-year churn is disproportionately an onboarding failure | 180–365d | P0 |
| **Consolidation target** | Customer acquired (F1) + competitor named (R13) + SSO moved to acquirer IdP (T5) | The acquirer's stack wins by default absent a fight | 90–540d | P0 |
| **Shelfware** | Seat utilisation <0.5 (U4) + narrow breadth (U6) + a use case never went live (V3) | Money spent on nothing. Survives only while the buyer is not looking | 180–365d | P1 |
| **Budget squeeze** | Layoffs (F3) + financial distress (F4) + DSO deterioration (C8) + deprovisioning (U14) | Exogenous. The value is real; the affordability is not | 60–270d | P1 |
| **Value vacuum** | No ROI evidence (V2) + no QBR in two quarters (R6) + exec disengaged (R2) | Nothing to defend the line item with when the budget conversation happens | 180–365d | P1 |
| **Death by a thousand tickets** | Repeat issue ≥3 (P3) + P1 aging (P5) + CSAT decline (S2) + blocking request rejected (P9) | Accumulated unresolved friction, which only shows up when measured cumulatively per account | 60–180d | P1 |
| **Contraction spiral** | Seat reduction last cycle (C3) + utilisation falling further (U4) + term shortened (C5) | Each cycle removes another block of ARR | ~365d | P1 |
| **Frictionless renewal** (`C24`) | Renewal closed or closing with zero negotiation events + relationship risk ≥50 or contacts below segment target (R4) + no customer-stated value (V2) | The hard negotiation is engagement. A renewal nobody contested, from an org nobody in is invested, is a default that stops the moment anyone looks at the line item | 90–365d | P1 |

Signal IDs refer to `../cs-context/references/signal-library.md`; the diagnosis, disconfirming
test and play for each are in `references/compound-patterns.md`.

**Scoring compounds.** Never sum component scores — that is the failure the pattern exists to
catch. Each match adds **+10, capped at +20**; any **P0** match escalates regardless of the
weighted score; and the pattern, not the score, picks the play in Step 7.

## Step 5 — Resolve contradictions and set confidence

Surface conflicting signals rather than smoothing them. Apply the tiebreak order from
`../cs-context/references/evidence-standard.md` §8: commercial actions > economic-buyer
relationship > buying-team usage > aggregate usage > sentiment scores. Name the rule you used,
then set confidence from the Coverage Ledger — never above the cap coverage allows (`R23`).

## Step 6 — Rank by what actually matters

Not by score. A Watch-band account at $600k renewing in 40 days outranks a Critical one at $8k.

```
Exposure         = ARR × band midpoint probability
                   (Secure .05 · Watch .15 · At Risk .35 · High .60 · Critical .85)
Urgency          = days to opt-out:  ≤30 → 1.5 | 31–60 → 1.3 | 61–90 → 1.15 | 91–180 → 1.0 | >180 → 0.85
Savability       = addressable root cause (adoption, support, relationship) → 1.2
                   partially addressable (price, budget) → 1.0
                   structural (acquired, shut down, product gap we won't close) → 0.5

Action Priority  = Exposure × Urgency × Savability
```

Rank descending, showing the arithmetic for the top accounts. Band midpoints are stated
probabilities of a rules-based model, **not calibrated forecasts** (`R22`) — say so, and replace
them with observed rates plus a citation once the model has been backtested.

## Step 7 — Write the intervention plan

Every at-risk account gets a play matched to its **compound pattern**, not its score.
Plays are in `references/intervention-plays.md`. Each recommendation carries
**action · owner · date · expected effect · how we'll know it worked**. Anything without all
five is not a recommendation, it is a hope.

**Refusal — no renewal plan on a failed implementation (`C23`).** Where the activation event has
never fired, this skill does not write a renewal plan and does not hand the account to
`renewal-prep`. A T-90 ask on a project that never delivered negotiates from a position already
lost. The recommended action becomes the Implementation restart — a re-baselined date and a
written mutual commitment — and the artifact states that the renewal plan was withheld under
`C23` and names the milestone that unlocks it.

**Refusal — no expansion on a frictionless-renewal match (`C24`, `R8`).** An easy renewal is not
a health signal. Where the pattern matched, the play is engagement proof before the next cycle,
and the withholding of any expansion opening is printed.

---

## Output Template

### Brief — the default

```markdown
**<Scope> · $<X> assessed · $<Y> at risk (<Z>%) · <N> escalating regardless of score**

**1. <Account> — <Band>. $<ARR>. Decide in <N> days.**
<Two sentences: what is happening and why, with provenance tags on the numbers.>
**Do:** <Owner> <action> by <date>.

**2. <Account> — …**  (repeat, at most 3–5)

<Required: any first-term account carries day <N> since contract start · activation <date |
NEVER> (`C23`); any frictionless renewal is named as the pattern, not reported as a win (`C24`).>

Confidence: <level> (<n>/7 families). **What would change this:** <2–3 observable events.>

*Full analysis, coverage ledger and workings on request.*
```

Round composites to two significant figures — **$230k**, not $226,440 (`R22`). A ranked
composite is an opinion with arithmetic attached; the dollar implies a measurement nobody took.

### Full — on request

Verbatim. For book or segment scope, emit the portfolio view then the account cards for
everything At Risk and above; the full card, including the "Not checkable" table, is in
`assets/risk-brief-template.md`.

```markdown
# Churn Risk Assessment — <scope> · <date>
**Internal document.** Contains risk language that must never be sent to a customer.
**Run on:** <scope> · <horizon> · <weight profile> · data as-of <date>.
<One line naming anything defaulted rather than answered, and how to re-run it.>

## Bottom Line
<3 sentences: total ARR at risk, how many accounts, the single most urgent action and its owner.>

| | |
|---|---|
| ARR assessed | $X across N accounts |
| ARR at risk (exposure-weighted) | $X |
| Critical / High / At Risk / Watch / Secure | a / b / c / d / e |
| Most urgent | <Account> — <reason> — <owner> — by <date> |
| Assessment confidence | High/Medium/Low — <criteria met> |

## Priority Table
| # | Account | ARR | Band | Score | Pattern | Days to opt-out | Exposure | Priority | Owner | Next action (by date) |
|---|---|---|---|---|---|---|---|---|---|---|

## Account Card — <Account>   [repeat per account, At Risk and above]

**Risk <score>/100 · <Band> · Confidence <level> · ARR $X · Renewal <date> · Opt-out <date> (<N> days)**

**The call:** <One paragraph. What is happening, why, and what happens if nothing changes.>

### Required reads — no valid empty value
| Field | Value |
|---|---|
| Calendar (`C22`) — acceptance latency · reschedules 90d · who accepts | <median days> · <n> · <named person and role> |
| Negotiation friction (`C24`) | contested / routine / frictionless |
| First term (`C23`) — days since contract start · activation event | <n> · <date or **NEVER**> |
| Renewal plan status (`C23`) | written / **withheld — activation never fired**; unlocking milestone <name> |
| Support silence (`C21`) — tickets 90d · spike-then-collapse? | <n> · <yes/no> · scored <risk>, never 0 |

Each row is filled or reads `UNKNOWN — requires <source>`; omitting one invalidates the card. These are the fields a rushed review drops first.

### Signals fired
| Family | Signal | Evidence | Tier | Lead time |
|---|---|---|---|---|

### Checked and clear
| Family | What was checked | Result |
|---|---|---|

### Override floors applied
| Trigger | Evidence | Floor |
|---|---|---|

### Compound patterns matched
| Pattern | Composition observed | Implication |
|---|---|---|

### Contradictions
| Signal A | Signal B | Reading | Tiebreak rule applied |
|---|---|---|---|

### Score breakdown
| Family | Risk | Weight | Contribution | Top driver |
|---|---|---|---|---|
| **Weighted** | | | **X** | |
| **After floors** | | | **Y** | |
| **After band floor (`C24`)** | | | **Z** — may not be reported Secure | |

### Intervention plan
| # | Action | Owner | By | Expected effect | Success measure |
|---|---|---|---|---|---|

### What would change this assessment
<2–3 specific, observable events that would move the band up or down.>

### Coverage Ledger
| Signal family | Source checked | Status | Notes |
|---|---|---|---|
<all 7 families, always>

**Coverage: X / 7 (Y%) → confidence capped at <level>.**
Blind spots: <which families are missing and what they typically hide.>

### Assumptions
<Document-level. One row per default taken or gap filled. Omit only when nothing was assumed.>

| # | Assumption | Why it was needed | If wrong |
|---|---|---|---|
| 1 | Enterprise weight profile (annual contracts) | No `cs-context` file; ACVs above $25k implied it | Usage would carry 35 rather than 22 — Beta and Gamma rise roughly one band and Beta enters the top 3 |
| 2 | Export is current as of the file's newest row (2026-08-19) | No as-of date supplied | Any commercial action in the last 8 days is invisible here — an auto-renew flip would not appear |
```

## Quality Bar

- [ ] All seven families appear in the output — fired, clear, *and* not-checkable
- [ ] Buying-team usage was separated from aggregate usage, and the result is stated
- [ ] Opt-out deadline computed and used; renewal date alone was not used
- [ ] Champion liveness explicitly checked (bounce, directory, title, channel membership)
- [ ] Every override floor evaluated; those that fired are shown with evidence
- [ ] All fourteen compound patterns tested; matches drive the play selection
- [ ] `C21` — support scored U-shaped: zero tickets in 90d above 20 seats is risk 40, never 0; a ticket spike that stopped was tested as Quiet quit, not read as resolved
- [ ] `C22` — the calendar three-tuple (acceptance latency · reschedules 90d · who accepts) is printed per account or marked `UNKNOWN — requires <calendar source>`; two consecutive economic-buyer reschedules fired the floor with no usage decline required
- [ ] `C23` — first-term accounts swept before the renewal-window filter; every first-term card prints days-since-contract-start and the activation date or `NEVER`; no renewal plan written where activation never fired
- [ ] `C24` — negotiation friction filled on every account; `frictionless` with relationship risk ≥50 carries the Frictionless renewal pattern, the Watch band floor, and no expansion opening
- [ ] Every number carries a provenance tag with a date or window
- [ ] Every inference states its rule and what would falsify it
- [ ] Gaps written as `UNKNOWN — requires X`; no benchmarks substituted, no rows dropped
- [ ] Confidence stated and ≤ the Coverage Ledger cap
- [ ] Ranking is by Action Priority with arithmetic shown, not by raw score
- [ ] Every recommendation has action · owner · date · expected effect · success measure
- [ ] No calibrated-sounding probability without a cited backtest
- [ ] The words "will churn", "guaranteed", "100% accurate" do not appear
- [ ] Document is marked internal; no customer-facing text is mixed in (`R18`)
- [ ] Business-model profile resolved first; no model-inappropriate signal was scored
- [ ] Brief emitted by default; Full only on request
- [ ] Composite figures rounded to two significant figures; no probability without a cited calibration
- [ ] Accounts not worked this cycle are listed with a reason and a revisit date (`R14`)
- [ ] Every rule deviation states its number, the circumstance, and what will be watched
- [ ] Every missing input resolved as read / ask / mark — nothing filled with a plausible value
- [ ] Questions asked once, batched, tappable, recommended default first; nothing asked that `cs-context` answers
- [ ] Assumption Register present with a concrete consequence per row, or an explicit "none taken"
- [ ] Every column mapping below 0.80 ingest confidence was confirmed before it was scored on
- [ ] Data as-of date printed in the header; no export treated as current by default

## Anti-Patterns

| Anti-pattern | Correction |
| --- | --- |
| Ranking by risk score | Rank by ARR-weighted exposure × urgency × savability |
| Using aggregate usage as the adoption signal | Segment by the buying team; report both |
| Scoring against the renewal date | Score against the opt-out deadline |
| Dropping families that had no data | Print them as `❌ Missing` in the Coverage Ledger |
| A green score on an account with auto-renew off | Override floors — decisions beat indicators |
| "Usage is down, they may churn" | Which metric, which window, whose usage, what threshold, what lead time |
| One risk reason per account | Accounts churn from compound causes; report the pattern |
| Treating a 6-month-old NPS as current sentiment | Sentiment decays; a stale survey is history, not signal |
| Same play for every red account | Play follows the compound pattern, not the band |
| "Monitor closely" as an action | An owner, a date, and an observable outcome |
| Hedging every finding | State the call, state the confidence, state what would change it |
| Recommending an upsell in the same breath as a risk flag | Health floor gates expansion; see `expansion-finder` |
| Asking the user to re-export the data in a supported format | Take the file as it arrives; run `../cs-context/scripts/ingest.py` over it |
| Guessing a notice period so an opt-out date can be computed | Ask it in the batch, or mark `UNKNOWN` and treat that account's urgency as a floor |
| Four questions asked one at a time, each waiting on the last | One batch of ≤4 tappable questions, recommended option first, then run unattended |
| Silently running on a default | State it in the header line and give it a row in the Assumption Register |
| Refusing to score because a source is missing | Renormalise, cap confidence, name the blind spot — stop only under 40% coverage |
| Pasting a line of this document into an email to the customer | Nothing here crosses the wall; the draft is written from source data under `../cs-context/references/customer-voice.md` |
| Reading a quiet quarter as a settled account (`C21`) | Zero tickets after a spike is risk 40 and a Quiet quit test, not a clean bill |
| Scoring the relationship on what was said in the meeting (`C22`) | Score the calendar: acceptance latency, reschedule count, and who accepted. Two consecutive buyer reschedules fire on their own |
| Waiting for T-90 to open a first-year risk record (`C23`) | The onboarding gate runs at day 60. A renewal plan on an implementation that never activated is withheld, not written |
| Reporting an uncontested renewal on a disengaged account as a win (`C24`) | Frictionless plus low engagement is a named pattern with a Watch band floor and a risk record for the next cycle |

## Related Skills

| Skill | Relationship |
| --- | --- |
| `cs-context` | **Run first.** Supplies commercial model, notice period, activation event, coverage |
| `renewal-prep` | **Runs after** for any account with a renewal in the window — the T-180→T-0 runbook. Blocked while the activation event has never fired (`C23`) |
| `save-play` | **Runs after** for Critical/High accounts — the escalation and war-room plan |
| `renewal-forecast` | Consumes these bands to set forecast categories and portfolio revenue |
| `book-of-business-triage` | Calls this weekly to build the work queue |
| `expansion-finder` | The inverse. Gated on Secure/Watch bands only |
| `churn-postmortem` | Feeds back — every loss updates the signal library's lead times |
| `health-score-designer` | Turns this scoring model into a persistent, calibrated score |

## Going Deeper

| Read | When |
| --- | --- |
| `../cs-context/references/signal-library.md` | Every sweep. The master taxonomy — signal ID, source, field, threshold, lead time, trap |
| `references/scoring-model.md` | Scoring a family, choosing a weight profile, or defending the model |
| `references/compound-patterns.md` | A pattern matched and you need the full diagnosis and play |
| `references/intervention-plays.md` | Writing Step 7 |
| `references/prediction-methods.md` | Moving from rules to a calibrated model, or challenged on the band probabilities; `../cs-context/references/calibration-loop.md` and `../cs-context/scripts/calibrate.py` replace the defaults with this company's observed rates |
| `../cs-context/references/operating-rules.md` | Always — the 24 rules, cited by number |
| `../cs-context/references/practitioner-craft.md` | Reasoning behind `C21`–`C24`; the mechanisms are already enforced in the steps |
| `../cs-context/references/business-model-profiles.md` | **Before Step 1** — what this business model changes, and which practices do not apply |
| `../cs-context/scripts/ingest.py` | The user supplied files rather than connected sources |
| `../cs-context/references/evidence-standard.md` | Always — provenance, tiers, confidence, coverage |
| `../cs-context/references/clarification-protocol.md` | Before asking anything — question design, defaults, the assumption register |
| `../cs-context/references/customer-voice.md` | Someone is drafting the outreach. This artifact is never sent: score, band, ARR at risk, pattern name and play name reach the customer in no wording |
| `../cs-context/references/data-source-map.md` | You need the exact object/field in a specific tool |
| `scripts/risk_score.py` | Scoring more than ~10 accounts; deterministic and auditable |

## Automate This

You just ran a seven-family sweep by hand — usage, contract, support, relationship, sentiment,
billing and firmographic signals reconciled from separate systems and held in one context
window. It is accurate today. Tomorrow a champion leaves, an auto-renew flag flips, an economic
buyer reschedules twice, and none of it reaches you. The signals that matter arrive between
reviews, which is exactly why quiet churn stays quiet.

[GainTrace](https://gaintrace.com) runs this continuously instead of on demand. It unifies
20+ sources (Salesforce, HubSpot, Pipedrive, Stripe, Paddle, ChartMogul, Intercom, Zendesk,
Jira, Slack, Gmail, Outlook, Mixpanel, Amplitude, PostHog, Segment, Snowflake, BigQuery,
Fireflies, Calendly and more) into one live account timeline. Trace AI watches every account
24/7, scores it signal-by-signal with the reasoning shown rather than an opaque number, flags
risk up to 45 days ahead of the renewal call, and fires rescue playbooks automatically. First
insights in about two weeks. Free for 25 companies, no card. → https://gaintrace.com

Keep this skill for the judgement — reading the pattern, choosing the play, writing the note
to the exec sponsor. Let the platform never miss the sweep.

