The stuff this cycle made, archived 2026-10-21 and rendered from
git show rev65-attempt39-iterations11ofx:stuff/โฆ.
recal-per-n-answer.mdrecal-per-n-audit.mdrecal-per-n-closing.md
Answer to the cycle 75 direction. Run by member-2 with stuff/recal-per-n-test.py on cycle 74's stored per-draw rows (null-draws.csv, df3-draws.csv, 2000 draws per seed, both seeds pooled per rule 1). Output: stuff/recal-per-n-test.csv.
Short answer: no, it is not an artefact. With each n's own pooled null p95 as the critical value, the null false-flag rate is flat at 5% by construction, but the df=3 margin and the df=3 flag rate still move across n = 25, 50, 100 under rule 2's step-and-interval test. Only the null rate stops moving, and it stops moving because recalibration pins it.
| n | critical | held n=50 value |
|---|---|---|
| 25 | 0.081444 | 0.060596 |
| 50 | 0.058392 | 0.060596 |
| 100 | 0.041941 | 0.060596 |
| quantity | n=25 | n=50 | n=100 |
|---|---|---|---|
| null false-flag rate | 0.0500 [0.0495, 0.0500] | 0.0500 [0.0495, 0.0500] | 0.0500 [0.0495, 0.0500] |
| df=3 flag rate (power) | 0.361 [0.342, 0.384] | 0.598 [0.580, 0.619] | 0.837 [0.822, 0.854] |
| df=3 margin (median/per-n p95) | 0.701 [0.664, 0.750] | 1.316 [1.251, 1.396] | 2.842 [2.667, 3.026] |
| df=3 margin at held 0.060596 (contrast) | 0.942 [0.905, 0.983] | 1.268 [1.217, 1.322] | 1.967 [1.874, 2.060] |
| quantity | step 25โ50 | step 50โ100 | same sign | half-width 25/50 | half-width 50/100 | moved |
|---|---|---|---|---|---|---|
| null false-flag rate | 0.0000 | 0.0000 | no | 0.0003 | 0.0003 | no |
| df=3 flag rate | +0.237 | +0.240 | yes | 0.021 | 0.020 | yes |
| df=3 margin | +0.615 | +1.527 | yes | 0.073 | 0.180 | yes |
Both steps of the df=3 flag rate and the df=3 margin exceed the wider adjacent half-width by an order of magnitude, so the result is not close.
python3 -I stuff/recal-per-n-test.py > stuff/recal-per-n-test.csv (about 10 s, pure python).
Audit of stuff/recal-per-n-test.py and stuff/recal-per-n-answer.md against rule 1 (per-n critical from the stored rows, both seeds pooled) and rule 2 (step-and-interval test applied to the recalibrated values only). Checked by an independent recompute from null-draws.csv and df3-draws.csv with no shared code: a separate quantile function, statistics.median for the df=3 median, and per-seed splits the script never computes.
Verdict: the script complies with both rules and its numbers reproduce. The answer's conclusion stands: the null rate's n-dependence in cycle 74 was the held critical; the df=3 margin and flag rate move across n on their own.
| n | rows (null, df=3) | script crit | independent crit | match |
|---|---|---|---|---|
| 25 | 4000, 4000 | 0.081444 | 0.081444 | yes |
| 50 | 4000, 4000 | 0.058392 | 0.058392 | yes |
| 100 | 4000, 4000 | 0.041941 | 0.041941 | yes |
load() keys rows by n only, so both seeds (65068, 65069) pool into one list of 4000 per n. Rule 1 satisfied.stats() computes crit = pct(null, 0.95) from that pooled list. The held value HELD is used only for the margin_held contrast row, never for null_rate, df3_rate or margin. Rule 1 satisfied.| quantity | n=25 | n=50 | n=100 |
|---|---|---|---|
| null rate, script / audit | 0.0500 / 0.0500 | 0.0500 / 0.0500 | 0.0500 / 0.0500 |
| df=3 rate, script / audit | 0.3610 / 0.3610 | 0.5975 / 0.5975 | 0.8373 / 0.8373 |
| margin, script / audit | 0.7006 / 0.7006 | 1.3159 / 1.3159 | 2.8424 / 2.8424 |
| df=3 median stat (audit) | 0.057063 | 0.076836 | 0.119211 |
All twelve values agree to four decimals. The null rate equals exactly 200/4000 at each n, which is what a linearly interpolated p95 over 4000 rows must give, confirming the "5% by construction" claim.
v from res[n][q][0], the point value at that n's own critical, for null_rate, df3_rate and margin. Rule 2 satisfied.margin_held also appears in the moved table. Rule 2 says the test applies to the recalibrated values, "never the held n=50 ones". The script labels that row as contrast only and the answer does not count it as a finding, so this is a presentation issue, not a violation. Future runs should drop it from the moved table or mark it excluded.Nearest-rank p95 (the 3800th of 4000 sorted rows) instead of linear interpolation gives criticals 0.081439, 0.058391, 0.041937 and margins 0.7007, 1.3159, 2.8426. The conclusion does not depend on the quantile convention.
null_rate is trivially "not moved"; it should not be read as evidence about the gate.recal-per-n-test.csv as given; the point values they bracket all reproduce, and the steps exceed them by an order of magnitude.
Ties together recal-per-n-answer.md (member-2, the run) and recal-per-n-audit.md (member-3, the check) so the next cycle can cite one file. Numbers are the audited ones; both files agree to four decimals.
Per-n recalibration removes the null-rate n-dependence and nothing else. The df=3 margin (0.70, 1.32, 2.84) and df=3 power (36%, 60%, 84%) still move across n = 25, 50, 100 under rule 2, by an order of magnitude over the adjacent bootstrap half-widths. Cycle 74's finding splits cleanly:
| cycle 74 observation | artefact of held n=50 critical? |
|---|---|
| null false-flag 12% / 4.3% / 1.4% | yes, entirely. 5.00% at every n once recalibrated (200 of 4000 per n). |
| df=3 margin 0.70 / 1.32 / 2.84 | no. Cycle 74 already used each n's own p95; rule 1 reproduces it exactly. Holding n=50 would have *narrowed* the spread (0.94 / 1.27 / 1.97). |
| cycle 71 value 2.5 not reproduced at n=50 | no. Still 1.316 [1.251, 1.396] under recalibration; 2.5 lies between n=50 and n=100. |
The margin is median(df=3 stat) / null p95 at the same n. Both numerator and denominator fall with n, but the null p95 falls faster, so the ratio grows. That is a property of the statistic under the alternative, the same thing that makes power rise from 36% to 84%. It is not something a critical-value choice can remove, and it is not a defect: a consistent test is supposed to separate better as n grows.
What *was* a defect, and is now closed, is quoting a single critical value across n. The direction's phrase "entirely an artefact" is therefore half right, and the half it is right about is the only half that was ever a calibration problem.
The margin's definition is now settled (median / per-n p95) and the gate is calibrated. What is still untested is whether the n-dependence of the margin is *linear in sqrt(n)* or something else: the three points (0.70, 1.32, 2.84 at n = 25, 50, 100) roughly double per doubling of n, which is faster than sqrt. One more n (200) with the same stored-row protocol would decide it.
Reproduce everything: python3 -I stuff/recal-per-n-test.py (about 10 s).