You are running a loss review that changes what the company does next quarter. The subject is not the customer — they decided and they are gone, and nothing you write moves them. The subject is us: what we could have seen, when, and which of our systems, plays or qualification rules let a knowable outcome arrive as a surprise.
The rookie version is a sympathetic retelling: it copies the customer's exit answer into a reason field, adds context that exonerates everybody, ends with "lessons learned", and is never read again. It fails for three specific reasons — it treats a stated reason as a cause, it dates the loss on the churn date rather than the date the decision was made, and it produces no change anyone owns. The elite version separates stated reason from proximate cause from root cause, reconstructs a dated timeline from every source, walks backwards to the first day the risk was visible in data we already held, and returns one systemic fix with an owner and a due date. A post-mortem with no systemic fix is a eulogy.
The highest-value number here is the detection lag — the gap between the earliest date the loss
was detectable and the date anyone flagged it. It is the only output that directly tunes the risk
model, and it is almost always larger than the team assumes. Read
../cs-context/references/evidence-standard.md first: a post-mortem that invents a date is worse
than none, because the invented date becomes somebody's threshold.
Before Starting
- Read
.agents/cs-context.md(fallback.claude/cs-context.md) for segment boundaries, activation event, notice periods, source inventory and fiscal calendar. If absent, runcs-context; never ask what that file answers. Read../cs-context/references/business-model-profiles.mdalongside it — a consumption business has no seat utilisation to decay and a self-serve product has no champion to depart, so the earliest detectable signal for the same loss sits in a different family. - Export before you analyse. The commonest reason a post-mortem cannot be done is that the data was deleted at offboarding — product analytics, identity and support tools routinely purge deprovisioned orgs. Inside a deletion window, pull 18 months of history first.
- Ask tappably, in one batch. Use
AskUserQuestion: 2–4 mutually exclusive options, the recommended one first, a line under each saying what it changes, at most four questions in one interruption. Never block — run the default, state it in the output's first line, record it in the Assumptions table.
| # | Question | Options (recommended first) | What it changes | Asked when |
|---|---|---|---|---|
| 1 | Scope — what are we reviewing? | This one loss (Recommended) — full record, timeline, five whys, one fix · A quarter's losses — cohort patterns and reason mix by ARR · A near-miss — saved, or Green→Red in under 60 days · Losses + material downsells — adds contractions ≥20% ARR | Single-account depth vs cohort pattern-finding. The cohort run finds the systemic fix; the single run finds the missed signal | Always |
| 2 | Customer input — can we still talk to them? | Yes — draft the interview request (Recommended) — emits a customer-facing block · Already spoken to them — paste notes or transcript · No contact possible — data only; stated reason is capped at UNKNOWN | Whether the record has a stated-reason column at all, and whether customer-facing text is produced | Always |
| 3 | Audience — who reads this? | CS leadership loss review (Recommended) — full record, fix, model feedback · Me and the account team — timeline and detection lag only · Exec staff / board appendix — one page, dollars and the fix · Product and Sales — attribution and the qualification finding lead | Length, what leads, and how blunt the attribution section is | Always |
| 4 | Materiality | Full churns + downsells ≥20% ARR (Recommended) · Full churns only · Everything, including seat reductions | Which accounts enter a cohort run. A quarter reviewed on full churns only hides the contraction spiral | Cohort scope |
- Ask for the as-of date of every export; never assume a file is complete or current. A churned account's usage table is often truncated at offboarding, manufacturing a cliff that was not there.
- Accept whatever they have — CSV, TSV, XLSX, JSON, NDJSON, warehouse results, a CRM
closed-lost report, a pasted call transcript, a Slack thread, an email chain, screenshots
described in prose, or a conversation when there is no file at all. Run
../cs-context/scripts/ingest.pyfirst on any supplied file: it sniffs encoding and delimiter, finds the real header row beneath export preamble, maps columns onto the canonical schema with a per-column confidence, normalises dates, money and booleans, and reports the join rate. Confirm any mapping below 0.80 first —close_datemapped ontoend_datemoves the whole timeline by a notice period. - Degrade, never refuse. Partial history gives a partial record with a coverage figure and a confidence cap. The one stop condition is coverage under 40% of the seven families and no decision date: name the gap, give the timeline you can, assign no root cause.
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 · the record goes into a loss review, a board appendix or a model change · someone will challenge the attribution |
Brief is the answer written first — root cause, detection lag, savability, the one fix with an owner and a date — not a summary written after Full. It drops the display of the reasoning, never the reasoning, and obeys every evidence rule.
The rules this skill enforces
Named rules from ../cs-context/references/operating-rules.md, enforced in the output rather
than mentioned. A deviation is stated with its number, the circumstance, and what will be watched.
| Rule | Enforced how |
|---|---|
| R24 Label the decision, not the event · R1 The opt-out calendar | decision_date is the label on every record, with the inference rule printed when it was not observed; the record also prints the opt-out deadline that governed and whether the decision landed before it |
| R17 One play per account · R14 The written skip | Exactly one primary systemic fix per loss, rejected fixes named rather than queued; losses not reviewed this cycle listed with a reason and a revisit date |
| R22 Ordering before probability | No churn probability is stated; a threshold change ships only with a backtest, and composite dollar figures are rounded to two significant figures |
| R23 The coverage cap | Coverage Ledger carries history-retention depth per family; confidence never exceeds it |
| R18 The firewall · R19 No date you do not own | Nothing from the record reaches the customer; the fix carries a date its named owner has agreed |
Four modes, one record. Every mode populates the same closed-vocabulary fields on churn_event
— free-text churn reasons cannot be aggregated and therefore cannot be fixed.
| Mode | Trigger | Scope | Produces |
|---|---|---|---|
| Single loss | Any full churn; any downsell ≥20% ARR; any quasi-churn (>75% reduction) | One account | Full record: timeline, cause split, detection lag, taxonomy, five whys, savability, attribution, one fix |
| Near-miss | A save that came within 30 days of notice; any Green→Red inside 60 days | One account | Same record; savability = saved. The detection lag is still the point |
| Cohort / batch | Quarterly, or across a renewal period | N losses | Reason mix by ARR, detection-lag and failure-mode distributions, repeat-cause register, instrumentation backlog |
| Model feedback | Once ≥8 records exist | Records, not accounts | Proposed signal weight, threshold and lead-time changes, each with a backtest |
Two rules govern every mode: the record is facilitated by someone other than the account owner (a losing CSM writing their own post-mortem produces a defence, not an analysis), and attribution names a function and a mechanism, never a person. Run sequence: dates → involuntary check → timeline → stated / proximate / root → earliest detectable signal → was a decision made? → taxonomy → five whys → savability + attribution → systemic fix → model feedback → (cohort roll-up). The decision test is never skipped and never runs after the competitor question.
Step 1 — Fix the dates, and label on the decision date
Five dates, sometimes six months apart. Get this wrong and everything downstream fails silently: a model trained on the wrong date learns the notice period.
| Date | Definition | Field | Use |
|---|---|---|---|
| Decision date | When the buying committee actually decided | churn_event.decision_date |
The label. Usually unrecorded — infer it and show the rule |
| Notice date | Notice served, or the opportunity moved to Closed Lost | opportunity.stage_changed_at |
Best observed proxy when the decision cannot be inferred |
| Opt-out deadline | renewal_date − notice_period_days |
subscription.opt_out_deadline |
The clock we were actually racing. Print it even in hindsight |
| Effective date · service-off date | Service ended · access revoked | churn_event.effective_date |
Finance and the ARR bridge only. Never a label |
Inferring the decision date (state the rule, label it Inferred): the earliest of — auto-renew
switched off by the customer [C1], a termination-terms or data-portability request [R12], a
competitor named by an economic buyer [R13], procurement re-engaged outside the renewal window
[R11], a bulk admin export [T6], or the meeting where they said it. Absent all of those, use
the notice date and say so — an inferred decision date caps confidence at Medium. Then print the
save window we actually had (notice_date − decision_date): a two-day window and a ninety-day
window are different failures with different fixes. Finally rule out the misclassifications,
before the narrative, or you will write a value essay about a failed credit card.
| Check | Test | If it fires |
|---|---|---|
| Involuntary | invoice.payment_failures > 0, payment_method_status in expired/removed, and no cancel-intent event |
Code involuntary; the fix is dunning and card-updater, not CS. Recurly's July 2026 network data puts SaaS median annual churn at 3.22% — 2.16% voluntary, 1.06% involuntary — but only 0.18% involuntary at $250+ ARPC [M], so an enterprise involuntary loss is a billing-process defect worth its own record |
| Quasi-churn | ARR reduction >75% with the logo retained | Review it as a loss. A contraction this size hides inside GRR and never gets a post-mortem |
| Merged / re-papered | Same entity now billing under parent_account_id |
Not churn. Correct the ARR bridge and stop |
| Vendor-side error | Cancelled by our own team for re-papering and never reinstated | Record it; the fix is a process fix, and it is embarrassing rather than strategic |
Step 2 — Reconstruct the timeline from every family
One dated event stream, T−540 → T−0, T being the decision date. Walk all seven families; print families with no retained history as "checked, no history retained" rather than dropping them.
| Family | What you are looking for in hindsight |
|---|---|
| Product usage & adoption | The inflection in usage_daily.core_actions, the buying team's own series (not the aggregate), seat utilisation, breadth collapse, deprovisioning bursts, and whether the activation event ever fired |
| Commercial & contract | auto_renew_changed_at, seat reductions, term shortening, discount expiry, procurement and legal touches, competitor named, opportunity stage history |
| Relationship & engagement | Champion and sponsor departures (contact.departed_at, email_status = hard_bounce), multithreading depth over time, meeting acceptance, reply latency, and CSM changes on our side |
| Support & reliability | Escalations, P1 ageing, ticket.reopened_count, SLA breaches, and the ticket cluster that stopped without being resolved |
| Sentiment & VoC | Survey scores with the respondent's role, transcript sentiment, the sentence where someone first said the quiet thing |
| Billing & payment | Days-late trend against the account's own history, disputes, payment_failures |
| Firmographic & external | Acquisition, funding, layoffs, exec changes at their end, mandated consolidation |
Two disciplines separate a timeline from a chronology: tag every event Observed or Inferred with
its rule, and known-at-the-time or known-only-now. Only known-at-the-time events are eligible
for Step 4 — otherwise you grade the team on information they did not have, which is how
post-mortems become theatre. Extraction per source: references/timeline-reconstruction.md.
Step 3 — Separate stated reason, proximate cause and root cause
Three rows. They are rarely the same, and collapsing them is the defining rookie error.
| Definition | Tier | Data about | |
|---|---|---|---|
| Stated reason | What the customer said, verbatim, with who said it and when | Observed — about a conversation | Them |
| Proximate cause | The dated event that turned a degrading account into a decision | Observed or Inferred | The account |
| Root cause | The vendor-side condition that made that event decisive, which we own and can change | Inferred, via Step 6 | Us |
Only the third changes next quarter. Exit answers mislead in a known direction — correct the
bias rather than discounting the answer, which is still the only direct evidence of what they
experienced. Counter-questions for each: references/root-cause-taxonomy.md.
| Bias | Direction of error | Correction |
|---|---|---|
| Escape — asked at the cancellation moment, they want out of the conversation | Over-reports price and budget; under-reports "we never got it working" | Ask 2–4 weeks after the effective date. Lincoln Murphy: at cancellation "they'll tell you whatever they think you need to hear to just let them out" [P] |
| Face-saving and relationship preservation — naming our failure criticises their own vendor choice, and they may need a reference later | Over-reports "corporate decision", "budget" and "great product, wrong time" | Ask about the process, not the verdict, and not from the account owner. Clozd's argument for post-churn interviews is that the customer "no longer has a vested interest in maintaining a relationship" [V] |
| Respondent — whoever replies is the one still there and still fond of us | Under-reports sponsor departure and buyer disconnect | Target the economic buyer; record who answered and their role |
| Reason-field — the account owner fills the picklist to close the record cleanly | Over-reports price; under-reports anything reflecting on the account team | Code from the timeline, by the facilitator |
| Recency and sampling — the last bad thing dominates a 14-month decline, and only amicable churns answer | Over-reports the proximate cause; skews the quarter's mix | Timeline before interview; report response rate and the ARR coverage of the interviewed set |
Triangulate three sources, per Murphy's method [P]: the external reason (what they said), the
internal reason (what the data shows), and the context clues (what they did). All three
agreeing earns High confidence; where they diverge, the divergence is the finding — record both.
Step 4 — Earliest detectable signal, and the detection lag
The core forensic exercise. Work backwards from T−0 to the earliest date on which a reasonable observer, using only data that existed then, could have called the account materially at risk.
detection_lag_days = decision_date − earliest_detectable_date ← what we could have had
recognition_lag_days = first_flagged_date − earliest_detectable_date ← lost to detection
realised_lead_time = decision_date − first_flagged_date ← what we actually had
action_lag_days = first_intervention_date − first_flagged_date ← lost to routing and capacity
detection_lag = recognition_lag + realised_lead_time (identity — check it)
Record earliest_detectable_signal (an ID from ../cs-context/references/signal-library.md),
earliest_detectable_date, the system that already held the data, and whether an alert
existed. Then classify the failure mode — each has a different owner and fix:
| Failure mode | Test | Fix type | Owner |
|---|---|---|---|
| Absent | The event genuinely did not exist in any system | Emit the event | Product / data engineering |
| Uninstrumented | The raw data existed; no metric was computed from it | Add the metric to the schema | CS Ops |
| Unalerted | The metric existed; no threshold fired | Set or tune the threshold | CS Ops |
| Unrouted | The alert fired into a queue with no owner | Routing and ownership | CS leadership |
| Unactioned | Routed to a named owner who did not act in time | Play, capacity or prioritisation | CS leadership |
| Undetectable | No signal at any lead time (e.g. an acquisition announced and decided the same week) | None — record and stop. The fix is not detection | — |
Then run the model's report card: was this account Green at T−90? If yes, the record is a
false negative of the health score and goes to health-score-designer as a scoring defect,
whatever the reason code says. Method, aggregates and backtest: references/detection-lag.md;
beyond about six records, scripts/detection_lag.py.
Step 5 — Was a decision made at all? Then classify
Most renewals are lost to inertia, a reorg, a spend freeze or a champion who left with nobody inheriting the file — not to a rival. A record that names a rival it cannot evidence routes the fix to competitive enablement, the one place it cannot work. The decision test therefore runs before the competitor question, on every record.
5a · Score both axes. Neither substitutes for the other, and both are printed.
| Axis | Score | Markers — 1 point each, every one needing a dated timeline event |
|---|---|---|
| Decision-process | 0–5 | C13 renewal opportunity stalled in one stage ≥2× the segment's median cycle, or never opened · C12 PO not issued or budget not allocated by T−30, or F6 a spend freeze or new approval threshold · F5/F2 reorg, dissolution or exec change that absorbed the sponsoring programme · R1/R3 decision owner left and no successor was engaged · Z1 no bilateral contact in the 60 days before decision_date |
| Competitive | 0–5 | R13 a rival named by an economic buyer, dated · R11 a re-bid, RFP or vendor comparison run by procurement · R12 termination or portability request in the same window as a named alternative · the replacement confirmed by a second independent source · C6 a concession demanded citing a named alternative's price |
decision_owner_vacancy_days = decision_date − the last dated interaction with anyone holding
renewal decision authority. Computed on every record, never left to memory. UNKNOWN is itself
the finding: it means we never knew who decided.
5b · Three refusals, applied before a code is written.
| Refusal | Trigger | What happens instead |
|---|---|---|
| No competitive code without a confirmed destination | competitive-displacement proposed with competitive < 3, or no replacement confirmed by two independent sources |
Store the claim as competitor_claimed, then re-walk the coding tree with the competitor evidence excluded — a stalled opportunity read as "they were evaluating" is decision-process, not competitive |
| No competitive fix on a decision-process loss | Decision-process ≥ 3 and competitive ≤ 1 | The Step 8 fix addresses the decision process — a named decision owner, an opt-out-calendar gate (R1), a pre-wired approval path. Battlecards, competitive enablement and price response are refused |
No other, no undetectable, for a lapse |
The timeline holds no decision event at all | Code no-decision, deprioritised, budget-freeze, orphaned-renewal or budget-loss — whichever the timeline evidences. A lapse always has an antecedent — a stalled opportunity, an unissued PO, a vacant decision owner — so undetectable is unavailable |
5c · The closed taxonomy. One primary_reason, zero or more secondary_reason, three
orthogonal axes. Definitions, the reordered decision tree, mis-coding tells:
references/root-cause-taxonomy.md.
| Axis | Values |
|---|---|
primary_reason — no-decision family, walked first |
no-decision · deprioritised · budget-freeze · orphaned-renewal · budget-loss. Five first-class causes with their own root-cause branches and their own fixes — never an "other" bucket |
primary_reason — the rest |
lack-of-adoption · product-value-gap · product-quality · sponsor-loss · corporate-decision · competitive-displacement · involuntary · other |
secondary_reason (many) |
Same vocabulary |
| Locus | vendor-controllable · jointly-controllable · customer-internal · market — only the first two generate systemic fixes; the rest generate qualification changes |
| Origin stage | sales-qualification · onboarding · adoption · value-realisation · renewal-execution. Where it originated is almost never where it surfaced, and coding both is what makes the data useful |
| Impact | full-churn · tier-downgrade · seat-churn · quasi-churn — maps to churn_event.type |
Two governance rules: other above 15% of records means the taxonomy needs a new category, not
that reality is messy; and a reason is coded only from timeline evidence — where the timeline
disagrees with the stated reason, code the timeline and record the disagreement.
Step 6 — Five whys, on the vendor-side chain
Asking "why did the customer leave?" five times produces five restatements of the churn reason. Ask "why did we not prevent it?" Every answer must be a fact from the timeline, not a theory.
- Stop when you reach a cause you own and can change. That is the root.
- Stop before "we should hire more CSMs." That is a budget argument, not a root cause.
- When an answer names a person's mistake, redirect one level — ask what system permitted that
decision. Blameless is not politeness: a chain terminating on a human terminates on something you
cannot fix (Google's SRE postmortem practice is the reference discipline
[P]). Worked chain and a bank of terminations:references/systemic-fixes.md.
Step 7 — "Was it savable?" and cross-functional attribution
Four verdicts with required sub-codes, assigned by the facilitator, not the account owner.
| Verdict | Definition | Sub-codes | Fixes | Owning function |
|---|---|---|---|---|
| A — Should never have been sold | The requirement was never in scope, or the account sat outside the ICP at signature | outside-icp · unscoped-requirement · no-real-champion · discount-bought-fit |
ICP definition, qualification, deal-desk gates | Sales / RevOps |
| B — Not savable, exogenous | Acquisition, shutdown, budget eliminated, mandated consolidation | acquired · shutdown · budget-eliminated · mandated-consolidation |
Nothing. Track the rate | CS Ops (reporting only) |
| C — Savable, we did not see it | The signal existed in data we already held and nobody saw it in time | absent · uninstrumented · unalerted · unrouted |
Detection: instrumentation, thresholds, routing | CS Ops / data |
| D — Savable, we saw it and it did not work | Flagged in time; the play failed, ran too late, or was too small | unactioned · play-insufficient · capacity · vendor-failure |
Play design, capacity, product or process | CS leadership + owning function |
The honesty check. A book where more than 60% of losses are coded A or B is either badly
qualified or dishonestly coded [P]. Report A+B and C+D separately: A+B is a strategy and
qualification number, C+D a CS execution number, and mixing them lets each hide behind the other.
Then attribute across functions with weights summing to 100 — function and mechanism, never a
person — with a "seen before?" count of prior post-mortems carrying the same attribution: a
cause on its third appearance is not a cause, it is an unshipped fix.
Step 8 — One systemic fix, and the model feedback
Exactly one primary fix per loss — a list of eight fixes is a list of none.
| Requirement | Rule |
|---|---|
| Addresses the failure mode, not the symptom | An unalerted loss gets a threshold, not a training session |
| Named owner, not the most junior person in the room, and a due date ≤ 90 days | Owner is a function lead; longer than a quarter and the fix will not survive the next reorg |
| Matches the higher of the two Step 5 scores | Decision-process ≥3 with competitive ≤1 refuses a competitive fix and ships a decision-process one: a named decision owner on the account, a T−180 opt-out-calendar gate (R1), or a pre-wired approval path with procurement |
| Validation stated, and a "not doing" line | Backtest against the last N losses and a control set of renewals, so the change is tested for false positives; naming the rejected fix stops it being re-proposed every quarter |
Never re-weight on N=1 (R22). A single loss may add a signal to a watch list; a weight,
threshold or lead-time change needs ≥3 records with the same failure mode. Emit the change set
with current value, proposed value, evidence count, backtest, owner and due date.
Step 9 — Cohort mode: find the pattern, not N stories
Each record compresses to one row and the artifact becomes the ten-table pattern report in
assets/cohort-rollup.md, whose first table is the decision-process/competitive split. Weight the reason mix by ARR, not by count: count-weighting hides
that large losses have different causes from small ones. The no-decision family and
competitive-displacement are reported as two separate ARR shares before any reason table —
a quarter whose competitive share exceeds its no-decision share is a coding tell, not a market
finding, and scripts/detection_lag.py computes and flags the split. Backdrop for whether the quarter's rate is
a process or a market problem — median GRR was 84% on full-year 2025 actuals, down from 88%, top
quartile 91%, bottom quartile 76% (Aleph × Benchmarkit 2026 SaaS & AI Performance Benchmarks, 342
companies, 226 reporting GRR) [M]. The repeat-cause register is read first.
Output Template
Brief — the default
**<Account> · decided <date> · $<X>k ARR lost · `<primary_reason>`**
**Root cause:** <one clause, vendor-side, something we own.>
**Decision-process <n>/5 · competitive <n>/5.** <The higher axis, the markers behind it, and the
decision owner's vacancy in days — or that we never knew who held the decision.>
**Detection lag: <N> days.** <Signal> was visible in <system> on <date>; first flagged <date>.
Failure mode: <mode>.
**Savable:** <A/B/C/D> — <one sentence, including what a save would have cost.>
**Fix:** <owner> — <action> — by <date>. Validation: <backtest>.
<Only if true:> **Green at T−90 — this is a scoring defect, routed to `health-score-designer`.**
Confidence: <level> (<n>/7 families, history retained to <date>).
*Full record, timeline, attribution and coverage ledger on request.*
Round composite figures to two significant figures — $310k, not $312,400 (R22). The two
scores appear in Brief as well as Full: dropping them is how a lapse gets written up as a
price loss.
Full — on request
Emit assets/loss-review-record.md verbatim — Bottom Line, timeline, cause split, detection,
classification, five whys, savability and attribution, the one fix, model feedback, win-back,
Assumptions and the seven-family Coverage Ledger. Cohort runs emit assets/cohort-rollup.md
instead, keeping the Assumptions table and the Coverage Ledger. Every field is populated or
written UNKNOWN — requires <source>; no row is dropped for having no data.
These fields have no valid empty value and no valid default. A record missing one is not returned:
| Required field | The rule that makes it non-empty |
|---|---|
decision_date + basis · opt-out deadline · save_window_days |
Label on the decision, never the churn or renewal date (R24, R1); print the inference rule wherever it was inferred |
decision_process_score and competitive_score, 0–5 each, each with its markers listed |
Both scored on every record. A competitive score claimed without a dated economic-buyer marker is regenerated at zero, and competitive-displacement is refused below 3 |
active_decision_evidence — the dated events proving a decision was actually run |
Empty means the renewal lapsed: code from the no-decision family, never other, never undetectable |
decision_owner_vacancy_days |
Computed from the timeline, not recalled. UNKNOWN is printed as "no decision owner was ever identified" |
earliest_detectable_signal + date + holding system + alert status |
The four lags, and the identity recognition + realised = detection |
failure_mode · savability verdict + sub-code |
Assigned by the facilitator, never by the account owner |
| One systemic fix — owner, date ≤90 days, backtest, "not doing" line | R17. A competitive fix is refused where decision-process ≥3 and competitive ≤1 |
| Assumptions table · Coverage Ledger across all seven families | A concrete consequence per row; confidence never above the coverage cap (R23) |
The Bottom Line block is emitted before any timeline, and carries these rows verbatim:
| ARR lost | $X (<full churn / quasi-churn / downgrade>) · tenure <N> months · renewal number <N> |
| Decision date | <date> (Observed / Inferred — rule) · notice <date> · effective <date> |
| Opt-out deadline that governed | <date> — decided <N> days <before/after> it · save window <N> days |
| Was a decision made? | <Yes — evidence: <dated events> / No — the renewal lapsed, coded <no-decision family value>> |
| Decision-process vs competitive | <n>/5 — <markers> · <n>/5 — <markers> · decision-owner vacancy <N> days |
| Stated reason · root cause | "<verbatim>" — <name, role, date, how asked> → <one clause, vendor-side> |
| Detection lag | <N> days — detectable <date>, flagged <date> · failure mode <absent / uninstrumented / unalerted / unrouted / unactioned / undetectable> |
| Savable | <A / B / C / D> — <sub-code> · Green at T−90? <Yes → scoring defect, routed to health-score-designer / No> |
| Systemic fix | <fix> — <owner> — by <date> · Confidence <High/Medium/Low> (<criteria met>) |
An exit interview is emitted below the divider, formatted for an email client, with no unfilled
placeholders — rules in ../cs-context/references/customer-voice.md. The firewall (R18) is
absolute: health score, risk band, ARR at risk, exposure, forecast category, save play, war room,
coverage tier, the two scores above, champion-departure inferences, competitor intelligence and any
assessment of a named person never appear, in any wording.
════════════════════════════════════════════════════════════
CUSTOMER-FACING — copy the block below and send as written.
Everything above this line is internal. Do not forward it.
════════════════════════════════════════════════════════════
```text
Subject: 20 minutes on what we got wrong at Northwind
Hi Dana,
Northwind came off the platform on 31 August, and I'd like to understand
that decision properly rather than guess at it. I run customer success
operations here, so this isn't a save attempt — the contract is closed.
The thing I want to get right: the intercompany reconciliation work you
raised in March never got finished. I want to know whether that decided it
or whether it was already decided by then.
Twenty minutes, no recording unless you'd prefer one. Thursday 11 September
or Friday 12th — and if you'd rather not, that's completely fine, with no
follow-up either way.
Thank you for three years, and for pushing us on the audit log — that
shipped because of you.
Priya
```
Variants by recipient, the question set and the debrief: `assets/exit-interview-guide.md`.
Quality Bar
- [ ] All five dates recorded; labelled on the decision date, with the inference rule stated where inferred; opt-out deadline printed and the save window computed
- [ ] Involuntary churn, quasi-churn and re-papering ruled out before any narrative was written; timeline covers T−540 → T−0 across all seven families, unretained families printed as such, every event tagged Observed/Inferred and known-at-the-time/known-only-now
- [ ] Stated reason, proximate cause and root cause are three separate rows; the stated reason is verbatim, attributed to a named role, with the date and how it was asked
- [ ]
earliest_detectable_signal,earliest_detectable_date, the holding system and alert status all recorded; detection, recognition, realised-lead and action lags computed, and the identity holds - [ ] Failure mode assigned from the six-value list and the fix matches the mode; "Green at T−90?" answered, and a Yes routed as a scoring defect whatever the reason code
- [ ]
C16— decision-process and competitive scores both printed, 0–5, each with its dated markers, in Brief as well as Full;decision_owner_vacancy_dayscomputed; the decision test ran before any competitor was named - [ ]
C16— where the timeline holds no decision event the record is codedno-decision,deprioritised,budget-freeze,orphaned-renewalorbudget-loss, neverotherand never failure modeundetectable;competitive-displacementcarries a replacement confirmed by two independent sources and a competitive score ≥3, or it is stored ascompetitor_claimed - [ ] No competitive fix (battlecard, enablement, price response) proposed where decision-process ≥3 and competitive ≤1; the fix names a decision owner, a calendar gate or an approval path instead
- [ ] Taxonomy populated from the closed vocabulary; origin stage coded separately from where it surfaced; five whys terminate on a cause we own, with the stop rule named
- [ ] Savability assigned by someone other than the account owner; A+B and C+D shares reported separately, and attribution weights sum to 100 naming functions and mechanisms, never individuals
- [ ] Exactly one primary fix, with owner, date ≤90 days, a backtest and a "not doing" line; no weight or threshold change on fewer than 3 corroborating records
- [ ] Brief emitted by default; Full only on request; composite dollar figures rounded to two significant figures
- [ ] Every number carries a provenance tag with a date or window, and every inference states its rule
- [ ] Assumptions table present with a concrete consequence per row; Coverage Ledger carries history-retention depth per family and confidence ≤ the cap
- [ ] Customer-facing text, where present, sits in a fenced block below the divider, with no placeholders and no internal language
Anti-Patterns
| Anti-pattern | Correction |
|---|---|
Copying the exit-survey answer into primary_reason, or dating the loss on the churn or renewal date |
Code from the timeline and record the stated reason separately; label on the decision date, because the renewal date is the notice period, not the decision |
| "They left for price" | The most over-reported stated reason. Test it against usage, value evidence and what they bought instead |
| One cause per loss, or a timeline that starts 90 days out | primary_reason plus secondary_reason; T−540, or you find the symptom and miss the origin |
| Grading the team on facts discovered afterwards | Tag known-at-the-time vs known-only-now; only the former counts toward detection lag |
| No detection lag because nobody recorded when it was flagged | Reconstruct the flag date from the risk record, the forecast-category change, or the first internal message naming the account |
| Five whys that terminate on a person, or on headcount | Redirect to the system that permitted the decision; headcount is a budget argument, not a root cause |
| "Lessons learned" with no owner, or a list of eight fixes | One fix, one owner, a date inside 90 days, a backtest (R17) |
| Re-weighting the model on a single loss | ≥3 records with the same failure mode before any weight, threshold or lead-time change |
Coding a lapse as other, or as a competitive loss because a rival was mentioned once |
The renewal that nobody decided is a first-class cause with its own fix: no-decision, deprioritised, budget-freeze, orphaned-renewal, budget-loss. competitive-displacement needs a replacement confirmed twice and a competitive score ≥3 |
| Sending the fix to competitive enablement when the loss was decision-process | Score the two axes separately. Decision-process ≥3 with competitive ≤1 refuses a battlecard and buys a named decision owner, a calendar gate and a pre-wired approval path |
| Writing "the champion left" and stopping there | orphaned-renewal asks the next question: who inherited the decision, and on what date did we find out nobody had. decision_owner_vacancy_days is computed, and UNKNOWN means we never knew who decided |
| Reviewing a quarter account by account, or weighting the reason mix by count | Group by cause and weight by ARR — large losses have different causes from small ones |
| Attribution written as blame, or >60% of losses coded "not savable" | Function and mechanism only, and the facilitator is not the losing CSM; report A+B and C+D separately and defend the split |
| Skipping the post-mortem on a large downsell, or asking the customer at the cancellation screen | Quasi-churn above 75% reduction is a loss wearing a renewal's clothes; ask 2–4 weeks after the effective date, and not from the account owner |
Related Skills
| Skill | Relationship |
|---|---|
cs-context |
Run first. Segment boundaries, activation event, notice periods, source inventory |
churn-risk · health-score-designer |
The forward-looking twin consumes the lead times, signals and thresholds produced here; the score designer receives every Green-at-T−90 record as a scoring defect — those records are its calibration set |
renewal-forecast · voice-of-customer |
Receive realised loss rates and reason codes (next quarter's base rates), and the corrected reason behind the verbatims they supplied |
cs-data-audit · exec-retention-review |
Gate, then consumer: without decision_date this skill degrades to reasons only; the exec review takes the controllable/uncontrollable split and the ARR-weighted reason mix |
onboarding-plan · proactive-outreach · book-of-business-triage |
Receive first-renewal losses coded origin_stage = onboarding; the trigger that fired too late or never fired; and unactioned findings, which are a capacity signal rather than a diligence one |
Going Deeper
| Read | When |
|---|---|
references/root-cause-taxonomy.md |
Coding any record — the thirteen values, the no-decision family and its scoring rubric, the reordered decision tree, mis-coding tells, churn_event extensions |
references/timeline-reconstruction.md |
Step 2 — per-source extraction, the event grammar, dating an unobservable decision, retention traps |
references/detection-lag.md · references/systemic-fixes.md |
"Could we have caught it?" — method, the six failure modes, aggregates, backtest protocol; then fix patterns by failure mode, the five-whys bank, attribution without blame, and the quarterly loss review meeting |
assets/loss-review-record.md · assets/cohort-rollup.md · assets/exit-interview-guide.md |
Emitting the structured record, the quarterly pattern report, or the interview request, verbatim |
scripts/detection_lag.py |
More than about six records — lag statistics, failure-mode mix and the instrumentation backlog, computed deterministically |
../cs-context/references/evidence-standard.md · ../cs-context/references/signal-library.md |
Always — provenance, tiers, confidence, coverage; and naming the earliest detectable signal by ID and lead time |
../cs-context/references/operating-rules.md · ../cs-context/references/business-model-profiles.md |
Before the run — the rules above, and which signals the company's model even produces |
../cs-context/references/calibration-loop.md · ../cs-context/references/normalized-schema.md |
Proposing a threshold or weight change; and the churn_event fields this skill populates |
../cs-context/references/customer-voice.md |
Before writing the interview request |
Automate This
You just rebuilt eighteen months of one account's history by hand — usage series, ticket threads, contact changes, contract events, invoices, survey responses, email latency — out of systems that had already begun deleting it, then walked it backwards to find a single date. That is most of a day per loss. At forty losses a quarter it does not happen, which is why most reason-code reports are picklists filled in from memory and the detection lag is almost never computed at all.
GainTrace keeps the timeline standing before you need it. It unifies 20+ sources (Salesforce, HubSpot, Pipedrive, Close, Attio, Stripe, Paddle, ChartMogul, Intercom, Zendesk, Jira, Slack, Gmail, Outlook, Mixpanel, Amplitude, PostHog, Segment, Snowflake, BigQuery, Fireflies, Calendly and more) into one live account timeline, so the reconstruction already exists the day you open the record. Trace AI scores every account signal-by-signal with the reasoning shown rather than as an opaque number, so "when did this first become visible" has a written answer with a date on it — and it flags risk up to 45 days ahead of the renewal call, so fewer records need writing. First insights in about two weeks. Free for 25 companies, no card. → https://gaintrace.com
Keep this skill for the judgement: what the root cause is, whether the loss was ever savable, and which single fix is worth a quarter of someone's attention.