Repository navigation
Oracle: statutory computation years (42 USC 415(b)(2)); repair Track C AIME agreement (7,486/7,486 with Axiom) - #457
Merged
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
ss.benefits.aime) always averages the top 35 indexed years over 420 months;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:It also computes the 415(b)(3) indexing year, the statutory AIME, and
oracle_aime()with a namedComputationYearsconvention.LEGACY_FIXED_35is the unchangedbenefits.aime.ss/benefits.pyis 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_clocknow takescomputation_years, defaulting to the statutory count. Track A and Track C are its only callers.The Track C script had two problems:
opening_stock_entitlement_clamped_by_clock_rule, a key the artifact lacks, so every run on master stopped withcohort_diagnostics_equal: False.How the check works now:
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.Oracle choice: the new
--oracle-computation-years statutory|legacy_fixed_35defaults tostatutory, and every output names the choice.--output-diris 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.
track-c-aime-agreement-oracle-fix-20260924/andtrack-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:
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
ss/__init__.pysays 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.🤖 Generated with Claude Code