Skip to content

AOTC is effectively disabled in Enhanced CPS because eligibility input is never true #841

@MaxGhenis

Description

@MaxGhenis

Summary

The Enhanced CPS artifact appears to make the American Opportunity Tax Credit effectively unavailable for all tax units, even though some people have nonzero qualified tuition expenses.

In PE-US, american_opportunity_credit depends on the person-level input is_eligible_for_american_opportunity_credit. That variable is a leaf/input variable, not a formula. In the current Enhanced CPS release, it appears to be false for every person, so american_opportunity_credit, refundable_american_opportunity_credit, and non_refundable_american_opportunity_credit are all zero for every tax unit.

Evidence

Using the bundled default dataset from policyengine.py / policyengine-us-data:

dataset: hf://policyengine/policyengine-us-data/enhanced_cps_2024.h5
periods checked: 2024 and 2025

refundable_payroll_tax_credit: nonzero=0/55,264 tax units
recovery_rebate_credit: nonzero=0/55,264 tax units
american_opportunity_credit: nonzero=0/55,264 tax units
refundable_american_opportunity_credit: nonzero=0/55,264 tax units
qualified_tuition_expenses: nonzero=662/101,384 people
is_full_time_college_student: true=3,748/101,384 people
is_eligible_for_american_opportunity_credit: true=0/101,384 people

Minimal check:

import numpy as np
from policyengine_us import Microsimulation

sim = Microsimulation()
for year in [sim.default_input_period, 2025]:
    print("period", year)
    for entity, var in [
        ("tax_unit", "american_opportunity_credit"),
        ("tax_unit", "refundable_american_opportunity_credit"),
        ("person", "qualified_tuition_expenses"),
        ("person", "is_full_time_college_student"),
        ("person", "is_eligible_for_american_opportunity_credit"),
    ]:
        arr = np.asarray(sim.calculate(var, year, map_to=entity, use_weights=False))
        if arr.dtype == bool:
            print(entity, var, int(arr.sum()), "/", arr.size)
        else:
            print(entity, var, int(np.count_nonzero(np.nan_to_num(arr))), "/", arr.size, float(np.nansum(arr)))

Why this matters

AOTC eligibility requires more than tuition expenses, but setting is_eligible_for_american_opportunity_credit false for all people means Enhanced CPS cannot represent any AOTC claims. This also makes income_tax_refundable_credits omit refundable AOTC mechanically, regardless of tuition expenses or student status.

Possible fixes

  • Populate/impute is_eligible_for_american_opportunity_credit in Enhanced CPS.
  • Add or impute the underlying eligibility inputs needed to derive it: credential program, at least half-time enrollment, first-four-years status, prior AOTC/Hope claim years, felony drug conviction exclusion, and eligible-institution/1098-T assumptions.
  • If AOTC is intentionally unsupported in public Enhanced CPS, document this limitation and consider suppressing or zeroing related tuition inputs that could otherwise imply AOTC support.

Related but not duplicate: PolicyEngine/policyengine-us#4034 discusses consolidating tuition variables. This issue is about the Enhanced CPS data path making AOTC eligibility false for every person.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions