Skip to content

M4 disability gate: floors and anchor evidence base#153

Merged
MaxGhenis merged 4 commits into
masterfrom
m4-gate-floors
Jul 12, 2026
Merged

M4 disability gate: floors and anchor evidence base#153
MaxGhenis merged 4 commits into
masterfrom
m4-gate-floors

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

M4 disability gate — floors + anchor evidence base (ceremony step 1)

Status: fixes round complete (referee findings 1–6 dissolved — round-1 comment 4950447491, fixes comment 4950571161, verification comment 4950648191). This body reflects the FIXED gate; the round-1 description it replaced is superseded.

DRAFT — the ceremony controls this PR; gates.yaml UNTOUCHED. The gate_m4 stub below is the flip source.

Gate surface (12 gate-eligible / 24 report-only)

Internal (8, candidate↔PSID reproduction): 6 flow cells @k=3 (incidence.40-49|f, incidence.50-59|{f,m}, recovery.50-59|f, recovery.60-66|{f,m}) + 2 stock cells @k=4 (prevalence.50-59|{f,m}, σ-units 3.225/3.123). Mixed-k rule committed as a pre-registered deviation with the k-selection block (k=2 flow OC 0.2901; option-(i) 0.9008; adopted OC 0.9689). Honest uniform-k sensitivity: k=2→21, k=3→12, k=4→2.

Anchor (4, PSID↔SSA concept bridges): T19 prevalence age-shape comonotone + 50-59 peak |{f,m}; T50 retirement-dominant conversion exit |{f,m} (death-censoring bridge; age-universe mismatch named). Candidate-side statistic PINNED: per gate seed, mean-over-K=20 rates, margin ≥ 3σ (bare ordinal insufficient — the ε-tilt degenerate fails at 0.0917/0.0912 ≪ 3; committed in the degenerate table).

Protocol

Ratified mean-over-K=20-draws estimator, streams 5200+k VERBATIM (tranche-2a amendment 1); fresh_run_artifact_schema [20,8,5] with per-draw rates, undefined-draw invalidation, and dispersion disclosure — in protocol and stub.

Report-only (24)

Machine reasons throughout: tolerance_above_t_max (incl. both conversion levels), no_pooled_year_series (T49 trend), denominator delta (6.B5.1 conversion level), half_split_fragile (conversion sex-ordering). Concept deltas 1-3/4/5/7 numbering per the frozen m4 module artifact; attrition censoring named beside death censoring.

Teeth (corrected wart 2)

Internal cells carry ALL level teeth (including the stock via prevalence.50-59@k=4); anchor cells carry exit-composition/shape teeth (the RTW-dominant degenerate is caught ONLY by them). Anchor booleans on the frozen tables are corroboration, not gate content.

OC

Faithful-candidate p_seed 0.9408 / p_gate(≥4/5) 0.9689 (marginally above the 2a/2b/2c band top 0.9685 — the band constraint is a floor; round-1's own computed remedy endorsed this OC).

gate_m4 stub (flip source)

gate_m4:
  kind: anchor_based
  status: unlocked  # flips after ratification
  gated: 12  # 8 internal (6 flow k=3, 2 stock k=4) + 4 anchor (margin >= 3*sigma)
  estimator: mean_over_k20_draws  # streams 5200+k VERBATIM
  fresh_run_artifact_schema: [20, 8, 5]  # + undefined-draw invalidation + dispersion
  anchors: data/external/di_asr_2023 (sha-pinned)
  floor_run: runs/m4_gate_floors_v1.json

Full machine-derivable thresholds: draft_thresholds in the committed artifact (the flip reads the artifact, not this prose).

Evidence: floors 100-seed person-disjoint; anchors re-derived from in-repo tables; rebuild deterministic; 34 binding tests incl. mutation coverage (9/9 caught) and label-swap catches.

Ceremony step 1 for the DI gate (roadmap #113, M4): the floors + anchor
basis its thresholds will derive from. Reads no gate, changes no gate;
gates.yaml is UNTOUCHED (the proposed gate_m4 stub-flip lives in the
artifact note + PR body for the referee rounds and eventual ratification).

ANCHOR-BASED (gate-1 external-check style), not holdout-only (gate-2): the
PSID EMPLOYMENT STATUS self-report is not the SSA DI program (seven named
concept deltas), so no SSA DI level is gated. Gated cells live only on
concept-bridgeable surfaces, scored against the sha-pinned in-repo DI ASR
2023 tables:
- (a) conversion-exit vs Table 50: retirement is the majority non-death
  disability exit near FRA (dominance, per sex).
- (b) prevalence age-shape vs Table 19: co-monotone rise + 50-59 peak
  (ordinal, per sex; bounded stats gated as invariants, not |ln ratio|).
- (d) internal incidence/recovery: the 100-seed person-disjoint half-split
  |ln(r_A/r_B)| floor, round(mean+3*sd,3) capped at ln(1.5).
Report-only with the delta named (never calibrated): the Table 49
termination-rate trend (period-pooling), the 6.B5.1 conversion level and
sex-ordering, all prevalence levels + the 60-FRA band, and the noisy
transition cells above the cap.

Deliverables: scripts/build_m4_gate_floors.py (deterministic; no populace-fit,
no pe-us), runs/m4_gate_floors_v1.json via write_new, binding tests (no dead
zones, label-swap catches, sha pins) + a PSID reproduction, tier refresh,
honest warts (k=4 empties the internal surface; the gate leans on the anchor
cells).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
social-security-model Ready Ready Preview, Comment Jul 12, 2026 9:16am

Request Review

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Round-1 adversarial referee: M4 disability gate floors

Verdict: AMEND BEFORE LOCK

Everything numerical in this artifact reproduces independently and exactly — panel (41,345 persons / 284,932 person-years / 227,579 pairs), all 32 reference moments to 1e-12, the full 100-seed floor to 1e-9, every tolerance, the partition and its machine reasons, the OC 0.9717, the training-copy 0.9161, the anchor margins (6.099/5.298/4.797/12.806 sigma), holds-on-all-100-halves, the T19/T50/T49 extractions re-derived from the committed table with an independent parser, and a full rebuild is substantively byte-identical with populace.fit never imported. gates.yaml is byte-identical to master (sha 3990e15a…, checked against current head 8348b64). The 27 new tests pass; the mutation table below shows no dead zones. That part of the ceremony is in excellent shape.

The gate cannot lock as designed, though. The internal surface quietly contradicts the frozen module artifact's own pre-registration under an invalid machine reason, and that unregistered restriction is what produces the headline "k=4 empties the internal surface" wart and the committed k-sensitivity table. Two further protocol objects (the K=20 draw stream and the anchor-cell candidate rule) drift from or under-specify the ratified conventions. Findings and required fixes follow.


Finding 1 (BLOCKER): the internal surface drops pre-registered families under an invalid reason, and the k=4 narrative is an artifact of that restriction

The frozen runs/m4_disability_v1.json proposed_thresholds_note (verified byte-for-byte, untouched by this branch) pre-registered, for the internal floor:

  • the statistic: "the weighted per-interval PSID transition rate … and disabled prevalence from this artifact, and a synthetic candidate's same-band rate built the same way … scored as |ln(r_candidate / r_PSID)| per cell";
  • the gate-eligible set: all 32 cells — incidence, recovery, prevalence, and conversion — under "defined on every seed AND ≥ 20 events on the weaker half of the worst seed" ("Report-only (numerator-fragile): []").

build_m4_gate_floors.py adds FAMILY_INTERNAL_GATED = {incidence, recovery} and demotes all 10 prevalence + 2 conversion cells with machine reason level_bridged_via_anchor_shape — "the concept deltas block a level gate". That reason is a category error. The seven concept_deltas are PSID-vs-SSA deltas; the internal cells score candidate-vs-PSID reproduction, in which no SSA concept appears. The deltas can (and correctly do) block gating PSID levels against SSA levels; they say nothing about gating a candidate's reproduction of PSID prevalence against a PSID holdout — which is exactly what the frozen note pre-registered. It also masks the conversion cells' true machine reason: they demote honestly on power (tol 0.596/0.611 > ln(1.5)), but the committed reason is the invalid family string, because the family check runs first.

Recomputed on the committed 100-seed floor, with the pre-registered families restored and the inherited power rules applied unchanged:

cell mean sd tol(k=3) tol(k=4) verdict at k=3 / k=4
prevalence.40-49|f / |m 0.1138 / 0.1183 0.0740 / 0.0883 0.336 / 0.383 0.410 / 0.472 gates / demotes
prevalence.50-59|f / |m 0.0916 / 0.1016 0.0700 / 0.0712 0.301 / 0.315 0.371 / 0.387 gates / gates
prevalence.60-66|f / |m 0.1207 / 0.1173 0.0899 / 0.0911 0.390 / 0.391 0.480 / 0.482 gates / demotes
conversion.|f / |m 0.1864 / 0.1693 0.1367 / 0.1472 0.596 / 0.611 demotes (power) at any k
prevalence.20-29, 30-39 0.430–0.698 demote (power) at k=3

Corrected k-sensitivity over the pre-registered surface: k=2 → 21, k=3 → 12, k=4 → 2 — not the committed 12/6/0, which is k-sensitivity over the unregistered transition-only restriction. So:

  • Wart 1 ("k=4 empties the internal surface") is true only after the restriction. On the pre-registered surface, k=4 gates prevalence.50-59 for both sexes at tolerances 0.371/0.387 (3.22/3.12 in realized-sigma units).
  • The gate currently binds no level anywhere on the occupancy stock — the quantity the module's own docstring calls "the integrative quantity a payable-baseline composition rides on". A candidate with correct hazards and a 3x-wrong disabled stock passes all 10 gated cells: the internal cells never see prevalence, and the anchor cells are ordinal (any rising shape passes — see the degenerate table).

Required fix A. Either (i) restore the pre-registered families to the internal partition and let the inherited power rules produce the honest partition — at k=3 that is 12 gated internal cells (six transitions + six prevalence), faithful OC 0.9008; or a computed variant that preserves the precedent OC: transitions at k=3 plus prevalence.50-59|{f,m} at the 2c-inherited k=4, OC 0.9689 (at the precedent level: 2a 0.9685, 2b 0.9678, 2c 0.9641) — any such mixed rule must itself be stated and pre-registered; or (ii) keep the exclusion but pre-register a valid stated reason (e.g., a module-boundary/initialization argument about whose module owns the simulated stock), disclosed as an explicit deviation from the frozen note — not the concept deltas.

Required fix B. Commit the k-sensitivity over the pre-registered surface alongside the transition-only table, rewrite wart 1 ("k=4 empties the transition families; prevalence.50-59 still gates at k=4"), and correct the conversion cells' machine reason to their true power demotion.

Finding 2 (MAJOR): K=20 estimator drift — the draw stream and the fresh-run audit contract

The ratified tranche-2a amendment-1 estimator pins numpy.random.default_rng(5200 + k), k=0..19; gate-2b and gate-2c both adopt it with the phrase "re-used VERBATIM" and the same 5200 base (the superseded single-draw convention was the 4200 family). This artifact's protocol block and the proposed gate_m4 stub use 4100 + k with no stated reason ("distinct from the split seeds 0..99" is equally true of 5200). The artifact claims the estimator is "the ratified tranche-2a amendment-1 estimator, adopted from the START" while quietly altering its pinned stream; test_protocol_is_k20_from_the_start then binds the test to the drifted constant, pinning the drift rather than catching it.

The ratified estimator also comes with fresh_run_artifact_schema — the per-draw per-cell rate cube ([20, n_gated_cells, 5]), the undefined-draw run-invalidation rule, and the per-draw dispersion disclosure — which 2b and 2c carry forward explicitly and which is what makes a 20-draw mean auditable rather than taken on trust. It is absent from this protocol block and from the stub.

Required fix C. Adopt 5200 + k and the fresh-run artifact schema verbatim (protocol block + stub), or state and pre-register the deviation with a reason.

Finding 3 (MAJOR): the anchor cells' candidate-side scoring rule is under-specified

The internal statistic is pinned precisely (mean-over-K rate, scored once, per gate seed, 4-of-5). The anchor statistic is: "the ordinal invariant … holds on the candidate's simulated holdout, as it does on the real full sample and all 100 halves." Unpinned: (i) is the candidate's simulated panel itself split into 100 halves, or scored once per gate seed? (ii) does the ≥ 3-sigma margin apply to the candidate, and if so with whose sigma? (iii) how do the K=20 draws enter (per draw / mean panel / any-draw-fails)? (iv) 4-of-5 conjunction or a single full-sample check?

The readings differ qualitatively: an epsilon-tilt candidate (shares rising by 0.001 per band) passes the bare ordinal reading and fails a 3-sigma-margin reading (3 x half-split sd is approximately 0.033 on the min-gap). Since 4 of the 10 gated cells are anchor cells, a locked gate cannot leave this open.

Required fix D. Pin the candidate-side anchor statistic exactly (recommend: computed per gate seed on the same mean-rate basis as the internal cells, with the margin requirement stated one way or the other), and add the binding test.

Finding 4 (MINOR): wart 2 has the teeth backwards, and the anchor-side conditions are frozen-table constants

Degenerate-candidate results (all scored against the committed tolerances and the five gate seeds' side-A rates; prevalence shapes via a 2-yr Markov cohort proxy on the PSID person-year age structure):

candidate anchor: prevalence shape anchor: conv dominance internal 6 cells (k=3)
verbatim train-copy (side B) passes (real halves) passes passes 5/5, max score 0.92x tol
age-flat hazards (pooled per-sex rates) FAILS — hump at 40-49, min gap −0.018 (f) / −0.027 (m) n/a (mix undefined) FAILS 0/5 — incidence.50-59|f at 1.19–1.68x tol
age-flat prevalence (equal shares) FAILS (min gap 0) n/a n/a
epsilon-tilt prevalence (+0.001/band) passes ordinal / fails margin (finding 3) n/a n/a
all-retire-at-60 (every exit to retired) n/a passes trivially (share 1.0) FAILS 0/5 — recovery.60-66 at 1.83–2.49x tol
return-to-work-dominant exit mix (0.45) n/a FAILS not seen — no internal cell gates exit composition

So the anchor cells are not vacuous: they uniquely catch exit-mix inversion (nothing internal sees composition) and reject flat/hump shapes. But every level catch in this table is internal. Wart 2's "the binding power is mostly the concept-bridged ordinal anchors" is backwards for level defects — and it is the level surface finding 1 shows is under-gated. Note also that t19_strictly_rises_bridged and t50_is_dominant are constants of the frozen table: they corroborate the choice of invariant at evidence time and constrain no candidate; T50 dominance is additionally near-mechanical (FRA conversion is automatic at FRA, and Table 50's cessations pool all ages against the PSID 60–67 window — an age-universe mismatch the bridge text should name).

Required fix E. Correct wart 2; name the T50 age-universe mismatch and the mechanical component of its dominance in the concept_bridge; describe the anchor-side booleans as corroboration, not candidate constraints.

Finding 5 (MINOR): redundant anchor conditions presented as independent corroboration

Within the four bridged bands, "peaks at 50-59" is implied by "strictly rises" (the argmax of a rising 4-vector is its last element), and "rank agreement 1.0 over the bridged bands" is implied by "PSID strictly rises" + "T19 strictly rises". Both add zero bite; the prose ("rank agreement 1.0", "the 50-59 peak") reads as extra co-movement evidence. The true Table 19 peak is 60-FRA (0.451/0.457 vs 0.350/0.333 at 50-59) — the "50-59 peak" exists only inside the bridged-band window whose boundary was set by the delta that excludes 60-66. Gating the rise is fine; the redundant conditions should be labeled as implied (or dropped from the gate rule), and the "peak" language qualified.

Finding 6 (MINOR): delta numbering and censoring disclosure nits

  • The bridge texts cite "deltas 1-2" for milder/younger self-report (severity is delta 3; should be 1–3) and "delta 3" for the relabel-to-retired near FRA (the relabel is delta 4, transience). Same off-by-ones in the PR body table. In a gate whose whole defense is named-delta bookkeeping, the numbering should be exact.
  • Wart 4 names death censoring in the conversion-exit statistic but not attrition censoring, which operates identically on pair formation and has no Table 50 analog. One sentence.

The k=3 adjudication (no finding beyond the required disclosures)

The pre-registration is real: the frozen note proposes "round(mean + k*sd)" with "a PROPOSED k in [2, 3] for the ceremony to fix", ≥ 20 events, and the |ln ratio| statistic, byte-for-byte. Two recomputed facts make top-of-range principled rather than convenient:

  1. The range was not reverse-engineered to dodge k=4: on the note's own 5-seed floor (noise_floor_seeds_0_4), k=4 clears T_max for 9 of 32 cells including 5 transition cells — at proposal time k=4 did not look empty. The emptiness (of the transition families) only emerged on this PR's 100-seed floor.
  2. Within [2, 3] on the committed floor and surface, k=2 gates 12 transition cells at mean+2sd tolerances and collapses the faithful-candidate OC to 0.5719 per seed / 0.2901 per gate — unusable against the 2a/2b/2c precedent band (0.9641–0.9685) — while k=3 delivers 0.9717. k=3 is the only in-range choice that clears precedent.

Required fix F. Commit that selection rule and the k=2 OC in the artifact (they are currently absent), so the k choice is machine-checkable rather than asserted — and note that fix A's surface decision changes the OC arithmetic (12-cell k=3: 0.9008; hybrid: 0.9689).

Half-overlap honesty (wart 3): quantified, and better than claimed

Person block-bootstrap (multinomial over the 41,345 persons, B=1000), fresh-sampling sd vs the across-100-overlapping-halves sd:

statistic half-split sd fresh sd ratio committed margin (half-sigma) margin in fresh-sigma violations in 1000 draws
prev min-gap, f 0.0109 0.0099 0.91 6.10 6.69 0 (min 0.035)
prev min-gap, m 0.0110 0.0119 1.09 5.30 4.88 0 (min 0.016)
conv share, f 0.0435 0.0415 0.95 4.80 5.03 0 (min 0.572)
conv share, m 0.0280 0.0311 1.11 12.81 11.53 0 (min 0.750)

The finite-population correction at 50% sampling offsets the half-scale factor, so the across-halves sd approximates full-sample fresh-sampling noise (ratios 0.91–1.11) — the sd does not materially understate here. At holdout (~50%) candidate scale, multiply noise by sqrt(2): the worst margin is still ~3.4 sigma. Wart 3 can be strengthened from "sd understates independent noise" to these measurements (recommend committing the bootstrap check).

Mutation table (all caught; no dead zones)

mutation caught by
builder DRAFT_K 3 → 4 (assignment line) constants pin
builder T_MAX ln(1.5) → ln(1.6) constants pin + partition reconstruction (recovery.50-59|m would gate)
builder MIN_EVENTS 20 → 200 constants pin + partition reconstruction
builder CANDIDATE_DRAWS 20 → 1 constants pin + K=20 protocol binding
artifact tolerance 0.358 → 0.36 (one cell) tolerance-floor binding + OC binding
artifact k-sensitivity k=4: 0 → 2 k4-empties binding
artifact conv-exit share label-swapped (0.709 → 0.291) conv gated + swap catch
artifact prevalence bands 20-29 ↔ 50-59 swapped (f) prevalence gated + swap catch
artifact T50 fra_conversion 455,267 → 400,000 anchor re-derivation + T50 arithmetic
gates.yaml: append a gate_m4: block no-gate-mutated
tables.json: one appended byte anchor sha pin

The T_max and min-events mutations flow through the partition reconstruction, not just the constant pins — genuine dead-zone closure. (The label-swap tests are arithmetic restatements of the gated assertions — they catch a rebuilt-with-swapped-labels artifact only because the gated is True tests already would — harmless, but they are not independent catches.)

Verified clean (no action)

  • Tier counts: branch live collection == committed (2,218 = 178/599/782/520/139); the PR body's "2,191 → 2,218" is correct for its base (8592a9b). Master has since moved +29 tests via Gate-2c candidate 1: couple formation from certified components (registration 4950250151) #155 (21 artifact + 8 oracle), so tier_counts.json/README-tiers.md will conflict at merge — mechanical re-refresh, CI-caught.
  • T49 report-only classification (period-pooling): verified, own parse 196 (1960) → 76 (2003 trough) → 90 (2015) → 107 (2023), rising; no year-indexed PSID analog exists in the module — correct to record, not gate.
  • Conversion-exit death-censoring bridge: re-derived. PSID pairs right-censor death (no w′ observation; deaths never counted as exits); the matched T50 denominator drops death: 455,267/(455,267+99,721) = 0.820319, and the medical-cessation family (99,721 = 20,569 + 63,699 + 14,392 + 1,061) is the correct return-to-work-side pool. Including the residual "other" reasons gives 0.8161 — dominance is robust to that choice. As a dominance bridge this is fair, not convenient (the level stays report-only with delta 5 named, and the gated exit-conditional denominator correctly avoids 6.B5.1's award-conditional denominator); the two disclosures it still owes are in findings 4 and 6.
  • Sex-ordering demotion (93/100 halves) and the 6.B5.1 level ratios (0.267/0.322): reproduced; report-only classification is right.
  • Rebuild determinism, artifact/foundation moment binding, sha pins, write_new no-overwrite, populace.fit never imported: all verified.

Summary of required fixes

  • A (finding 1): restore the pre-registered internal families under the inherited power rules (12-cell k=3, OC 0.9008; or the computed hybrid transitions@k=3 + prevalence.50-59@k=4, OC 0.9689, itself pre-registered) — or pre-register a valid, stated exclusion reason that is not the concept deltas, disclosed as a deviation from the frozen note.
  • B (finding 1): commit k-sensitivity over the pre-registered surface (k=2 → 21, k=3 → 12, k=4 → 2); rewrite wart 1; correct the conversion cells' machine reason to the power demotion.
  • C (finding 2): 5200+k verbatim (or pre-registered deviation) + fresh_run_artifact_schema in protocol and stub.
  • D (finding 3): pin the anchor candidate-side statistic (halves/draws/margin/conjunction) + binding test.
  • E (finding 4): correct wart 2; name the T50 age-universe mismatch and mechanical dominance; anchor booleans described as corroboration.
  • F (k rule): commit the k-selection rule with the k=2 OC (0.2901); recompute OC under A's surface decision. Plus finding 5/6 text corrections (redundant conditions labeled, delta numbering, attrition censoring), and optionally commit the bootstrap check from the wart-3 table.

Every number above was recomputed from the raw committed inputs (PSID individual file, di_asr_2023/tables.json, the frozen m4_disability_v1.json) with independent implementations of the moments, splits audit, anchors, OC, and parses; the builder's own measure_seed_halfsplit was reused only for the 100-seed rerun after auditing the splitter (person-disjoint, exact cover, deterministic). No repo state was left modified. This PR correctly never marks itself ready; the next step after fixes is the verification round, per the 2c precedent.

MaxGhenis and others added 2 commits July 12, 2026 04:37
A/B (finding 1, BLOCKER): restore the pre-registered internal families
(incidence/recovery/prevalence/conversion) -- the concept deltas are PSID-vs-SSA
and never touch a candidate-vs-PSID reproduction cell. Adopt the referee's
computed mixed-k remedy: flow hazards @k=3 + prevalence.50-59 STOCK @k=4 (8
gated internal cells, faithful OC 0.9689). Commit the honest uniform-k
sensitivity over the pre-registered surface (k=2->21, k=3->12, k=4->2); correct
the conversion cells' machine reason to the power demotion.

C (finding 2, MAJOR): adopt the ratified 5200+k draw stream VERBATIM (was
4100+k) and carry the fresh_run_artifact_schema (per-draw rate cube [20,8,5],
undefined-draw invalidation, dispersion disclosure) into protocol + stub.

D (finding 3, MAJOR): pin the candidate-side anchor statistic -- per gate seed,
mean-over-K=20 rate basis, MARGIN >= MARGIN_K sigma (not the bare ordinal). Add
the degenerate table with the builder-computed epsilon-tilt row that FAILS the
pinned margin (margin_sigma ~0.09 << 3).

E/F (findings 4-6 + k rule): correct wart 2 (internal = level teeth incl. the
occupancy stock; anchors = exit-composition/shape teeth); name the T50
age-universe mismatch + mechanical dominance; label redundant anchor conditions
implied and frozen booleans corroboration; fix delta numbering (1-3 self-report,
4 transience, 5 conversion, 7 period pooling); name attrition censoring. Commit
the k-selection rule + the k=2 flow OC (0.2901) and the option-(i) uniform-k3 OC
(0.9008).

Full rebuild via the regenerator; updated always-runnable binding tests;
black/ruff clean; tier counts re-refreshed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Master moved (#155 + w2-seam-caregiver + gate2c-candidate1). Only
tests/tier_counts.json and tests/README-tiers.md conflicted; resolved by a
live full-suite recount of the merged tree: 178/647/782/520/148 = 2,275
(master 2,241 + the m4 gate's 34 tests: 32 artifact derivations + 2
integration_psid reproduction). All other files auto-merged; the m4 gate
artifact, builder and tests are untouched by the merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Fixes round — referee findings 1-6 (round-1 verdict AMEND BEFORE LOCK)

All six required fixes applied on m4-gate-floors (fixes commit 05d8292, plus a master merge 45bbabe for the tier re-refresh). Every committed number below is builder-recomputed from the raw inputs and bound by an always-runnable test; the full rebuild reproduces the referee's independently-computed remedy exactly. gates.yaml stays byte-identical (untouched); the PR remains draft.

A + B (Finding 1, BLOCKER) — restore the pre-registered internal surface

Hunks (scripts/build_m4_gate_floors.py): new ELIGIBLE_INTERNAL_FAMILIES / FLOW_FAMILIES / STOCK_FAMILIES / STOCK_K constants; new _cell_k; raw_tolerances, _demote_reason (family branch deleted), partition_cells, k_sensitivity, draft_thresholds rewritten; gate_design.surfaces.d + surface-(d) docstring.

The concept deltas are PSID-vs-SSA and never enter a candidate-vs-PSID reproduction cell, so the round-1 level_bridged_via_anchor_shape demotion of the 10 prevalence + 2 conversion cells was a category error. All four pre-registered families are restored to the internal partition. Adopted the referee's computed mixed-k remedy: flow hazards @k=3 + prevalence.50-59 STOCK @k=4.

  • New internal gated surface (8 cells) — the STOCK now has teeth:
    cell tol k σ-units
    incidence.40-49|f 0.358 3 (flow) 2.60
    incidence.50-59|f 0.334 3 (flow) 2.60
    incidence.50-59|m 0.354 3 (flow) 2.51
    recovery.50-59|f 0.400 3 (flow) 2.65
    recovery.60-66|f 0.332 3 (flow) 2.55
    recovery.60-66|m 0.400 3 (flow) 2.65
    prevalence.50-59|f 0.371 4 (stock) 3.23
    prevalence.50-59|m 0.387 4 (stock) 3.12
  • New faithful OC = 0.9689 (p_seed 0.9408), within the 2a/2b/2c precedent band (0.9641–0.9685). Option-(i) uniform-k=3 (12 cells) recorded at 0.9008 for the record.
  • Honest uniform-k sensitivity over the pre-registered surface: k=2 → 21, k=3 → 12, k=4 → 2 (committed at internal_noise_floor.k_sensitivity, with by_family). At k=4 the flow families empty but prevalence.50-59|{f,m} still gate — which is exactly why the stock inherits k=4.
  • Conversion machine reason corrected to the true power demotion: conversion.retired_from_disabled|{f,m}tolerance_above_t_max (tol 0.596/0.611 > ln 1.5). No cell carries level_bridged_via_anchor_shape anywhere.

C (Finding 2, MAJOR) — K=20 estimator stream + fresh-run audit contract

Hunks: DRAW_STREAM_BASE/CANDIDATE_DRAW_STREAM constants, new fresh_run_artifact_schema, protocol_block, _gate_m4_stub_proposal.

4100+k → the ratified 5200+k VERBATIM (the tranche-2a amendment-1 stream that 2b/2c re-used). Carried the fresh_run_artifact_schema forward: per-draw per-cell rate cube [20, 8, 5], undefined-draw run-invalidation, per-draw dispersion disclosure — in both the protocol block and the stub.

D (Finding 3, MAJOR) — pin the candidate-side anchor statistic

Hunks: protocol_block.anchor_statistic + new anchor_statistic_pins; new degenerate_candidates; prevalence_ageshape_checks / conversion_exit_checks gate_rule text.

Pinned rule: score the candidate's simulated holdout per gate seed on the mean-over-K=20-draws rate basis, require the invariant to hold with margin ≥ MARGIN_K=3 × the real half-split sd (not the bare ordinal); 4-of-5 conjunction. The anchor_statistic_pins block fixes halves / draws / margin-basis / conjunction explicitly.

  • Degenerate table (degenerate_candidates) adds the builder-computed ε-tilt row: a +0.001/band tilt passes the bare ordinal but FAILS the pinned margin — margin_sigma = 0.0917 (f) / 0.0912 (m) ≪ 3. Bound by test_epsilon_tilt_degenerate_fails_the_pinned_margin (recomputes margin = tilt / committed sd).

E (Finding 4) — wart 2 teeth + corroboration framing

Hunks: warts (wart 2 + wart 1 + wart 4), conversion_exit_checks.concept_bridge + anchor_corroboration, prevalence_ageshape_checks.anchor_corroboration/implied_conditions.

Wart 2 corrected to the right direction: internal cells = the level teeth (incl. the occupancy stock now); anchor cells uniquely catch exit-composition inversion + flat/hump shape. Named the T50 age-universe mismatch (cessations pooled over all ages vs the PSID 60-67 window) and the mechanical component of its dominance. t19_strictly_rises_bridged / t50_is_dominant relabeled as evidence-time corroboration, not candidate constraints.

Finding 5 — redundant anchor conditions

The "50-59 peak" and rank-agreement are labeled implied by the strict rise (implied_conditions); the "peak" language qualified (Table 19's true peak is 60-FRA, inside the bridged window only).

F (k rule) + Finding 6 — k-selection, delta numbering, attrition

Hunks: new k_selection + _uniform_k_cells + _oc_4of5; delta strings in prevalence_ageshape_checks / conversion_reports / termination_trend_report / warts.

  • k-selection rule committed (k_selection): flow k pinned by OC against precedent — k=2 flow OC = 0.2901 (unusable), k=4 flow surface empty (0 cells), k=3 flow OC = 0.9717 (clears precedent); stock k=4 the sole k a prevalence cell survives the cap. Bound by test_k_selection_rule_and_k2_oc_committed + test_k_selection_oc_recomputes_from_the_floor.
  • Delta numbering fixed: self-report milder/younger = deltas 1-3 (severity added); 60-FRA relabel = delta 4 (transience); 6.B5.1 conversion = delta 5; period-pooling = delta 7.
  • Attrition censoring named alongside death in the conversion-exit concept_bridge + wart 4 (no Table 50 analog).

Verification

  • Restored cell inventory: 8 internal gated (6 flow @k=3 + 2 prevalence.50-59 stock @k=4) + 4 anchor = 12 gate-eligible; 24 report-only. New faithful OC 0.9689.
  • Suite: always-runnable tiers green — 787 passed, 38 skipped (unit + artifact) on the merged tree; the m4 derivations file went 25 → 32 binding tests; PSID reproduction (test_m4_gate_floors.py, integration_psid) 2/2 pass with populace.fit never imported.
  • Tier re-refresh (mechanical, against current master which gained Gate-2c candidate 1: couple formation from certified components (registration 4950250151) #155 + w2-seam + gate2c-cand1): live full-suite recount 178 / 647 / 782 / 520 / 148 = 2,275; tier_counts.json + README-tiers.md conflicts resolved by recount.
  • black -l 79 + ruff clean; gates.yaml untouched; PR stays draft.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Round-2 verification referee: fixes round (05d8292 + merge 45bbabe)

Verdict: AMEND BEFORE LOCK — one amendment, metadata-only: the PR body. Every committed object verifies exactly.

The committed evidence is lock-clean. Every number in runs/m4_gate_floors_v1.json recomputes independently from the committed 100-value floors and from raw PSID: a full regenerator rebuild (my own driver, populace.fit never imported) is identical on every non-volatile field — zero diffs (only build.*, elapsed_seconds, and the revision_pins shas differ, as designed). All six fixes are faithfully executed in the artifact, builder, and tests. What is not executed is finding 6's PR-body limb — and the body is not inert metadata here: the builder's own docstring says "the gate_m4 stub-flip text lives in draft_thresholds_note and the PR body, for … the eventual maintainer ratification to insert", and the body's stub still carries rng 4100+k, the bare-ordinal anchor statistic, and the 6-cell internal surface — i.e. a maintainer ratifying from the body's stub would reinstate findings 2 and 3 into gates.yaml. The body also still states the withdrawn level_bridged_via_anchor_shape partition, "Gated (10)", OC 0.972, k-sensitivity 12/6/0, the round-1 (backwards) warts 1–2, and the exact delta off-by-ones ("delta 3" relabel, "delta 6" pooling) that finding 6 named in the body specifically. Amendment: rewrite the PR body to the committed state (gh pr edit; no code, artifact, or test change — those are verified exact). Then LOCK.


Per-fix verification (everything recomputed with independent implementations)

Fix Claim Recomputed Verdict
A — families restored all four pre-registered families internal-gate-eligible; no concept-delta demotion ELIGIBLE_INTERNAL_FAMILIES = {incidence, recovery, prevalence, conversion}; family branch deleted from _demote_reason; my own partition logic over the committed floor + stability reproduces every one of the 32 machine reasons; reason set ⊆ {gate_eligible, tolerance_above_t_max}; level_bridged_via_anchor_shape appears nowhere in the artifact PASS
A — mixed-k remedy flow@k=3 + prevalence.50-59 stock@k=4, 8 internal cells gated internal = exactly round-1's computed remedy: incidence.40-49|f, incidence.50-59|{f,m}, recovery.50-59|f, recovery.60-66|{f,m} @k=3 + prevalence.50-59|{f,m} @k=4; tolerances recompute from the committed 100-value floors as round(mean+k·sd, 3): 0.358 / 0.334 / 0.354 / 0.400 / 0.332 / 0.400 / 0.371 / 0.387; stated as a pre-registered deviation from the single-k frozen note (surface-d docstring, k_selection.rule, note) — the round-1 fix-A condition PASS
A — OC 0.9689 faithful OC 0.9689 (p_seed 0.9408) own erf implementation over the committed floors: p_seed 0.9408, p_gate 0.9689; all 8 per-cell pass probs match to 6dp. Stock σ-units: committed 3.225 / 3.123 (= tol/realized-σ; exact 3.2246 / 3.1231 — the fixes table's "3.23/3.12" and round-1's "3.22/3.12" are both 2dp renderings of these) PASS
B — honest k-sensitivity k=2→21, k=3→12, k=4→2 over the pre-registered surface recomputed 21 / 12 / 2 with matching cell lists; identical with and without the min-events filter (no hidden events dependence); k=4 survivors exactly prevalence.50-59|{f,m} (tol 0.371/0.387 ≤ ln 1.5); conversion machine reason corrected to the true power demotion (tol 0.596/0.611 > 0.4055 at k=3; > cap at any k∈[2,4]) PASS
C — 5200+k verbatim ratified stream + fresh-run schema in protocol + stub core string byte-equal to gate-2c's ratified candidate_draw_stream ("numpy.random.default_rng(5200 + k), k=0..K-1"); DRAW_STREAM_BASE = 5200; no active 4100 anywhere (only the "NOT the 4100/4200 family" disclaimer). fresh_run_artifact_schema [20, 8, 5]: field-level diff vs gate-2c's shows the only deltas are the gate name, the cell-count phrase, the shape, and the dims label — the undefined-draw rule, its rationale, and the dispersion block are byte-identical. In protocol ✓ and in the artifact's stub by reference ✓. (The PR body's stub still says rng 4100+k — the amendment.) PASS in artifact; body stale
D — pinned anchor statistic per gate seed, mean-over-K rate basis, margin ≥ 3σ, 4-of-5 anchor_statistic_pins closes all four round-1 ambiguities: (i) per gate seed, not re-split into 100 halves; (ii) margin vs fixed committed real half-split sd, never recomputed on the candidate; (iii) draws enter via rbar only; (iv) per-seed margin AND ≥4-of-5. Two-readings attack (below): no operative split survives. ε-tilt row reproduces exactly: 0.001/sd = 0.0917 (f) / 0.0912 (m) ≪ 3, passes-ordinal/fails-margin, test-bound. Anchor margins unchanged and recomputed: 6.099 / 5.298 / 4.797 / 12.806 σ, holds on all 100 halves PASS
E — wart 2 + corroboration teeth direction corrected; T50 disclosures wart 2 now: "every LEVEL defect is caught INTERNALLY … the anchors' UNIQUE catches are exit-COMPOSITION inversion … and flat/hump prevalence SHAPE" — the round-1 direction, corrected. T50 age-universe mismatch (all-ages cessations vs the PSID 60–67 window) + the near-mechanical dominance component named in anchor_corroboration and concept_bridge; t19_strictly_rises_bridged / t50_is_dominant relabeled evidence-time corroboration, constraining no candidate; degenerate_candidates commits the catch-structure rows + the builder-computed ε-tilt PASS
5 — redundant conditions implied, not independent implied_conditions: peak + rank agreement "add NO bite" (argmax of a rising 4-vector; PSID-rises + T19-rises force rank agreement); "50-59 peak" qualified everywhere it appears — Table 19's true peak is 60-FRA, excluded by the same delta-4 relabel that sets the window PASS
F — k-selection committed k=2 OC 0.2901; option-(i) 0.9008 recomputed with my own OC implementation: k=2 flow = 12 cells, per-seed 0.5719, gate 0.2901 (< band floor — unusable); k=4 flow surface empty; k=3 flow 0.9717; option-(i) uniform-k3 = 12 cells (6 flow + 6 prevalence), gate 0.9008; stock k=4 the sole k any prevalence cell survives. All equal the committed k_selection values; bound by two tests PASS
6 — deltas + attrition exact numbering; attrition named frozen foundation order verified: 1 definition, 2 population, 3 severity, 4 transience, 5 conversion denominator, 6 biennial censoring, 7 period pooling; artifact texts cite deltas 1-3 / 4 / 5 / 7 correctly. Attrition censoring named alongside death in the conversion concept_bridge + wart 4 ("NO Table 50 analog"). (The PR body still says delta 3 / delta 6 — the amendment.) PASS in artifact; body stale

The deliberate omission (wart 3): adjudicated correct

No bootstrap was committed; wart 3 is strengthened textually — primary evidence stays the non-parametric "holds on all 100 halves", plus "at the 50% finite-population correction the across-halves sd tracks full-sample fresh-sampling noise within ~10%". That is the right call: committing my round-1 B=1000 numbers without a builder recompute would break this ceremony's every-committed-number-recomputes invariant, and the ~10% summary is doubly supported (round-1 measured ratios 0.91–1.11; the f=1/2 FPC identity gives ratio 1 exactly for linear statistics). If the maintainer wants the bootstrap committed, it must enter through the builder — optional, at flip time.

Finding-3 adversarial attempt: constructing a two-readings candidate

Tried three constructions against the pinned rule. (a) Share-denominator ambiguity: a candidate scored on four-band-renormalized shares could pass where five-band shares fail — but the statistic is pinned by reference to the committed min_gap construction (five-band sex-total denominator, gaps over the bridged four), which the PSID pin test reproduces to 1e-12 and whose sd constant is only defined for that construction; a scorer using another denominator is not computing the pinned statistic. (b) Sparse-exit candidate: near-empty simulated FRA-window exit set, all→retired (share 1.0, margin ~11σ) — passes the pinned per-seed margin, but would fail the anchor_checks[*].gate_rule prose read literally ("holds on all 100 halves + ≥ 20 exits" in a sentence beginning "candidate…"). Under the pins those are evidence-time conditions (the candidate is never re-split; the exit floor gated the cell), and any candidate realizing this profile must distort the gated recovery.60-66/incidence hazards and fails internally. Operative contract (protocol + stub) is single-reading; the gate_rule prose mix is a flip-time wording note, not an open reading. (c) Margin-of-what: "min adjacent gap" is a committed scalar per seed; per-band and averaged readings are excluded by the pinned field names. The pinned ε-tilt discriminator reproduces exactly (0.0917/0.0912).

Mutation table (hermetic: bytecode disabled, pycache purged between steps; each run 32 bindings)

Mutation Caught by Result
builder STOCK_K 4→3 constants pin + partition reconstruction 2 failed
builder DRAFT_K 3→2 constants pin + partition reconstruction 2 failed
builder T_MAX ln(1.5)→ln(1.6) constants pin + partition reconstruction + k-selection-OC recompute 3 failed
builder MIN_EVENTS_FOR_GATE 20→200 constants pin + partition reconstruction 2 failed
artifact protocol.anchor_statistic → bare-ordinal text anchor-statistic pin (margin/"per gate seed"/"bare ordinal" discriminators) 1 failed
artifact T50 fra_conversion 455267→400000 anchor re-derivation from committed table + T50 arithmetic 2 failed
artifact tolerance prevalence.50-59|f 0.371→0.41 tolerance-floor binding + OC binding 2 failed
builder DRAW_STREAM_BASE 5200→4100 (bonus) constants pin + protocol-5200 binding 2 failed
artifact k_sensitivity k=4: 2→0 (bonus) k-sensitivity binding 1 failed

No dead zones found. One honest caveat: the anchor_statistic_pins sub-strings are bound by key presence plus the anchor_statistic discriminators (the margin arithmetic is separately bound by the ε-tilt recompute test), so a hostile rewrite of one pin's prose while keeping the key would pass the always-runnable tier — acceptable, since any scored use binds to the protocol strings the tests do discriminate, and the PSID tier reproduces the underlying constants. (Method note: an early non-hermetic battery showed run-to-run variance; it traced to my harness — CPython pyc (mtime-second, size) staleness under same-length source swaps within one second — not to the repo. Hermetic reruns are fully deterministic; CI's fresh checkouts cannot hit this.)

Suite, hygiene, CI

Flip-time notes (beyond the one amendment)

  1. Re-refresh tier_counts.json/README-tiers.md against master-at-flip (Gate-2c candidate 2: earnings-conditioned first-marriage timing (registration 4950370498) #157 already conflicts).
  2. "OC within the precedent band" (fixes comment; k_selection alt note "within precedent"): 0.9689 sits 4e-4 above the band top (0.9641–0.9685). The band constraint is a floor and round-1 endorsed exactly this OC — but say "at/above precedent". Cosmetic.
  3. Reword anchor_checks[*].gate_rule to separate the evidence-time cell conditions ("holds on all 100 halves", "≥ 20 exits") from the candidate-voiced sentence; if a candidate-side exit floor is intended, pin it explicitly (see the sparse-exit construction above).
  4. σ-units presentation: the committed values are 3.225/3.123; both comments' 2dp renderings are the same numbers.
  5. Optional: commit the wart-3 bootstrap through the builder; the current no-uncomputed-numbers choice is correct as-is.

Summary: artifact, builder, and tests are LOCK-clean — every recomputation exact, every mutation caught, rebuild zero-diff. The single blocking item is the PR body (a designated stub-flip source) still describing the round-1 gate: rewrite it to the committed state, then this gate is ready for the flip step. Verified with independent implementations of the partition, tolerances, OC, k-sensitivity, k-selection sweeps, anchor margins, ε-tilt, schema diff, and the full-suite/tier recounts; no repo state modified.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Verification amendment executed: the PR body now reflects the fixed gate (sourced from the committed artifact's draft_thresholds — mixed-k surface, 5200+k streams, pinned ≥3σ anchor rule, corrected teeth/warts/delta numbering) and the tier conflict from #157 is resolved by live recount (2,321). Per the verification verdict (comment 4950648191: every committed object verified exactly; amendment was metadata-only), ratifying by merge under the standing delegation; the flip PR follows with the artifact-derived gate_m4 block, the in-repo anchor pins, and the legacy-manifest --transition mode.

@MaxGhenis MaxGhenis marked this pull request as ready for review July 12, 2026 09:19
@MaxGhenis MaxGhenis merged commit 0fa4a29 into master Jul 12, 2026
7 checks passed
MaxGhenis added a commit that referenced this pull request Jul 12, 2026
…side) (#159)

* M4 gate lock flip: ratified thresholds live

Add gate_m4 (the M4 DI disability gate) as a NEW LOCKED top-level gate
(unlike gate_2b/2c, it had no pre-existing unlocked stub). The full lock
ceremony ran on PR #153 (floor runs/m4_gate_floors_v1.json): round-1 AMEND
BEFORE LOCK (comment 4950447491, findings 1-6 / fixes A-F) -> fixes
(comment 4950571161, 05d8292 + merge 45bbabe) -> verification AMEND
metadata-only, the PR body (comment 4950648191) -> body amendment executed
(comment 4950660426) -> ratifying squash merge 0fa4a29, under the standing
campaign directive of 2026-07-07.

gates.yaml gate_m4 (kind anchor_based): the 12-cell surface (8 internal
mixed-k -- flow incidence/recovery @k=3 + prevalence.50-59 STOCK @k=4 -- + 4
concept-bridged anchor cells at the pinned >=3 sigma margin), tolerances
machine-derived as round(floor mean + k*sd, 3) from the FROZEN floor and
capped at ln(1.5), the 24 report-only cells (all tolerance_above_t_max), the
K=20 mean-over-draws protocol (5200+k) + fresh_run schema [20,8,5], the
k_selection rule (k=2 flow OC 0.2901 / k=3 flow OC 0.9717 / stock k=4), the
in-repo sha-pinned di_asr_2023 anchor (reported, never gated), the
ceremony_record (four comment ids + ratified-by-merge 0fa4a29 + delegated
authority) and the 2026-07-12-m4-gate-lock history entry. ZERO threshold
movement vs the ratified floor: the frozen artifact is READ, never rewritten.
The five verification flip-time notes are implemented.

Locked-hot bindings extend tests/test_gates_derivations.py (21 tests:
tolerance derivations, 12/24 partition set-equality, OC 0.9408/0.9689
recompute, mixed-k + k_selection, anchor margins + epsilon-tilt failure,
protocol equality, D1 SUBSET master-compare, history). The floor's own
gates.yaml guard (test_m4_gate_derivations.py) flips to assert gate_m4
locked. The legacy manifest's contract_revision + gates.yaml entry track the
flip via --transition (41 frozen entries byte-identical). Tier manifest
artifact 744 -> 765 (CI-equivalent collection, openpyxl present), total
2,422.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix gate_m4 weight_definition to the ratified start-wave weight (flip referee finding 1); annotate precedent_oc_band

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant