Skip to content

Gate-1 baseline run: chained weighted QRF - #40

Merged
MaxGhenis merged 2 commits into
masterfrom
gate1-qrf-baseline
Jul 5, 2026
Merged

Gate-1 baseline run: chained weighted QRF#40
MaxGhenis merged 2 commits into
masterfrom
gate1-qrf-baseline

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Verdict: gate-1 FAILS

The first pre-registered model run of populace-dynamics. Scores the locked baseline earnings process — populace-fit's regime-gated chained weighted QRF, run as a one-step backward biennial backcast — against the gate-1 thresholds locked in gates.yaml (ratified in #33 / #39, commit eaa7c47). The protocol is read from gates.yaml at runtime and implemented literally: no threshold is hardcoded and no model choice is tuned against holdout scores.

Geometry passes 0/5 seeds; the battery passes 0/5 seeds (gate rule: ≥4/5 on each). This is the scientifically expected outcome for a one-step chained baseline — the naive Markov backcast cannot reproduce the real earnings process's long-horizon persistence, exactly the failure mode the lock's own prose predicts for a chained model.

Per-seed conjunction

seed geometry pass battery pass
0
1
2
3
4
gate 0/5 → fail 0/5 → fail

What fails (every seed)

The pairs view (window-2) passes all six locked thresholds on all five seeds — as the lock notes, a chained one-step candidate matches the pairs view by construction. The failures are concentrated exactly where persistence understatement shows:

seed runs-view c2st_auc (locked ≤ 0.54) autocorr_log_4yr (ref 0.657 ± 0.06) autocorr_log_10yr (ref 0.539 ± 0.07)
0 0.5657 ❌ 0.5774 ❌ 0.3090 ❌
1 0.5564 ❌ 0.5646 ❌ 0.3197 ❌
2 0.5535 ❌ 0.5732 ❌ 0.3682 ❌
3 0.5612 ❌ 0.5567 ❌ 0.3190 ❌
4 0.5572 ❌ 0.5909 ❌ 0.3484 ❌
  • Runs view (window-3) c2st_auc: 0.553–0.566 vs the locked ≤ 0.54. The window-3 view sees the two-consecutive-transition persistence understatement that the window-2 pairs view cannot.
  • autocorr_log_4yr (2 chained steps): 0.557–0.591 vs reference 0.657, tolerance 0.06.
  • autocorr_log_10yr (5 chained steps): 0.309–0.368 vs reference 0.539, tolerance 0.07 — the chain decays autocorrelation far faster than the real process.

Everything else passes on all seeds: pairs-view geometry (c2st ≤ 0.520, coverage ≥ 0.949, energy, both tail-ratio bands, w1/sd), the 2-year autocorrelation, the mobility diagonal, zero persistence, entry/exit rates, and mean spell length.

Battery-reference reproduction (pre-flight)

All eight committed battery_reference values in runs/noise_floor_psid_family_9822.json reproduce to float precision on the full filtered panel (126,867 person-periods, 22,300 persons), proving the battery code path matches the committed definitions before any candidate is scored:

  • autocorr 2/4/10yr = 0.730123510230560 / 0.657166897978905 / 0.538879427219318
  • mobility diagonal = 0.604051920570276 (6 diagonal cells: five weighted quintile bins + zero bin)
  • zero persistence / entry / exit / mean spell length all exact.

Baseline design (fixed by the feature author, implemented as stated)

  • Model: populace.fit.qrf.RegimeGatedQRF at DEFAULT hyperparameters (100 trees, zero_atol=1e-6, max_samples_leaf=None), plain-table front door (explicit weight column), seeded from the gate seed s.
  • Transition: one-step backward biennial — target = earnings at t-2, predictors = (earnings at t, age at t-2), sample_weight = the pair's earlier (t-2) weight; fit on the 80% complement's adjacent 2-year pairs. The target is zero-inflated positive; the regime gate handles the zeros.
  • Generation: anchor each holdout person's chronologically last observed period at its real earnings, chain backward over observed periods (drawing each earlier period conditional on the next period's generated/anchor value and the earlier period's age); a 4+ year gap applies the one-step model once across the gap. Only earnings is generated; person_id/period/age/weight copy from the holdout, and the candidate panel holds exactly the holdout persons on exactly their observed periods (the locked candidate-panel pin).

Protocol

Filter first (age 25–59, reference years 1998–2022, positive weights), then per seed 0–4 split_panel_by_person(panel, "person_id", fraction=0.2, seed=s) — the drawn 20% is the holdout, the complement trains a fresh model. Geometry via panel_scorecard(candidate, holdout, view, seed=s) on both locked views (psid_family_earnings_pairs window-2, psid_family_earnings_runs window-3); battery on the candidate panel vs the committed reference. Seed-level conjunction exactly as locked.

Deliverables

  • scripts/run_gate1_baseline.py — deterministic runner (fit, generation, scoring, artifact write).
  • runs/gate1_qrf_baseline_v1.json — evidence artifact: per-seed per-view geometry scores vs locked thresholds with per-metric pass/fail, per-seed battery values vs references/tolerances with pass/fail, the seed-conjunction table, the gate verdict, model description, revision pins (populace-dynamics eaa7c47, populace 2c93936, schema gate1_qrf_baseline.v1), and per-seed n_persons/n_windows.
  • tests/test_gate1_qrf_baseline.py — a seed-0 reproduction test (skipif PSID absent) pinning the artifact to float precision (1e-12), and always-runnable internal-consistency tests that recompute every reported pass/fail from its own stored score vs stored threshold, check stored thresholds against gates.yaml, and recompute the verdict from the seed table.

Determinism & CI

  • A fresh full run reproduces the artifact's scientific content byte-for-byte; the seed-0 reproduction test matches every stored geometry and battery value to 1e-12.
  • black -l 79 and ruff check clean repo-wide. In a CI-exact environment (pip install -e ".[dev]", no PSID data / no external engine), the full suite is 97 passed, 24 skipped, 0 failed — the reproduction test and other data-gated tests skip, and the always-runnable consistency tests pass.

Locked gate: #33 (lock) / #39 (ratification flip). Draft — do not merge.

🤖 Generated with Claude Code

The first pre-registered model run of populace-dynamics. Scores the
locked baseline earnings process -- populace-fit's regime-gated chained
weighted QRF, run as a one-step BACKWARD biennial backcast -- against
the gate-1 thresholds locked in gates.yaml (ratified, pull request 39,
commit eaa7c47). The protocol is read from gates.yaml at runtime and
implemented literally; no threshold is hardcoded and no model choice is
tuned against holdout scores.

VERDICT: gate_1 FAILS. Geometry passes 0/5 seeds and the battery passes
0/5 seeds (rule: >=4/5 on each). This is the scientifically expected
outcome for a one-step chained baseline: the naive Markov backcast
cannot reproduce the real earnings process's long-horizon persistence,
which the lock's own prose predicted for a chained model.

What fails, on every seed:
* Geometry, runs view (window-3) c2st_auc: 0.553-0.566 vs the locked
  <= 0.54 (fails 5/5). The window-2 pairs view passes all six
  thresholds on all five seeds -- as the lock notes, a chained
  one-step candidate matches the pairs view by construction, so the
  runs view is where persistence understatement shows.
* Battery autocorr_log_4yr (2 chained steps): 0.557-0.591 vs
  reference 0.657, tolerance 0.06 (fails 5/5).
* Battery autocorr_log_10yr (5 chained steps): 0.309-0.368 vs
  reference 0.539, tolerance 0.07 (fails 5/5) -- the chain decays
  autocorrelation far faster than the real process.
Everything else passes on all seeds: pairs-view geometry, the 2-year
autocorrelation, the mobility diagonal, zero persistence, entry/exit
rates, and mean spell length.

Battery-reference reproduction: all eight committed battery_reference
values in runs/noise_floor_psid_family_9822.json reproduce to float
precision on the full filtered panel (autocorr 0.730123510230560 /
0.657166897978905 / 0.538879427219318, mobility diagonal
0.604051920570276, and the four spell statistics), proving the battery
code path matches the committed definitions before any candidate is
scored.

Baseline design (fixed by the feature author, implemented as stated):
* RegimeGatedQRF at DEFAULT hyperparameters (100 trees, zero_atol
  1e-6, max_samples_leaf None), plain-table front door, seeded from
  the gate seed s.
* Backward transition: target = earnings at t-2, predictors =
  (earnings at t, age at t-2), sample_weight = the pair's earlier
  (t-2) weight; fit on the 80% complement's adjacent 2-year pairs.
* Generation: anchor each holdout person's last observed period at its
  real earnings, chain backward over observed periods, drawing each
  earlier period conditional on the next period's generated/anchor
  value and the earlier period's age; a 4+ year gap applies the
  one-step model once. Only earnings is generated; the candidate panel
  holds exactly the holdout persons on exactly their observed periods.

Protocol: filter first (age 25-59, 1998-2022, positive weights), then
per seed 0-4 split_panel_by_person(fraction=0.2) -- the drawn 20% is
the holdout, the complement trains a fresh model. Geometry via
panel_scorecard on both locked views; battery on the candidate panel
vs the committed reference. Seed-level conjunction exactly as locked.

Deliverables:
* scripts/run_gate1_baseline.py -- deterministic runner (fit,
  generation, scoring, artifact write).
* runs/gate1_qrf_baseline_v1.json -- evidence artifact: per-seed
  per-view geometry scores vs locked thresholds with per-metric
  pass/fail, per-seed battery values vs references/tolerances with
  pass/fail, the seed-conjunction table, the verdict, model
  description, revision pins, and per-seed n_persons/n_windows.
* tests/test_gate1_qrf_baseline.py -- a seed-0 reproduction test
  (skipif PSID absent) pinning the artifact to float precision, and
  always-runnable internal-consistency tests that recompute every
  reported pass/fail from its own stored score vs stored threshold,
  check the stored thresholds against gates.yaml, and recompute the
  verdict from the seed table.

Determinism verified: a fresh full run reproduces the artifact's
scientific content byte-for-byte, and the seed-0 reproduction test
matches every stored geometry and battery value to 1e-12.

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:04pm

Request Review

populace-fit pins scikit-learn below 1.9 (quantile-forest imports a
symbol 1.9 removed), so it cannot coexist with this repo's default
venv; gate runs use a dedicated venv. Without the guard the test
raised ImportError instead of skipping on machines with the PSID
files staged but no populace-fit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review July 5, 2026 15:14
@MaxGhenis
MaxGhenis merged commit 90d4c41 into master Jul 5, 2026
7 checks passed
MaxGhenis added a commit that referenced this pull request Jul 5, 2026
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>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
The fifth pre-registered gate-1 run, and the first non-generative
candidate: deterministic donor matching + age-indexed whole-career
splicing, implemented literally from the frozen candidate-5a
registration (issue #42 comment 4891949761). One shot on the locked
gate; publishes the failure exactly as computed.

VERDICT: gate_1_pass=False (geometry 0/5, battery 0/5). Geometry fails
only on c2st_auc, on both locked views, all five seeds (pairs
0.590-0.612 vs 0.53; runs 0.605-0.628 vs 0.54); every other geometry
metric passes. Battery fails 5/5 on mobility_diagonal (0.665 vs
0.604+/-0.05), exit_rate (0.227 vs 0.299+/-0.05) and its identity
zero_persistence, 4/5 on mean_spell_length, and partially on the
autocorr ladder overshoot; entry_rate passes. Realized ladder
0.779/0.704/0.616 (2/4/10yr) -- the closest long-horizon
autocorrelation of any candidate, but over all three bands.

Deterministic: no RNG, no model fit, no populace-fit; runs under the
repo .venv. The gate seed enters only through the person-disjoint 0.2
split. The protocol machinery (filter-first load, split, two locked
views, panel_scorecard, battery vs committed battery_reference with
locked definitions, thresholds from gates.yaml at runtime, seed-level
>=4/5 conjunction on both blocks, battery-reference bit-exact precheck)
is imported byte-for-byte from the merged baseline runner (#40). To let
that machinery import under .venv, the baseline's populace.fit import is
made lazy (moved into the two fit functions); no gated logic changes and
the baseline run path is unchanged under .venv-gate.

Adds scripts/run_gate1_candidate5a.py, runs/gate1_splice_v1.json (same
schema; spec_registration = the candidate-5a comment URL; reported-not-
gated diagnostics: age-window widening distribution, nearest-age
fallback rate, scaling-clip rate, donor reuse distribution), and
tests/test_gate1_qrf_candidate5a.py (seed-0 reproduction without a
populace-fit gate, determinism / panel-pin / anchor / nearest-age-tie
tests, and always-runnable internal-consistency tests). All prior tests
stay green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
The fifth pre-registered gate-1 run, and the first non-generative
candidate: deterministic donor matching + age-indexed whole-career
splicing, implemented literally from the frozen candidate-5a
registration (issue #42 comment 4891949761). One shot on the locked
gate; publishes the failure exactly as computed.

VERDICT: gate_1_pass=False (geometry 0/5, battery 0/5). Geometry fails
only on c2st_auc, on both locked views, all five seeds (pairs
0.590-0.612 vs 0.53; runs 0.605-0.628 vs 0.54); every other geometry
metric passes. Battery fails 5/5 on mobility_diagonal (0.665 vs
0.604+/-0.05), exit_rate (0.227 vs 0.299+/-0.05) and its identity
zero_persistence, 4/5 on mean_spell_length, and partially on the
autocorr ladder overshoot; entry_rate passes. Realized ladder
0.779/0.704/0.616 (2/4/10yr) -- the closest long-horizon
autocorrelation of any candidate, but over all three bands.

Deterministic: no RNG, no model fit, no populace-fit; runs under the
repo .venv. The gate seed enters only through the person-disjoint 0.2
split. The protocol machinery (filter-first load, split, two locked
views, panel_scorecard, battery vs committed battery_reference with
locked definitions, thresholds from gates.yaml at runtime, seed-level
>=4/5 conjunction on both blocks, battery-reference bit-exact precheck)
is imported byte-for-byte from the merged baseline runner (#40). To let
that machinery import under .venv, the baseline's populace.fit import is
made lazy (moved into the two fit functions); no gated logic changes and
the baseline run path is unchanged under .venv-gate.

Adds scripts/run_gate1_candidate5a.py, runs/gate1_splice_v1.json (same
schema; spec_registration = the candidate-5a comment URL; reported-not-
gated diagnostics: age-window widening distribution, nearest-age
fallback rate, scaling-clip rate, donor reuse distribution), and
tests/test_gate1_qrf_candidate5a.py (seed-0 reproduction without a
populace-fit gate, determinism / panel-pin / anchor / nearest-age-tie
tests, and always-runnable internal-consistency tests). All prior tests
stay green.

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
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>
MaxGhenis added a commit that referenced this pull request Jul 6, 2026
…cks) (#58)

The tenth pre-registered gate-1 run, and the last planned candidate
iteration before the governance track resolves. Candidate 7's k-NN
conditional rank bootstrap VERBATIM with exactly two registered
substitutions, both conditioning refinements with no new tuned constant.
Frozen spec registered before the run in issue #42
(issuecomment-4897723604); implemented literally, no tuning.

Substitution 1 (long memory): every train donor record carries
u_w = Phi(what / sigma_hat_w), the donor person's correlated-noise-shrunk
permanent rank from candidate 3's stage-1 decomposition APPLIED TO THE
Z-PANEL (z = Phi^-1(rank) of positive observations; the same rank map that
forms u_prev/u_next). The k-NN third term becomes |u_w(donor) - u_A(target)|
at candidate 7's 0.25 weight, upgrading the donor side from a single noisy
anchor draw to the shrunk full-career permanent estimate. The target side
keeps u_A.

Substitution 2 (attachment-aware zero conditioning): for zero-anchor
holdout persons (u_A = p0/2 identically) every k-NN distance replaces the
third term with |d age|/40 + |d n_observed_periods|/13 (scales pinned as
the range widths -- age over the 25-59 filter, the observed-period count
over the 13 biennial reference years -- not tuned), and the donor pool is
restricted to train records whose person's own anchor earnings are zero.

Everything else -- donor pools, k=25, the 1/0.5 lag weights, the weighted
single-record draw, no smoothing/jitter, the re-entry pools, the regime
gate, the rank machinery, the gap rule, the substream seeding -- is
byte-identical to candidate 7. Protocol machinery imported from the
baseline runner (PR #40); rank machinery / participation gate from
candidate 5b (PR #52); the k-NN draw and anchor quintiles from candidate 7
(PR #55); the u_w decomposition from candidate 3 (PR #44); the reported
benefit-space functional from PR #56. Scored under the CURRENT locked gate;
the artifact additionally REPORTS the proposed benefit-space block (PIA-proxy
gaps incl. Q0) so this run carries evidence for both standards.

VERDICT: gate_1_pass = False (geometry 0/5, battery 0/5).

Substitution 1 overshot persistence rather than repairing it. Candidate 7
undershot the 10-year autocorrelation (mean 0.459, band 0.539 +/- 0.07);
candidate 8 overshoots it (mean 0.670) and now overshoots ALL THREE
autocorrelation lags -- 2yr 0.791 (dev 0.053-0.071), 4yr 0.733 (dev
0.066-0.085), 10yr 0.670 (dev 0.110-0.145) -- so the battery fails 5/5.
Mobility diagonal (0.61, within 0.05) still passes. Geometry fails 5/5: the
runs-view c2st (mean 0.5495) misses 0.54 on every seed; pairs-view c2st
(mean 0.5307) clears 0.53 on seeds 2-4 only.

The Q0 fix did not work. The zero-anchor subgroup's PIA-proxy overstatement
did not shrink -- Q0 mean gap +12.2% (candidate 7 +9.3%), Q0 median +24.0%
(c7 +22.9%), Q0 KS 0.092 (c7 0.097). Overall benefit space also degraded:
the persistence overshoot flipped the pooled mean gap to -2.1% (c7 +1.85%)
and worsened the KS to 0.040 (c7 0.025).

Reported-not-gated per seed: the u_w decomposition (rho 0.74-0.78,
sigma_hat_w ~0.72, permanent share ~0.55; u_w spans [0.002, 1.0], median
~0.45), the Q0 pool sizes (~6,400 pairs / ~4,400 triples / ~2,950 re-entry;
Q0 draws ~11-14% of positive draws), the neighbor-distance distribution,
usage shares, corner masses, and the full PIA-proxy benefit-space block.

Runner deterministic; seed-0 reproduction test run live in .venv-gate
(matches the committed artifact to float precision). Full pytest green in
the repo .venv (281 passed, 12 skipped). Battery-reference reproduced to
float precision before scoring.

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