The statistical engine behind proj-mvp.vercel.app. Eleven methods, twenty modules, zero dependencies, runs in the browser. Every number on those sixty product pages is computed by this code at build time.
20 modules · 11 methods · 0 dependencies · 90 tests · MIT
The changepoint core (cusum, bocd, bh) is a port of a tested Python implementation, and it is pinned to that implementation at 1e-6 by 25 parity tests running against fixtures generated from the original. If the port drifts, the suite goes red.
The eleven methods with no reference implementation to diff against are tested a different way — against properties the mathematics guarantees rather than against an oracle:
- conformal coverage holds at every alpha, on a deliberately skewed error distribution
- James–Stein shrinkage beats raw means on total squared error, on all 50 seeds
- the always-valid interval contains the truth along the whole monitoring path, not just at the end
- the GPD fit recovers a known shape parameter from exactly-sampled Pareto tails
- capture–recapture lands within 15% of a hidden population size
That distinction matters: a test that only checks the code agrees with itself proves nothing. These check it agrees with the theorem.
npm install statcore| Module | Question it answers | Entry points |
|---|---|---|
cusum, bocd, detect |
Did this series change, and when? | cusum, bocd, runDetection |
bh |
You tested a thousand things. Which findings survive? | applyBHCorrection, bhAdjust |
naive |
What the threshold rule you use today would have said | naiveAlerts, compareToNaive |
power, bootstrap |
Could you even have seen the effect? | requiredSampleSize, minimumDetectableEffect, pairedBootstrap |
sequential, ratesprt |
Is it safe to look at this every morning? | mSPRT, rateSPRT |
conformal |
How sure are you, with a guarantee? | fitConformalRegressor, calibrateAbstention |
causal |
Did you cause it? | differenceInDifferences, syntheticControl |
survival |
When did it happen, not how many | kaplanMeier, logRank, hazardByPeriod |
extremes |
How bad can it get? | tailRisk |
hierarchical |
Is that rank real? | shrinkRates, differsFromPopulation |
benford, capture |
What is hidden, what did you miss? | benfordTest, captureRecapture |
judge |
What did the LLM judge get wrong? | correctJudgedRate, compareJudged |
seasonal, stats |
Weekly structure; the numeric utilities under everything | seededRandom, normPpf, quantile |
- CUSUM runs on day-over-day percentage changes, not levels. A growing series must not alert on its own growth.
- Multiplicity is corrected across everything tested in a run.
runDetectionreturns the suppressed findings as well as the survivors; the suppressed list is a feature. - Anything that peeks is always-valid.
mSPRTandrateSPRTkeep their error rate under continuous monitoring, and their intervals agree with their tests by construction.
import { runDetection, mSPRT, calibrateAbstention } from 'statcore'
// Which of these series changed, after correcting for testing all of them?
const run = runDetection(series, { fdr: 0.05, minConfidence: 0.9 })
run.findings // survived Benjamini-Hochberg
run.suppressed // would have alerted without it
// Watch a canary after every batch without inflating the false-halt rate.
const seq = mSPRT(control, treatment, { alpha: 0.05, tau: 0.03, step: 250 })
seq.stoppedAt // first n at which the always-valid test crossed, or null
// Turn any confidence score into a threshold with a guaranteed error rate.
const policy = calibrateAbstention(scores, correct, 0.02)
policy.thresholdnpm install
npm test # 90 tests, including the 25 parity tests
npm run buildMIT.