{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/churn-risk",
  "slug": "adapters/domain/churn-risk",
  "kind": "capabilities",
  "bucket": "package",
  "title": "churn-risk",
  "name": "Churn Risk",
  "eyebrow": null,
  "chip": null,
  "summary": "Customer churn-risk and account-health scoring for SaaS retention & customer-success teams: score turns a bundle of usage/engagement/support/billing signals (login recency, usage trend, feature...",
  "keywords": [
    "churn-risk",
    "customer-success",
    "adoption",
    "utilization",
    "tickets",
    "per-signal",
    "contributions",
    "protective"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# churn-risk\n\nAn intelligent microservice adapter pack that scores customer churn risk and account health for SaaS\nretention / customer-success teams. The weighted-signal scoring engine is deterministic and runs fully\noffline. Only the optional \"save narrative\" on `score` (with `options.narrate`) uses the shared LLM\nhelper, and it silently falls back to a templated recommendation offline. Hybrid results are tagged\n`{ mode: 'heuristic' | 'llm' }` — the score is always exact regardless of mode.\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `score` | Turns a bundle of `signals` into a 0-100 risk score, a band (low/moderate/high/critical) and per-signal contributions. **Optional LLM narrative.** |\n| `drivers` | Ranks the top risk factors and the protective factors behind the score. |\n| `segment` | Buckets the account into a lifecycle segment (champion / healthy / passive / at-risk / dormant / likely-churn) with a recommended play. |\n| `healthScore` | Inverse 0-100 health index with an A–F grade and status. |\n| `cohortRisk` | Aggregates many `accounts` into a cohort distribution, at-risk MRR, expected revenue loss and the highest-risk accounts. |\n| `renewalLikelihood` | Estimates the probability the account renews and an expected renewal note. |\n\n## Signals\n\nAll optional — provide any subset; missing signals are dropped and the weights re-normalize:\n\n```\ndaysSinceLogin, usageTrend (-1..1 or %), featureAdoption (0-1), seatUtilization (0-1),\nnps (0-10), sentiment (-1..1), supportTickets, openBugs, paymentFailures,\ndaysToRenewal, monthsTenure, mrr\n```\n\n## Usage\n\n```js\nimport pack from './index.js';\n\nconst signals = { daysSinceLogin: 21, usageTrend: -0.4, nps: 5, featureAdoption: 0.3, paymentFailures: 1, daysToRenewal: 25 };\n\nawait pack.adapters.score({ signals });          // { riskScore, band, contributions, ... }\npack.adapters.drivers({ signals });              // top risk + protective factors\npack.adapters.segment({ signals });              // lifecycle segment + play\npack.adapters.healthScore({ signals });          // health index + grade\npack.adapters.renewalLikelihood({ signals });    // renewal probability\n\npack.adapters.cohortRisk({ accounts: [ { id: 'A', mrr: 500, signals }, { id: 'B', mrr: 1200, signals: { nps: 9, usageTrend: 0.2 } } ] });\n```\n\nCustom `weights` (per-signal importance) can override the defaults for any tool.\n\n## DRY boundary notes\n\n- Not generic stats: `numbers` / `statistics` provide series primitives; this pack encodes the\n  retention scoring model, lifecycle segments and recommended plays on top of the domain signals.\n- Not billing/finance: it consumes MRR/payment signals but does no invoicing or interest math\n  (`invoice` / `finance` own those).\n- Self-contained: no cross-pack imports except `../_shared/llm.js`.\n",
  "source": {
    "path": "shared/engines/adapters/domain/churn-risk/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 3006,
    "hash": "e8054dfc736e48dea8b095be9e76565d4db5ca26"
  },
  "urls": {
    "html": "/p/adapters/domain/churn-risk",
    "json": "/docs/adapters/domain/churn-risk.json",
    "md": "/docs/adapters/domain/churn-risk.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
