Repository navigation
Track B G part 2 and R2 part (b): deductions before reduction; SSA's operational saving clause - #563
Conversation
…fore first use #530's round-14 review found that the shared attribute writer treated deleting __notes__ as an assignment and read args[0], so removing a refusal's exception notes raised IndexError in G, R2, ARF and recomputation. Assignment keeps its list-of-strings check; deletion goes through the original __delattr__. A four-layer test adds and deletes notes and checks provenance and the denominator. Stateful constructors now register their declared enums before the first explicit call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al saving clause Max ruled d1802: the rules lane builds G part 2 (the operational saving clause, per d1338) and R2 part (b), which removes R2's deduction_before_reduction_part_b refusal. Deduction before reduction (Act 203(a)(4); GN 02603.020, .040, .050): - family_benefits_after_deductions and its household form take declared monthly deductions and apply the reduction for the maximum after them. Non-deductees share PTAP / (TOTOB - deductees' OBs), capped at OB and dime-floored. Temporary deductions leave separate households unchanged until permanent (GN 02603.050D, .090). - Supported reasons are an auxiliary's or survivor's own earnings-test deduction (full or partial, permanent or estimated), no child in care, and Parisi, which is unchanged through the new path. Workers' compensation, prisoner and drug-addiction suspensions, foreign work, penalty, maritime and election-certificate events are refused by name. - Reproduced: GN 02603.060 A.1, A.2, B.1, C.1, C.2 (and A.5, A.8, A.9, B.2 through the new path), RS 02501.130B and RS 02501.160 examples 1 and 2. 403(a)(5): SavingsClauseReading on the guard, with SSA_OPERATIONAL the default (RS 00630.400, RS 00615.801B.2) and LITERAL_REFUSAL the named alternative. Existing tests that pin the literal guard now select it. A fall not caused by a PIA increase starts no protection, and a COLA alone starts one only with an age-reduced beneficiary. Membership changes while a protection is active, and unsettled concurrent changes, are refused. R2 part (b): monthly RETFamilyMonth context lets an auxiliary's own deduction release maximum room to the others through the new G entry point. Final deductions flow to R3, and a delayed household increase creates no own-work credit. Missing family facts refuse as deduction_readjustment_requires_family_context. Two source readings are taken under the 2026-10-20 delegation and logged: partial temporary deductions follow RS 02501.160's worked example (us:oasdi-ret-temporary-partial-deduction), and protected equal rates round up to the least sufficient dime, as Act 203(a)(5) requires (us:oasdi-saving-clause-operational-rate-rounding). The brief asked for an absolute invariant that adding a deduction never lowers another beneficiary's rate. GN 02603.050A.1's "no other deduction" condition and .050C's age reserve make that false: a minimized PIA $48 case is pinned, and the invariant is stated as the rules allow. A cross-head harness shows 240 R2 and 240 downstream R3 results unchanged from master, and six rows that R2 refused now compute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecord mutations and verification; recount tiers The 356,400-row lattice is unchanged. A separate 16-row invented deduction denominator is added, and every one of the 37 G refusal reasons has an executed witness. The mutation and verification records pin the 13 one-line mutations and the lane's commands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Master added the holdout registry and an ARF change. Only the tier files conflicted; they take master's version and are recounted (unit 18,880; total 25,429). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's round-1 review of #563 found seven issues. This part derives two-record entitlement from G's facts, adds the savings-clause membership refusal, checks own benefits in both months and looks up the R1 year before releasing held refusals. Part 2 finishes and verifies the round. Subfleet job 20261025-031318-trackb-fix-g2-2 (a1) wrote this part. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This part adds the no-child-in-care age checks under Act 203(c)(2) and 20 CFR 404.421(a), rejects zero-amount events in every layer, rewrites the R2 statutory-order step, rewords the reservation case as deferred coverage, and records fifteen new mutations and the verification ledger. Subfleet job 20261025-105211-trackb-fix-g2-2b (gpt-6.1-sol) wrote this work and left it uncommitted; salvage ref 0d96d2e1 preserved its tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 2 added two under_full_retirement_age lines to the example registry after the fix lane's conformance check, so the report's registry hash went stale and CI's byte-for-byte test failed at bbcdf7f. Regeneration changes that one line; all 356,400 configurations match. The verification ledger records the before and after hashes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit's message says the ledger records the before and after hashes, but that edit did not apply. This commit adds them. The ledger's earlier sha256 values stay as measurements from before the refresh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's second review found three more defects. R2 accepted an FRA declaration that the family's G birth cohort contradicted, which let an own-earnings deduction run after FRA. RecordYear now checks the NH and every auxiliary against the twelve months each cohort allows, and own delayed credits against the snapshot month, before any coverage refusal. Act 203(f)(9) and RS 02501.021B.3 apply the old-age FRA to every role, so this needed no ruling. An OWN_EARNINGS_TEST event whose payable plus NH reservation equals the original benefit withholds nothing, so it's now an input error, even on a held record. An age-reduced divorced spouse outside the maximum could start operational protection. Act 203(a)(3)(C) determines the other benefits as if that spouse were absent, so operational membership, the age basis, the age trigger and the person count now skip anyone outside the maximum. That person's own rate stays ordinary, and the literal reading doesn't move. The tier files add this round's 176 unit tests to the previous sum; the coordinator's slot recount replaces them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s first (#563 round 4) Sol's third review kept the round-3 fixes and found three mediums, plus an open question on two POMS exceptions. An outside divorced spouse's deduction counted as an "other deduction" under GN 02603.050A.1, so a governed child got $175, not $200. Act 203(a)(3)(C) and GN 02603.020B keep outside people out of the governed decision, so deduction decisions and the reservation total now read subject rows only. Outside events still apply to their own cash. The same audit showed an outside event was what activated a subject's NH reservation, so a reservation now reduces cash with or without an event. A held coverage refusal hid a contradiction in declared NH entitlement. apply_ret_year now compares every month's declared facts before any G computation, through a helper shared with G. The lane's audit of the loop adds raw own-PIA spouse eligibility, NH original rates and DIB gross rates. Checks that need G's money stay after it. RecordYear now rejects two known cohorts for one person across months and fields. A missing cohort adds no constraint. GN 02603.050A.1 and A.2 don't settle how a sole full permanent deduction composes with a zero-rate dual row. The rule adopts neither reading: a new named refusal fires only where their exact payments differ. The conformance report gains that reason and nothing else moves, and 240 R2 and 240 R3 cross-head results stay unchanged. Adds 637 unit tests and eleven caught mutations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's fourth review found that a held G refusal still masked contradictions in RIB gross, auxiliary original rates and widow eligibility. Reproducing it showed round 4's preflight had already gone too far the other way: RS 00615.754A.3's first example under administrative finality raised InvalidFamilyInput, though the capture says "the rate to the NH is protected by administrative finality and cannot be changed". A protected rate rests on another PIA, so that mismatch isn't a contradiction. A preflight now compares a fact before a held refusal only when nothing declared on the record or that beneficiary can lawfully change it. One table classifies every RecordCondition, BeneficiaryCondition and UnsupportedReason against six facts: NH original, DIB gross, RIB gross, auxiliary original, spouse raw own-PIA eligibility and other own-benefit entitlement. _check_settled_family_facts compares settled facts only, through G's own validated helpers, and catches only FamilyConfigurationUnsupported. Unsettled facts keep their refusal, one row and the weight. Settled contradictions raise with no row. The ordinary OB deduction bound follows the same table. Strict withholding of actual gross still runs after G, and no money moves. Two historical bounds carry new reasons: a declared legacy widow can exceed ordinary OB under RS 00615.010's sole-survivor alternative, so that row keeps its refusal, and an unresolved parent keeps the one-parent 82.5% bound. Nine tests under round 4's reading split into a protected case with its exact refusal, row and weight, and a settled case that keeps the input error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's fifth review of a135519 found three mediums, and all three reproduced. Each fact table treated a fact as wholly open or wholly settled, where the sources settle one direction of it. - RS 00615.712 protects a widow's adjusted cash and leaves a child's original rate alone, so a child's original above its OB now raises under a declared clause and under unknown history. - 20 CFR 404.411(c)(2) keeps a prior reduced WIB's carryover before cohort 1928 and reaches someone with no current WIB, so an NH's own RIB below its ordinary rate keeps dual_entitlement_sequence and its weight. Cohort 1928 stays settled. - A hold that can only lower an NH rate keeps that rate as a cap, so a DIB above its PIA raises. Only administrative finality lifts a cap. The same class reaches a DIB after a reduced WIB, which Sol's probe showed outside its verdict. A DIB below the PIA now keeps its row under dual_entitlement_sequence in every cohort, because the schema omits the onset that scopes 404.411(b)(2). The pre-1978 reasons open it before cohort 1928 only. Protected cash stays a named refusal, because the capture states no cap. No money moves. The conformance report regenerates byte-identically, and the cross-head comparison keeps 240 R2 and 240 R3 results. Invariants: under a reduction-only hold, an NH rate above its ordinary rate raises and one at or below it keeps its row. Every rate the carryover can reach stays a counted refusal, with or without the preflight. A nonwidow's OB stays settled under widow DRC protection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's sixth review of 3212f82 found three mediums, and all three reproduced. Two lost a lawful row by comparing a rate with an amount the declaration had already put in doubt. One kept a row no filling can make lawful. - A declared pre-1978 history reaches past an omitted cohort, because RS 00615.005C.2's money reduction can exceed today's fraction. PIA $333.30 at RF 8 pays $318.50 on all sixteen rounding paths from the captured COLAs, against $318.40 today. That rate now keeps its row, and only for an old-age benefit with a PIA and a remaining reduction, in a cohort before 1916 or none. - Every test of an actual own RIB shares the 404.411(c)(2) carryover, so a mother's $359.10 against an ordinary $373.30 keeps its row beside a $360 threshold. - No reduced benefit starts before age 50, so a cohort below that age has one lawful DIB rate. A DIB below the PIA now raises under every hold that works through a prior reduced benefit. Workers' compensation and finality need no such benefit and keep young rows. The same classes reach F6 under a declared history, and REDUCED_BENEFIT_HISTORY_BEFORE_1978 now opens F6 in the carryover scope. The age floor uses 50 for DIB_AFTER_REDUCED_RIB too, because the schema has no separate declaration for a DIB after a reduced WIB. That row stays a named refusal from 50 through 61. No money moves. The conformance report regenerates byte-identically, and the cross-head comparison keeps 240 R2 and 240 R3 results. Invariants: under a declared history, every rate in its scope keeps its row, and past that scope a reduction-only hold keeps the cap. F6 opens under a carryover hold for exactly the roles that read an actual own RIB. Before January of cohort + 50, a DIB equals its PIA or raises. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's seventh review of fbe491d found three mediums and a nit, and all three mediums reproduced. Each kept a counted row for a declaration no filling can make lawful. - History leaves a RIB at or below its PIA. RS 00615.005C.2 subtracts a money reduction from the new PIA, so with no delayed credits a rate above the PIA has no lawful filling. Round 7 dropped that cap with the exact rate. The check also reaches a known cohort before 1916 with no declaration. Finality, positive delayed credits and months before 1983 keep their rows. - A zero threshold fails every RIB, known cohort or not. The preflight tests a RIB it can't compute at zero, the lowest RIB there is, so a test that fails there fails on every filling. A positive threshold passes at zero and keeps its row, and a deemed PIA counts. - A reduced DIB needs a month before it. RS 00615.010 counts only months before the first DIB month, and RS 00615.005 dates each route: RIB from 11/56 at 62, WIB from 9/65 at 60, disabled WIB from 2/68 at 50, and the reduced DIB itself from 9/65. So January of cohort + 50 has one lawful DIB rate, and so do February 1958, 1966 and 1968 for the cohorts Sol named. The floor reads the payment month, because first_dib_entitlement holds the first-ever DIB month and RS 00615.010 counts from the most recent period. Every hold shares the earliest route, and a modern cohort keeps the WIB route because the schema omits the onset that ends it. No money moves. The conformance report regenerates byte-identically, and the cross-head comparison keeps 240 R2 and 240 R3 results. Invariants: with no delayed credits, no history admits a RIB above its PIA. A zero threshold fails every RIB on every filling, and only a zero threshold does. A route opens the month after its own first month, and before any route opens a DIB equals its PIA or raises. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the tier files conflicted. They take master's counts plus this branch's 2,300 unit tests, and the slot recount replaces them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sol's eighth review of aa86a4d found two mediums, and both reproduced. - The child-in-care minimum read the family before the month's deductions. 402(q)(5)(D) sets it by what a mother or father would get "for such month". A child's full deduction frees room, so a mother takes more and a widow did not: $0.80 where the rule pays $1.00, and $612.80 where it pays $750. The comparison now takes the month's events and households, each caregiver compares alone, and a deductee keeps the ordinary minimum. - RET skipped G on an unbound month. A surviving divorced spouse sits outside the actual maximum and the mother it compares with sits inside, so the comparison can bind when the actual maximum doesn't. RET now reaches G wherever a minimum can move, and asks for family facts by the existing refusal where it has none. - A partial deduction refuses by name where it can move the rate. No capture carries a partial amount to a comparison rate, so the ordinary and all-full comparisons bound every reading, and only a rate at or above the higher one computes. - A month before 1983 keeps the PIA cap. Upward dime rounding can't pass a PIA G holds to dimes, so a no-credit RIB above its PIA raises and leaves no row. Finality and positive credits keep their rows. Money moves for child-in-care widow(er)s on a month with another person's deduction, and only theirs. The conformance lattice stays identical, with one new named witness. Invariants: the minimum equals the better of the reduced rate and what a mother or father receives this month. It moves only the caregiver's own money. A partial deduction computes only where every amount between the two bounds agrees. RET asks for family facts exactly where a minimum can move. With no delayed credits, no RIB exceeds its PIA in any month. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the tier files conflicted. They take master's counts plus this branch's 2,364 unit tests, and the slot recount replaces them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new refusal reason also adds four parametrized cases in tests/test_track_b_ret_ledger_fix_round_6.py, outside the round's count, so CI collects 22,032 unit tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31eb787 to
bc460e3
Compare
Sol's ninth review of bc460e3 found one medium and one low, and both reproduced. - The child-in-care comparison cleared every other widow(er)'s care flag. 402(q)(5)(D) replaces one entitlement, so another caregiver keeps its own minimum there. Without it, G counted a deducted caregiver's whole age reduction against the maximum, and the first caregiver's comparison came out low: $1,287 where the rule pays $1,349.30, and $715 where it pays $746.60, through G, the household entry and RET's provisional ledger. The comparison now changes only the caregiver it compares. Each nesting converts one more caregiver, so the recursion ends. - One call computes each comparison family once. A family depends only on which caregivers it has converted, so a call with k caregivers runs at most 2^k families. - RET asked for family facts below any widow(er)'s original rate. A survivor child's OB and a mother's are both 3/4 of the PIA, and no comparison passes a mother's OB, so RET now asks only below the lower of the widow(er)'s original rate and an entitled child's. A widow at $905 beside a child at $750 now computes, and pays what G pays with the facts. Money moves for a child-in-care widow(er) beside another caregiver who takes a deduction, and only there. A seeded sweep of 4,000 invented two-caregiver families moved 11, all on a month with a deduction. Invariants: each caregiver gets the better of its reduced rate and what it would receive as a mother or father where only its entitlement changes. No comparison passes a mother's OB. One call computes each comparison family once. A month RET settles without family facts pays what G pays with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master brings SSI0 (#573), which touches no Track B file. The tier files take master's counts plus this branch's new tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the conflicts with #563's new row helper and relocated NH charge refusal. _original_entitlement_rows now takes the payment month and the resolved (count, excluded) parent set, and a _parent_threshold helper gives each parent its 402(h)(1)(D) rate in G and in R2's context check (which #563 added with the old parent_ob argument). The NH-age marker moves to the relocated reserve check, and the G note adopts #563's framing of it as deferred coverage, not a conflict. The marker test now requires every marker to be documented in a Track B design note rather than matching this pass's fixed set, since #563 logs its own readings. Tier counts: unit 22,089, total 28,659. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for hub review Sol's round-9 findings
My findings (none of medium or higher severity)
Gates
{
"verdict": "APPROVE",
"head": "03530e8bd99db9608ecfb60ae4f17508fde1b3be",
"reviewer": "cloud Opus 5.5, independent review",
"summary": "I reviewed the whole diff against origin/master (63 files) and focused hardest on round 10 (434a39c): the care comparison now keeps other caregivers' care facts, there is a per-call comparison cache, and RET's request bound has moved. Both of Sol's round-9 findings are resolved. I rebuilt every counterexample through the family, household and RET entry points, and each now pays the right amount: 1349.30/1349, 2.00/2, 746.60/746 provisional with 750 final, and 1207.20/1207 on the 2026 formula maximum. Sol's widow at 905 beside a child at 750 now computes, pays 905, and withholds the child's 750. I hand-derived the 1800/2891.50 case and GN 02603.060 C.2 (225.30, 182.80) from the captures. The registry checks each published figure against the cited capture text. My own properties passed: 400 Hypothesis families of 2-3 caregivers and 1-2 children, with mixed full and partial, temporary and permanent events across households. They checked permutation invariance, determinism, each caregiver at or above its public-API comparison, and no comparison above a mother's OB. 360 cases computed and 40 refused by name. A refused RET row stays in the shared denominator. The gates passed: 82 named modules gave 12918 passed and 8 skipped. Every skip is the policyengine-us oracle, which is absent in this VM. The conformance report regenerated byte-identical (sha256 b5dfc011...). Cross-head against origin/master dd9c7be gave 240 R2 and 240 R3 rows stable, and the six former part_b refusals now compute. Black and ruff are clean on 53 files, all 148 captures match their manifests, and no protected path changed. All 7 of my mutations were killed, and the tree was clean after each revert. I found nothing of medium or higher severity. I have one low disclosure point, on how the nested hypothetical composes, and one nit about a design note that cites an untracked scratch file. I used Python 3.14.6 via uv. I opened no barred path and made no population claim.",
"sol_findings": [
{
"severity": "medium",
"location": "src/populace_dynamics/track_b/gross_benefits.py:3923 (_mother_father_comparison)",
"issue": "The comparison cleared other caregivers' child_in_care, which overstated a deducted caregiver's age reserve and underpaid the focal caregiver.",
"resolved": true,
"evidence": "PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/psid $PY -m pytest -p no:cacheprovider -p no:xdist -q -s scratch/review/test_review_care.py -> 9 passed: former 1349.30/whole 1349 (PIA 1800, MAX 2891.50, 1966 84/84, temporary spouse event, same household); minimized PIA 2.70/MAX 4.20 gives 2 through family and household entries; PIA 1000/MAX 1600 1960 80/80 gives 746.60; formula MAX 2586.90 on PIA 1688 gives 1207.20; RET provisional_net 746.60, provisional_payment 746, net_due 750; hand derivation reserve 1156.60-963.80=192.80 gives floor_dime(1350*2698.70/2700)=1349.30. The nearby 400-case Hypothesis property over 2-3 caregivers passed. Mutation M1, which restores the clearing, fails 4 tests."
},
{
"severity": "low",
"location": "src/populace_dynamics/track_b/ret_ledger.py:1148 (_care_minimum_can_move)",
"issue": "Without context, RET requested family facts for any reduced widow rate, even above the highest possible mother/father amount.",
"resolved": true,
"evidence": "scratch test_sol_low_trigger: widow 905/1000 beside child 750/750 with January wages 25980 now gives supported=True. Round-10 tests: 749.90 and 600 still refuse with FAMILY_CONTEXT_REQUIRED, and 750 computes. Bound reasoning: child OB = mother OB = floor_dime(0.75*PIA) (original_benefit, gross_benefits.py:3106), and a readjusted rate is capped at its OB, so gross >= child OB means the minimum cannot bind. Mutations M3 (min child) and M4 (<=) are both killed."
}
],
"executed": [
{
"command": "git rev-parse HEAD",
"result": "03530e8bd99db9608ecfb60ae4f17508fde1b3be"
},
{
"command": "git diff --name-only origin/master...HEAD | grep -E 'gates.yaml|engine/loop.py|engine/steps.py|^runs/'",
"result": "no output; protected paths untouched; no scratch, report or bundle files committed"
},
{
"command": "PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/psid HYPOTHESIS_STORAGE_DIRECTORY=$PWD/scratch/review/hyp $PY -m pytest -p no:cacheprovider -q -n 4 <82 named modules: tests/test_track_b_gross_benefits*.py, test_track_b_refusal_notes.py, test_track_b_input_schema.py, test_track_b_ret_*.py, test_track_b_arf*.py, test_track_b_recompute*.py, test_track_b_r3_*.py>",
"result": "exit 0: 12918 passed, 8 skipped in 202s; skips are all tests/test_track_b_gross_benefits_oracle.py (no policyengine-us tree)"
},
{
"command": "PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/psid $PY scripts/track_b_g_conformance_report.py --output scratch/review/conformance.json && cmp scratch/review/conformance.json docs/design/track_b_g_conformance_report.json",
"result": "exit 0, 356400 configurations, IDENTICAL, sha256 b5dfc011181eb5fdaf795719ae7557dbc23d0a680058f24c6a5aa03ba28f2a70"
},
{
"command": "git worktree add --detach ../master origin/master (dd9c7be); PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/psid $PY scripts/track_b_r2_cross_head.py --baseline-root ../master --output scratch/review/cross_head.json",
"result": "exit 0; r2_stable_rows 240, r3_stable_rows 240, identical_declared_output_bytes true, stable_sha256 799fc9e23a902ac1ca0c2563579ceb094d0dbcd631a912305c40062cf21a5f55; 6 transitions part_b -> supported"
},
{
"command": "$PY -m black -l 79 --check <53 changed .py files>; $PY -m ruff check <same>",
"result": "53 files unchanged; All checks passed"
},
{
"command": "manifest sha256/bytes check over tests/data/track_b/*_sources/manifest.json",
"result": "148 entries, all match, no unlisted captures"
},
{
"command": "PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/psid $PY -m pytest -p no:cacheprovider -p no:xdist -q -s scratch/review/test_review_care.py",
"result": "9 passed; Hypothesis STATS ok=360, refused=40 (care_minimum_partial_deduction)"
},
{
"command": "$PY scratch/review/mutate.py (each mutation applied, rounds 9+10 modules run -x -n 4, then git checkout -- file)",
"result": "7/7 killed: M1 clear other caregivers' care (4 failed); M2 events cache key drops households (1 failed); M3 RET bound min(children) (1 failed); M4 RET bound <= (3 failed); M5 floor ignores full settlement (4 failed); M6 ordinary cache key drops state (2 failed); M7 other deductee's reserve drops age reduction (4 failed). git status --porcelain empty"
},
{
"command": "alternative-reading probe (family_benefits on actual and former-as-mother families)",
"result": "spouse payable 1350 in the actual world vs 963.80 in former's hypothetical; carrying the actual-world minimum would pay former 1350 instead of 1349.30"
},
{
"command": "git status --porcelain",
"result": "empty"
}
],
"findings": [
{
"severity": "low",
"location": "docs/design/track_b_r2_ret_ledger.md:2761",
"issue": "The nested composition is not called out as a composition choice. When one caregiver's 402(q)(5)(D) hypothetical holds a second caregiver, that second caregiver's minimum is recomputed with the first already converted to a mother or father. The note describes this mechanism, but it doesn't say that carrying the second caregiver's actual-world minimum would pay differently. No source discusses two caregivers. I read the nested form as the literal counterfactual, so I'm not raising it as an unsettled case.",
"counterexample": "PIA 1800, MAX 2891.50, 2026-01; former=SURVIVING_DIVORCED_SPOUSE and spouse=WIDOW, both 1966 84/84 with child_in_care='child'; one child; temporary full own-work event on spouse; all in one household. Head (nested) pays former 1349.30, whole dollar 1349. Carrying spouse's actual-world payable of 1350 (reserve 0) would pay 1350, whole dollar 1350. Executed.",
"fix": "Add one sentence to the round-10 note naming the nested composition, the alternative, and this $0.70 example. No code change."
},
{
"severity": "nit",
"location": "docs/design/track_b_r2_ret_ledger.md:2821",
"issue": "The round-10 note cites `scratch/review/round10_mutate.py`, which is gitignored and not in the repository. Round 10's mutation results are not yet in docs/design/track_b_g2_r2b_mutations.json, though the PR says a later commit will add them.",
"counterexample": "git ls-files scratch prints nothing.",
"fix": "Record round 10's mutations in the committed mutations ledger and cite that file."
}
],
"needs_max": [
{
"item": "Other caregivers in the hypothetical (round 10, nested composition)",
"assessment": "keep; add the disclosure in findings[0]",
"source_text": "402(q)(5)(D): 'below the amount to which he or she would have been entitled had he or she been entitled for such month to mother's or father's insurance benefits'; RS 00615.340 does not address two caregivers.",
"conclusion": "The hypothetical replaces one entitlement. Applying the same subsection to the other caregiver inside that hypothetical is the literal reading. Carrying an actual-world minimum would mix the actual world with the hypothetical one. Example: 1349.30 nested versus 1350 alternative. No ruling is needed, only a sentence in the note."
},
{
"item": "RET context-request bound",
"assessment": "resolve",
"source_text": "402(d)(2) and 402(g)(2) both give 3/4 of the PIA; GN 02603.050 NOTE: 'beneficiaries are still limited to the original benefit amount'.",
"conclusion": "Settled. A widow at or above a child's OB can't be raised by a mother/father minimum. With 905 against 750, RET computes and agrees with G."
},
{
"item": "us:oasdi-ret-temporary-partial-deduction",
"assessment": "keep",
"source_text": "GN 02603.050D.2: 'there are no partial deductions for temporary work deductions'; RS 02501.160 Example 2 pays a partial temporary month.",
"conclusion": "The tension is genuine. Following the specific worked example is defensible, and R2's provisional full suspension, with a named refusal on the partial path, discloses the choice."
},
{
"item": "us:oasdi-saving-clause-operational-rate-rounding",
"assessment": "keep",
"source_text": "RS 00630.400: 'Difference ÷ By the Number of Auxiliaries (rounded)' gives no direction; 203(a)(5) requires the smallest amount that keeps the total from falling.",
"conclusion": "Rounding up to the least sufficient dime is the only direction that meets 203(a)(5). LITERAL_REFUSAL stays as the alternative under d1338."
},
{
"item": "us:oasdi-finality-protected-rates-before-coverage (Appendix B)",
"assessment": "keep",
"source_text": "RS 00615.754A.3: NH keeps $1,000 although 'the correct PIA is really $750.00'; the rate 'is protected by administrative finality and cannot be changed'.",
"conclusion": "The capture itself shows a lawful rate that differs from the correct PIA. Treating that gap as an input error would drop a lawful row, so the named refusal with its weight is right."
},
{
"item": "us:oasdi-sole-full-deduction-zero-dual-composition (Appendix B)",
"assessment": "keep",
"source_text": "GN 02603.050A.1: 'no other deduction is involved for any beneficiary'; A.2: zero dual rate disregarded 'regardless of other deductions'.",
"conclusion": "Both readings are defensible. I re-derived the PIA 400 / MAX 600 / spouse RF36 example: reserving the age reduction gives the child 175, and applying A.2 first gives 200 (record 575 versus 600). Refusing where the payments differ is the safer default."
}
]
}Generated by Claude Code |
The cloud round-4 review (APPROVE at 1fa5686) found two low items in this PR's bookkeeping: - The reverse marker test matched substrings, so a truncated or misspelled id passed when it was a prefix of a documented id. It now extracts whole ids from the Track B notes. - The G note still said the test checks markers against the logged ids in both directions. The test now does so again: the markers in the G, R2, R3 and grace modules must equal this pass's readings plus the ids other rounds register (#563's two), and the note says what it checks. The insured-status modules keep their own register, as in the round-3 test, so #562's markers don't enter these checks once it lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Ready for hub review Cloud run of the round 10 mutation list and the Track B gate at Environment. Hashes. All 4 file hashes in the brief's #563 table matched, and both #563 script hashes matched (
Totals. 19 of 22 exited 1 (a test failed). 3 survived (exit 0): Last 20 lines of
|
A cloud session ran round 10's 22 listed mutations at 03530e8, each in a copied source tree with its own Hypothesis database. 19 failed a named test, and the runner's audit counted no restricted open, subprocess or os.system call. Three change no result and stay out of the count as equivalent: dropping the month or the parameters from the care comparison key (every key in one cache carries the opening call's month and parameters), and giving the events key the ordinary tag (the two keys differ in length). The ledger holds the driver and runner sources, the verification file records the run and its Track B gate, and the RET note cites the committed ledger in place of a scratch script. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master brings the B0.2 stream flush (#596), which touches one B0.2 test file and no Track B payment file. The tier files take master's counts plus this branch's new tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plural "# Sources conflict us:oasdi-..." still slipped past the parse rule. The mention pattern is now sources?[\W_]*conflict (any case). On this head, #562's 168bb3a and #563's dbdceac, every mention in a non-exempt Python or YAML file still parses as a marker; the only mismatch is #562's two wrapped markers in the exempt insured_status.py. All 32 mutations behave as the note says. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merge request for the coordinator's slot (Track B payment session) The "Microcosm dynamics" coordinator can merge #563 at
One call for the coordinator under condition 1: the master merge brings #596, which adds 11 lines to Money impact: none. The PR changes statutory conformance on invented cases only; the axiom line sits in the PR body. Sol audits the merged commit later, when the Codex lanes place (condition 4). A medium finding from that audit becomes a follow-up PR. |
Master adds #563's Track B changes. Only the two tier files conflicted; take master's, and the next commit recounts them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The Microcosm Dynamics coordinator merged this PR at
|
This PR covers Max's d1802 for the rules lane: G part 2 and R2 part (b). It applies Act 203(a)(4)'s deductions before the family-maximum reduction, which removes R2's
deduction_before_reduction_part_brefusal. It also adopts SSA's operational reading of the 1972 saving clause, per Max's d1338, with the literal reading behind a switch. It also fixes #530's round-14 low finding. The work is statutory conformance on invented cases and SSA's published examples only, with no population claim.Status: draft. Round 10 sits at
434a39c6, and03530e8bmerges master 89d064b (SSI0, #573), which touches no Track B file. An independent cloud review (Opus 5.5) approved03530e8bwith nothing of medium or higher severity (verdict).f5a18c84records round 10's cloud mutation run (docs only), anddbdceac5merges master dd9c7be (#596, one B0.2 test file). Sol's tenth review waits for a lane and audits the PR later. GPT-6 Astra reviewed the first round, and GPT-6.1 Sol reviewed rounds 2 and 3. Each round below lists what that review found. #562 (insured status) and this PR touch_provenance.py, the shared schema and audit fixtures, and the tier files. Whichever merges second will merge master and recount. The coordinator's slot order after #574 is #562, #563, #565.What changes
Deductions before reduction (G)
Act 203(a)(4); GN 02603.020, .040, .050, .090.
family_benefits_after_deductions, and its household form, take declared monthly deductions and apply the reduction for the maximum after them.403(a)(5): the saving clause (G)
SavingsClauseReadingonSavingsClauseGuard:SSA_OPERATIONALis the default (RS 00630.400, RS 00615.801B.2), andLITERAL_REFUSALkeeps the earlier behaviour. Existing tests that pin the literal guard select it explicitly.R2 part (b)
RETFamilyMonthcontext lets an auxiliary's own deduction release maximum room to the others through the new G entry point (RS 02501.155–.160).deduction_readjustment_requires_family_context.Fixes from #530's review
Invariants
Each is a Hypothesis property:
One invariant is qualified, not absolute. Adding a deduction does not always keep the others' rates from falling: GN 02603.050A.1 disregards age reduction for a single full permanent deduction only when "no other deduction is involved", and GN 02603.050C reserves the age reduction otherwise. A minimized case is pinned (PIA $48, maximum $78): the children's rates fall from $10 to $9.90 when a second, $0.10, deduction appears. The property therefore covers adding the first deduction.
Examples and differentials
Reproduced exactly:
These are eight new registry examples. A.6 and A.7 need combined maximums and stay refused, as do the workers' compensation examples.
Source discrepancies, both sides pinned. GN 02603.060 A.2's narrative omits the OB cap. RS 02501.160 and .130 quote OBs a dime above G's post-1982 floor.
Cross-head differential (
scripts/track_b_r2_cross_head.py). 240 previously supported R2 results, and their 240 downstream R3 results, are byte-identical to master. The six invented rows R2 used to refuse asdeduction_before_reduction_part_bnow compute, with no other refusal in their place.Conformance report. The 356,400-row G lattice is unchanged. A separate 16-row deduction denominator is added, and every one of G's 37 refusal reasons has an executed witness.
Mutation checks. Thirteen one-line mutations were caught and reverted (
docs/design/track_b_g2_r2b_mutations.json).Source readings taken (session, under Max's 2026-10-20 delegation)
Both are logged in
~/reviews/us-hub/source-conflicts/RULINGS.mdand marked at their decision lines:us:oasdi-ret-temporary-partial-deduction. GN 02603.050D.2 says temporary deductions are never partial, while RS 02501.160's worked example pays a partial one. G follows the example (specific over general). R2 keeps its full-month provisional suspension and refuses a provisional partial path by name.us:oasdi-saving-clause-operational-rate-rounding. RS 00630.400 says "rounded" without a direction, and Act 203(a)(5) requires the smallest amount that keeps the total from falling. So protected equal rates round up to the least sufficient dime (P1).LITERAL_REFUSALremains the alternative.The rest of the build report's judgment items are refusals by name, not readings, so none needs Max.
Round 10 (after the ninth review)
Sol's review of
bc460e32found one medium and one low, and both reproduced.Another caregiver keeps its care facts. 402(q)(5)(D) compares a widow(er)'s benefit with what the person would have had "had he or she been entitled for such month to mother's or father's insurance benefits", which replaces one entitlement. Round 9's comparison also cleared every other widow(er)'s care flag. When that other caregiver took a deduction, G counted its whole age reduction against the maximum, and the first caregiver's comparison came out low. A surviving divorced spouse beside a deducted widow, both 1966 cohort and 84 of 84 months, one child:
bc460e32_mother_father_comparisonnow changes only the caregiver it compares, and each nesting converts one more caregiver, so the recursion ends. The fix reaches the household entry, a disabled widow(er) deductee, a dual deductee on a temporary or permanent event, and RET's provisional ledger, where Sol's case now pays $746.60 instead of $715 and the final $750 stays.One call computes each comparison family once. A family depends only on which caregivers it has converted, so
_care_scopeopens one cache per call and a call with k caregivers runs at most 2^k families. Six caregivers ran 1,957 family computations without the cache and 64 with it. G sets no bound on how many caregivers a family holds.RET asks for family facts only where a minimum can reach the rate. A survivor child's OB and a mother's are both 3/4 of the PIA, a readjusted rate stops at its OB, and the new property finds no comparison above a mother's OB. So without a context RET now asks only below the lower of the widow(er)'s original rate and an entitled child's. Sol's widow at $905 of $1,000 beside a working child at $750 now computes and pays what G pays with the facts.
Round 9's tests.
test_each_caregiver_compares_alonecleared the other caregiver's care. It now keeps it, astest_each_caregiver_compares_with_only_its_entitlement_replaced, with the same amounts. Two RET records gave a child a $500 OB beside a widow's $1,000; they now carry the $750 a survivor child gets on that PIA.Money moves this round, for a child-in-care widow(er) beside another caregiver who takes a deduction, and only there. A seeded sweep of 4,000 invented two-caregiver families moved 11, all on a month with a deduction; the 2,016 without one kept every outcome, refusals and input errors included.
Sol's
needs_maxitems need no new call. Sol read 402(q)(5)(D) as replacing only the one entitlement, and no source clears another caregiver's care.New invariants:
Local checks at
434a39c6: the 25 care-related G and RET modules pass (2,720 tests), rounds 9 and 10 pass (99 tests), and Black and ruff pass. Fleet ops holds heavy local runs, so CI runs the whole Track B suite and regenerates the conformance report byte for byte. 25 of the new module's 37 tests fail againstbc460e32, and round 9's 62 all pass there. A cloud session ran the 22 listed mutations at03530e8b(results). 19 failed a named test. Three change no result and stay out of the count as equivalent: dropping the month or the parameters from the comparison cache key, since every key in one cache carries the opening call's month and parameters, and giving the events key the ordinary tag, since the two keys differ in length.f5a18c84records them indocs/design/track_b_g2_r2b_mutations.json.Round 9 (after the eighth review)
Sol's review of
aa86a4dafound two mediums, and both reproduced. The first underpaid a supported widow(er) through G and RET. The second kept a counted row for a RIB no filling can make lawful, and round 8's own exception caused it.FAMILY_CONTEXT_REQUIREDnames the missing facts where it has none.care_minimum_partial_deduction, keeping its row and weight.Money moves this round, for child-in-care widow(er)s on a month with another person's deduction, and only theirs. A dual comparison keeps its fixed rate, like the actual family's. R3's
mother_father_rate_monthsstays a caller's declaration.Sol's
needs_maxitems each keep a standing ruling or resolve inside these fixes, so none reaches Max. Sol read the minimum as settled by the sources, and a named refusal for the partial case adopts no reading.New invariants:
Local checks at the tree that became
bc460e32: all 14,261 Track B tests pass and 7 skip in a session process. Black and ruff pass. The conformance report regenerates with one new named witness and no lattice row moved. The cross-head comparison keeps the same stable hash as round 8, and that comparison holds no child-in-care case, so it can't see this round's money. 34 fresh mutations each failed a named test, and 34 of the new module's 62 tests fail againstaa86a4da. Ten of a first pass's eleven survivors showed test gaps that new tests closed, and the eleventh stays out of the ledger as equivalent, held by a differential.Round 8 (after the seventh review)
Sol's review of
fbe491d4found three mediums and a nit, and all three mediums reproduced. Each kept a counted row for a declaration no filling can make lawful. Round 7 caused the first and third by reading too far past an exact comparison.The session renamed round 6's
test_only_finality_lifts_an_nh_rate_cap_outside_money_history_scope, which was Sol's nit.The floor reads the payment month, because
first_dib_entitlementholds the first-ever DIB month and RS 00615.010 counts from the most recent period. Two limits stay on purpose. Every hold shares the earliest route, because the schema doesn't say which route a hold took. A modern cohort keeps the WIB route, because the schema omits the onset that ends it. Each one leaves a named refusal, and no money moves either way.Sol's
needs_maxitems each keep a standing ruling or resolve inside these fixes, so none reaches Max.New invariants:
Local checks at the tree that became
aa86a4da: all 14,193 Track B tests pass and 7 skip in a session process. Black and ruff pass, the conformance report regenerates byte-identically, and the cross-head comparison matches master with the same stable hash as round 7. 39 fresh mutations each failed a named test, and 96 of the new module's 148 tests fail againstfbe491d4. A first mutation pass killed 38 of 39, and the survivor gained a test.Round 7 (after the sixth review)
Sol's review of
3212f823found three mediums, and all three reproduced. The session read each one against its capture before changing the rule. Two lost a lawful row by comparing a rate with an amount the declaration had already put in doubt. One kept a row no filling can make lawful.OWN_RIB_HISTORY_BEFORE_1978orREDUCED_BENEFIT_HISTORY_BEFORE_1978says RS 00615.005C.2's money reduction set the amount, and that reduction can exceed today's fraction. PIA $123.40 at RF 8 in December 1977, every captured COLA through 1999 and an upward recomputation to PIA $333.30 give $318.50 on all sixteen rounding paths, against $318.40 today. That declaration raised and lost its row. It now keeps its reason and weight 7, in both directions, for an old-age benefit with a positive PIA and a remaining reduction, in a cohort before 1916 or none. Cohort 1916 keeps the cap, and a DIB keeps its PIA as its cap. Round 6's claim that only finality lifts a cap was wrong, and the note says so.dual_entitlement_sequence, in a pre-FRA year too. A spouse's raw own-PIA test and a child's lack of one stay settled.evaluate_retand leaves no row. A rate at the PIA keeps its named refusal. Workers' compensation and finality need no prior benefit, so each keeps a young row, even beside a dual declaration.The session extended the same classes past the findings. F6 reads the same own RIB as F3, so a declared history now opens it too.
REDUCED_BENEFIT_HISTORY_BEFORE_1978opens F6 in the carryover scope, because it carries through the rule that already opened F3. The age floor covers all five holds that work through a prior reduced benefit.One choice for the reviewer to check: the floor takes the earliest age on any route, 50, even for
DIB_AFTER_REDUCED_RIB, which names a RIB that starts at 62. The schema has no separate declaration for a DIB after a reduced WIB under 404.411(b)(2), so that row stays a named refusal from 50 through 61. The direction rule decides this, and no money moves either way.What stayed:
Sol's
needs_maxitems each keep a standing ruling or resolve inside these fixes, so none reaches Max.New invariants:
Local checks at the tree that became
fbe491d4: all 14,032 Track B tests pass and 7 skip in a session process. Black and ruff pass, the conformance report regenerates byte-identically, the cross-head comparison matches master, and 42 fresh mutations each failed a named test. Against3212f823, 44 of the new module's 158 tests fail. A first mutation pass killed 39 of 43: one survivor showed a redundant month comparison, so the rule now compares years, and three exposed test gaps that each gained a test.Round 6 (after the fifth review)
Sol's review of
a135519ffound three mediums, and all three reproduced. Each came from a fact table that treated a fact as wholly open or wholly settled, where the sources settle one direction of it.dual_entitlement_sequence, weight kept. Cohort 1928 stays settled: "There is no further reduction."The session extended the same class past the findings. Sol's exploratory probe of a DIB after a reduced WIB didn't enter its verdict, but it reproduces: $398.10 on PIA $400 raised under
dual_entitlement_sequence. 404.411(b) reduces that DIB, and the schema omits the onset that scopes it, so the row now stays in every cohort. The two pre-1978 history reasons open the same comparison before cohort 1928 only, because a later cohort reached age 50 after 1977.Protected cash stays a refusal. A child paid $300.10 on OB $300, and a deduction above that OB, keep the named refusal, because the capture states no cap on protected cash. A stricter proof could drop those rows, and no amount moves either way.
Sol's three new
needs_maxitems are these fixes, and Sol called each source-settled, so none reaches Max.New invariants:
UnsupportedReasonclassifies a lower DIB, a lower RIB and a rate above the cap against an expectation written out in the test, not read from G's table.Two existing assertions moved, and each now states both sides.
test_protected_widow_cannot_be_excluded_from_unknown_drc_historyasserts the input error and the finality refusal on the matching child. The round 4 property keeps an input error for a DIB above the PIA under workers' compensation.Local checks at the tree that became
3212f823: all 13,874 Track B tests pass and 7 skip in a session process. Black and ruff pass, the conformance report regenerates byte-identically, the cross-head comparison matches master, and 38 fresh mutations each failed a named test. Againsta135519f, 50 of the new module's 224 tests fail.Round 5 (after the fourth review)
Sol's review of
e3315bafconfirmed round 3's three counterexamples, the $175 and $192.10 corrections and the composition refusal. It found one medium: a held refusal still masked contradictions in RIB gross, auxiliary original rates and widow eligibility. Reproducing that showed round 4 had already gone too far the other way, so the fix reverses part of the finding.InvalidFamilyInputate3315baf, and at1ce508e5it refused by name. The capture says "the rate to the NH is protected by administrative finality and cannot be changed", so a protected rate rests on a PIA other than the declared one._PREFLIGHT_FACT_UNSETTLERSclassifies everyRecordCondition,BeneficiaryConditionandUnsupportedReasonagainst six facts: NH original, DIB gross, RIB gross, auxiliary original, spouse raw own-PIA eligibility and other own-benefit entitlement. A new enum member fails a test until someone classifies it. Each deferred reason applies only within its own person, role, record kind and payment period._check_settled_family_factscompares settled facts through G's validated helpers and catches onlyFamilyConfigurationUnsupported. The path with the preflight removed gives the same valid outcomes and refusals.Readings this round:
us:oasdi-finality-protected-rates-before-coverage: under finality, a rate that differs from the declared PIA staysadministrative_finality, one row, weight kept. This is the session's single reading under Max's 10/20 delegation, logged inRULINGS.md.Invented examples:
DIB_AFTER_REDUCED_RIB:dib_after_reduced_rib, one row, weight kept. The same gross under a maximum-only hold:InvalidFamilyInput, no row.eligibility_before_1983in January 1972, because RS 00615.005A.2 set 82 1/2%.InvalidFamilyInputin January 1973, because A.5 set 100%.Nine tests under round 4's reading split into a protected case with its exact refusal, row and weight, and a settled case that keeps the input error. No money moves: the cross-head comparison keeps all 240 R2 and 240 R3 rows, and G's conformance artifact stays byte-identical.
New invariants:
Local checks at
a135519f: all 13,650 Track B tests pass and 7 skip in a session process. Black and ruff pass, the cross-head comparison matches master, and the lane's 30 mutations each failed a named test.Round 4 (after the third review)
Sol's review of
1ce508e5confirmed all three round-3 fixes and found three new mediums, plus a question on how two POMS exceptions compose.e3315baffixes all four.apply_ret_yearcompares declared NH entitlement with RET before it computes any G money, in both directions, so a held refusal can no longer mask a contradiction. One helper now serves G and RET. The lane's audit of the whole loop added the same preflight for spouse eligibility under the raw own-PIA test, NH original rates and DIB gross rates. The checks that need G's money stay after it.RecordYearnow rejects two known cohorts for one person, across months and across record and own-benefit fields. A missing cohort adds no constraint.sole_full_deduction_zero_dual_compositionrefuses only where the two readings pay differently, and the rule computes where they agree. RULINGS logs this asus:oasdi-sole-full-deduction-zero-dual-composition.Invented examples:
New invariants:
Local checks at
e3315baf: all 13,341 tests across the 104 Track B modules pass (7 skip), and black and ruff pass on the round's Python files. The lane's 11 new mutations were all caught. The conformance report changes only for the new reason, and 240 R2 and 240 R3 cross-head results stay unchanged. One existing test moved its reason count from 37 to 38. The tier files add this round's 637 unit tests; the coordinator's slot recount replaces them.Round 3 (after the second review)
Sol's review of
bbcdf7f4kept every round-1 fix and reading, and found four mediums.7fa124e3and872cebc7had already fixed the stale conformance hash.1ce508e5fixes the other three.RecordYearnow checks the NH and every auxiliary against the twelve months each cohort allows, and an input error comes before any coverage refusal. Applied own delayed credits prove FRA by the snapshot month. A deceased worker's credits and old age reductions prove nothing about a survivor's age. Act 203(f)(9) and RS 02501.021B.3 apply the old-age FRA to every role, so this needed no ruling.New invariants:
Local checks at
1ce508e5: all 12,704 tests across the 102 Track B modules pass (7 skip), and black and ruff pass on the round's Python files. The lane's 11 new mutations were all caught. All 480 literal rows and 240 R2 and 240 R3 cross-head results stay unchanged, and the conformance report regenerates byte for byte. The tier files add this round's 176 unit tests; the coordinator's slot recount replaces them.Round 2 (after the first review)
RETFamilyMonthcontext, R2 derives it from G's admitted own-benefit facts, for actual and estimated excess.two_record_entitlementis now optional: a value that contradicts G's facts isInvalidFamilyInput, and a consistent one refuses by name.NO_CHILD_IN_CAREon such a spouse isInvalidFamilyInput. The rule derives age status from supplied birth facts and delayed credits.BenefitDeduction.under_full_retirement_ageis required only when those leave age unknown.RETFamilyMonth. The G note, the docstring and the refusal notes now call the reservation case deferred coverage.docs/design/track_b_g2_r2b_verification.json. All 356,400 G conformance rows are byte-identical, and the cross-head harness shows 240 R2 and 240 R3 results unchanged with the six former refusals computed. Both ran against master1ec57a5d; the round-2 review reruns them at this head.docs/design/track_b_g2_r2b_mutations.jsonkeep its results and its 15 new mutations.bbcdf7f4. 87 tests pass across the four round-2 modules, and black and ruff pass on the 42 changed Python files. A one-off audit hook over a sample of those modules counted no opens of the barred names. CI and the round-2 review cover the rest.872cebc7. CI failed atbbcdf7f4on the byte test fordocs/design/track_b_g_conformance_report.json: round 2 edited the registry YAML after the lane's last conformance run, so the report kept an old registry hash.7fa124e3regenerates the report. One line differs and all 356,400 rows match.872cebc7records the new hashes indocs/design/track_b_g2_r2b_verification.json. Neither commit changes Python.Checks (local, at
f3b9a719)readingpropertyBlack and ruff are clean, and the conformance report regenerates byte for byte.
Cost, measured back to back by the lane under load. G regeneration: 152 → 173 CPU seconds. R2 tests: 87 → 114 CPU seconds, for 786 → 818 tests.
Tiers:
Protected files are untouched.
axiom: n/a: not a country-model change. G and R2 are Python statutory references per d515, and rulespec-us has no 42 U.S.C. 403 encoding.
🤖 Generated with Claude Code