survival-analysis — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited survival-analysis (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use when the outcome is "how long until X happens?" and some observations haven't experienced X yet (censored). Triggers:
If you only care about whether an event happens within a fixed window, use logistic-regression. If you need fixed-time-point retention rates without timing, use cohort-analysis.
| Question | Right tool |
|---|---|
| Did the user churn within 90 days? | logistic |
| When did the user churn? Distribution? | survival |
| How does plan tier affect churn timing? | survival |
| Users still active — do we throw them out? | survival (treats as censored, not missing) |
Throwing out censored observations biases logistic regression toward early events.
| Input | Why it matters |
|---|---|
| Subject ID | One row per subject |
| Duration | Time from start to event OR last observation |
| Event indicator (1/0) | 1 = event happened, 0 = censored (still observed without event) |
| Covariates | Features that may affect timing |
| Start time | When observation begins (often signup_at) |
start, duration, event. df = pd.DataFrame({
"subject_id": ...,
"duration_days": (event_date - start_date).dt.days,
"event": did_event.astype(int),
# ... covariates
})# Survival Analysis: <event>
## Setup
- Event: <e.g., subscription cancellation>
- Start time: <e.g., signup_at>
- Censoring: subjects still active as of <observation_end_date>
- Sample: N = <total>, events = <X (X%)>
- Duration unit: <days | weeks | months>
- Median follow-up: <D days>
## Kaplan-Meier summary
| Segment | N | Events | Median survival | S(30d) | S(90d) | S(180d) |
|---|---|---|---|---|---|---|
| Overall | 24,800 | 6,420 (26%) | 312 days | 92% | 81% | 71% |
| Monthly plan | 12,400 | 4,810 (39%) | 184 days | 88% | 71% | 58% |
| Annual plan | 12,400 | 1,610 (13%) | not reached | 96% | 91% | 84% |
Log-rank test (monthly vs annual): χ² = 2,143, p < 0.0001 — **significantly different**
## Cox proportional hazards model
| Covariate | HR | 95% CI | p | Notes |
|---|---|---|---|---|
| plan = annual (ref: monthly) | 0.42 | [0.38, 0.46] | < 0.001 | annual reduces hazard by 58% |
| tenure_segment = enterprise | 0.31 | [0.25, 0.39] | < 0.001 | |
| support_tickets_30d | 1.18 | [1.14, 1.22] | < 0.001 | each ticket: +18% hazard |
| has_team_admin | 0.67 | [0.61, 0.73] | < 0.001 | |
| age_days (per 30 days) | 0.94 | [0.93, 0.95] | < 0.001 | older accounts more stable |
Concordance index: 0.74
## Proportional hazards assumption check
- Schoenfeld residuals: <p-value per covariate>
- Covariates violating PH: <list, or "none">
- For violators: <stratified by | time-interacted | accepted with caveat>
## Visualization
- KM curves with 95% CI bands (overall + key segments)
- Hazard ratios with CIs as forest plot
- (Optional) Cumulative incidence functions
## Caveats
- <e.g., observation window 18 months; long-term survival beyond ~500 days extrapolated>
- <e.g., Annual-plan users haven't reached median — estimate uncertain>
- <e.g., Right censoring assumption assumes censoring is independent of churn likelihood; verify>
## Decision implications
- <e.g., shifting customers to annual plans should yield ~50% reduction in long-run churn>
- <e.g., support ticket spike is a strong leading indicator — trigger intervention at 3+ tickets in 30 days>
## Next steps
- <e.g., A/B test annual plan upsell campaign>
- <e.g., build early-warning model using ticket count + tenure>entry parameter in lifelines.scripts/survival_fit.py — Fit KM by segment + Cox PH model, output readout.python scripts/survival_fit.py \
--input subjects.csv \
--duration tenure_days \
--event churned \
--segment plan_tier \
--covariates plan_tier,support_tickets_30d,has_team_admincohort-analysis — for fixed-time-point retention without censoring complexitylogistic-regression — for binary outcome within a fixed windowdata-quality-audit — verify start/end dates and event indicators before fittingcausal-inference — if you need to estimate intervention effect on survival~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.