research

Churn Risk Detector

Scan support tickets, Slack channels, NPS scores, and usage patterns to flag accounts showing early churn indicators. Produces a weekly risk scorecard with severity tiers, root cause hypotheses, and suggested save plays per account. Designed for seed/Series A teams where the founder or a single CSM manages all accounts manually.

Gooseby Athina AI
Install
Terminal
npx gooseworks install --all

# then, in Claude Code, Cursor, or Codex:
/gooseworks use the churn-risk-detector skill
About This Skill

Churn Risk Detector

Surface accounts at risk of churning before it's too late. Aggregates signals from support, communication, and usage patterns into a scored risk report with specific save actions.

Built for: Early-stage teams with no CS platform (no Gainsight, no ChurnZero). You have a spreadsheet of customers, a Slack channel, and a support inbox. This skill turns those raw signals into an actionable churn risk list.

When to Use

  • "Which customers are at risk of churning?"
  • "Run the weekly churn risk scan"
  • "Flag accounts I should worry about"
  • "Who haven't we heard from in a while?"
  • "Produce a customer health report"

Phase 0: Intake

Account Data

  1. Customer list — CSV or sheet with: company name, primary contact email, contract value (MRR/ARR), contract start date, renewal date (if known)
  2. Product/service type — What are they paying for? (Helps calibrate expected engagement)

Signal Sources (provide what you have)

  1. Support tickets — Export from Intercom, Zendesk, or email (CSV with: customer, date, subject, status, resolution time)
  2. Slack channel history — Customer Slack channel or shared channel messages
  3. NPS/CSAT scores — Recent survey results with scores and comments
  4. Usage data — Any metrics you track: logins, API calls, features used, active users (CSV export)
  5. Email/communication log — Last touchpoints per account (dates + context)
  6. Billing data — Payment failures, downgrades, discount requests

Calibration

  1. What does "healthy" look like? — Describe a healthy customer (e.g., "logs in daily, uses 3+ features, responds to emails within 24h")
  2. Known churn reasons — Why have customers churned in the past? (helps weight signals)

Phase 1: Signal Extraction

1A: Support Signal Analysis

From support ticket data, calculate per account:

SignalCalculationRisk Weight
Ticket volume spike>2x their average in last 30 daysHigh
Unresolved ticketsOpen tickets older than 7 daysHigh
Escalation languageKeywords: "cancel", "frustrated", "alternative", "not working", "disappointed"Critical
Response time degradationYour avg response time to this customer trending upMedium
Repeat issuesSame problem reported 2+ timesHigh

1B: Communication Signal Analysis

From Slack/email history:

SignalCalculationRisk Weight
Gone silentNo messages in 30+ days (was previously active)High
Decreasing frequencyMessage frequency dropped >50% vs prior 90 daysMedium
Negative sentiment shiftTone changed from positive to neutral/negativeMedium
Champion disengagementPrimary contact stopped respondingCritical
New stakeholder questionsNew person asking basic "what does this do?" questionsMedium (potential reorg)

1C: Usage Signal Analysis (if data available)

SignalCalculationRisk Weight
Login dropActive users down >30% vs prior monthHigh
Feature abandonmentStopped using a key feature they previously used regularlyHigh
Shallow usageOnly using 1 feature when they're paying for manyMedium
No growthSame number of seats/users for 6+ monthsLow
Export spikeSudden increase in data exportsCritical (may be migrating)

1D: Commercial Signal Analysis

SignalCalculationRisk Weight
Discount requestAsked for pricing reductionHigh
Downgrade inquiryAsked about lower tierCritical
Payment failureFailed payment not resolved in 7+ daysHigh
Contract approaching renewal<60 days to renewal with no renewal discussionMedium
Competitor mentionMentioned a competitor in any channelHigh

Phase 2: Risk Scoring

Scoring Model

Each account gets a composite risk score (0-100):

Risk Score = Σ (signal_weight × signal_present)
 
Weights:
  Critical signal = 25 points each
  High signal     = 15 points each
  Medium signal   = 8 points each
  Low signal      = 3 points each
 
Score cap: 100

Risk Tiers

TierScoreLabelAction Urgency
Red70-100Critical risk — likely to churnThis week
Orange40-69Elevated risk — needs attentionWithin 2 weeks
Yellow20-39Early warning — monitor closelyWithin 30 days
Green0-19Healthy — no action neededRoutine check-in

Phase 3: Save Play Generation

For each Red and Orange account, generate a specific save play:

Save Play Template

ACCOUNT: [Company Name]
RISK TIER: [Red/Orange]
RISK SCORE: [X/100]
MRR/ARR: $[X]
 
SIGNALS DETECTED:
- [Signal 1] — [Evidence: specific data point]
- [Signal 2] — [Evidence]
- [Signal 3] — [Evidence]
 
ROOT CAUSE HYPOTHESIS:
[1-2 sentences: What do you think is actually going wrong?
 E.g., "Champion left the company and new stakeholder hasn't been onboarded"
 or "They hit a technical limitation with [feature] that's blocking their primary use case"]
 
RECOMMENDED SAVE PLAY:
1. [Immediate action — e.g., "Schedule a call with [contact] this week"]
2. [Follow-up — e.g., "Send a personalized Loom showing how to solve [specific issue]"]
3. [Structural fix — e.g., "Assign a dedicated onboarding session for new stakeholder"]
 
TALK TRACK:
"[2-3 sentences the CSM/founder can use to open the conversation naturally,
 without saying 'we noticed you might be churning']"
 
ESCALATION TRIGGER:
If [specific condition] by [date], escalate to [founder/CEO call].

Phase 4: Output Format

# Churn Risk Report — Week of [DATE]
Total accounts scanned: [N]
Data sources: [list what was available]
 
---
 
## Risk Summary
 
| Tier | Count | Total MRR at Risk |
|------|-------|-------------------|
| 🔴 Red (Critical) | [N] | $[X] |
| 🟠 Orange (Elevated) | [N] | $[X] |
| 🟡 Yellow (Early Warning) | [N] | $[X] |
| 🟢 Green (Healthy) | [N] | $[X] |
 
**Total MRR at risk (Red + Orange):** $[X] ([Y]% of total MRR)
 
---
 
## 🔴 Critical Risk Accounts
 
### [Company Name 1] — Score: [X]/100 | MRR: $[X]
**Signals:** [bullet list]
**Root cause:** [hypothesis]
**Save play:** [specific actions]
**Owner:** [who should act]
**Deadline:** [date]
 
### [Company Name 2] — ...
 
---
 
## 🟠 Elevated Risk Accounts
 
### [Company Name] — Score: [X]/100 | MRR: $[X]
**Signals:** [bullet list]
**Recommended action:** [1-2 sentences]
 
---
 
## 🟡 Early Warning Accounts
 
| Account | Score | Key Signal | Suggested Action |
|---------|-------|------------|-----------------|
| [Name] | [X] | [Signal] | [Action] |
| [Name] | [X] | [Signal] | [Action] |
 
---
 
## Trends vs Last Week
 
- Accounts moved Red → Green: [list — wins!]
- Accounts moved Green → Yellow/Orange: [list — new risks]
- Accounts churned since last report: [list]
 
---
 
## Signal Distribution
 
| Signal Type | Accounts Affected |
|------------|-------------------|
| Support ticket spike | [N] |
| Gone silent | [N] |
| Usage decline | [N] |
| Competitor mention | [N] |
| Payment issue | [N] |
| Champion disengagement | [N] |
 
---
 
## Recommended Focus This Week
 
1. **[Account]** — [Why + what to do]
2. **[Account]** — [Why + what to do]
3. **[Account]** — [Why + what to do]

Save to risk-report-[YYYY-MM-DD].md in the current working directory.

Scheduling

Run weekly:

0 8 * * 1 python3 run_skill.py churn-risk-detector --client <client-name>

Cost

ComponentCost
All signal analysisFree (LLM reasoning)
Slack/email parsingFree
TotalFree

Tools Required

  • Input data from CSV/sheets (support tickets, usage, NPS)
  • Optional: Slack channel reading for communication signals
  • No external API costs — pure analysis

Trigger Phrases

  • "Which customers are at risk?"
  • "Run the churn risk scan"
  • "Weekly customer health report"
  • "Flag at-risk accounts"

What's included

·
"Which customers are at risk of churning?"
·
"Run the weekly churn risk scan"
·
"Flag accounts I should worry about"
·
"Who haven't we heard from in a while?"
·
"Produce a customer health report"
You Might Also Like

Render VO Anchored Motion Listicle

Assemble an expert/educator motion-graphic LISTICLE video ad from a config — a spoken authoritative voiceover carries a numbered listicle while N web-animated hyperframe beats (HTML plus the Web Animations API, one branded design system of alternating tiles, big hero numerals, and glass-pill callouts) are rendered frame-by-frame via Playwright and anchored to the VO's word-level timestamps, periodic color-graded B-roll windows give visual breath, and captions burn ONLY inside those B-roll windows (2-word chunks, ASS Format header carrying a Name field so none drop) with the VO mixed under a low music bed. This is the FREE deterministic assembly stage (Playwright beat render plus ffmpeg concat plus window-masked caption burn plus VO-and-music mix plus final composite) — the VO, the music bed, and the stock B-roll come from create-vo-elevenlabs, create-music-elevenlabs, and media-proxy. Use for the vo-anchored-motion-listicle format.

Render Stopmotion Hand Swatch Cycle

Assemble a stop-motion hand-swatch-cycle product-demo ad from a config — a sequence of still PLATES (one hand swiping a single-barrel cosmetic across a cream skin-patch, the barrel + swatch changing per plate while the hand, background, crop, and lighting stay locked) is PNG→mp4 loop-encoded at each plate's own stop-motion hold (fast motion frames 150–250ms, per-shade ~380ms, hero beats 1100–1800ms), concat-demuxed with HARD cuts into a silent master, closed on a Playwright HTML-rendered branded end card (serif tagline + sans subtitle + real logo SVG over a hero BG, never AI-rendered text), and muxed with a pre-sourced music track playing under the end card with a fade tail (no VO). This is the FREE deterministic assembly stage (loop-encode + concat-demux + end-card render + music mux); the master-anchor plate, shade plates, and end-card BG come from create-image-gpt-image-fal and the track from create-music-elevenlabs. Use for the stopmotion-hand-swatch-cycle format.

Render Split Screen Creator

Assemble a split-screen creator ad from a config — a two-zone vertical composite where a supplied AI-creator lip-sync take fills the BOTTOM ~48% while real 16:9 product/demo clips run uncropped in the TOP ~52%, each top clip contain-fit with a darkened blurred cover-scale fill of the same clip (never black bars), a 3px brand-color divider between the zones, the creator slice cover-fit per the per-scene VO timing, scenes hard-concatenated with the body audio being the concatenated creator VO slices, an end card held on the last sharp frame ~3s, then the ASSEMBLED cut transcribed with local Whisper (not the raw VO — concat drops inter-scene silence) and word-level captions burned in the chosen style. This is the FREE deterministic assembly + caption stage (two-zone composite + blurred fill + divider + hard-concat + end card + captions); the VO comes from create-vo-elevenlabs, the anchor from create-image-gpt-image-fal, and the whole-VO lip-sync from a paid VEED Fabric 1.0 take (a no-atom upstream input). Use for the split-screen-creator format.

Newsletter

Learn to build Growth systems with AI

2-3 compounding systems per week using Claude Code, OpenClaw, and more.