Skip to content

Oracle: statutory computation years (42 USC 415(b)(2)); repair Track C AIME agreement (7,486/7,486 with Axiom) - #457

Merged
MaxGhenis merged 5 commits into
masterfrom
dynamics-oracle-elapsed-years-20260924
Sep 24, 2026
Merged

MaxGhenis merged 5 commits into
masterfrom
dynamics-oracle-elapsed-years-20260924

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Adds statutory benefit computation years (42 USC 415(b)(2)) to the transitional Python oracle as an opt-in convention, and repairs the Track C AIME agreement script, which stopped before any engine call on master.

Why

Track C step 1 (#455) compared the Axiom 415(b) candidate's AIME with the oracle's on the real Track A cohort. They matched for 7,235 of 7,486 people. All 251 mismatches were people born before 1929. The cause is the oracle's divisor:

  • the oracle (ss.benefits.aime) always averages the top 35 indexed years over 420 months;
  • the statute sets the number of computation years to the elapsed years less 5, never fewer than 2. Elapsed years are the calendar years after the later of 1950 and the year the worker turns 21, and before the year the worker turns 62 or dies.

The two counts agree from the 1929 birth cohort on.

What changes

  • ss/statutory_aime.py (new, opt-in). It computes elapsed years and benefit computation years for three cases:

    • old age;
    • death before 62;
    • disability onset, with the one-fifth dropout rule capped at 5 and the 2-year minimum.

    It also computes the 415(b)(3) indexing year, the statutory AIME, and oracle_aime() with a named ComputationYears convention. LEGACY_FIXED_35 is the unchanged benefits.aime.

    • It refuses workers turning 62 before 1975 (1972 amendments §104(j)(2)).
    • It quotes the statute it implements, checked word for word against the saved 42 USC 415 source.
  • ss/benefits.py is not edited. It sits inside the first-estimates birth-evidence source seal (reviewed commit 1c7f354), and the reviewer confirmed that.

  • Track A is unchanged. It passes TRACK_A_COMPUTATION_YEARS = LEGACY_FIXED_35, so Registration 13's arithmetic is the same. Its PIA path is bit-identical on 1,680 invented careers born 1917–2000.

  • scenario_benefits.eligibility_pia_for_clock now takes computation_years, defaulting to the statutory count. Track A and Track C are its only callers.

  • The Track C script had two problems:

    • It compared the whole cohort-diagnostics dict with the committed Track A artifact. Track A: fix the four artifact-check findings for future registered runs #454 added opening_stock_entitlement_clamped_by_clock_rule, a key the artifact lacks, so every run on master stopped with cohort_diagnostics_equal: False.
    • Once the statutory default was added, its PIA consistency check would also have stopped at the first person born before 1929.
  • How the check works now:

    • Every diagnostic the artifact records must be present and equal.
    • A reviewed table, KNOWN_ADDITIVE_DIAGNOSTICS, lists the one new key, and that key must sum to its recorded total and stay within the recorded per-rule counts. Any other new diagnostic refuses the run.
    • An artifact-tier test keeps the table equal to what the code emits.
    • With the new key removed, the fresh cohort's seal equals the 2026-09-23 run's exactly.
  • Oracle choice: the new --oracle-computation-years statutory|legacy_fixed_35 defaults to statutory, and every output names the choice. --output-dir is now required. The results schema is v3.

Result (AIME only; not an exercise statistic)

The runs used the real Track A cohort and the pinned Axiom engine.

Oracle Primary pass, exact Born 1917–1928 Born 1929–1968 Diagnostic pass
legacy fixed 35 (reproduces 2026-09-23 exactly) 7,235 / 7,486 71 / 322 7,164 / 7,164 1,229 / 1,334
statutory 415(b)(2) 7,486 / 7,486 322 / 322 7,164 / 7,164 1,334 / 1,334
  • Unchanged: every engine request hash and every engine AIME equals the 2026-09-23 run's.
  • The Axiom candidates are still unaccepted. Agreement is diagnostic: the engine and the statutory oracle compute the same AIME from the same rows.
  • Evidence is in the lane's evidence directories track-c-aime-agreement-oracle-fix-20260924/ and track-c-aime-agreement-20260924-head{,-legacy}/. The latter two ran at 71c9474, and the check was tightened afterwards. A final run at the merge commit will be recorded after merge.

Review

An independent Opus 5.5 reviewer checked the builder's work and made two rounds of fixes:

  • 5c83bbb: the Track C PIA check was pinned to Track A's convention;
  • afb462b: the reviewer restored the fail-closed diagnostics binding, which 71c9474 had weakened. 12 regression tests fail at 71c9474 and pass here.

The reviewer recomputed all 40 hand cases from the statute text and found no mismatches. The unit and artifact tiers pass, and black and ruff are clean.

Open, not changed here

  • Track A's successor registration: whether it moves from the fixed 35 to the statutory count. Track C refuses to run if Track A's convention changes.
  • Oracle scope: ss/__init__.py says not to extend the oracle's rule coverage, but the death and disability counts are extra functions that no production path calls. This is disclosed in the module docstring.
  • The §104(j)(2) quote: no copy of its source page is saved in the evidence directory. It was checked against the live law.cornell.edu page.

🤖 Generated with Claude Code

MaxGhenis and others added 5 commits September 24, 2026 02:28
ss.benefits.aime divides every worker's highest 35 indexed years by 420.
42 USC 415(b)(2) sets the number of benefit computation years to the
elapsed years (calendar years after the later of 1950 and the year of
attaining 21, before the year of attaining 62 or of earlier death)
less 5, never fewer than 2.  The two agree from the 1929 birth cohort
on; Track C step 1 traced all 251 of its Axiom-vs-oracle AIME
disagreements (people born before 1929) to that count.

ss/benefits.py is inside the first-estimates birth-evidence source
seal (reviewed commit 1c7f354) and is called by the sealed ledger and
the gate-2c couple-earnings proxy, so it is not edited.  Instead:

- New opt-in module ss/statutory_aime.py (quotes 415(b)(1),
  (b)(2)(A), (b)(2)(B)(i) and (iii), (b)(3)(A)(ii)(I), and 104(j)(2) of
  the 1972 amendments): elapsed years, benefit computation years
  (old-age, death before 62, and a disability onset with the
  one-fifth dropout capped at 5, 2-year minimum), the 415(b)(3)
  indexing year, the statutory AIME, and oracle_aime() with a named
  ComputationYears convention.  LEGACY_FIXED_35 is the unchanged
  benefits.aime.  It refuses workers attaining 62 before 1975
  (104(j)(2)), a death after a disability entitlement, and history
  years before 1951.  Child-care dropout years are not encoded.
- scenario_benefits.eligibility_pia_for_clock takes computation_years,
  default STATUTORY.
- Track A passes TRACK_A_COMPUTATION_YEARS = LEGACY_FIXED_35 for its
  oracle retirement level (Registration 13's arithmetic);
  approximate_pia stays on benefits.aime.
- The new module is registered in POST_REVIEW_SOURCE_EXCLUSIONS, the
  pinned tuple and the reachability guard.
- Tests: hand-computed counts and AIMEs (born 1913, 1917, 1920, 1928,
  1929, 1935; attaining 21 after 1950; the 2-year minimum; death and
  disability cases), equality with benefits.aime for every birth year
  1929-1995 on invented careers, a Track A legacy test, the
  sealed-ledger test under both conventions, and a source scan pinning
  every legacy user.  Tier manifest: unit 2922, total 7249.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: the tier manifest (recollected with recount-tiers.py: unit
3034, artifact 2801, integration_psid 862, reproduction_legacy 520,
oracle_policyengine 163, total 7380) and the post-review source
exclusions, where master's Track U modules and this branch's
ss/statutory_aime.py are both kept, in the reducer tuple, the pinned
tuple and the reachability guard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After the merge of master (#455), scripts/track_c_aime_agreement.py
checked that Track A's PIA rests on its oracle AIME by calling
scenario_benefits.eligibility_pia_for_clock without computation_years.
This branch made that function default to the statutory 415(b)(2)
count, while the script's oracle side is the fixed-35 benefits.aime and
Track A passes LEGACY_FIXED_35.  A real run would therefore stop with a
PIA mismatch at the first person born before 1929 (the oracle-fix
rerun's NOTE records the same stop: person 6002, born 1921).  The
merged tree also failed tests/ss/test_statutory_aime.py's source scan,
because the script called benefits.aime directly without being pinned.

- The check moves into check_track_a_pia() and passes
  computation_years=TRACK_A_COMPUTATION_YEARS, as the Track A assembly
  does.
- oracle_aime() calls ss.statutory_aime.oracle_aime under
  ORACLE_CONVENTION = LEGACY_FIXED_35.  That call is benefits.aime, so
  the numbers the 20260923 run recorded are unchanged.  main() refuses
  to run if Track A's convention stops being LEGACY_FIXED_35, because
  the attribution and the report text assume 35 years.
- The report prose and the module docstring name the convention, and
  ss/statutory_aime.py joins the recorded source list.
- The source scan pins the script as a LEGACY_FIXED_35 user.
- ss/statutory_aime.py: the 104(j)(2) provenance line said all bracketed
  text was the note's, but "[...]" is an omission made here.  It now
  says so, and that no copy of the page is saved with the evidence.  The
  list of what is not encoded adds the birth-year convention: the year
  of attaining 21 or 62 is taken to be birth year plus age.
- Tests (INVENTED data): check_track_a_pia passes for people born 1925
  and 1960 and refuses a PIA that does not rest on oracle_aime.  The
  default statutory call gives the 1925 person another PIA.  The
  convention guard refuses STATUTORY.  Removing the computation_years
  pin makes the new check test fail.
- Tier manifest recollected: unit 3036, total 7382.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… make the oracle's computation years a choice

On master, scripts/track_c_aime_agreement.py stopped before any engine
call.  Its check that the cohort is the one in the registered Track A
artifact (runs/replication_urban2010_cola_v1.json, committed in 7b580dc)
compared the whole cohort diagnostics dict.  bfe9fa3 (merged in #454)
later added opening_stock_entitlement_clamped_by_clock_rule to the
diagnostics, so the comparison failed on that key alone.

Artifact binding
- track_a_artifact_binding compares every diagnostic the artifact
  records and refuses a missing or changed one.  The source provenance
  and the parameter revision are still compared as whole values.
- Diagnostics the artifact does not record are allowed and returned as
  additive keys.  An additive <total>_by_<rule> key must be a mapping of
  integers summing to the recorded <total>.
- result.json records the compared keys, the additive keys and their
  reconciliation; RESULTS.md lists them.  require_track_a_artifact
  raises SystemExit naming each failed check, missing key and changed
  key.
- A 20-person smoke run on the real cohort (--limit, not kept) passed
  every check.  It found one additive key, whose clock-rule counts
  (1, 2, 46) sum to the recorded 49.

Oracle choice
- --oracle-computation-years statutory|legacy_fixed_35, default
  statutory.  statutory is ss.statutory_aime's 42 USC 415(b)(2) count.
  legacy_fixed_35 is ss.benefits.aime: Track A's convention and the
  oracle of the 2026-09-23 report.
- The choice is named in the header, the labels, a new "oracle" record,
  and the not-compared list.  RESULTS.md names it in the title, the
  result paragraph, the oracle-side description and the attribution
  note.
- Each record now has oracle_aime (the chosen oracle's AIME),
  track_a_oracle_aime (always Track A's fixed-35 AIME) and
  oracle_computation_years.  Summaries count the people whose two AIMEs
  differ.
- The count attribution applies only when the candidate's count differs
  from the oracle's.  Under the statutory oracle the two counts are
  equal (tested for births 1913-2000), so it never applies there.
- check_oracle_pia checks eligibility_pia_for_clock against the recorded
  AIME under both the chosen convention and Track A's.  Its record is
  kept in result.json.
- The script still refuses to run if Track A's convention stops being
  LEGACY_FIXED_35.
- Schema v2.  --render-only refuses a v1 result, whose prose belongs to
  the script at the commit that result records.

Tests (INVENTED data)
- The additive-key regression, and refusal of missing, changed and
  non-summing keys, with the SystemExit message.
- The oracle choice and its parser default; classification under both
  oracles; the PIA check under both conventions and without the
  computation_years pin; the rendered oracle names; and the actual-engine
  test under both oracles.
- New artifact-tier module tests/test_track_c_track_a_artifact_binding.py
  reads the committed artifact's recorded keys.  They are a subset of
  what the current code produces for INVENTED people, and the recorded
  2011 cohort binds when an INVENTED split of its clamped total is added.
- These regression tests fail against the previous script.

Tier manifest recollected: unit 3047, artifact 2803, total 7395.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of 71c9474.  Its artifact binding fixed the stop at master (the
whole-dict comparison refused the key bfe9fa3 added) but accepted any
diagnostic the artifact lacks: a key not named <total>_by_<rule> was
recorded and allowed, and one so named was allowed whenever its counts
summed to the recorded total, even with a negative count or a count
above what the artifact records for that category.  The old whole-dict
comparison refused every new diagnostic, so the binding was weaker than
the check it replaced.

- KNOWN_ADDITIVE_DIAGNOSTICS lists the reviewed additive diagnostics with
  the commit that added each and the recorded diagnostics it breaks
  down.  It holds one entry:
  opening_stock_entitlement_clamped_by_clock_rule (bfe9fa3), a breakdown
  of opening_stock_entitlement_clamped by opening_stock_clock_rules.
- The binding refuses any other diagnostic the artifact lacks
  (additive_diagnostic_keys_known) and requires a listed one to sum to
  its recorded total and to count only recorded categories, each at most
  its recorded count (additive_breakdowns_within_recorded_categories).
  Recorded keys, source provenance and parameter revision are compared
  as before.  result.json names unknown keys; RESULTS.md names the
  commit and the category check.
- On the real 2011 cohort the binding passes: the one additive key
  (1 + 2 + 46 = 49) fits the recorded clock-rule counts (248, 58,
  1340).  With that key removed, the fresh cohort's Track A seal is
  142f72d0..., the seal of the 2026-09-23 run that passed the old
  whole-dict check.
- --output-dir no longer defaults to the 2026-09-23 evidence directory;
  a run without it is refused before any git, data or engine step.
- Schema v3.  --render-only renders only v3 results; v1 and v2 prose
  belongs to the script at the commit each records.

Tests (INVENTED data, plus the committed artifact's recorded keys): an
unreviewed key, a <total>_by_<rule>-named unreviewed key, a count above
the recorded category, an unrecorded category and a negative count are
each refused; the listed table equals what the current code adds to
both recorded waves; the run refuses a missing --output-dir; v2 results
are not rendered.  These tests fail against 71c9474.  The artifact-tier
"one short" split is now one short of the recorded total.  Tier manifest
recollected: unit 3053, artifact 2804, total 7402.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
social-security-model Ready Ready Preview Sep 24, 2026 5:43pm UTC

Request Review

@MaxGhenis
MaxGhenis merged commit 088772f into master Sep 24, 2026
12 checks passed
@MaxGhenis
MaxGhenis deleted the dynamics-oracle-elapsed-years-20260924 branch September 25, 2026 14:12

This branch was successfully deployed

1 active deployment
Preview — afb462b1 Deployed Sep 24, 2026 by vercel[bot]
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