Skip to content

Populate passive_partnership_s_corp_income (NIIT passive pass-through leg, pe-us#9306): SCF non-active-business shape, SOI/8960 level #722

Closed

Description

@MaxGhenis

What

PolicyEngine/policyengine-us#9306 adds passive_partnership_s_corp_income — the §469 passive subset of partnership_s_corp_income — and puts it in the NIIT base (§1411(c)(1)(A)(ii)). It defaults to zero, so until Microcosm populates it the engine under-taxes passive pass-through income under NIIT exactly as before. Microcosm needs a stage that assigns each record's passive share.

Design (follows the #530 doctrine: measured / derived-from-law / anchored prior)

  • Not derivable from law alone: passivity is a facts-and-circumstances material-participation test (§469(h), the 500-hour and related tests); the PUF and CPS observe neither hours nor participation. So this is an anchored-prior stage, not a derivation.
  • Survey shape: the SCF distinguishes businesses the household actively manages (X3103/X3104, the basis of qbi_employer_structure_v1) from holdings with no active management role (X3401-X3452) — the cleanest public survey signal for "owner is passive." Extend the v3 SCF extract to that section: P(passive holding | income band, legal form) and the passive share of pass-through income by band.
  • Administrative level: SOI partnership passive/nonpassive tables and Form 8960 line-4 aggregates (chronicle ingestion companion issue) pin the aggregate passive share the assignment must hit — same SCF-shape / SOI-level rule v3 used for employer presence.
  • Placement: a per-record seeded draw of passive share (own rng family, so v1–v3 streams stay byte-identical), conditioned on income band and latent entity form (the v3 partnership/S-corp split already exists), emitting passive_partnership_s_corp_income = share × partnership_s_corp_income where positive. Gate behind the version flag like every other QBI family.
  • Validation: NIIT aggregate vs the JCT/SOI NIIT totals becomes a new row on the Standing per-component repeal-revenue validation surface (#298) #535 standing surface; the passive-income aggregate vs Form 8960 line 4 is the direct anchor check.

Dependencies

Consistency note

Today the engine's NIIT base includes rental_income in full while Schedule E rental is often passive-by-default; the new stage should not create an asymmetry where pass-through passivity is modeled but rental passivity is asserted. Document the treatment either way.

Activity

  1. MaxGhenis commented on Oct 13, 2026

    @MaxGhenis
    ContributorAuthor

    #1251 (draft, from #1239) populates passive_partnership_s_corp_income on the PUF channel from the PUF's own Schedule E passive columns: (E25940 − E25920) + (E26170 − E26160), the §469-limited passive income less allowed passive loss for partnerships and S corporations (field roles from the IRS SOI 2014 PUF General Description Booklet).

    Form 8960 filers in the TY2015 PUF agree with that reading. The weighted regression of their investment income on the Schedule E legs puts 0.97 on passive and 0.03 on nonpassive. For filers whose only pass-through income is passive, Form 8960's Schedule E amount (net of rent, estate and farm rent) over passive has median 1.000.

    If #1251 merges, this issue's anchored-prior design (an SCF-shaped passive share levelled to Form 8960) is not needed for the PUF channel, and building it on top would assign passivity twice. The ASEC channel carries no partnership income, so it has nothing to assign either; the late ACS transfer carries the PUF leaf. Whether to close this issue and PR #734 is queued for a ruling with #1251's merge.

    The open note on rental income (the engine counts rental_income in NII in full) is outside #1251 and still applies.

  2. MaxGhenis commented on Oct 31, 2026

    @MaxGhenis
    ContributorAuthor

    Closed by #1251, which populates passive_partnership_s_corp_income from the PUF donor's Schedule E fields. The open note on rental_income in NII stays relevant to that engine rule and appears in #1251's body.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions