Skip to content

Gate-1 candidate 2: latent-permanent conditioned chained QRF - #43

Merged
MaxGhenis merged 1 commit into
masterfrom
gate1-candidate2-latent-perm
Jul 5, 2026
Merged

Gate-1 candidate 2: latent-permanent conditioned chained QRF#43
MaxGhenis merged 1 commit into
masterfrom
gate1-candidate2-latent-perm

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Gate-1 candidate 2: latent-permanent conditioned chained QRF

The second pre-registered model run of the locked gate 1, following the failed baseline (#40). The candidate spec was frozen before the run in the issue #42 registration comment (#42 (comment)); every modeling degree of freedom is pinned there and implemented literally. One shot against the LOCKED gates.yaml thresholds — no tuning against holdout scores.

Verdict: FAIL — geometry 3/5, battery 0/5 (rule: ≥4/5 each)

The battery-reference bit-exact reproduction precheck passed (every committed value reproduced to float precision) before any candidate was scored, so the battery code path is the locked definition.

The latent permanent state did what the registration memo said it would structurally — it put a floor under long-horizon autocorrelation roughly equal to the variance share the drawn perm explains. That share came out 0.52–0.55 (vs the memo's 0.467 back-out), which overcorrected the baseline's persistence shortfall: the 10-year autocorrelation moved from the baseline's 0.31–0.37 (far below the band) to 0.615–0.668 — just above the locked band's upper edge on all five seeds.

Per-seed conjunction

seed geometry battery λ perm-share (measured) runs c2st 10yr autocorr
0 0.546 0.527 0.5421 (>0.54) 0.6382
1 0.541 0.549 0.5344 0.6608
2 0.550 0.523 0.5222 0.6684
3 0.552 0.518 0.5328 0.6150
4 0.547 0.541 0.5467 (>0.54) 0.6615

Geometry (3/5, need 4/5). The pairs (window-2) view passes 5/5 (c2st 0.508–0.526 ≤ 0.53). The runs (window-3) view — gate 1's persistence guard — passes 3/5; seeds 0 and 4 clip the c2st_auc ≤ 0.54 threshold at 0.5421 and 0.5467. Coverage passes everywhere on both views.

Battery (0/5, need 4/5). The single failing statistic on every seed is autocorr_log_10yr: measured 0.615–0.668 vs reference 0.5389, deviation 0.076–0.130 against the 0.07 tolerance (the effective band [0.469, 0.609]). Every other locked battery statistic passes on all seeds — 2yr autocorr (0.727–0.735), 4yr autocorr (now within tolerance, 0.60–0.63), mobility diagonal, zero-persistence/exit/entry, and mean spell length.

Perm-share diagnostic (reported, not gated)

The memo backs a permanent share of 0.467 out of the committed battery autocorrelations (permanent + AR(1)-transitory + noise decomposition). The candidate's realized perm share — variance of the drawn holdout perms over the variance of the Stage-0 train residuals — is 0.518–0.549 across seeds (structural MoM share σ²ₚₑᵣₘ/(σ²ₚₑᵣₘ+σ²_within) is 0.644–0.649). The drawn state carries more persistence than the back-out predicted, which is the direct cause of the 10yr overshoot. λ (= σ²_within/σ²ₚₑᵣₘ) is stable at ≈ 0.54–0.55 across seeds.

What ran

  • scripts/run_gate1_candidate2.py — deterministic runner. Thresholds read from gates.yaml at runtime; the battery-reference bit-exact precheck is a hard stop. The protocol mechanics (split, refit-per-seed, both locked views, panel_scorecard scoring, battery vs the committed battery_reference, seed-level conjunction, the reproduction precheck) are imported byte-for-byte from the baseline runner (Gate-1 baseline run: chained weighted QRF #40) — only the model differs.
    • Stage 0: weighted-OLS quadratic-in-age residualization of log positive earnings (train split only).
    • Stage 1: empirical-Bayes person effects with the registered method-of-moments λ; zero-positive-obs persons get perm 0.
    • Stage 2: RegimeGatedQRF (populace-fit defaults) drawing perm from (anchor earnings, anchor age); anchor = chronologically last observed period; holdout perms are draws conditioned on holdout anchor rows, seeded from the gate seed.
    • Stage 3: the baseline's backward one-step biennial chain with perm added as a transition predictor (estimated for training pairs, drawn at generation), anchor real, one-step across gaps, regime gate, earlier-period weight, all RNG from the gate seed.
  • runs/gate1_qrf_latent_perm_v1.json — the artifact, same schema as the baseline plus the model description, a spec_registration field carrying the issue-comment URL, per-seed λ + perm-share diagnostics, and the perm-share context block.
  • tests/test_gate1_qrf_candidate2.py — mirrors the baseline's tests: seed-0 reproduction (skips when PSID absent AND when populace.fit is unimportable — the dedicated-venv pattern) plus always-runnable internal-consistency tests (every pass/fail recomputes from stored scores and thresholds; stored thresholds equal gates.yaml; the verdict recomputes from the seed table; the perm-share diagnostics are recorded and never enter the gate).

Reproducibility

populace-fit pins scikit-learn < 1.9 (via quantile-forest; populace #318), which the repo's .venv (sklearn 1.9) violates, so the run used a dedicated venv (Python 3.14, sklearn 1.8.0, quantile-forest 1.4.2). The seed-0 reproduction test reruns Stages 0–3 and matches every stored geometry score, battery value, λ, and perm-share diagnostic to float precision. In the repo .venv (and CI, which installs neither populace-fit nor the PSID data) the reproduction test skips cleanly and the internal-consistency tests pass against the committed artifact.

Registration: #42 · Baseline: #40

🤖 Generated with Claude Code

The second pre-registered model run of the locked gate 1, following the
failed baseline (#40). The candidate spec was frozen before the run in
the issue #42 registration comment (comment 4886538087); every modeling
degree of freedom is pinned there and implemented literally. One shot
against the LOCKED gates.yaml thresholds, no tuning against holdout
scores.

Verdict: FAIL, geometry 3/5 and battery 0/5 (rule: >=4/5 each). The
battery-reference bit-exact reproduction precheck passed before any
candidate was scored.

The latent permanent state put a floor under long-horizon autocorrelation
roughly equal to the variance share the drawn perm explains, exactly as
the registration memo argued. That share came out 0.52-0.55 (vs the
memo's 0.467 back-out), which overcorrected the baseline's persistence
shortfall: the 10-year autocorrelation moved from the baseline's
0.31-0.37 (far below the band) to 0.615-0.668, just above the locked
band's upper edge on all five seeds. The only failing battery statistic
on every seed is autocorr_log_10yr (deviation 0.076-0.130 vs the 0.07
tolerance); every other battery statistic passes. Geometry: the pairs
view passes 5/5, the runs view (the persistence guard) passes 3/5, with
seeds 0 and 4 clipping c2st_auc <= 0.54 at 0.5421 and 0.5467.

The protocol mechanics (split, refit-per-seed, both locked views,
panel_scorecard scoring, battery vs the committed battery_reference,
seed-level conjunction, the reproduction precheck) are imported
byte-for-byte from the baseline runner; only the model differs. The run
used a dedicated venv (Python 3.14, scikit-learn 1.8, quantile-forest
1.4.2) because populace-fit pins scikit-learn < 1.9 (populace #318). The
seed-0 reproduction test reruns Stages 0-3 and matches every stored
geometry score, battery value, lambda, and perm-share diagnostic to
float precision.

Adds scripts/run_gate1_candidate2.py, runs/gate1_qrf_latent_perm_v1.json,
and tests/test_gate1_qrf_candidate2.py.

Registration: #42. Baseline: #40.

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

vercel Bot commented Jul 5, 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 5, 2026 3:39pm

Request Review

@MaxGhenis
MaxGhenis marked this pull request as ready for review July 5, 2026 17:07
@MaxGhenis
MaxGhenis merged commit 93ba96a into master Jul 5, 2026
7 checks passed
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
The sixth pre-registered gate-1 run. Candidate 5a' (segment splicing) is
registered, frozen before the run, in issue #42's candidate-5a' comment;
every rule -- segmentation, boundary, period-indexed match, fallback
cascade, per-segment scaling -- is pinned there and implemented
literally. One shot on the locked gate.

Verdict: FAIL (gate_1_pass=false). Geometry passes 0/5 seeds, battery
passes 5/5. This is the first candidate to clear the battery: segments
from multiple donors, spliced by calendar period and level-adjusted per
segment at each boundary, pull every locked battery statistic (all three
autocorrelation rungs, mobility, exit, mean spell, entry, zero
persistence) inside its band on every seed -- the block the single-donor
5a (#50) failed 0/5. Geometry still fails, but the failure is isolated to
the omnibus C2ST on both views (pairs 0.547 > 0.53; runs 0.567 > 0.54,
seed means); energy distance, PRDC coverage, and the whole tail block
pass 5/5. The spliced panel is closer to the held-out data than any prior
candidate, but the classifier still separates it.

Protocol machinery -- filter-first load, person-disjoint 0.2 split per
seed, both locked views, panel_scorecard, battery vs the committed
battery_reference with locked definitions, gates.yaml thresholds at
runtime, the >=4/5 seed-level conjunction, and the battery-reference
bit-exact precheck -- is imported byte-for-byte from the baseline runner
(#40), identical to every prior run. The battery reference reproduced
exactly to float precision before scoring. Only the generation
(segmentation + period-indexed splicing) is local, and it is fully
deterministic: no RNG, no model fit, no populace-fit; the gate seed
enters only through the split. Runs in the repo .venv.

Reported-not-gated splice diagnostics (in the artifact, ~41,600 segments
across five seeds): segments/person mean 1.86; segment-length mean 2.52;
age-window widening 0 on every seed; segment shortening 0 (0 unmatched
one-period segments); scaling-clip rate 0.00012 over segments; distinct
donors/person mean 1.44 (max 4), up to 35 holdouts per donor; boundary
match error p50 = 0.0 on every seed.

Deliverables:
- scripts/run_gate1_candidate5a2.py -- deterministic runner; the
  registered rules exactly; protocol machinery imported from #40.
- runs/gate1_splice_v2.json -- schema gate1_splice.v2; spec_registration
  = the candidate-5a' comment URL; the diagnostics above and the
  bit-exact battery_reference_reproduction.
- tests/test_gate1_qrf_candidate5a2.py -- seed-0 reproduction (PSID
  skipif, no populace-fit gate), synthetic-pool tests for segmentation /
  boundary / scaling-clip / the widen-then-shorten cascade / donor-zero
  copying, and always-runnable internal-consistency tests against the
  committed artifact and locked gates.yaml.

Full suite green in the repo .venv (189 passed, 4 skipped -- the skips
are the prior candidates' populace-fit reproduction tests). ruff clean;
black -l 79 clean.

Refs #42, #40, #43, #44, #48, #50.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
The sixth pre-registered gate-1 run. Candidate 5a' (segment splicing) is
registered, frozen before the run, in issue #42's candidate-5a' comment;
every rule -- segmentation, boundary, period-indexed match, fallback
cascade, per-segment scaling -- is pinned there and implemented
literally. One shot on the locked gate.

Verdict: FAIL (gate_1_pass=false). Geometry passes 0/5 seeds, battery
passes 5/5. This is the first candidate to clear the battery: segments
from multiple donors, spliced by calendar period and level-adjusted per
segment at each boundary, pull every locked battery statistic (all three
autocorrelation rungs, mobility, exit, mean spell, entry, zero
persistence) inside its band on every seed -- the block the single-donor
5a (#50) failed 0/5. Geometry still fails, but the failure is isolated to
the omnibus C2ST on both views (pairs 0.547 > 0.53; runs 0.567 > 0.54,
seed means); energy distance, PRDC coverage, and the whole tail block
pass 5/5. The spliced panel is closer to the held-out data than any prior
candidate, but the classifier still separates it.

Protocol machinery -- filter-first load, person-disjoint 0.2 split per
seed, both locked views, panel_scorecard, battery vs the committed
battery_reference with locked definitions, gates.yaml thresholds at
runtime, the >=4/5 seed-level conjunction, and the battery-reference
bit-exact precheck -- is imported byte-for-byte from the baseline runner
(#40), identical to every prior run. The battery reference reproduced
exactly to float precision before scoring. Only the generation
(segmentation + period-indexed splicing) is local, and it is fully
deterministic: no RNG, no model fit, no populace-fit; the gate seed
enters only through the split. Runs in the repo .venv.

Reported-not-gated splice diagnostics (in the artifact, ~41,600 segments
across five seeds): segments/person mean 1.86; segment-length mean 2.52;
age-window widening 0 on every seed; segment shortening 0 (0 unmatched
one-period segments); scaling-clip rate 0.00012 over segments; distinct
donors/person mean 1.44 (max 4), up to 35 holdouts per donor; boundary
match error p50 = 0.0 on every seed.

Deliverables:
- scripts/run_gate1_candidate5a2.py -- deterministic runner; the
  registered rules exactly; protocol machinery imported from #40.
- runs/gate1_splice_v2.json -- schema gate1_splice.v2; spec_registration
  = the candidate-5a' comment URL; the diagnostics above and the
  bit-exact battery_reference_reproduction.
- tests/test_gate1_qrf_candidate5a2.py -- seed-0 reproduction (PSID
  skipif, no populace-fit gate), synthetic-pool tests for segmentation /
  boundary / scaling-clip / the widen-then-shorten cascade / donor-zero
  copying, and always-runnable internal-consistency tests against the
  committed artifact and locked gates.yaml.

Full suite green in the repo .venv (189 passed, 4 skipped -- the skips
are the prior candidates' populace-fit reproduction tests). ruff clean;
black -l 79 clean.

Refs #42, #40, #43, #44, #48, #50.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
…locks) (#55)

The ninth pre-registered gate-1 run. Replaces candidate 6's discretized
rank kernel with continuous empirical conditional draws and deepens the
conditioning memory: a k-nearest-neighbor conditional rank bootstrap over
train transition records, matched on the next two generated-or-real ranks
(v1, v2) and the person's continuous anchor rank a. Frozen spec registered
before the run in issue #42 (issuecomment-4896132094); implemented
literally, no tuning.

Mechanics (all constants fixed a priori at registration):
- Rank machinery (cells, Qhat_pos/rhat, continuous anchor rank u_A) reused
  byte-for-byte from candidate 5b; protocol machinery imported from the
  baseline runner; participation gate is candidate 2's backward regime
  gate.
- Donor pools per seed from train positives: pairs (u_prev, u_next) --
  candidate 6's kernel pairs, verified bit-identical (64,603 seed 0) --
  triples (u_prev, u_next, u_next2) where the next-later observed period is
  also positive, and re-entry pairs (candidate 6's, 4,994 seed 0). Records
  pinned in a stable (person_id, period) order fixing the k-NN tie-break.
- Conditional draw: triples when v2 exists else pairs; distance
  |u_next - v1| + 0.5|u_next2 - v2| (triples) + 0.25|u_A - a|; k=25 nearest;
  one record drawn with probability proportional to its weight; generated
  u_prev is that record's u_prev exactly (no binning/smoothing/jitter).
  Earnings = Qhat_pos of the target cell at u_prev. Zero crossings use the
  re-entry pool matched on |u_A - a| alone.

Verdict: gate_1_pass = False (geometry 2/5, battery 2/5; needs >=4/5 both).
The deepened memory is a real improvement over candidate 6 (which failed
0/5 both) but does not clear the conjunction.
- Geometry: the only failing metric is the runs-view (window-3) c2st_auc,
  failing seeds 0/2/4 (0.548/0.546/0.549 vs 0.54) and passing 1/3
  (0.539/0.532). The pairs-view c2st passes on all five seeds
  (0.516-0.529 <= 0.53); every other geometry threshold passes everywhere.
- Battery: the only failing metric is the 10-year autocorrelation, failing
  seeds 2/3/4 (0.445/0.442/0.465; deviations 0.094/0.097/0.074 vs
  tolerance 0.07) and passing 0/1 (0.470/0.473). This is the registered
  risk: two-step-plus-anchor memory does not carry the full permanent share
  on 3/5 seeds. Every other battery tolerance passes on all five seeds.

Determinism: battery_reference reproduces bit-exact before scoring; the
live seed-0 reproduction test passes in the gate venv; the run reproduces
from the seeds alone. Reported-not-gated diagnostics per the registration
(neighbor distances, triple/pair share, donor reuse, drawn corner mass by
anchor quintile, clamped share) are carried in the artifact.

Deliverables on this branch: scripts/run_gate1_candidate7.py,
runs/gate1_rank_knn_v1.json (schema gate1_rank_knn.v1, spec_registration =
the candidate-7 comment), tests/test_gate1_qrf_candidate7.py. Full pytest
green (249 passed, 7 skipped); ruff clean; black -l 79 clean.

Refs issue #42, forensics #54, and the eight prior run PRs
(#40, #43, #44, #48, #50, #51, #52, #53).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
…pace (#56)

* Gate-1 candidate 7: k-NN conditional rank bootstrap (fails 2/5 both blocks)

The ninth pre-registered gate-1 run. Replaces candidate 6's discretized
rank kernel with continuous empirical conditional draws and deepens the
conditioning memory: a k-nearest-neighbor conditional rank bootstrap over
train transition records, matched on the next two generated-or-real ranks
(v1, v2) and the person's continuous anchor rank a. Frozen spec registered
before the run in issue #42 (issuecomment-4896132094); implemented
literally, no tuning.

Mechanics (all constants fixed a priori at registration):
- Rank machinery (cells, Qhat_pos/rhat, continuous anchor rank u_A) reused
  byte-for-byte from candidate 5b; protocol machinery imported from the
  baseline runner; participation gate is candidate 2's backward regime
  gate.
- Donor pools per seed from train positives: pairs (u_prev, u_next) --
  candidate 6's kernel pairs, verified bit-identical (64,603 seed 0) --
  triples (u_prev, u_next, u_next2) where the next-later observed period is
  also positive, and re-entry pairs (candidate 6's, 4,994 seed 0). Records
  pinned in a stable (person_id, period) order fixing the k-NN tie-break.
- Conditional draw: triples when v2 exists else pairs; distance
  |u_next - v1| + 0.5|u_next2 - v2| (triples) + 0.25|u_A - a|; k=25 nearest;
  one record drawn with probability proportional to its weight; generated
  u_prev is that record's u_prev exactly (no binning/smoothing/jitter).
  Earnings = Qhat_pos of the target cell at u_prev. Zero crossings use the
  re-entry pool matched on |u_A - a| alone.

Verdict: gate_1_pass = False (geometry 2/5, battery 2/5; needs >=4/5 both).
The deepened memory is a real improvement over candidate 6 (which failed
0/5 both) but does not clear the conjunction.
- Geometry: the only failing metric is the runs-view (window-3) c2st_auc,
  failing seeds 0/2/4 (0.548/0.546/0.549 vs 0.54) and passing 1/3
  (0.539/0.532). The pairs-view c2st passes on all five seeds
  (0.516-0.529 <= 0.53); every other geometry threshold passes everywhere.
- Battery: the only failing metric is the 10-year autocorrelation, failing
  seeds 2/3/4 (0.445/0.442/0.465; deviations 0.094/0.097/0.074 vs
  tolerance 0.07) and passing 0/1 (0.470/0.473). This is the registered
  risk: two-step-plus-anchor memory does not carry the full permanent share
  on 3/5 seeds. Every other battery tolerance passes on all five seeds.

Determinism: battery_reference reproduces bit-exact before scoring; the
live seed-0 reproduction test passes in the gate venv; the run reproduces
from the seeds alone. Reported-not-gated diagnostics per the registration
(neighbor distances, triple/pair share, donor reuse, drawn corner mass by
anchor quintile, clamped share) are carried in the artifact.

Deliverables on this branch: scripts/run_gate1_candidate7.py,
runs/gate1_rank_knn_v1.json (schema gate1_rank_knn.v1, spec_registration =
the candidate-7 comment), tests/test_gate1_qrf_candidate7.py. Full pytest
green (249 passed, 7 skipped); ruff clean; black -l 79 clean.

Refs issue #42, forensics #54, and the eight prior run PRs
(#40, #43, #44, #48, #50, #51, #52, #53).

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

* Downstream relevance of candidate 7: what the classifier residual costs in benefit space

REPORTED, NOT GATED. Reads no gate, changes no gate. Translates the
candidate-7 population-view classifier residual into the downstream
benefit-magnitude space a Social Security analysis consumes, as evidence for
whether a FUTURE public gate amendment (which would need its own referee
round) is warranted. gates.yaml and every committed gate artifact are
untouched.

The functional is a STATUTE-SHAPED PROXY, not the full 42 USC 415(b) AIME:
the filtered panel's careers are partial (biennial PSID, prime age 25-59,
1998-2022), so a faithful highest-35 AIME cannot be formed. The proxy caps
each positive-earnings year at its wage base, indexes to 2022 by the NAWI
ratio, averages the top min(10, n_pos) indexed years over (count * 12 * 2),
and runs the result through the exact 2022-eligibility 415(a)/415(g) PIA
formula. It is monotone in lifetime earnings; the constant scale cancels in
every real-vs-candidate comparison. Every artifact and doc says so.

Per gate seed 0-4, candidate 7 is regenerated deterministically over the
holdout via the merged candidate-7 machinery (filter-first load, locked
person-disjoint 0.2 split, train marginals/donor pools/participation gate,
backward k-NN chain) -- reproducing the committed candidate-7 artifact's
seed-0 diagnostics to float precision, so the histories pushed through the
proxy are exactly the ones the gate scored. Both real holdout and candidate
(same persons, same rows, only earnings differ; anchor held real) go through
the proxy, weighted by each person's anchor-period weight. Gaps are anchored
to a real-vs-real noise floor at the same scale: the ctx20 construction
(fraction=0.4 seed=1000+s, then fraction=0.5 seed=s) on the seed's TRAIN
split.

Findings (pooled over 5 seeds; candidate-vs-real / real-vs-real noise):
- Overall shape holds: KS 0.025 (within the 0.028 noise floor); mean gap
  +1.85% and median +1.02% (above the tight sub-0.5% real-vs-real floor but
  well inside the paper's +/-5% AIME-percentile criterion).
- Deciles d2-d9 within +/-5% (mostly under 2%); the bottom decile d1 is
  +32.6% vs a +4.1% noise floor -- a near-zero-denominator artifact (bottom
  PIA-proxy ~$290-500/mo, so ~$80-145 absolute gaps read as huge percents),
  not a wholesale divergence.
- Person-level (a bootstrap, not a predictor): weighted MAE $315/mo, RMSE
  $493/mo; only 26.8% of persons within 5% and 40.8% within 10% of their
  real PIA-proxy. It matches the distribution, not who-is-where.
- Concentration: the residual sits in the zero-anchor group (Q0: mean +9.3%,
  median +22.9%, KS 0.097, 4.9% within 5%) -- the low/no-attachment workers
  the k-NN bootstrap conditions weakest and whom the progressive PIA formula
  weights most. Positive-earner quintiles Q1-Q4 are within a couple percent.

Deliverables:
- scripts/build_downstream_relevance.py: deterministic; the pinned
  functional; oracle parameters loaded once with the pe-us revision
  (bf71be3b) recorded.
- runs/downstream_relevance_c7_v1.json: per-seed + pooled measurements, the
  noise-anchor rows, the pe-us revision, the candidate-7 artifact sha256
  reference, reported_not_gated=true and a one-line purpose.
- tests/test_downstream_relevance.py: always-runnable internal-consistency
  (gaps recompute from stored per-side statistics; schema; weighted-stat
  helpers) + a seed-0 reproduction pin (skipif PSID, importorskip
  populace.fit) that passes live in the gate venv.

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