Repository navigation
Conversation
MaxGhenis
marked this pull request as ready for review
October 27, 2026 08:44
Merges main 8ea4342 (which carries #10400) into 1aeb9e4. Resolved hunks: - Makefile, test-yaml-structural-other: the one conflict. Took main's recipe unchanged. SSA stays excluded from the per-subdir run and has its own per-file run with POLICYENGINE_BATCH_WORKERS=1, so this PR's three SSA YAML files run one file per process (review P2 #2). - policyengine_us/system.py: merged without a conflict. #10400 adds an import, a module-level install of its input hooks, a class attribute and a migrate call in each simulation constructor. This PR adds the current-law cap snapshot inside CountryTaxBenefitSystem.__init__. The hunks do not overlap. make format changed nothing after the merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No conflicts. Since 8ea4342, main has changed none of Makefile, policyengine_us/system.py, the SSA variables, reforms or contrib tests, the self-employment tax variables, reforms.py or the code-health tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cover signed subsets, phase-in, cap preservation, disabled equality, reporting floor, HI, deduction, and benefit credit with generated batches and explicit edge examples. Keep private simulation policies isolated and supply explicit earlier earnings history for the default AIME lookback. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Avoid reading a post-2012 SE parameter while computing default-lookback AIME before the reform starts. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Keep both structural reform registrations after the new main-side S.770 section 8 addition. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Use the calculated cap-, floor- and factor-aware exclusion while owners' draw is active, and preserve the existing manual hooks otherwise. Add joint examples and generated inactive-path equivalence; reject passive-inclusive joint draws until their active/NII allocation is supplied. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Retain the reviewed S.770 bridge and both reform registrations. Main updates the version and state AGI invariant generation; no merge hunk needed manual resolution. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10483 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 4 1 -3
Lines 76 26 -50
Branches 2 3 +1
=========================================
- Hits 76 26 -50
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Use Core instants in the raised-cap class fixture and retain every YAML case while grouping each existing file within five reform combinations. Keep three generated public-simulation batches per route, all explicit edges, and forty fast formula examples to reduce measured test cost. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Co-authored-by: OpenAI Codex <noreply@openai.com>
Stage the independent baseline and disabled calculations so their full historical parameter caches do not coexist. Retain the 45-year checks, use an exact hand baseline for credit-off AIME, and cover the inactive NIIT factor validation path. Co-authored-by: OpenAI Codex <noreply@openai.com>
Compare fresh public baseline and disabled simulations with exact outputs while sharing one privately owned, fingerprinted parameter history. Restore the complete baseline variable registry between examples to avoid repeated cold 45-year histories. Co-authored-by: OpenAI Codex <noreply@openai.com>
Use Core parameter types when reading child keys, scale brackets and scalar histories. A regular parameter node can expose a child named brackets; treating that child as a list raised KeyError in the disabled-reform differential. Co-authored-by: OpenAI Codex <noreply@openai.com>
This branch has not been 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.
Add an opt-in contributed reform that taxes eligible pass-through owners' draws under SECA OASDI. It is disabled by default and supports configurable phase-in, net-earnings factors, cap treatment, HI, deduction and benefit credit.
Review-update head:
b5fb5cabb2227fab8e00d40a9fc3bb964768f0cd. Main is merged throughbf108e931a1caed757339fadf79fa9e4da3166f9; this includes the SECA-room correction in #10380, Social Security benefit-input compatibility in #10400 and the S.770 section 8 options in #10402.Design and defects fixed
For each owner, net signed entity income before flooring:
G = T - Q - K + overlap, whereT = s_corp_income + partnership_income, Q is the combined passive subset and K is the already-SE partnership subset. If Q and K are both nonzero, require a validated disjointness assertion or a supplied signed intersection. Losses net within the supplied entity totals; a negative residual does not reduce wages or existing SE earnings. Nonpassive income is the material-participation proxy. Source income remains in gross income once.Track the planned draw, actual gross draw D, adjusted earnings N, cap room and taxed base B separately. The default factor is
q = 1 - employer_share × (SE_OASDI_rate + SE_HI_rate); a positive override replaces it. The planned adjusted draw must independently meet the $400 reporting floor. The default phase-in rises from 10% in 2027 to 100% in 2036, with configurable start, duration and annual shares. The default cap basis preserves the current-law cap before user reforms; the explicit alternative removes the draw ceiling. Wages have priority, then the existing adjusted/capped SE base, thenB = min(N, max(preserved_cap - wages - existing_SE_base, 0)).Added liability enters the existing SECA tax leaves and OASDI accounting once. HI defaults off; enabling it taxes all N without a ceiling. The added deduction uses the existing deductible-share parameter, with nondependent aggregation. Benefit credit adds adjusted annual earnings before the AIME helper's annual wage-base cap, preserves positive supplied AIME precedence and has no tax effect. It inherits main's age/lookback rules and separate benefit wage-base path; it does not change reported benefits or provide a complete annual-history ledger. Population scoring uses the tax side only. Reform documentation.
Generated coverage reproduced a default-45-year AIME crash: an installed draw reform read the reporting-floor parameter before its 2013 start, even in inactive earning years. Commit
4877a973f20f01788983e875811086be7b2d16bareturns zero fromowners_draw_grossbefore that read when the reform is inactive. The hand-computed YAML regression keeps the default lookback; the publicSimulationreproduction and final-head validation are distinguished below.Main merge and #10402 bridge
225c449fa88727ee8cce848e0f838b17e121bedfmerges main8ea43422e68fdb7dbae21ac2cc13e0081688ee4b. Its only resolved hunk is Makefile'stest-yaml-structural-other: retain main's recipe, excluding SSA from the shared contrib per-subdir command and running SSA separately withPOLICYENGINE_BATCH_WORKERS=1 .../ssa --mode per-file --workers 1.5d0d943611b141241dde4726e52100de10a0b911merges mainfce6c03f9dfec72a58b538d281cab11b2c6dc932without conflicts.d3532f1e79dc14c545a8d2478c01c718dc4b1e3amerges mainfe9ec1270fand Add S.770 section 8 investment and active income tax options #10402. Resolve the structural-reform-list insertion inpolicyengine_us/reforms/reforms.pyby retaining both owners' draw and S.770 section 8 registrations. Main's new S.770 implementation is retained.7f1f875d55e7b65a0fb45cbd3c280cfaefe0608cmergesbf108e931a1caed757339fadf79fa9e4da3166f9; resolved hunks:none; automatic merge.system.pymerged without a textual conflict. The draw's cap snapshot occurs after loading, interpolation, uprating and backdating, before user/structural reforms. #10400's module-level compatibility installer wraps input/array methods; its constructor migration moves stored benefit-component arrays. Neither rebuilds parameters, and the draw does not read those benefit components. The recursive system clone copies the cap's parameter/value history and clears instant caches. The public wrapper clones a supplied system before applying a constructor reform. No order or shared-state interaction was found; the constructor and isolation tests exercise these paths.#10402 supplied manual draw hooks, but they did not consume this reform's calculated exclusion. The only model file from #10402 changed here is
s770_active_business_income.py, at that integration point. An installed, enabled draw at/after its start year now suppliesowners_draw_niit_exclusion:B / qfor OASDI-only treatment, or all actual D when uncapped HI applies. This respects the floor, cap room and an explicit q override. The signed active residual, existing-SE/FICA exclusions, dependent exclusion, tax-unit aggregation and S.770 rates/allocation remain main's. Disabled, pre-start and uninstalled draws retain main's manual hooks and rate-derived factor, including nonzero manual inputs.The automatic joint bridge requires
material_participation_only=True. Setting it false admits passive draw income, but the aggregate draw does not identify its active/NII allocation. An active installed bridge therefore raisesValueErroruntil a validated allocation is available; silently subtracting the whole exclusion from active income would misallocate categories. Standalone passive-inclusive draw calculations remain supported, and inactive/pre-start/uninstalled S.770 manual hooks retain main's behavior. This unsupported joint sensitivity is explicit, rather than a claimed calibrated policy result.The first CI run at
7f1f875d55found two test defects: six reform combinations in the net-earnings YAML exceeded the existing five-combination budget, and the raised-cap class fixture supplied date strings where Core requiredInstantobjects. Commitb0c7f37394fixes that fixture and moves the default-q joint case into the existing credited-earnings file, adding the hand credit400,000 × .9235 = 369,400for both owners. All 28 named cases remain; each file has exactly five combinations.At
7f1f875d55, the Python file had 28 passes and one class-fixture failure; original 13 phases totaled 23.651 s and added 16 totaled 141.234 s. Atb0c7f37394, all 29 Python cases passed in CI, but added phases still took 143.155 s (old 13: 28.817 s; total: 171.972 s). These are JUnit phase sums, excluding import/collection, not an isolated before/after file-wall benchmark. Reducing public generated batches from five to three had not established the requested approximately two-minute added-cost target.Commit$.03 to $ .05: one float32 rounding step near its active base is $.03125. Its hand expectations remain unchanged. This responds to the earlier Quick Feedback precision failure. That run also reported 81.81% changed-hook coverage; the new existing-case assertions exercise main's nonpositive-q rejection on disabled, pre-start and uninstalled fallback paths. Both corrections passed Quick Feedback at
5d1d622855922167472a7b1beaba47186c918f0eincreases only the default-q joint YAML's absolute margin from4b0a0aedf303; its changed-hook report has 26 statements and six branches, 100% coverage, no missing or partial branches. Codecov patch and project checks passed.Commit
4b0a0aedf303c93854d29188e67166fc4f4841a7reduces public generated batches to two while retaining every explicit batch, both cap-constructor routes, shrinking and all 40-example fast properties. The benefit-credit test retains its full 45-year actual calculation and compares credit-off AIME with an independent hand baseline for age 62, zero earlier earnings and the scoring-year wage base, avoiding a redundant third simulation. It checks exact array equality after casting that hand oracle to the actual stored AIME dtype. The disabled differential still calculates every required output through independent real public baseline and reform simulations with default 45-year histories. It snapshots baseline results, releases derived parameter caches and the simulation before calculating the disabled system, and releases that system's caches after each example. It clears root and descendant instant caches, not policy values or inputs. This responds to an earlier local 4 GiB RSS termination while both histories were resident. At4b0a0aedf303, all 29 cases passed ordinary Rest CI: original 13 phases 27.244 s, added 16 phases 189.133 s, total 216.377 s. The disabled differential alone took 114.523 s, so the approximate two-minute added-cost target was still missed. A local run timed out at 1,800.403 s capped wall with 2.602966 GiB peak RSS, before a complete file result.Commit
4640c0c630d85a16223406f7d3e2efe8c76d9c17responds to that measured cost by retaining one privately owned parameter tree and its warm 45-year views. Each generated example restores the entire saved baseline variable registry anddata_modifiedflag, calculates and copies every baseline output through a fresh publicSimulation, installs the production draw factory into that private registry, and compares every disabled output through a second fresh publicSimulation. It releases the first holder graph before the second and restores the registry infinally. Parameter-root identity, inactive status and a streamed fingerprint of all scalar histories and scale/bracket structure protect policy equality. This differential now installs via the factoryapplymethod; the original constructor activation/isolation tests and both generated raised-cap routes still exercise the publicreform=constructor argument. No model code, output assertion, explicit example or lookback changes. The fingerprint correction and latest-head validation are recorded below.At
4640c0c630d8, Quick Feedback passed all 28 draw YAML cases twice and 28 Python cases, but the new fingerprint helper failed before its differential comparison. A regular Core parameter node can expose a child namedbrackets; generic attribute inspection mistook that child scale for a bracket list and raisedKeyError: 8. Commitb5fb5cabb2227fab8e00d40a9fc3bb964768f0cdrestricts child keys, bracket lists and scalar histories to their actual Core parameter types. It retains complete descendant traversal, scale structure and policy-history checks. This is a test-helper correction; model arithmetic and all differential assertions are unchanged. Final-head ordinary Rest and Quick Feedback now pass; the measured added-test cost still exceeds the approximately two-minute target, as recorded below.Joint hand calculations
All joint YAML owners have no preexisting SE earnings, phase-in share 1, cap $200,000, MAGI $1,000,000, no NII and single filing status. Thus the MAGI excess does not constrain these active bases. Set
R = max(200,000 - W, 0),N = D × q,B = min(N, R),E = B/qwithout HI orE = Dwith HI, andA = D - E. S.770's active tax is0.162 × A. All listed draws exceed the floor.The paired rows show every joint fixture with and without the explicit q=.8 override. The changed-rate fixture has OASDI=.20 and HI=.04, so its rate-derived q=.88; all other fixtures have OASDI=.124 and HI=.029, giving q=.9235. These arithmetic comparisons include sensitivities beyond the exact YAML rows and are not additional passing-test claims.
OASDI liability is B times the applicable rate: $17,600/$16,000 for the changed-rate no-wage pair, $20,000 for its room-limited pair and $12,400 for other room-limited rows. For the three HI fixtures, uncapped HI is respectively $5,356.30, $4,017.225 and $10,712.60; with q=.8 it is $4,640, $3,480 and $9,280. Applying the default half deduction yields $8,878.15/$2,008.6125/$11,556.30 without the override, or $8,520/$1,740/$10,840 with it. No-room OASDI is zero in both HI modes.
Invariants
Tests below are in
policyengine_us/tests/reforms/test_owners_draw.py. Formula properties generate batches; publicSimulationproperties use one private system per test and household batches. Hypothesis uses the repository's module-levelSETTINGSconvention, deterministic generation, explicit examples and shrinking; no registered profile exists. Private policies are released at test end. Fast formula properties retain 40 generated examples; public-simulation properties use two generated batches plus every explicit example. The disabled differential uses fresh baseline and disabled holders on one private parameter tree, with policy-history fingerprints and the full default lookback. Explicit boundaries include adjusted $399.99/$400/$400.01, exact/zero cap room, above-cap wages, losses netting to zero and a phase-in step.test_generated_draw_bounds_and_adjustmenttest_generated_raised_cap_paths_preserve_current_law_roomtest_generated_disabled_reform_matches_public_baselinetest_generated_phase_in_tax_is_monotonetest_generated_signed_residual_never_double_counts_setest_generated_reporting_floor_is_separate_from_existing_setest_generated_hi_defaults_off_and_is_uncapped_when_enabledtest_generated_deduction_tracks_existing_deductible_sharetest_generated_benefit_credit_cap_override_and_historical_lookbacktest_generated_s770_excludes_actual_owners_draw;test_s770_rejects_unclassified_passive_inclusive_drawtest_generated_disabled_owners_draw_preserves_main_s770, with an independent scalar main-formula oracle.Scratch mutants change one source expression each. Their country-importing checks run sequentially against the same committed test file in one foreground interpreter under a shared total 2 GiB / 900 s cap, including import. Formula/factory aliases and model source are restored between variants. These source-injection checks share imported country state; they do not reconstruct a registry independently per variant. An interrupted variant is unrun, never a mutant rejection.
4877a973f2, but the raw runner omitted embedded HEAD.7f1f875d55, 310.914 s. A later attempt atb0c7f37394timed out before a completed result.7f1f875d55, 12.713 s.7f1f875d55, 6.206 s.7f1f875d55, 11.150 s.7f1f875d55, 14.115 s.7f1f875d55, 15.132 s.7f1f875d55, 29.159 s.7f1f875d55, 54.624 s.AttributeErrorin the deliberately incomplete historical-parameter harness atb0c7f37394, 53.220 s.AssertionErroratb0c7f37394, 23.692 s.AssertionErroratb0c7f37394, 257.696 s.pytest.raisesfailure atb0c7f37394, 35.197 s; verified by a separate posthoc audit.The priority attempt covering 12, 11, 10 and 13 completed within the unchanged common caps: 761.657 s capped wall, 0.867706 GiB peak RSS, no timeout/RSS kill/monitor error; wrapper wall 763.144 s, excluding 423.484 s waiting for load. The runner exited 2 because its classifier mislabeled property 13's
builtins.Failed: DID NOT RAISE ValueErroras unexpected. A 36/36-check source/log audit verified the exact intended failure and preserved the raw classifier status and logs. This is an audited rejection, not a successful aggregate runner exit.Properties 2–9 completed in the earlier common-cap
7f1f875d55invocation before it timed out during 10: 900.188 s, .846100 GiB. The separateb0c7f37394attempt timed out after 900.235 s while property 2 was active, before a completed pytest result, at 0.825790 GiB; later variants were not reached. Neither timeout counts as a mutant rejection. The table distinguishes completed observations from that interruption. The owners-draw and S.770 model blobs remain unchanged by the later YAML/runtime-only commits. None of these observations is relabeled as execution at the latest head. The earlier 51/51-check source audit established unchanged production expressions and mutant-catching probes at4b0a0aedf303; the refreshed audit also passes 51/51 checks at this test-only head.Routing and validation
The batch runner recursively includes
.yamland.yml, including loose top-level SSA files. Per-file mode creates singleton batches before combination packing; it cannot split one file, and continuation checks run between files. With the explicit worker override, the six SSA files form six logical sequential file batches plus the supervisor; each attempt has one model subprocess, and retries/continuations can add attempts. Python remains in the existing Rest route, and.github/is unchanged.Static production-helper checks confirm five structural combinations, weight 5.0, in each draw file. All 28 named cases and hand expectations remain, including the added joint credit assertion; the later float32 correction changes only its absolute margin. Static budget checks are not runtime pass counts.
owners_draw.yamlowners_draw_credited_earnings.yamlowners_draw_net_earnings.yamlThese pytest elapsed times exclude earlier country import and are not whole process wall. Quick Feedback did not record file-process RSS. No final-head local whole-YAML runs were attempted; historical scratch processes cannot establish their whole-file peaks.
Local ordinary-file checks use fresh foreground interpreters, one file at a time, thread limits of four, load1≤100 at launch, and unchanged 4 GiB / 1,800 s limits. Mutants retain 2 GiB / 900 s. Python invokes pytest; YAML invokes the direct Core CLI with
-c policyengine_us. An exact-HEAD, Git-blob-verified byte/discovery cache reduces filesystem latency while tests remain uncached. No preloaded country or initialized-system fallback replaces these file runs. A planned/load-gated job is not an execution result, and incomplete scratch splits do not establish a whole-file pass.b5fb5cabb2227fab8e00d40a9fc3bb964768f0cdtests/reforms/test_owners_draw.pyThe final local Python process launched with load1 66.268 after 32.843 s waiting (300 s maximum); load1 ended at 95.606. It used four threads and the unchanged 4 GiB/1,800 s cap. The original 13-test snapshot passed at
b0c7f37394in 407.613 s wrapper wall, peak 2.881088 GiB; production model bytes match final HEAD. A timeout is not a completed timing pair. Shared-host load, filesystem QoS and cache warmth also limit observational comparisons. No unverified cleanup/GC optimization was applied.Earlier local evidence at
b0c7f37394: the original 13-case baseline passed in 407.613 s wall, with 2.881088 GiB peak RSS. The then-current 29-case file was terminated at the unchanged 4 GiB cap after 893.499 s, peak 4.003418 GiB, after 21 completion markers. This is incomplete and does not establish a final pass/fail count or a whole-file result. It motivated the new staged-cache cleanup. At7f1f875d55, an earlier full-file local attempt timed out at 1,800 s after 12 completed cases, peak 2.41983 GiB.At
b0c7f37394, CI passed all 29 owners-draw Python cases, with 171.972 s total phases: 28.817 s original and 143.155 s added. These sums exclude import/collection and differ from isolated file wall time; the latest measured added cost is 174.248 s, still above the target. Earlier Quick Feedback's float32 assertion and 81.81% changed-hook coverage are historical failures addressed by the new tests, not new-head passing evidence.The earlier lock check resolved 150 packages in 3 ms resolver time without lock changes; that log did not record process wall. Earlier
make formatand Ruff checks passed with 7,893 files unchanged. The historical original 13-test run (108.3 s process wall / 39.3 s pytest, 2.95 GiB) is separate from the later matched baseline above. The public historical AIME crash reproduction completed its assertions before itstime -lwrapper failed on deniedkern.clockrateaccess; it establishes the reproduced defect, not a fixed-head passing regression.Under the continuation's runtime scope, long YAML folders,
test_tob_revenue.pyand outside-change files are delegated to CI. This includestest_ss_calculator_differential.py, the requested code-health files and #10400's real-core/lever-property files unless a completed local result is recorded. The calculator reference removesgov.contrib.ssa.piaandgov.contrib.congress.s770, retaining the neutral owners-draw subtree. Individual requested file results will be reported from completed logs, not inferred from an in-progress containing job.At historical
4b0a0aedf303, Quick Feedback and all five Rest shards passed. At finalb5fb5cabb2227fab8e00d40a9fc3bb964768f0cd, run 40760043706 is exact-head verified. The saved 2026-10-28 21:12:46 UTC snapshot has 33 passing checks, 2 pending and 1 skipped, with no failures. All five Rest shards, Quick Feedback and both Codecov checks pass. Quick Feedback's 116 selected test executions all passed, including the three draw YAML files twice and all 29 Python cases. These results resolve the historical float32/coverage and fingerprint failures; earlier CI and mutation observations retain their actual heads.Final-head Rest JUnit artifacts report:
tests/reforms/test_owners_draw.pytests/unit/test_ss_calculator_differential.pytests/code_health/test_make_test_matches_ci.pytests/code_health/test_rest_python_groups.pytests/code_health/test_source_conflicts.pytests/core/test_social_security_real_core.pytests/core/test_social_security_lever_properties.pytests/policy/baseline/gov/ssa/revenue/test_tob_revenue.pytests/reforms/test_s770_section_8.pyThe containing remaining-Python process ran 3,119 cases in 1,644.46 s wall, peak 7.9022 GiB. Those resources belong to the entire process, not the owners-draw file. JUnit sums setup/call/teardown and exclude import/collection; they do not establish isolated file wall/RSS. The added 174.248 s exceeds the approximate two-minute target by 54.248 s, so runtime acceptance remains unmet despite passing assertions.
Final structural-other job 123086651928 (Contrib other-shard-1) succeeded in 54:40, from 20:38:00Z to 21:32:40Z; the same shard took 45:15 at main
c55b806541. Its serial SSA command took 967.297 s, against 426.408 s at main. The three draw YAML files account for about 538 s of that increase; the original SSA files kept nearly the same times. These figures come from the completed job logs.Data and sources
Current production exports force S-corporation income to zero, combine nonpassive donor income in partnership income and lack the passive column; calibration can overstate the active residual. Current-data scoring remains provisional. Nonprovisional results require a pinned artifact containing Microcosm #1251 and #1261, plus a column-contract check. The intended contract separates entity totals, subtracts the combined passive subset once and removes already-SE income without double counting.
impact: the hub will measure
axiom: n/a: contributed reform, not enacted law
CI at the final head: run 40760043706 completed with success. 35 checks passed and 1 skipped, including Contrib other-shard-1 and states-shard-1.