peeksafe 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/LICENSE +190 -0
  3. package/NOTICE +78 -0
  4. package/README.md +492 -2
  5. package/RESEARCH-NOTES.md +274 -0
  6. package/dist/baseline.d.ts +45 -0
  7. package/dist/baseline.d.ts.map +1 -0
  8. package/dist/baseline.js +49 -0
  9. package/dist/baseline.js.map +1 -0
  10. package/dist/check.d.ts +64 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +172 -0
  13. package/dist/check.js.map +1 -0
  14. package/dist/cluster.d.ts +328 -0
  15. package/dist/cluster.d.ts.map +1 -0
  16. package/dist/cluster.js +598 -0
  17. package/dist/cluster.js.map +1 -0
  18. package/dist/errors.d.ts +87 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +143 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/evidence.d.ts +15 -0
  23. package/dist/evidence.d.ts.map +1 -0
  24. package/dist/evidence.js +30 -0
  25. package/dist/evidence.js.map +1 -0
  26. package/dist/frontier.d.ts +269 -0
  27. package/dist/frontier.d.ts.map +1 -0
  28. package/dist/frontier.js +460 -0
  29. package/dist/frontier.js.map +1 -0
  30. package/dist/gate.d.ts +173 -0
  31. package/dist/gate.d.ts.map +1 -0
  32. package/dist/gate.js +196 -0
  33. package/dist/gate.js.map +1 -0
  34. package/dist/index.d.ts +60 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +79 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/plan.d.ts +248 -0
  39. package/dist/plan.d.ts.map +1 -0
  40. package/dist/plan.js +482 -0
  41. package/dist/plan.js.map +1 -0
  42. package/dist/rand.d.ts +17 -0
  43. package/dist/rand.d.ts.map +1 -0
  44. package/dist/rand.js +92 -0
  45. package/dist/rand.js.map +1 -0
  46. package/dist/stats.d.ts +397 -0
  47. package/dist/stats.d.ts.map +1 -0
  48. package/dist/stats.js +1245 -0
  49. package/dist/stats.js.map +1 -0
  50. package/dist/stop.d.ts +163 -0
  51. package/dist/stop.d.ts.map +1 -0
  52. package/dist/stop.js +262 -0
  53. package/dist/stop.js.map +1 -0
  54. package/package.json +64 -4
  55. package/src/baseline.ts +72 -0
  56. package/src/check.ts +238 -0
  57. package/src/cluster.ts +830 -0
  58. package/src/errors.ts +208 -0
  59. package/src/evidence.ts +62 -0
  60. package/src/frontier.ts +782 -0
  61. package/src/gate.ts +358 -0
  62. package/src/index.ts +206 -0
  63. package/src/plan.ts +778 -0
  64. package/src/rand.ts +121 -0
  65. package/src/stats.ts +1579 -0
  66. package/src/stop.ts +452 -0
@@ -0,0 +1,598 @@
1
+ /**
2
+ * cluster.ts: the suite-level effect, with the cases treated as what they are.
3
+ *
4
+ * ## The bug this module exists to fix
5
+ *
6
+ * The obvious summary of a suite effect is an ordinary normal interval over the
7
+ * per-case differences:
8
+ *
9
+ * mean ± 1.96 · sd / √n with n = 200 cases
10
+ *
11
+ * That formula is only correct if the 200 numbers are 200 independent draws.
12
+ * They usually are not. A suite of **40 case files, each expanded into 5
13
+ * variants**, is typical: `extract.pricing#saas` and `extract.pricing#api`
14
+ * share a prompt template, a grader, an expectation shape and a failure mode.
15
+ * When one moves, its four siblings move with it. The effective number of
16
+ * independent observations is closer to 40 than to 200, the true standard error
17
+ * is larger than √(s²/200), and the reported interval is **too narrow**.
18
+ *
19
+ * A too-narrow interval on the headline number is the exact failure this whole
20
+ * package exists to prevent, so it gets a proper estimator rather than a fudge
21
+ * factor.
22
+ *
23
+ * ## What is estimated here, and what is not
24
+ *
25
+ * Clustering touches **only the suite-level (and family-level) summary**.
26
+ * Specifically:
27
+ *
28
+ * affected the across-case mean difference and its interval
29
+ * (`clusteredEffect`), plus any family-level roll-up.
30
+ *
31
+ * NOT affected every per-case quantity. Each case's e-value is its own
32
+ * self-contained test on that case's own runs; nothing about
33
+ * case *A* enters case *B*'s likelihood ratio. And the
34
+ * multiplicity correction is **e-BH**, which controls FDR under
35
+ * *arbitrary* dependence between the tested hypotheses, that
36
+ * is the whole reason it was chosen over BH. So `gate`'s
37
+ * verdict, its regressed cases and its thresholds are all
38
+ * bit-for-bit identical whether or not the cases cluster.
39
+ *
40
+ * In other words: clustering makes the *description* honest. It does not, and
41
+ * must not, move the *decision*.
42
+ *
43
+ * ## Two estimators, because they fail in different directions
44
+ *
45
+ * **CR2 (the headline).** A cluster-robust sandwich with the Bell-McCaffrey
46
+ * bias reduction. For the intercept-only model that a mean is, the hat matrix
47
+ * is H = J/n, so each cluster's leverage block is (I − J_{n_g}/n) and the CR2
48
+ * adjustment `A_g = (I − H_gg)^{-1/2}` collapses to a scalar on the cluster's
49
+ * residual sum:
50
+ *
51
+ * Var̂(ȳ) = (1/n²) · Σ_g (Σ_{i∈g} ê_i)² / (1 − n_g/n)
52
+ *
53
+ * Assumption-light: it needs the *families* to be independent of each other and
54
+ * nothing at all about the correlation structure *inside* a family. It does not
55
+ * assume the family effects are normal, or exchangeable, or even
56
+ * identically distributed. Paired with Bell-McCaffrey/Satterthwaite degrees of
57
+ * freedom (which, for equal-sized families, reduce exactly to G − 1; see the
58
+ * derivation in the comment above `dfRaw` below) it is the estimator you want
59
+ * when there are 40 clusters rather than 4,000.
60
+ *
61
+ * **Random effects (the cross-check).** The one-way model
62
+ * y_gi = μ + u_g + e_gi with the ANOVA (Swamy-Arora) estimators for τ² and σ².
63
+ * More efficient *if* its assumptions hold, and it yields the number that
64
+ * actually explains the width change: the intra-class correlation
65
+ * ρ = τ²/(τ² + σ²). If the two estimators disagree materially, that is itself
66
+ * information, and `compareEstimators` says so rather than picking a winner.
67
+ *
68
+ * ## The design effect
69
+ *
70
+ * `designEffect` = (clustered SE / naive iid SE)². It is the factor by which
71
+ * the naive analysis overstated its own information, "these 200 cases carry
72
+ * the information of 200/DEFF independent ones". For roughly equal families of
73
+ * size k it tracks the textbook 1 + (k − 1)ρ, which is the sanity check the
74
+ * tests assert.
75
+ */
76
+ import { PeeksafeError } from "./errors.js";
77
+ import { normalQuantile, tQuantile } from "./stats.js";
78
+ /* ────────────────────────── the clustering key ───────────────────────── */
79
+ /**
80
+ * The cluster a case belongs to: its **case file**.
81
+ *
82
+ * Variant ids are expected as `<fileId>#<variant>`, so everything before
83
+ * the first `#` is the file, and the file is the unit an author actually wrote.
84
+ * A case with no `#` is its own family of one, which is correct, not a
85
+ * degenerate case: an unexpanded case file shares its template with nobody.
86
+ */
87
+ export function caseFamily(caseId) {
88
+ const i = caseId.indexOf("#");
89
+ return i < 0 ? caseId : caseId.slice(0, i);
90
+ }
91
+ /**
92
+ * The cluster key for a case: the one it **declares**, or its case file.
93
+ *
94
+ * `caseFamily` sees exactly one reason two cases correlate, that they were
95
+ * minted from the same file, and is blind to every other: a shared grader, a
96
+ * shared fixture directory, one flaky tool that six unrelated cases happen to
97
+ * call. Those cases are correlated too, and the interval will be too narrow
98
+ * again for a reason the id cannot express. So a case may declare its own key.
99
+ *
100
+ * A wrong key is worse than no key, which is why `clusterKeyDiagnostic` ships
101
+ * alongside: declaring two genuinely independent cases into one family throws
102
+ * away real information and widens the interval for nothing, and the only way
103
+ * to know is to look at the ICC the declared grouping actually exhibits.
104
+ */
105
+ export const clusterKey = (c) => {
106
+ // Trimmed, so `cluster: " "` is not a distinct family that silently merges
107
+ // every case that has one. An all-whitespace key is no key.
108
+ const declared = c.cluster?.trim();
109
+ return declared ? declared : caseFamily(c.id);
110
+ };
111
+ // Called before the early returns, which never reach a quantile, so every suite refuses the same level.
112
+ function requireLevel(level, where) {
113
+ if (!(level > 0 && level < 1)) {
114
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `${where}: level must be in (0,1), got ${level}`, {
115
+ detail: { level },
116
+ hint: "a two-sided confidence level such as 0.95, not a percentage and not an error budget",
117
+ });
118
+ }
119
+ }
120
+ /** Group observations by cluster, preserving first-seen order. */
121
+ export function groupByCluster(obs) {
122
+ const m = new Map();
123
+ for (const o of obs) {
124
+ if (!Number.isFinite(o.value)) {
125
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `clustered mean: value for cluster "${o.cluster}" is not finite`, {
126
+ detail: { cluster: o.cluster, value: o.value },
127
+ });
128
+ }
129
+ const xs = m.get(o.cluster);
130
+ if (xs)
131
+ xs.push(o.value);
132
+ else
133
+ m.set(o.cluster, [o.value]);
134
+ }
135
+ return m;
136
+ }
137
+ /** The naive iid interval, kept so the two can be printed side by side. */
138
+ export function iidMean(values, level = 0.95) {
139
+ requireLevel(level, "iidMean");
140
+ const n = values.length;
141
+ if (n === 0)
142
+ return { low: -1, high: 1, point: 0, observations: 0 };
143
+ const mean = values.reduce((a, b) => a + b, 0) / n;
144
+ const sd = n > 1 ? Math.sqrt(values.reduce((a, x) => a + (x - mean) ** 2, 0) / (n - 1)) : 0;
145
+ const z = normalQuantile(1 - (1 - level) / 2);
146
+ const half = (z * sd) / Math.sqrt(n);
147
+ return { low: mean - half, high: mean + half, point: mean, observations: n };
148
+ }
149
+ /**
150
+ * CR2 cluster-robust interval for a mean, with Bell-McCaffrey degrees of
151
+ * freedom. See the module header for the derivation; the short version is that
152
+ * for an intercept-only design the whole apparatus collapses to
153
+ *
154
+ * Var̂ = (1/n²) Σ_g (Σ_{i∈g} ê_i)² / (1 − n_g/n)
155
+ *
156
+ * and the Satterthwaite df to a closed form in the cluster sizes alone.
157
+ */
158
+ export function clusterRobustMean(obs, level = 0.95) {
159
+ requireLevel(level, "clusterRobustMean");
160
+ const groups = groupByCluster(obs);
161
+ const n = obs.length;
162
+ const G = groups.size;
163
+ const sizes = [...groups.values()].map((xs) => xs.length);
164
+ const naive = iidMean(obs.map((o) => o.value), level);
165
+ const naiveSe = n > 1 ? Math.sqrt(obs.reduce((a, o) => a + (o.value - naive.point) ** 2, 0) / (n - 1) / n) : 0;
166
+ const base = {
167
+ point: naive.point,
168
+ observations: n,
169
+ clusters: G,
170
+ largestCluster: sizes.length ? Math.max(...sizes) : 0,
171
+ meanClusterSize: G > 0 ? n / G : 0,
172
+ naiveSe,
173
+ method: "CR2",
174
+ };
175
+ // One cluster is one observation. There is nothing to average over, so there
176
+ // is no standard error, and saying "±0.4 points" here would be exactly the
177
+ // fabricated-precision failure this module was written to remove.
178
+ if (n === 0 || G < 2) {
179
+ return {
180
+ ...base,
181
+ low: -1,
182
+ high: 1,
183
+ se: Infinity,
184
+ designEffect: Infinity,
185
+ widthRatio: Infinity,
186
+ df: 0,
187
+ tCritical: Infinity,
188
+ effectiveSampleSize: G,
189
+ degenerate: n === 0
190
+ ? "no cases contributed an estimate"
191
+ : `all ${n} cases belong to one family ("${[...groups.keys()][0]}"), a single cluster carries no ` +
192
+ "information about between-family variation, so no interval is estimable",
193
+ };
194
+ }
195
+ const mean = base.point;
196
+ let meat = 0;
197
+ for (const xs of groups.values()) {
198
+ const sumRes = xs.reduce((a, x) => a + (x - mean), 0);
199
+ const leverage = 1 - xs.length / n; // > 0 because G ≥ 2
200
+ meat += (sumRes * sumRes) / leverage;
201
+ }
202
+ const variance = meat / (n * n);
203
+ const se = Math.sqrt(variance);
204
+ // Bell-McCaffrey / Satterthwaite df. With g_g = M b_g the closed forms are
205
+ // tr(G) = Σ n_g/n² = 1/n
206
+ // tr(G²) = Σ_g (n_g/n²)² + Σ_{g≠h} (n_g n_h)² / (n⁶ (1−n_g/n)(1−n_h/n))
207
+ // and df = tr(G)² / tr(G²). For equal cluster sizes this is exactly G − 1.
208
+ const n2 = n * n;
209
+ let trG2 = 0;
210
+ for (let i = 0; i < G; i++) {
211
+ const ni = sizes[i];
212
+ trG2 += (ni / n2) ** 2;
213
+ for (let j = 0; j < G; j++) {
214
+ if (i === j)
215
+ continue;
216
+ const nj = sizes[j];
217
+ const denom = (1 - ni / n) * (1 - nj / n);
218
+ trG2 += (ni * nj) ** 2 / (n2 * n2 * n2 * denom);
219
+ }
220
+ }
221
+ const trG = 1 / n;
222
+ const dfRaw = trG2 > 0 ? (trG * trG) / trG2 : G - 1;
223
+ const df = Math.min(n - 1, Math.max(1, dfRaw));
224
+ const t = tQuantile(1 - (1 - level) / 2, df);
225
+ const half = t * se;
226
+ const z = normalQuantile(1 - (1 - level) / 2);
227
+ const naiveHalf = z * naiveSe;
228
+ return {
229
+ ...base,
230
+ low: mean - half,
231
+ high: mean + half,
232
+ se,
233
+ designEffect: naiveSe > 0 ? (se / naiveSe) ** 2 : se > 0 ? Infinity : 1,
234
+ widthRatio: naiveHalf > 0 ? half / naiveHalf : half > 0 ? Infinity : 1,
235
+ df,
236
+ tCritical: t,
237
+ // n / DEFF, **capped at n**. When the families happen to disagree less than
238
+ // the cases within them, the CR2 standard error lands below the iid one and
239
+ // DEFF comes out under 1, a finite-sample fact about this sample, not
240
+ // information the clustering created. Uncapped, this read "worth
241
+ // 222 independent cases / 200", which claims a suite of 200 carries more
242
+ // than 200 cases' worth of evidence. It does not. The design effect itself
243
+ // is reported unclamped, because *that* number is the estimate.
244
+ effectiveSampleSize: naiveSe > 0 ? Math.min(n, n / Math.max(1e-12, (se / naiveSe) ** 2)) : n,
245
+ degenerate: null,
246
+ };
247
+ }
248
+ /**
249
+ * One-way random-effects (hierarchical) estimate of the same mean.
250
+ *
251
+ * y_gi = μ + u_g + e_gi, u_g ~ (0, τ²), e_gi ~ (0, σ²)
252
+ *
253
+ * τ² and σ² come from the ANOVA decomposition (the Swamy-Arora estimator,
254
+ * unbiased and closed-form, and it does not need the normality that REML would
255
+ * lean on). μ̂ is the GLS weighted mean of the family means with
256
+ * w_g = 1/(τ² + σ²/n_g), so its variance is 1/Σw_g.
257
+ *
258
+ * Two properties worth knowing before trusting it:
259
+ * - at τ̂² = 0 it degenerates **exactly** to the naive iid interval, which is
260
+ * the correct behaviour: no between-family variance means the cases really
261
+ * were exchangeable;
262
+ * - it weights families by information rather than by size, so unlike the
263
+ * unweighted mean it is not the same point estimate as CR2 when families
264
+ * differ in size. That difference is a feature and it is reported.
265
+ */
266
+ export function randomEffectsMean(obs, level = 0.95) {
267
+ requireLevel(level, "randomEffectsMean");
268
+ const groups = groupByCluster(obs);
269
+ const n = obs.length;
270
+ const G = groups.size;
271
+ const grand = n > 0 ? obs.reduce((a, o) => a + o.value, 0) / n : 0;
272
+ const shell = {
273
+ observations: n,
274
+ clusters: G,
275
+ method: "random-effects",
276
+ };
277
+ if (n === 0 || G < 2) {
278
+ return {
279
+ ...shell,
280
+ point: grand,
281
+ low: -1,
282
+ high: 1,
283
+ tauSquared: 0,
284
+ sigmaSquared: 0,
285
+ icc: 0,
286
+ se: Infinity,
287
+ df: 0,
288
+ degenerate: n === 0 ? "no cases contributed an estimate" : "a single family cannot separate τ² from σ²",
289
+ };
290
+ }
291
+ const entries = [...groups.entries()].map(([k, xs]) => ({
292
+ key: k,
293
+ size: xs.length,
294
+ mean: xs.reduce((a, x) => a + x, 0) / xs.length,
295
+ values: xs,
296
+ }));
297
+ let ssw = 0;
298
+ let ssb = 0;
299
+ for (const g of entries) {
300
+ for (const x of g.values)
301
+ ssw += (x - g.mean) ** 2;
302
+ ssb += g.size * (g.mean - grand) ** 2;
303
+ }
304
+ const dfW = n - G;
305
+ const dfB = G - 1;
306
+ // Every family has exactly one member: there is no within-family replication,
307
+ // so σ² is not identified, and there is also no clustering left to correct
308
+ // for. The iid interval is then the right answer, not an approximation.
309
+ if (dfW === 0) {
310
+ const iid = iidMean(obs.map((o) => o.value), level);
311
+ return {
312
+ ...shell,
313
+ point: iid.point,
314
+ low: iid.low,
315
+ high: iid.high,
316
+ tauSquared: dfB > 0 ? ssb / dfB : 0,
317
+ sigmaSquared: 0,
318
+ icc: 1,
319
+ se: dfB > 0 ? Math.sqrt(ssb / dfB / n) : 0,
320
+ df: dfB,
321
+ degenerate: "every family has exactly one case, no within-family replication, so σ² is not identified " +
322
+ "and the observations are already independent",
323
+ };
324
+ }
325
+ const msw = ssw / dfW;
326
+ const msb = ssb / dfB;
327
+ // k₀: the "average" cluster size the ANOVA estimator divides by. Equals the
328
+ // common size when families are balanced.
329
+ const sumSq = entries.reduce((a, g) => a + g.size * g.size, 0);
330
+ const k0 = (n - sumSq / n) / dfB;
331
+ const sigmaSquared = msw;
332
+ const tauSquared = k0 > 0 ? Math.max(0, (msb - msw) / k0) : 0;
333
+ // Neither variance component is positive, so every case took the same value.
334
+ // The GLS weight 1/(τ² + σ²/n_g) is then 1/0 for every family, the total
335
+ // weight is Infinity, and the weighted mean came out Infinity/Infinity, i.e.
336
+ // NaN, with `degenerate` left null, which says the estimate was formed. A
337
+ // pull request that moved nothing produces exactly this: every per-case
338
+ // difference is zero. CR2 and the iid interval both answer the grand mean
339
+ // with a zero-width interval here, and so does this.
340
+ if (!(tauSquared + sigmaSquared > 0)) {
341
+ return {
342
+ ...shell,
343
+ point: grand,
344
+ low: grand,
345
+ high: grand,
346
+ tauSquared: 0,
347
+ sigmaSquared: 0,
348
+ icc: 0,
349
+ se: 0,
350
+ df: dfB,
351
+ degenerate: null,
352
+ };
353
+ }
354
+ let sumW = 0;
355
+ let sumWY = 0;
356
+ for (const g of entries) {
357
+ const w = 1 / (tauSquared + sigmaSquared / g.size);
358
+ sumW += w;
359
+ sumWY += w * g.mean;
360
+ }
361
+ const point = sumW > 0 ? sumWY / sumW : grand;
362
+ const se = sumW > 0 ? Math.sqrt(1 / sumW) : Infinity;
363
+ const df = dfB;
364
+ const t = tQuantile(1 - (1 - level) / 2, df);
365
+ return {
366
+ ...shell,
367
+ point,
368
+ low: point - t * se,
369
+ high: point + t * se,
370
+ se,
371
+ tauSquared,
372
+ sigmaSquared,
373
+ icc: tauSquared + sigmaSquared > 0 ? tauSquared / (tauSquared + sigmaSquared) : 0,
374
+ df,
375
+ degenerate: null,
376
+ };
377
+ }
378
+ const fmtPts = (x) => `${x >= 0 ? "+" : ""}${(x * 100).toFixed(1)}`;
379
+ /**
380
+ * The whole suite-level story in one object: the honest interval, the naive one
381
+ * it replaces, the factor between them, and whether swapping them changes what
382
+ * a reader would conclude.
383
+ */
384
+ export function clusteredEffect(obs, level = 0.95) {
385
+ const cr2 = clusterRobustMean(obs, level);
386
+ const re = randomEffectsMean(obs, level);
387
+ const naive = iidMean(obs.map((o) => o.value), level);
388
+ const groups = groupByCluster(obs);
389
+ const families = [...groups.entries()]
390
+ .map(([family, xs]) => {
391
+ const m = xs.reduce((a, x) => a + x, 0) / xs.length;
392
+ const sd = xs.length > 1 ? Math.sqrt(xs.reduce((a, x) => a + (x - m) ** 2, 0) / (xs.length - 1)) : 0;
393
+ return { family, cases: xs.length, point: m, sd, min: Math.min(...xs), max: Math.max(...xs) };
394
+ })
395
+ .sort((a, b) => a.point - b.point || (a.family < b.family ? -1 : 1));
396
+ const excludesZero = (i) => i.low > 0 || i.high < 0;
397
+ const signFlippedByClustering = excludesZero(naive) && !excludesZero(cr2);
398
+ const headline = cr2.degenerate
399
+ ? `suite effect ${fmtPts(cr2.point)}pts, no interval: ${cr2.degenerate}`
400
+ : `suite effect ${fmtPts(cr2.point)}pts [${fmtPts(cr2.low)}, ${fmtPts(cr2.high)}] ` +
401
+ `over ${cr2.clusters} case families (${cr2.observations} cases); ` +
402
+ `clustering widens the interval ${cr2.widthRatio.toFixed(2)}× (design effect ${cr2.designEffect.toFixed(2)}, ` +
403
+ `ICC ${re.icc.toFixed(2)}), so the suite is worth ~${Math.round(cr2.effectiveSampleSize)} independent cases, not ${cr2.observations}` +
404
+ (signFlippedByClustering
405
+ ? ". The naive interval excluded zero and this one does not, the apparent suite-level move does not survive the correction."
406
+ : "");
407
+ return {
408
+ cr2,
409
+ randomEffects: re,
410
+ naive,
411
+ designEffect: cr2.designEffect,
412
+ widthRatio: cr2.widthRatio,
413
+ icc: re.icc,
414
+ clusters: cr2.clusters,
415
+ observations: cr2.observations,
416
+ families,
417
+ signFlippedByClustering,
418
+ headline,
419
+ };
420
+ }
421
+ /**
422
+ * Do the two estimators tell the same story? They rest on different
423
+ * assumptions, so agreement is evidence and disagreement is a warning worth
424
+ * printing rather than resolving by fiat.
425
+ */
426
+ export function compareEstimators(e) {
427
+ if (e.cr2.degenerate || e.randomEffects.degenerate) {
428
+ return { agree: true, seRatio: 1, note: e.cr2.degenerate ?? e.randomEffects.degenerate ?? "" };
429
+ }
430
+ // Two estimators that both report a standard error of zero agree; it is only
431
+ // a zero model-based SE under a positive robust one that is an infinite
432
+ // ratio. Reading every zero as Infinity made the note say "the family effects
433
+ // are not behaving like independent draws from one distribution, so trust CR2
434
+ // and not the hierarchical fit" about a suite with no variance at all, where
435
+ // the two estimators had produced the same number. Same shape as
436
+ // `designEffect` in `clusterRobustMean`, for the same reason.
437
+ const seRatio = e.randomEffects.se > 0 ? e.cr2.se / e.randomEffects.se : e.cr2.se > 0 ? Infinity : 1;
438
+ const agree = seRatio > 0.7 && seRatio < 1.45;
439
+ return {
440
+ agree,
441
+ seRatio,
442
+ note: agree
443
+ ? `CR2 and the random-effects model agree to within ${(Math.abs(seRatio - 1) * 100).toFixed(0)}% on the standard error`
444
+ : seRatio > 1
445
+ ? `the robust SE is ${seRatio.toFixed(2)}× the model-based one, the family effects are not behaving like ` +
446
+ "independent draws from one distribution, so trust CR2 and not the hierarchical fit"
447
+ : `the robust SE is only ${seRatio.toFixed(2)}× the model-based one, with this few families CR2 can be ` +
448
+ "optimistic; report the wider of the two",
449
+ };
450
+ }
451
+ /**
452
+ * Below this many clusters, a cluster-robust standard error is optimistic even
453
+ * with small-cluster degrees of freedom. Standard practice; `compareEstimators`
454
+ * says the same thing from the other direction.
455
+ */
456
+ export const MIN_TRUSTWORTHY_CLUSTERS = 20;
457
+ const summarise = (key, obs) => {
458
+ const cr2 = clusterRobustMean(obs);
459
+ const re = randomEffectsMean(obs);
460
+ return {
461
+ key,
462
+ // Only CR2 decides whether this grouping has an interval, which is what
463
+ // `degenerate` documents. The random-effects fit degenerating is a
464
+ // different fact about a different estimator: with one case per family σ²
465
+ // is not identified, so there is no ICC to report, but the cluster-robust
466
+ // interval is estimable and is in fact the iid one. Folding the two
467
+ // together made `clusterKeyDiagnostic` answer "no suite-level interval is
468
+ // estimable ... it is no claim at all" about a grouping whose standard
469
+ // error it had just computed, in a sentence reading "collapses 8 case-file
470
+ // groups into 80".
471
+ degenerate: cr2.degenerate,
472
+ clusters: cr2.clusters,
473
+ meanClusterSize: cr2.meanClusterSize,
474
+ icc: re.icc,
475
+ designEffect: cr2.designEffect,
476
+ widthRatio: cr2.widthRatio,
477
+ se: cr2.se,
478
+ effectiveSampleSize: cr2.effectiveSampleSize,
479
+ iccEstimable: re.degenerate === null,
480
+ };
481
+ };
482
+ /**
483
+ * Does a user-declared cluster key carry anything?
484
+ *
485
+ * The honest answer is a comparison, not a number: the same observations are
486
+ * grouped both ways and the intra-class correlation of each grouping is
487
+ * reported. A declared key that merges cases which do not in fact move together
488
+ * shows an ICC near zero while having *fewer, larger* clusters than the
489
+ * fallback, it has thrown away real information and widened the interval to
490
+ * pay for it. A declared key that finds correlation the case ids could not see
491
+ * shows a higher ICC and a larger design effect, and is doing its job. A
492
+ * declared key that is *finer* than the fallback, splitting apart files whose
493
+ * variants do move together, narrows the interval instead, and that is the
494
+ * dangerous direction rather than the merely wasteful one.
495
+ *
496
+ * Neither outcome is corrected automatically. A cluster key is a claim about
497
+ * the world and only the person who made it can say whether it is true; this
498
+ * says what the data thinks of it.
499
+ */
500
+ export function clusterKeyDiagnostic(declared, fallback) {
501
+ if (declared.length !== fallback.length) {
502
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `clusterKeyDiagnostic: the two groupings must cover the same observations (${declared.length} vs ${fallback.length})`, {
503
+ detail: { declared: declared.length, fallback: fallback.length },
504
+ hint: "group the same value array twice; do not filter one of them",
505
+ });
506
+ }
507
+ const d = summarise("declared", declared);
508
+ const f = summarise("case-id", fallback);
509
+ // A grouping with fewer than two clusters has no estimable between-family
510
+ // variance, so its design effect is Infinity and its ICC is meaningless.
511
+ // Comparing those against the fallback produces a verdict full of `Infinity×`
512
+ // that reads like a very large finding and is really an absence of one.
513
+ if (d.degenerate !== null) {
514
+ return {
515
+ declared: d,
516
+ fallback: f,
517
+ mergesUncorrelatedCases: true,
518
+ narrowsOnTooFewClusters: false,
519
+ narrowsBySplitting: false,
520
+ findsHiddenCorrelation: false,
521
+ verdict: `the declared key collapses ${f.clusters} case-file groups into ${d.clusters}, ${d.degenerate}. ` +
522
+ "No suite-level interval is estimable under this grouping, so it is not a tighter claim " +
523
+ "than the default; it is no claim at all",
524
+ };
525
+ }
526
+ // "Materially positive" rather than "> 0": the ANOVA ICC estimator is noisy
527
+ // and routinely lands slightly above zero on independent data, so a test at
528
+ // exactly zero would call every grouping useful.
529
+ const ICC_FLOOR = 0.05;
530
+ const coarser = d.clusters < f.clusters;
531
+ const mergesUncorrelatedCases = coarser && d.iccEstimable && d.icc < ICC_FLOOR;
532
+ const narrowsOnTooFewClusters = mergesUncorrelatedCases && d.widthRatio < f.widthRatio && d.clusters < MIN_TRUSTWORTHY_CLUSTERS;
533
+ // The other direction. Both flags above require `coarser`, so a key that
534
+ // *splits* the case files apart fell through every branch to "it is not
535
+ // changing the answer either way", on a grouping that had just taken the
536
+ // interval from 3.90× the iid one to 1.02×. Gated on the fallback showing
537
+ // real correlation: when the case files do not move together anyway,
538
+ // splitting them costs nothing and there is nothing to warn about.
539
+ //
540
+ // Sharing ICC_FLOOR with `mergesUncorrelatedCases` also shares its noise. On
541
+ // 8 families of 10 this fires on every seed where the families really move
542
+ // and on 0.195 of the seeds where they do not; `cluster.test.ts` costs both
543
+ // out. That asymmetry is the one to have: the flag errs toward asking an
544
+ // operator to look again at an interval that got narrower, which is the
545
+ // question this module exists to make people ask.
546
+ const narrowsBySplitting = d.clusters > f.clusters && f.iccEstimable && f.icc >= ICC_FLOOR && d.widthRatio < f.widthRatio;
547
+ // `iccEstimable` first: a grouping of singletons reports ICC exactly 1 as an
548
+ // artifact of σ̂² = 0, which sailed past this floor and could announce that a
549
+ // one-case-per-cluster key had "found correlation the case ids could not
550
+ // see". One case per cluster is the absence of within-cluster correlation.
551
+ const findsHiddenCorrelation = d.iccEstimable && d.icc >= ICC_FLOOR && d.designEffect > f.designEffect * 1.1;
552
+ // Quote the *interval width*, not the design effect. They do not move
553
+ // together: a coarse grouping with near-zero ICC can have a design effect
554
+ // below 1 and still produce a much wider interval, because 4 clusters buy 3
555
+ // degrees of freedom and a t-critical to match. The first draft of this line
556
+ // said "widening the interval (0.11× vs 0.91×)", which reads as narrowing.
557
+ const widths = `its interval is ${d.widthRatio.toFixed(2)}× the iid one against ${f.widthRatio.toFixed(2)}× for the case-file default`;
558
+ // "ICC 1.00" is what a singleton grouping prints, and it says the cases are
559
+ // perfectly correlated when the grouping is the statement that they are not
560
+ // correlated at all. Say the number is missing rather than inventing one.
561
+ const icc = (g) => (g.iccEstimable ? g.icc.toFixed(2) : "not identified");
562
+ const verdict = narrowsOnTooFewClusters
563
+ ? `the declared key merges ${f.clusters} case-file groups into ${d.clusters}, and those ${d.clusters} show ` +
564
+ `ICC ${icc(d)}, they do not move together, so ${widths}. That is the wrong direction: ` +
565
+ `a cluster-robust interval over fewer than ${MIN_TRUSTWORTHY_CLUSTERS} clusters is optimistic, and this key has ` +
566
+ `made the suite-level claim *tighter* than the default on cases that share nothing`
567
+ : mergesUncorrelatedCases
568
+ ? `the declared key merges ${f.clusters} case-file groups into ${d.clusters}, and those ${d.clusters} show ` +
569
+ `ICC ${icc(d)}, they do not move together, so ${widths}, and the extra width is ` +
570
+ `buying no information`
571
+ : narrowsBySplitting
572
+ ? `the declared key splits ${f.clusters} case-file groups into ${d.clusters}, but those ${f.clusters} files ` +
573
+ `show ICC ${icc(f)}, they do move together, so ${widths}. The split is a claim that the suite is worth ` +
574
+ `~${Math.round(d.effectiveSampleSize)} independent cases rather than ~${Math.round(f.effectiveSampleSize)}, ` +
575
+ "and it buys a narrower suite-level interval than the default with nothing behind it"
576
+ : findsHiddenCorrelation
577
+ ? `the declared key finds correlation the case ids could not see: design effect ` +
578
+ `${d.designEffect.toFixed(2)} against ${f.designEffect.toFixed(2)} over ${d.clusters} groups rather than ` +
579
+ `${f.clusters} (ICC ${icc(d)} within the declared groups, ${icc(f)} within case files). ` +
580
+ `The suite is worth ~${Math.round(d.effectiveSampleSize)} independent cases, not ${Math.round(f.effectiveSampleSize)}` +
581
+ (d.clusters < MIN_TRUSTWORTHY_CLUSTERS
582
+ ? `. Treat the interval as a lower bound on the width: ${d.clusters} clusters is below the ${MIN_TRUSTWORTHY_CLUSTERS} ` +
583
+ "a cluster-robust estimator needs to be trusted"
584
+ : "")
585
+ : `the declared key and the case-file default agree to within ` +
586
+ `${((Math.abs(d.designEffect - f.designEffect) / Math.max(1e-9, f.designEffect)) * 100).toFixed(0)}% on the design effect ` +
587
+ `(ICC ${icc(d)} vs ${icc(f)}), it is not changing the answer either way`;
588
+ return {
589
+ declared: d,
590
+ fallback: f,
591
+ mergesUncorrelatedCases,
592
+ narrowsOnTooFewClusters,
593
+ narrowsBySplitting,
594
+ findsHiddenCorrelation,
595
+ verdict,
596
+ };
597
+ }
598
+ //# sourceMappingURL=cluster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"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"}