PolicyEngine / PolicyEngine/policyengine-us

Migrate partner contract tests to the receipt-vs-eligibility contract (after 4-PR series + partner sign-off)

Open
#9,111 1 comment 0 reactions 1 assignee Claimed by @hua7450 View on GitHub
Dominant language
Python
Stars
162
Forks
212
Avg merge
3d 3h
Merged PRs (30d)
97

Description

## Summary

Migrate the partner contract tests under `policyengine_us/tests/policy/baseline/partners/**` from the legacy reported-receipt mechanism to the receipt-vs-eligibility contract introduced by the 4-PR series (#9041, #9043, #9112 `applicable_ssi` deprecation, #9044).

**Do not start this work until BOTH preconditions are met:**
1. All 4 PRs in the series have merged (#9041 and #9043 are merged; #9112 and #9044 are open).
2. The API partners have been consulted and have signed off on the input migration — these files are partner contract tests, and editing them is a partner-facing API change (see the partner-test policy in `CLAUDE.md`; the three-question gate applies).

## Why

The series establishes one consistent contract for reported vs. eligible receipt:
- `receives_X` (bool input) — reported receipt when the model computes $0
- amount known → send it as the `X` input directly
- `takes_up_X_if_eligible: false` — reported non-receipt
- `X_if_takes_up` (output) — computed entitlement regardless of take-up

PR 3 retires the SSI-specific legacy mechanism (`ssi_reported`, `use_reported_ssi`, `applicable_ssi`), and #9044 derives `is_tanf_enrolled` from `receives_tanf`. The partner tests still exercise the legacy inputs exclusively and use none of the new contract inputs, so they must be migrated in coordination with the partners whose integrations they pin.

## Current legacy usage inventory (as of 2026-07-21)

| Legacy variable | File | Occurrences |
|---|---|---|
| `ssi_reported` | `analytics_coverage/signatures/tx.yaml` | 28 |
| `ssi_reported` | `analytics_coverage/signatures/il.yaml` | 28 |
| `ssi_reported` | `analytics_coverage/signatures/ma.yaml` | 20 |
| `ssi_reported` | `analytics_coverage/signatures/co.yaml` | 20 |
| `ssi_reported` | `analytics_coverage/signatures/nc.yaml` | 20 |
| `ssi_reported` | `analytics_coverage/signatures/wa.yaml` | 16 |
| `ssi_reported` | `analytics_coverage/edge_cases/federal/cash/ssi/federal.yaml` | 2 |
| `ssi_reported` | `my_friend_ben/2025.yaml` | 1 |
| `use_reported_ssi` | `analytics_coverage/edge_cases/federal/cash/ssi/federal.yaml` | 2 |
| `applicable_ssi` | `analytics_coverage/edge_cases/federal/cash/ssi/federal.yaml` | 2 |
| `is_tanf_enrolled` | `analytics_coverage/edge_cases/state/tx/tanf.yaml` | 1 |
| `is_tanf_enrolled` | `analytics_coverage/edge_cases/federal/cash/tanf/federal.yaml` | 1 |

New-contract inputs (`receives_ssi`, `receives_tanf`, `receives_snap`, `takes_up_*_if_eligible`, `*_if_takes_up`) currently appear **zero** times in the partner folder.

## Migration sketch (to confirm with partners)

The core shape of the new contract, as it applies to these files:

- **Entitlement output: `X_if_takes_up`.** The variable partners request for the computed entitlement — what the household would receive if it took the program up — is `X_if_takes_up` (e.g. `ssi_if_takes_up`). Signature/edge-case assertions that read the computed `X` while overriding receipt should move to `X_if_takes_up`.
- **`X` itself becomes an override input.** When the household reports receiving X and the amount is known, the partner sends it as the `X` input (e.g. `ssi: 8_400`) and the model uses that amount everywhere downstream (income counting, categorical eligibility). This replaces the `ssi_reported` + `use_reported_ssi` pair.
- `receives_X: true` — receipt reported but the amount is unknown or the model computes $0; triggers receipt-based categorical eligibility without asserting an amount.
- `takes_up_X_if_eligible: false` — reported non-receipt; zeroes `X` and switches off receipt-conferred eligibility, while `X_if_takes_up` still reports the entitlement in the same response.
- `applicable_ssi` assertions → assert `ssi` (or `ssi_if_takes_up` for the entitlement view).
- `is_tanf_enrolled: true` → `receives_tanf: true` (after #9044, `is_tanf_enrolled` is derived from `receives_tanf` by default, so this may be a no-op — verify)
- Expected outputs must be re-derived from the underlying model change, not rewritten to match new behavior blindly

## Affected partners

- `analytics_coverage` (signatures for TX, IL, MA, CO, NC, WA + federal SSI/TANF edge cases)
- `my_friend_ben` (one `ssi_reported` use in `2025.yaml`)
- `amplifi`, `impactica`: no legacy usage found — confirm no action needed

## References

- #9041 — [1/4] core contract (`X_if_takes_up`, `receives_X`, take-up through the API)
- #9043 — [2/4] state/local `receives_X` sweep
- #9112 — [3/4] `applicable_ssi`/`ssi_reported`/`use_reported_ssi` deprecation (draft; keeps the trio as deprecated no-op inputs so partner tests pass until this migration)
- #9044 — [4/4] derive `is_tanf_enrolled` from `receives_tanf`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.