diff --git a/packages/irs_soi/table_1_4/source_package.yaml b/packages/irs_soi/table_1_4/source_package.yaml index ad952c5..b7f52d1 100644 --- a/packages/irs_soi/table_1_4/source_package.yaml +++ b/packages/irs_soi/table_1_4/source_package.yaml @@ -611,3 +611,173 @@ record_sets: national calibration source for self_employed_pension_contribution_ald. legal_vintage: tax_year_{year} value_scale: 1000 + - measure_id: capital_gain_distributions_returns + label: Returns with capital gain distributions reported on Form 1040 + ordinal: 17 + column: AJ + column_by_year: + 2021: X + 2022: AJ + 2023: AJ + concept: irs_soi.returns_with_capital_gain_distributions_1040 + unit: count + aggregation: sum + - measure_id: capital_gain_distributions_amount + label: Capital gain distributions reported on Form 1040 + ordinal: 18 + column: AK + column_by_year: + 2021: Y + 2022: AK + 2023: AK + concept: irs_soi.capital_gain_distributions_1040 + unit: usd + aggregation: sum + source_concept: irs_soi.capital_gain_distributions_1040 + concept_relation: broad_match + concept_authority: ledger-us + concept_evidence_url: https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-returns-complete-report-publication-1304-basic-tables-part-1 + concept_evidence_notes: > + IRS SOI Table 1.4 "Capital gain distributions reported on Form 1040" + is the capital-gain component filers report directly on Form 1040 + without a Schedule D. PolicyEngine-US carries this as the + non_sch_d_capital_gains input (the non-Schedule-D leg of the + net-capital-gains split), so Ledger treats the SOI line as a broad + match to that component. + legal_vintage: tax_year_{year} + value_scale: 1000 + - measure_id: estate_trust_net_income_returns + label: Returns with estate and trust net income + ordinal: 19 + column: BX + column_by_year: + 2021: BL + 2022: BX + 2023: BX + concept: irs_soi.returns_with_estate_and_trust_net_income + unit: count + aggregation: sum + - measure_id: estate_trust_net_income_amount + label: Estate and trust net income + ordinal: 20 + column: BY + column_by_year: + 2021: BM + 2022: BY + 2023: BY + concept: irs_soi.estate_and_trust_net_income + unit: usd + aggregation: sum + source_concept: irs_soi.estate_and_trust_net_income + concept_relation: broad_match + concept_authority: ledger-us + concept_evidence_url: https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-returns-complete-report-publication-1304-basic-tables-part-1 + concept_evidence_notes: > + IRS SOI Table 1.4 "Estate and trust — Net income" is the positive leg + of Schedule E Part III estate and trust income. PolicyEngine-US carries + the signed estate_income input; Ledger treats this SOI line as a broad + match to the positive component of that input. + legal_vintage: tax_year_{year} + value_scale: 1000 + - measure_id: estate_trust_net_loss_returns + label: Returns with estate and trust net loss + ordinal: 21 + column: BZ + column_by_year: + 2021: BN + 2022: BZ + 2023: BZ + concept: irs_soi.returns_with_estate_and_trust_net_loss + unit: count + aggregation: sum + - measure_id: estate_trust_net_loss_amount + label: Estate and trust net loss + ordinal: 22 + column: CA + column_by_year: + 2021: BO + 2022: CA + 2023: CA + concept: irs_soi.estate_and_trust_net_loss + unit: usd + aggregation: sum + source_concept: irs_soi.estate_and_trust_net_loss + concept_relation: broad_match + concept_authority: ledger-us + concept_evidence_url: https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-returns-complete-report-publication-1304-basic-tables-part-1 + concept_evidence_notes: > + IRS SOI Table 1.4 "Estate and trust — Net loss" is the negative leg of + Schedule E Part III estate and trust income (reported as a positive + magnitude). PolicyEngine-US carries the signed estate_income input; + Ledger treats this SOI line as a broad match to the magnitude of the + negative component of that input. + legal_vintage: tax_year_{year} + value_scale: 1000 + - measure_id: other_income_net_income_returns + label: Returns with other income (net income) + ordinal: 23 + column: CN + column_by_year: + 2021: CB + 2022: CN + 2023: CN + concept: irs_soi.returns_with_other_income_net_income + unit: count + aggregation: sum + - measure_id: other_income_net_income_amount + label: Other income (net income) + ordinal: 24 + column: CO + column_by_year: + 2021: CC + 2022: CO + 2023: CO + concept: irs_soi.other_income_net_income + unit: usd + aggregation: sum + source_concept: irs_soi.other_income_net_income + concept_relation: broad_match + concept_authority: ledger-us + concept_evidence_url: https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-returns-complete-report-publication-1304-basic-tables-part-1 + concept_evidence_notes: > + IRS SOI Table 1.4 "Other income — Net income" is the positive leg of + the Form 1040 Schedule 1 other-income line (miscellaneous income not + reported elsewhere). PolicyEngine-US carries the signed + miscellaneous_income input; Ledger treats this SOI line as a broad + match to the positive component of that input. + legal_vintage: tax_year_{year} + value_scale: 1000 + - measure_id: other_income_net_loss_returns + label: Returns with other income (net loss) + ordinal: 25 + column: CP + column_by_year: + 2021: CD + 2022: CP + 2023: CP + concept: irs_soi.returns_with_other_income_net_loss + unit: count + aggregation: sum + - measure_id: other_income_net_loss_amount + label: Other income (net loss) + ordinal: 26 + column: CQ + column_by_year: + 2021: CE + 2022: CQ + 2023: CQ + concept: irs_soi.other_income_net_loss + unit: usd + aggregation: sum + source_concept: irs_soi.other_income_net_loss + concept_relation: broad_match + concept_authority: ledger-us + concept_evidence_url: https://www.irs.gov/statistics/soi-tax-stats-individual-income-tax-returns-complete-report-publication-1304-basic-tables-part-1 + concept_evidence_notes: > + IRS SOI Table 1.4 "Other income — Net loss" is the negative leg of the + Form 1040 Schedule 1 other-income line (reported as a positive + magnitude). PolicyEngine-US carries the signed miscellaneous_income + input; Ledger treats this SOI line as a broad match to the magnitude of + the negative component of that input. + legal_vintage: tax_year_{year} + value_scale: 1000 diff --git a/packages/irs_soi/table_2_1/source_package.yaml b/packages/irs_soi/table_2_1/source_package.yaml index 12a9d7d..32468d7 100644 --- a/packages/irs_soi/table_2_1/source_package.yaml +++ b/packages/irs_soi/table_2_1/source_package.yaml @@ -566,3 +566,34 @@ record_sets: aggregation: sum value_scale: 1000 expected_cell_type: number + - measure_id: home_mortgage_interest_returns + label: Returns with total home mortgage interest deduction + ordinal: 37 + column: CW + column_by_year: + 2021: CK + 2022: CW + 2023: CW + source_column_id: home_mortgage_interest_returns + expected_column_header_row: 8 + expected_column_header: Number of returns + concept: irs_soi.returns_with_total_home_mortgage_interest_deduction + unit: count + aggregation: sum + expected_cell_type: number + - measure_id: home_mortgage_interest_amount + label: Total home mortgage interest deduction amount + ordinal: 38 + column: CX + column_by_year: + 2021: CL + 2022: CX + 2023: CX + source_column_id: home_mortgage_interest_amount + expected_column_header_row: 8 + expected_column_header: Amount + concept: irs_soi.total_home_mortgage_interest_deduction + unit: usd + aggregation: sum + value_scale: 1000 + expected_cell_type: number diff --git a/tests/test_ledger_bundle.py b/tests/test_ledger_bundle.py index 9cb7232..f0dac34 100644 --- a/tests/test_ledger_bundle.py +++ b/tests/test_ledger_bundle.py @@ -27,7 +27,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "aggregate_duplicate_key_count": 0, "entity_count": 8, "error_count": 0, - "fact_count": 38971, + "fact_count": 39173, "geography_count": 1053, "period_count": 16, "semantic_duplicate_key_count": 12, @@ -36,7 +36,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "source_package_count": 58, "warning_count": 1, } - assert len(rows) == 38971 + assert len(rows) == 39173 assert rows[0]["aggregate_fact_key"].startswith("ledger.aggregate_fact.v2:") assert rows[0]["semantic_fact_key"].startswith("ledger.semantic_fact.v2:") assert source_packages["source_package_count"] == 58 @@ -52,7 +52,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "cms-aca-oep-state-level-2025", "jct-tax-expenditures-2024", ] - assert coverage["fact_count"] == 38971 + assert coverage["fact_count"] == 39173 assert coverage["counts"]["by_source"] == { "bea": 445, "bfp_economic_outlook": 5, @@ -69,7 +69,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "hhs_acf_tanf": 110, "ici": 12, "hmrc": 193, - "irs_soi": 33535, + "irs_soi": 33737, "jrc_euromod_be": 18, "kff": 52, "nbb_national_accounts": 1, @@ -211,7 +211,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "month:2024-12": 260, "month:2025-12": 255, "tax_year:2022": 5886, - "tax_year:2023": 28187, + "tax_year:2023": 28389, "tax_year:2024": 34, } assert coverage["counts"]["by_geography"]["country:BE"] == 31 @@ -219,7 +219,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): assert coverage["counts"]["by_geography"]["nuts1:BE2"] == 17 assert coverage["counts"]["by_geography"]["nuts1:BE3"] == 6 assert coverage["counts"]["by_geography"]["commune:11002"] == 1 - assert coverage["counts"]["by_geography"]["country:0100000US"] == 1861 + assert coverage["counts"]["by_geography"]["country:0100000US"] == 2063 assert coverage["counts"]["by_geography"]["state:0400000US06"] == 217 assert ( coverage["counts"]["by_geography"]["congressional_district:5001700US0601"] == 56 @@ -234,7 +234,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "institutional_sector": 13, "pension_plan": 2, "person": 3682, - "tax_unit": 33541, + "tax_unit": 33743, } assert not coverage["duplicates"]["aggregate_fact_keys"] assert len(coverage["duplicates"]["semantic_fact_keys"]) == 12 diff --git a/tests/test_ledger_soi_targets.py b/tests/test_ledger_soi_targets.py index 1b0023a..d514f00 100644 --- a/tests/test_ledger_soi_targets.py +++ b/tests/test_ledger_soi_targets.py @@ -127,7 +127,7 @@ def test_build_soi_table_1_4_wage_facts_from_packaged_source(): } assert validate_facts(facts).valid - assert len(facts) == 340 + assert len(facts) == 540 assert ( facts_by_concept_and_range[("irs_soi.returns_with_total_wages", "all")].value == 128_591_050 diff --git a/tests/test_ledger_source_package.py b/tests/test_ledger_source_package.py index b188a21..eeb89d9 100644 --- a/tests/test_ledger_source_package.py +++ b/tests/test_ledger_source_package.py @@ -267,7 +267,7 @@ def test_source_package_path_builds_valid_soi_table_1_4_facts(): assert package.package_id == "soi-table-1-4" assert len(cells) == 8109 - assert len(facts) == 340 + assert len(facts) == 540 assert validate_facts(facts).valid assert facts[0].source.source_table == "Publication 1304 Table 1.4" assert ( @@ -580,8 +580,8 @@ def test_national_soi_source_package_aliases_validate_fixture_counts(): "soi-table-2-1": { "record_set_count": 1, "row_count": 1, - "measure_count": 37, - "source_record_count": 37, + "measure_count": 39, + "source_record_count": 39, "source_region_count": 1, }, "soi-table-2-5": { @@ -681,7 +681,7 @@ def test_soi_table_2_1_package_builds_itemized_deduction_details(): assert validate_source_rows(rows).valid assert validate_source_cells(cells).valid assert validate_facts(facts).valid - assert len(facts) == 37 + assert len(facts) == 39 charitable = values_by_record[ "irs_soi.ty2023.table_2_1.itemized_all_returns.all.charitable_amount" diff --git a/tests/test_ledger_suite.py b/tests/test_ledger_suite.py index 941ca92..356aad8 100644 --- a/tests/test_ledger_suite.py +++ b/tests/test_ledger_suite.py @@ -137,13 +137,13 @@ def test_build_source_suite_supports_soi_table_1_4(tmp_path): assert summary["counts"] == { "artifact_count": 1, "agent_acceptance_error_count": 0, - "concept_alignment_count": 2, - "constraint_count": 612, - "consumer_fact_count": 340, - "fact_count": 340, + "concept_alignment_count": 7, + "constraint_count": 972, + "consumer_fact_count": 540, + "fact_count": 540, "lineage_coverage": 1.0, "source_cell_count": 8109, - "source_record_count": 340, + "source_record_count": 540, "source_region_count": 1, "source_row_count": 0, }