Skip to content

Rebase congressional-district capital gains onto Table 1.4 and drop mislabeled CD SALT and PTC columns on the full surface - #1040

Open
MaxGhenis wants to merge 12 commits into
mainfrom
us-cd-capital-gains-concept
Open

MaxGhenis wants to merge 12 commits into
mainfrom
us-cd-capital-gains-concept

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1038 (capital gains). Stacked on #1036 and #1224.

Waiting on Max's ruling (d539), together with #1036 (d468). It changes published full-surface target values, and choosing shares over exclusion is a methodology call.

Summary

On the default --target-surface full, the congressional-district file (22incd.csv) compiles its N01000/A01000 rows onto capital_gains_gross. Those columns are "net capital gain (less loss)" at Form 1040 line 7: gain, capped loss and distributions-only returns. The model measures something else: the positive part of Schedule D, whose IRS counterpart is Table 1.4 col 37/38 (#1035).

On the pinned feed (51aa40f), the district file's states and its districts each summed to:

  • 29,845,710 returns, 2.41x the national Table 1.4 target of 12,392,020 on the same surface;
  • $1,522.2B, 1.198x the target's $1,270.9B.

This PR makes those rows shares of the district file's own US row, scaled to the Table 1.4 control, exactly as #1036 does for Historic Table 2:

  • the district file's US row retires;
  • every share row declares soi_source_concept, soi_control_concept and its denominator, soi_share_total_source_record_id;
  • CD children keep scaling to their CD state parent.

Option (a) shares, or (b) exclusion

Quantified on the sha-matched IRS files and the compile dumps. Scripts and JSON: ~/PolicyEngine/_reviews/cd-cg-concept-20260927/lane-b/. Critic re-derivations: critic.md.

The share assumption is #1036's. A district's share of line-7 returns stands in for its share of Schedule D gain returns. AGI composition is the measurable source of error. Reweighting each of the 428 numbered districts' N01000 by AGI class, with Table 1.4's per-class gain share, moves its share by:

  • counts: median 2.1%, 95th percentile 4.7%, max CA-18 +9.7%;
  • amounts: median 0.5%, 95th percentile 2.4%.

AGI composition is one measurable source of error, not a bound on the total: non-AGI variation in the gain/loss/distributions mix cannot be measured from IRS geography and could add to or offset it.

Exclusion would discard more.

  • District capital-gains incidence runs from 8.3% to 31.5% of returns (5th to 95th percentile), against 13.7% to 23.4% across states.
  • Within a state, the district share left after AGI has log SD 0.22 (counts) and 0.20-0.22 (amounts). That is 9-20x the share proxy's AGI error.
  • Without these rows, district capital gains would be constrained only by the 9 HT2 at-large copies.

Agreement with the HT2 state rows already on full. Both files' state rows stay on full; 45 measures pair two state targets. After dividing out each pair's common coverage-and-aging offset:

  • capital-gains return counts differ by a median 0.4% and at most 1.4%, among the tightest pairs (ninth of 45 by median gap);
  • capital-gains amounts differ by a median 1.8%, with the widest 95th percentile of the 45 pairs: Montana −28%, West Virginia −18%, Mississippi −17%.

The amount gap comes from item suppression in the district file's A01000; Montana's state total is 32.5% below HT2's. Other pairs have worse single states, for example qualified dividends in Hawaii at −58%.

Split of the control. The district file has no other-area rows, so its US row equals the sum of its states, and its rebased states and districts each sum to the control. HT2's US row includes other areas, so its rebased states sum to 99.2% (returns) and 98.0% (amounts).

  • So in aggregate the district-file capital-gains targets sit above the matching HT2 shares by about 0.8% (returns) and 2.1% (amounts). State by state they scatter around that; Montana's amount is 0.73x HT2's.
  • This is accepted. The model has households in the 50 states and DC only, and the national row on the same surface already asks them for the whole control.
  • The alternative is to scale the district file by HT2's 51-state share. It would mix the two families' totals in one factor.

Interplay

The congressional_district_children_scale_to_state_parent profile rule.

  • One factor per family, quantity and period scales the district file's states and districts alike, and the file's districts sum exactly to its states.
  • So all 872 district children still reconcile with factor 1. The rule never used the US row.

The ACS-local state_cd surface.

  • It already takes district capital gains as within-state shares of HT2, which a national factor does not move.
  • Its capital-gains rebase factors scale by the reciprocal of this PR's factor. That leaves every factor-band verdict and its contract counts unchanged (test_pinned_feed_state_cd_surface_matches_its_contract passes).

#1030 (source-vintage correction).

  • A share divides the district rows by the district US row of the same restamped package, so the stamp cancels. The value lands at the control's period (2023) and ages from there.
  • test_congressional_district_capital_gains_ignore_the_package_stamp compiles and ages the package stamped ty2023 and truthfully at 2022 and asserts identical values. Its facts carry the pinned 22incd.csv digest and raw key.
  • Read restamped Chronicle facts at their data year before aging #1030 as written refuses every restamped fact that was rebased, so Read restamped Chronicle facts at their data year before aging #1030 plus this PR refuses every compile.
  • Read restamped Chronicle facts at their data year before aging #1030 has been adopted, rebased onto main (head 03ceca6ad), and carries the reviewed narrowing (lane-a/source_vintage_share_narrowing.patch):
    • admit a rebased restamp only when its soi_share_total_source_record_id is a correction of the same package and stamp;
    • move source_period and uprating_from_period to the data year;
    • never move uprating_to_period. Starting the aging at 2022 would apply the Table 1.4 2022→2023 fall twice (×0.761).
  • Merge order. Whichever of the two merges second runs CI on a merge ref containing the first, and the stamp test fails until the narrowing is in.

What changes (fiscal_targets.py)

  • _rebase_stale_soi_capital_gains_distributions rebases every row of a share family: a registered family whose concept is not the model's, today historic_table_2 and congressional_district (_soi_capital_gains_share_family).
  • Each row is divided by its own family's national all-AGI row at its own period, via _soi_capital_gains_share_national_totals, which is keyed by family and refuses conflicting duplicates. A row with no control, or no national row of its own family, is dropped, never shipped as a level. That is the established rule (test_stale_soi_capital_gains_without_source_total_is_dropped).
  • Every share row names its denominator in soi_share_total_source_record_id.

Effect on the pinned feed

Release compile on 51aa40f: target period 2024, aging, packaged CD crosswalk, Medicaid substitution.

#1036 on main this PR (with #1224)
District-file capital-gains returns: states / districts (each sum) 29,845,710 (2.41x national) 12,392,020
District-file capital-gains amounts: states / districts $1,522.19B (1.198x) $1,270.86B
California returns / amount 3,808,930 / $214.08B 1,581,478 / $178.73B
Compiled targets (= full) 33,250 (f09571684885) 31,784 (6e1ac91262bc)
national_state 6,102 (882f4764a248) 6,102 (84504a7afd57)
District-file families past their national target on full 3 of 38 compared 0 of 35
  • Values: 974 district-file capital-gains values move, by 0.415202720927 (returns) and 0.834893818418 (amounts).
  • Removed: the 2 district-file capital-gains US rows, plus Drop congressional-district SALT and PTC facts read from the wrong IRS column #1224's 1,464.
  • Metadata only: 120 HT2 capital-gains rows (102 on national_state) gain soi_share_total_source_record_id. That is the whole national_state change: no national_state value or membership moves.
  • Hierarchy: all 872 district children reconcile with factor 1.
  • ACS local: state and state_cd keep their counts and band verdicts. state_cd's capital-gains amount rebase factors move from 0.77–1.00 to 0.93–1.20 (median 0.98).

Invariants

  • Shares conserve the control. Every district-file capital-gains row is raw × control / district US. The states, and each state's districts, sum to control × (Σ states / district US), never past the control. HT2 rows drawn beside them divide by, and name, their own US row. No district-file capital-gains row ships at the country level. This is a Hypothesis property over random packages, HT2 rows, controls and feed orders.
  • Stamp-invariance. A differential test: stamped ty2023 or truthfully at 2022, the aged values are identical, and amounts age from the control's 2023 period.
  • Denominators. Conflicting national totals refuse. Equal totals name the smaller id in either order.
  • District-file families stay inside their national targets on full. Pinned, two-sided: every compared family keeps its state and district rows and sums to within (0.85, 1] of its national target. Before this change, the capital-gains returns family was at 2.41x and the amount family at 1.198x.

Tests

These runs were local, on the pinned 51aa40f feed, run sequentially with peak RSS 3.6 GB. CI has no feed and skips the pinned-feed tests.

  • engine_free/us/test_us_fiscal_targets.py at 21a638dec: 210 passed, none skipped. That includes all six pinned-feed tests:
  • Neighbouring suites at 21a638dec: the ACS-local release tool, the state_cd sparse surface (its contract included), source coverage, release target parity, the Chronicle feed and the fiscal refresh builder: 495 passed, none skipped.
  • Follow-up commit 90ad595a6 (the ACS-local count pins and the state_cd doc paragraph) was verified with the same contract test on Drop congressional-district SALT and PTC facts read from the wrong IRS column #1224.
  • Static checks: tools/ci_test_plan.py verify passes; ruff check is clean.

New tests:

  • district-file rows are shares, while HT2 rows keep their own denominator;
  • with no control, or no own-family US row, the row is dropped;
  • conflicting totals refuse, and equal totals name the smaller id in either order;
  • share-family classification;
  • the Hypothesis share-conservation property, with HT2 rows and feed order in the draw;
  • the stamp-invariance differential;
  • the two pinned-feed tests above.

Review

The 2026-09-27 independent review (review-1040.md) asked for changes. Each finding is addressed below. A GPT-6.1 Sol re-review at 90ad595a6 (review-1040b.md) returned APPROVE WITH NITS. It found no P0–P2 in this PR's own change and confirmed that each prior answer holds, including that the stamp test is a real #1030 tripwire. Its four P3 nits are addressed at d3a625350:

  • the return counts agree "among the tightest" pairs (ninth of 45 by median gap);
  • the CD-over-HT2 tilt holds in aggregate, not state by state (Montana's amount is 0.73x);
  • AGI composition is "one measurable source of error";
  • what the generic invariant catches is stated exactly;
  • the parity-manifest note now names the capital-gains shares, the retired US row and the column exclusions.

d3a625350 also carries #1224's review fix byte-identical (the column check runs before the district crosswalk merges source districts).

  • P1-1 (Read restamped Chronicle facts at their data year before aging #1030 merge safety).
  • P2-1 (interest paid). Not added to the register.
    • N19300/A19300 (line 8a mortgage interest) is a component of the line-10 deduction the measure id means, not another concept. Its remedy is the same share-or-drop question as capital gains, and the rows also feed state_cd's itemized bridge.
    • The register comment and docs say so; the "56 compared" claim is corrected to 50 twins; a chip is filed.
  • P2-2 (ACS-local). Disclosed. The ACS-local counts are in docs/us-acs-local-soi-target-surface.md: totals 607 → 120, full 31,321 → 29,860, state/state_cd unchanged. The column exclusion is now its own PR, linked above.
  • P2-3 (tilt). Stated plainly in the doc and here: each CD capital-gains target sits above the matching HT2 share by 0.8% (returns) and 2.1% (amounts) in aggregate. It is accepted with the reason given; the alternative is named.
  • P2-4 (silent drop). The established rule is kept: a share row without its own family's national row is dropped, never divided by another family's total. test_stale_soi_capital_gains_without_source_total_is_dropped on main codifies it, and the interest twin does the same. The pinned invariant is now two-sided: every compared CD family must keep its state and district rows and sit in (0.85, 1] of its national target. So a family that vanishes, or loses a whole geography level, fails on the pinned feed; a family losing a few states can still pass that generic check, and for capital gains the dedicated pinned test (51 states and 436 districts per measure, exact control sums) catches it.
  • P2-5 (fail-open column). Fixed. A listed congressional-district fact with no column refuses (MissingSoiSourceColumnError).
  • P2-6 (qualified-dividends comparison). Reworded on the demeaned comparison. Capital-gains returns agree among the tightest pairs (ninth of 45 by median gap); amounts are the loosest pair at the 95th percentile. The worst states are named.
  • P3-1: the worst states are named instead of a p95.
  • P3-2: accepted as fail-closed.
  • P3-3: a comment notes that CD boundary vintages share one family.
  • P3-4: a comment notes that a corrected PTC package compiles without a further gate, by design.
  • P3-5: the key stays on every share row. On national_state that is a metadata-only change on the 102 HT2 rows.
  • P3-6: the parity-manifest note ("congressional-district rows inform shape while national and state actuals retain control ownership") is now literally true for capital gains, so it is unchanged.
  • P3-7: the Hypothesis property now draws HT2 rows alongside and checks that each family divides by, and names, its own US row.

axiom: n/a: microsim target compilation, no policy rule changes.

🤖 Generated with Claude Code

MaxGhenis and others added 4 commits September 27, 2026 04:55
…ed order

Historic Table 2 and congressional-district N01000 count Form 1040 line 7
returns (gain, loss-limited loss or distributions only); Table 1.4 col 37,
the population capital_gains_gross measures, counts Schedule D gain returns
only. The rebase control is now the latest Table 1.4 fact not after the build
period, CD and HT2 rows never qualify, a tie between matched records refuses
the compile, and a line-7 row without a usable control is dropped instead of
shipping as a level. Rebased rows declare the bridge in soi_source_concept /
soi_control_concept.

On the pinned feed the 51 national_state HT2 state return counts go from
29,599,604 (2.39x the national 12,392,020 target) back to Build P's
12,289,836; amounts keep their values. national_state registry
d315c75804ef -> 65e4dde11c83 (microcosm#1035).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…review)

The chooser now treats one record id carrying two values or period labels at
the winning period as ambiguous too, so no feed order can pick the value.
Tests cover that, an equivalent period label, and a tie at a superseded period.
The model-concept comment scopes "no loss returns" to the Build P release
data, and the doc's AGI-mix median is the median absolute change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…abeled CD columns (#1038)

On the full target surface the congressional-district file's capital-gains
rows compiled as Form 1040 line-7 levels onto capital_gains_gross (Schedule D
gain): its states and districts each summed to 29,845,710 returns, 2.41x the
Table 1.4 target, and $1,522.2B, 1.198x. They now enter as shares of the
file's own US row scaled to the Table 1.4 control, as Historic Table 2 rows do
since #1036; the US row retires and every share row names its denominator in
soi_share_total_source_record_id.

The same package reads N18425/A18425 (state and local income taxes) as the
limited SALT deduction and N85530/A85530 (additional Medicare tax) as the
premium tax credit. US_FISCAL_TARGET_SOURCE_COLUMN_EXCLUSIONS drops facts by
(measure id, IRS column), replaces the hard-coded CD PTC-amount check, and is
listed in the exclusion receipt and the release coverage report.

On the pinned feed: 31,376 compiled targets (was 32,842), no CD-file family
past its national target on full (was 3), national_state values and
membership unchanged (version moves only for the new provenance key).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 4 commits October 12, 2026 08:35
…s and totals (#1040 review)

The congressional-district package reads interest_paid_deduction_* from
N19300/A19300, Schedule A line 8a mortgage interest, while interest_deduction
is the line 10 total; add both to US_FISCAL_TARGET_SOURCE_COLUMN_EXCLUSIONS.
A congressional-district fact of a listed measure with no
layout.source_column_id now refuses (MissingSoiSourceColumnError) instead of
compiling unchecked, and a capital-gains share row that has a control but no
national total of its own family refuses
(MissingSoiCapitalGainsShareTotalError) instead of dropping silently.

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

# Conflicts:
#	packages/microcosm-build/tests/engine_free/us/test_us_fiscal_targets.py
…-concept

# Conflicts:
#	packages/microcosm-build/tests/engine_free/us/test_us_fiscal_targets.py
main re-pinned the US Chronicle feed to 51aa40f (#940), whose capital-gains
cells are identical to c5e5bf8's. Compiled there, this change still moves the
same 60 Historic Table 2 return counts by 0.415202720927 and adds the concept
keys to the 60 amount specs; national_state goes from e1f9906bf0e0 to
882f4764a248 at 6,102 targets (full f5bd921d6b21 to f09571684885).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 12, 2026 09:08
…n exclusions with #1224

Review (review-1040.md) follow-ups:
- Interest paid stays out of US_FISCAL_TARGET_SOURCE_COLUMN_EXCLUSIONS: N19300
  (line 8a mortgage interest) is a component of the line 10 deduction, not
  another concept, and it feeds state_cd's itemized bridge; its share-or-drop
  decision is a separate chip. The register comment, docs and claims now say
  50 of the package's 56 measures have a Historic Table 2 twin.
- A share row with no national row of its own family is dropped, as the
  established rule and test_stale_soi_capital_gains_without_source_total_is_dropped
  require; the pinned invariant is now two-sided (every compared district
  family keeps its state and district rows and sits in (0.85, 1] of its
  national target), so a vanished or partial family fails.
- The CD-vs-HT2 tilt (0.8% returns, 2.1% amounts) is stated plainly; the
  amount agreement is reported on the demeaned comparison with the worst
  states named.
- The Hypothesis property draws Historic Table 2 rows alongside and checks
  each family divides by, and names, its own US row; comments on CD boundary
  vintages sharing a family and on a corrected PTC package.

The SALT/PTC column exclusions are now #1224 (a bug fix that lands on its
own); this branch carries them byte-identical until it merges. Pins on the
51aa40f feed: 31,784 compiled (full 6e1ac91262bc), national_state 6,102 at
84504a7afd57.

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

# Conflicts:
#	packages/microcosm-build/tests/engine_free/us/test_us_fiscal_targets.py
… under the share rebase

The ACS-local contract test pins totals at 120 SOI specs and full at 29,860
(identical to #1224). With the district file's capital-gains rows as shares of
the Table 1.4 control, state_cd's capital-gains amount rebase factors move from
0.77-1.00 to 0.93-1.20 (median 0.98); its counts and factor-band verdicts are
unchanged (measured on the pinned 51aa40f feed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 12, 2026
…d total

apply_source_vintage_corrections refused every restamped fact that carried
uprating_factor. A congressional-district capital-gains row rebased as a share
of the same package's US row times the Table 1.4 control (microcosm#1040) is
such a fact, so #1030 plus #1040 refused every pinned compile.

A rebased restamp is now admitted only when the total its rebase names in
soi_share_total_source_record_id is a restamp of the same package, stamp and
data year, and its uprating_from_period is the stamp or the data year. The
stamp then cancels in the share and the level is the control's: source_period
and uprating_from_period move to the data year, and uprating_to_period, where
aging starts, stays at the control's period. Moving it would age the
control's data-year-to-control-period change twice (x0.761 for CD capital
gains). A missing, truthful or mixed-vintage total still refuses.

The module docstring no longer says the CD row wins the capital-gains control
tie: a restamped control keeps the selection its stamp won, which holds
whichever rule picks the control.

Tests: an admitted same-package share (and its idempotence), seven refusals
(no total, truthful total, another package, stamp or data year, another
reading period, no reading period), and the Hypothesis property now draws
uprating_factor, uprating_from_period and share totals across packages and
vintages, with the exact refusal oracle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Oct 12, 2026
On a local merge of #1040, the 487 congressional-district capital-gains
amount shares are admitted and aged from the control's 2023 period, and
aging records that start in source_period. The counter test's "every
corrected CD spec reads 2022" now allows exactly that case (a rebased spec
whose source_period is its uprating_to_period), so a later merge re-pins only
counts. Measured on #1040 + this branch: all 974 shares keep #1040's values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1040 re-review nits

From the #1224 review (P2/P3), carried here byte-identical: the
congressional-district crosswalk sums source districts under the first
contributor's layout, so US_FISCAL_TARGET_SOURCE_COLUMN_EXCLUSIONS and the
missing-column refusal now run on each source fact before translation, in the
compile and the receipt (which therefore lists 4 x 480 source ids); tests
cover mixed-column merges in both orders, every missing-column order, and a
corrected A85770 PTC amount.

From the #1040 re-review (APPROVE WITH NITS): the doc says the return counts
agree among the tightest pairs (ninth of 45 by median gap) and that the
CD-over-HT2 tilt holds in aggregate (Montana's amount is 0.73x); the
congressional-district parity-manifest note names the capital-gains shares,
the retired US row and the column exclusions.

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

Copy link
Copy Markdown
Contributor Author

Heads-up from #1244, which makes the SOI congressional-district guards vintage-free. Two things to adjust when this rebases after it, or that #1244 would need if this lands first:

  1. Duplicate helper. Match the SOI congressional-district file by family, at any vintage #1244 adds _soi_record_set_family (identical to the copy here) next to _is_soi_congressional_district_record_set, so the second to land gets ruff F811. Keep one copy.
  2. PTC tests. This PR deletes _is_soi_cd_premium_tax_credit_amount_conflict. Match the SOI congressional-district file by family, at any vintage #1244's new tests/engine_free/us/test_us_soi_congressional_district_vintage.py calls it:
    • _ptc_conflict in test_district_record_set_is_matched_by_family;
    • the property test;
    • the pinned-feed fact test.
      Its test_district_ptc_amount_never_compiles also builds district PTC facts with no layout.source_column_id, which the column fence here would refuse with MissingSoiSourceColumnError. Those assertions should move to the column-exclusion mechanism, for example asserting the A85530 column is excluded at any district vintage.

The _is_soi_cd_premium_tax_credit_amount_conflict deletion merges without a conflict against #1244, since its changed lines are two unchanged lines away.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

#1244 has merged (8fd39a21b). The heads-up above now applies on this PR's next rebase onto main.

MaxGhenis added a commit that referenced this pull request Oct 13, 2026
#1250 review)

From the in-session Opus review (review-opus.md):
- F3: state_cd district blocks read their rows through cd_file_level, so
  state_cd_cd_file_value, state_cd_cd_file_state_sum and the rebase factor
  record the district file's own values again and the receipt's rebase
  factors match #1247's base. Bound values are unchanged.
- F2: re-aging a share sibling like the bridged row refuses when the two age
  on different series, and the sibling's band median is re-aged with it, so
  its recorded ratio matches the unrebased case.
- F4: AGI slices of the district file take the measure's one factor, as #1229
  and #1040 rebase district slices, and the column guard checks them; tests
  pin the guard's eligibility rule and the slice rebase.

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

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Congressional-district capital-gains, SALT and PTC targets on the full surface cross IRS concepts

1 participant