Skip to content

Implement Alabama Unemployment Insurance (al_ui) (ref #8282) - #8283

Open
daphnehanse11 wants to merge 9 commits into
PolicyEngine:mainfrom
daphnehanse11:al-ui
Open

Implement Alabama Unemployment Insurance (al_ui) (ref #8282)#8283
daphnehanse11 wants to merge 9 commits into
PolicyEngine:mainfrom
daphnehanse11:al-ui

Conversation

@daphnehanse11

@daphnehanse11 daphnehanse11 commented May 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the Alabama Unemployment Insurance program (Code of Alabama Title 25, Chapter 4).
Closes #8282.

Regulatory Authority

Monetary Eligibility (§ 25-4-77(a)(4))

A claimant is monetarily eligible if ALL of the following are true:

  1. Wages reported in at least 2 quarters of the base period
  2. Total base-period wages ≥ 1.5 × the high-quarter wages
  3. Unrounded weekly benefit amount > $44.50

Weekly Benefit Amount (§ 25-4-72(b))

  • Formula: WBA = (High Quarter Wages + 2nd-High Quarter Wages) / 52
  • Rounding: Nearest $1; ties round DOWN (Alabama-specific; implemented via np.ceil(x - 0.5))
  • Min: $0 if unrounded ≤ $44.50; otherwise rounded amount
  • Max: $275 (effective 2020-01-01; Act 2019-204)

Maximum Benefit Amount and Duration (§ 25-4-74(a))

  • Duration: Sliding-scale tied to the state's unemployment rate (Act 2019-446):
State unemployment rate Maximum weeks
≤ 6.5% 14
> 6.5% to ≤ 7.0% 15
> 7.0% to ≤ 7.5% 16
> 7.5% to ≤ 8.0% 17
> 8.0% to ≤ 8.5% 18
> 8.5% to ≤ 9.0% 19
> 9.0% 20
  • MBA dual-cap: min(max_weeks × WBA, ¼ × base-period wages), rounded to nearest $1
  • State unemployment rate is sourced from FRED ALUR (monthly values stored as a parameter)

Partial-Benefit Provisions (§ 25-4-72; NELP 2015 reform)

  • A claimant is on partial unemployment if weekly earnings < WBA
  • Earnings disregard: 1/3 × WBA (effective 2015-06-13 onward)
  • Partial weekly benefit = max(WBA - max(weekly_earnings - WBA/3, 0), 0)

Waiting Week

  • 1 non-compensable week subtracted from the duration of payable benefits
  • Effective 2012-08-01 per BRR handbook p. 6 and Admin Code 480-4-3

Requirements Coverage

REQ Description Param Variable Test
REQ-001 ≥2 base-period quarters eligibility/quarters_with_wages.yaml al_ui_monetarily_eligible.py al_ui_monetarily_eligible.yaml
REQ-002 BPW ≥ 1.5 × HQW eligibility/bpw_to_hqw_multiplier.yaml al_ui_monetarily_eligible.py al_ui_monetarily_eligible.yaml
REQ-003 Unrounded WBA > $44.50 wba/min_threshold.yaml al_ui_monetarily_eligible.py, al_ui_weekly_benefit_amount.py al_ui_weekly_benefit_amount.yaml
REQ-004 WBA = (HQW + 2HQW) / 52 al_ui_unrounded_wba.py al_ui_unrounded_wba.yaml
REQ-005 Ties-down rounding al_ui_weekly_benefit_amount.py al_ui_weekly_benefit_amount.yaml
REQ-006 WBA = 0 when ≤ threshold wba/min_threshold.yaml al_ui_weekly_benefit_amount.py al_ui_weekly_benefit_amount.yaml
REQ-007 WBA cap $275 wba/max.yaml al_ui_weekly_benefit_amount.py al_ui_weekly_benefit_amount.yaml
REQ-008 UR-bracket 14-20 weeks mba/duration_weeks.yaml, state_unemployment_rate.yaml al_ui_max_weeks.py al_ui_max_weeks.yaml
REQ-010 MBA dual-cap mba/bpw_fraction.yaml al_ui_maximum_benefit_amount.py al_ui_maximum_benefit_amount.yaml
REQ-011 MBA rounded to $1 al_ui_maximum_benefit_amount.py al_ui_maximum_benefit_amount.yaml
REQ-012 Partial-week threshold al_ui_partial_weekly_benefit.py al_ui_partial_weekly_benefit.yaml
REQ-013 1/3 WBA disregard partial/disregard_rate.yaml al_ui_partial_weekly_benefit.py al_ui_partial_weekly_benefit.yaml
REQ-014 1 waiting week waiting_weeks.yaml al_ui.py al_ui.yaml, integration.yaml

Not Modeled

  • Training-program +5-week extension (§ 25-4-74(b)) — opt-in, requires participation data not in CPS
  • Extended Benefits (§ 25-4-75) — federally-triggered, transient
  • Non-monetary eligibility (able/available/seeking work) — not simulatable
  • Disqualifications (voluntary quit, misconduct, refusal, labor dispute) — requires reason-for-unemployment data
  • Federal-conformity escalator on WBA max — programmatic, not in claimant calculations
  • Alternative base period — Alabama has none
  • Dependents' allowance — Alabama has none
  • Pre-2020 history (uniform 26-week cap, pre-2015 $15 partial disregard) — out of scope per scope decision

Historical Notes

All AL UI parameters in this PR start at 2020-01-01, matching the effective date of Act 2019-204 which introduced:

  • The current $275 WBA cap (previous: $265 from 2009; $255 from 2008)
  • The unemployment-rate-tied duration bracket (replacing a flat 26-week cap)

The 1/3 partial-earnings disregard has been in effect since 2015-06-13 (prior was a flat $15) — using the 2020-01-01 effective date in the parameter is conservative (i.e., the rule was already in effect by then).

State unemployment rate values in state_unemployment_rate.yaml are approximate decimal-form FRED ALUR series values for 2020-01 through 2026-04. Reviewers should verify these against the authoritative FRED series before merge.

Test Coverage

  • 76 YAML test cases across 8 unit-test files + 1 integration file
  • All tests pass (verified by implementation-validator)
  • Coverage includes: each formula variable's edge cases, all 7 duration brackets, both MBA caps binding, half-down rounding boundaries, monetary ineligibility scenarios, partial-week dynamics, full annual-benefit lifecycle, multi-person and cross-state cases

Files Added

policyengine_us/parameters/gov/states/al/dol/unemployment_insurance/
├── eligibility/
│   ├── bpw_to_hqw_multiplier.yaml
│   └── quarters_with_wages.yaml
├── index.yaml
├── mba/
│   ├── bpw_fraction.yaml
│   └── duration_weeks.yaml
├── partial/
│   └── disregard_rate.yaml
├── state_unemployment_rate.yaml
├── waiting_weeks.yaml
└── wba/
    ├── max.yaml
    └── min_threshold.yaml

policyengine_us/variables/gov/states/al/dol/unemployment_insurance/
├── al_ui.py
├── al_ui_base_period_wages.py
├── al_ui_high_quarter_wages.py
├── al_ui_max_weeks.py
├── al_ui_maximum_benefit_amount.py
├── al_ui_monetarily_eligible.py
├── al_ui_partial_weekly_benefit.py
├── al_ui_quarters_with_wages.py
├── al_ui_second_high_quarter_wages.py
├── al_ui_unrounded_wba.py
├── al_ui_weekly_benefit_amount.py
└── al_ui_weekly_earnings.py

policyengine_us/tests/policy/baseline/gov/states/al/dol/unemployment_insurance/
├── al_ui.yaml
├── al_ui_max_weeks.yaml
├── al_ui_maximum_benefit_amount.yaml
├── al_ui_monetarily_eligible.yaml
├── al_ui_partial_weekly_benefit.yaml
├── al_ui_unrounded_wba.yaml
├── al_ui_weekly_benefit_amount.yaml
├── integration.yaml
└── set_state_unemployment_rate.py (reform helper)

Modified: policyengine_us/variables/gov/states/unemployment_compensation.py — added al_ui to the adds list so it flows into the federal unemployment_compensation aggregator.

@codecov

codecov Bot commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4c6ac7e) to head (0186b54).
⚠️ Report is 9 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #8283    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            3        12     +9     
  Lines           49       158   +109     
==========================================
+ Hits            49       158   +109     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

daphnehanse11 and others added 8 commits July 28, 2026 10:58
Adds the Alabama Unemployment Compensation program (Code of Alabama Title 25,
Chapter 4) with monetary eligibility, weekly benefit amount, sliding-scale
duration tied to state unemployment rate, dual-cap maximum benefit, partial-week
earnings disregard, and the 1-week waiting period. All parameters effective
2020-01-01 per Act 2019-204.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- al_ui.py: fix partial-benefit fallback (was returning full WBA when
  weekly_earnings >= WBA; should return 0 per "deemed employed" rule
  in § 25-4-72 / USDOL Tbl 3-8). Now uses al_ui_partial_weekly_benefit
  directly, which already handles this case correctly.
- Fix 5 BRR PDF page anchors (printed page vs file page; off by 3):
  eligibility/{bpw_to_hqw_multiplier,quarters_with_wages}.yaml,
  wba/{max,min_threshold}.yaml, waiting_weeks.yaml.
- Replace Ala. Admin. Code 480-4-3-.11 citation with statute § 25-4-73
  for the 1/3 WBA partial disregard (480-4-3-.11 is procedural).
- Add al_ui entry to programs.yaml registry.
- Add test case for weekly_earnings >= WBA returning 0 (locks in the
  al_ui.py fix).
- Fix two parameter description verbs ("requires" → "sets").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round 2 review identified that the "two quarters of your base period"
sentence is on file page 7 of the BRR handbook (printed page 4), not
page 8. Page 8 has the related "two highest base period quarters"
phrasing, which supports the value but is less direct. Tightening the
anchor for precision.

Round 2 found 0 critical issues otherwise — all Round 1 fixes verified
correct, no regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@daphnehanse11
daphnehanse11 requested a review from DTrim99 July 28, 2026 16:12
@DTrim99

DTrim99 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Program Review — PR #8283 (Implement Alabama Unemployment Insurance, al_ui)

Author: daphnehanse11 · Draft · Closes #8282 · New program (Code of Alabama Title 25, Ch. 4)

Source Documents (verified during review)

  • Code of Alabama §§ 25-4-72 (WBA), -73 (partial), -74 (MBA/duration), -75, -77 (eligibility)
  • Alabama UC Benefit Rights & Responsibilities (BRR) handbook (p.324: $275 max) · USDOL 2023 Comparison of State UI Laws — Monetary (Table 3-5)

Branch Status

⚠ PR branch is 1689 commits behind main (draft, 9 ahead). A rebase is strongly advised before merge. Review was scoped to the merge-base diff (33 files), so staleness did not cause false-positive findings.

Summary

A clean, well-parameterized new-program implementation. 0 critical. Every core rule is implemented correctly and verified against the statute:

  • WBA = (high-quarter + 2nd-high-quarter wages)/52, with Alabama's round-half-DOWN rule (np.ceil(x − 0.5)) — hand-checked: 100.50→100 (tie down), 100.51→101. ✅
  • $275 max (2020-01-01, Act 2019-204) and $44.50 unrounded-WBA floor (strict >) — both pinned on all sides. ✅
  • 3-prong monetary eligibility (≥2 quarters; base-period wages ≥ 1.5× high quarter; unrounded WBA > $44.50) — ANDed, each prong tested in isolation. ✅
  • MBA = min(weeks × WBA, 0.25 × base-period wages) and the 14→20-week sliding-scale duration tied to the state unemployment rate. ✅
  • No reinvented variables — every existing state UI (PA, NJ) defines its own per-state base-period/high-quarter inputs; al_ui follows that established pattern. Zero hardcoded policy numbers. Test suite is unusually complete (66 unit cases + 11 integration). CI passing.

Critical (Must Fix)

None.

Should Address (non-blocking)

  1. Reference URLs point to the wrong article — the links don't resolve. Every Justia citation uses .../chapter-4/**article-4**/section-25-4-7X/, but the regulatory reviewer reports §§ 25-4-72/74/77 live in Article 3 (Benefits), so the deep links 404. This affects essentially every changed file (all 12 variables, the parameter files, and test headers). The cited authority (§ 25-4-72 etc.) is right — only the URL slug is wrong. Verify the correct article and fix the slug so the citations resolve. (Caveat: both reviewers were bot-blocked from Justia (403), so please confirm article-3 directly before a bulk find-replace.)
  2. Remove the stray lessons/agent-lessons.md. It lives outside policyengine_us/ and is agent retrospective/scratch notes ("New Lessons from Alabama UI Implementation…") — an accidental commit, not model code/tests/docs.
  3. programs.yaml agency + naming. programs.yaml:913 uses agency: Alabama Department of Workforce, but every other state program uses agency: State. Also the program is administered by the Alabama Dept. of Labor (the parameter path is .../al/dol/... and the statute/handbook are DOL), so "Department of Workforce" is a third, inconsistent name. Set the field to State per convention. (Rest of the entry is complete and correctly ordered.)
  4. Verify pinpoint subsection cites for the $275 max and $44.50 floor. wba/max.yaml cites § 25-4-72(b)(5) and wba/min_threshold.yaml cites (b)(2), but those specific sub-numbers don't line up with the statute's actual subdivisions. Values are correct (BRR handbook confirms); just fix the pinpoints.
  5. Document two intentional modeling choices so a future contributor doesn't "correct" them:
    • al_ui.py applies the partial weekly benefit to every payable week (assumes the same weekly earnings across the whole spell) — harmless when earnings = 0 (all standard cases), but worth a one-line note.
    • The code encodes the statutory (HQW+2nd-HQW)/52 WBA and 0.25×BPW MBA, which differ from the BRR one-pager's simplified "1/25 of high quarter" / "1/3 of base-period wages" gloss. A short comment noting the statute (and USDOL tables) is the authority prevents a regression back to the BRR summary.

Suggestions

  • Test the middle duration brackets. al_ui_max_weeks.yaml pins 14/15/19/20 weeks but the 16/17/18-week bands (UR ≥7.01/7.51/8.01%) are untested, and only the 6.5% edge is pinned as an adjacent pair. Given the uniform "above X%" 0.0001-shift convention, each of the 0.0701/0.0751/0.0801/0.0851/0.0901 boundaries is an off-by-one candidate — add just-below/just-at pairs (append to the existing file).
  • Reconcile the duration-scale enabling act. The PR body cites Act 2019-446 for the sliding scale, but the reference validator couldn't corroborate that act and found Act 2019-204 covers both the $275 max and the 14-20-week scale (and the param files already cite 2019-204). Confirm the correct act number.
  • Rounding consistency: WBA uses round-half-down (ceil(x−0.5)) while MBA and partial-benefit use plain np.round — confirm the statute intends ordinary rounding for those two (vs the same half-down rule).
  • state_unemployment_rate is read at YEAR period and resolves to the January value of the benefit year; the duration scale is sensitive to which monthly rate is used, and period: 2024 benefit tests are coupled to the live 2024 data (a future refresh could flip Case 5). Documented already; consider an explicit-override baseline case to remove the coupling.
  • Minor: the WBA/3 partial-disregard boundary test (91.67) is one cent above true WBA/3 and doesn't crisply pin the edge; disregard_rate is stored as truncated 0.3333333333.

Validation Summary

Check Result
Regulatory Accuracy Correct — WBA/round-half-down/$275/3-prong eligibility/duration all match statute; no reinvented variables; documentation/pinpoint-citation items only
Reference Quality 0 missing refs, format PASS; broken article-4 URLs + pinpoint subsections to fix; act-number to reconcile
Code Patterns 0 critical / 3 should / 4 suggestion — zero hardcoded values, correct Person/YEAR entities, complete programs.yaml; stray lessons file + agency field
Test Coverage Strong (round-half-down tie, $44.50, $275, 3 prongs, MBA both caps, partial boundaries, 11 integration); gap: middle duration brackets 16/17/18
Source Audit $275 / $44.50 / 1.5× / 2-quarter / 14-20-week scale / round-half-down all confirmed vs statute + BRR + USDOL
CI Status Passing

Review Severity: COMMENT

A correct, thorough, cleanly-parameterized new program with an unusually complete test suite and no blocking defects. Before marking ready: fix the broken reference URLs (item 1), drop the stray lessons/agent-lessons.md (item 2), align the programs.yaml agency field (item 3), add the middle-duration-bracket tests, and rebase off the 1689-commit lag.

Next Steps

To auto-apply the actionable items: /fix-pr 8283

Review generated with Claude Code via /review-program

@daphnehanse11
daphnehanse11 marked this pull request as ready for review July 28, 2026 17:06
@daphnehanse11
daphnehanse11 removed the request for review from DTrim99 July 28, 2026 17:40
- Remove stray lessons/agent-lessons.md
- Set programs.yaml agency to State per convention
- Add just-below/just-at boundary tests for the 16/17/18-week duration
  brackets (Cases 5-14)
- Document intentional modeling choices: partial weekly benefit applied
  to every payable week, and the statutory WBA/MBA formulas as
  authoritative over the BRR handbook's simplified gloss
- Justia URLs and pinpoint cites verified correct as-is (Article 4;
  (b)(5)/(b)(2)) and left unchanged

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daphnehanse11

Copy link
Copy Markdown
Collaborator Author

Addressed the review items and rebased onto current main (branch is now main + 9 commits):

  1. Reference URLs — verified directly rather than bulk-replaced, per the review's caveat: the Justia slugs are correct as-is. Code of Alabama Title 25, Chapter 4, Article 4 ("Benefits") is where §§ 25-4-70 through 25-4-78 live (Article 3 is "Contributions and Payments"), so the article-4 links resolve. Left unchanged.
  2. Stray filelessons/agent-lessons.md removed.
  3. programs.yamlagency set to State per convention.
  4. Pinpoint cites — also verified correct as-is: § 25-4-72(b)(5) carries the $275 maximum (Act 2019-204's amendment) and (b)(2) the $44.50 threshold. Left unchanged.
  5. Duration brackets — added just-below/just-at pairs for every previously untested boundary (7.0/7.5/8.0/8.5/9.0%), Cases 5–14 in al_ui_max_weeks.yaml, including a live-data 2024 baseline case.
  6. Modeling-choice comments — documented the partial-benefit-every-payable-week assumption in al_ui.py and the statutory (HQW+2nd-HQW)/52 WBA and 0.25×BPW MBA formulas as authoritative over the BRR one-pager's gloss.

Alabama suite passes 391/391 locally (includes the 10 new bracket cases).

@daphnehanse11
daphnehanse11 requested a review from DTrim99 July 28, 2026 18:50
@DTrim99

DTrim99 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Re-review — items addressed, and a correction to my own prior finding

Thanks for the fixes. First, an important retraction of the top item from my earlier review:

❌→✅ The article-4 reference URLs are CORRECT — my prior "should be article-3" finding was wrong. I verified against Justia (2015, 2023, and 2024 Code of Alabama editions): §25-4-72 lives in Title 25 → Chapter 4 → Article 4 ("Benefits"), i.e. exactly the .../chapter-4/article-4/section-25-4-72/ path the PR uses. The earlier reviewers were bot-blocked (403) from Justia and mis-guessed article-3 — which is precisely why I'd caveated "verify before a bulk find-replace." You correctly left the URLs unchanged; there is nothing to fix here. Apologies for the noise.

Everything else I flagged is resolved:

  • Stray lessons/agent-lessons.md — removed from the PR.
  • programs.yaml agency — now State (matches convention).
  • Middle duration brackets — now fully pinned. al_ui_max_weeks.yaml Cases 5–13 exercise every bracket boundary (7.0/7.5/8.0/8.5/9.0%) with at / just-above pairs → 15/16/17/18/19/20 weeks. This is exactly the coverage the earlier review asked for; a shifted or dropped middle bracket would now be caught.
  • Doc comments — both intentional-modeling notes added: al_ui.py documents that the partial weekly benefit is applied to every payable week (assuming constant weekly earnings; equals full WBA when earnings are zero), and al_ui_unrounded_wba.py documents that the statutory (HQW+2nd-HQW)/52 is authoritative over the BRR handbook's "1/25" gloss and should not be "corrected" back.
  • Partial/MBA roundingal_ui_partial_weekly_benefit now rounds (np.round), consistent with the MBA. The round-half-down ceil(x−0.5) remains WBA-specific per §25-4-72(b), which is the right scope (that tie-down rule is stated for the WBA, not for MBA/partial).

Two minor residuals (non-blocking, optional):

  • Pinpoint subsection cites on wba/max.yaml (§25-4-72(b)(5)) and wba/min_threshold.yaml ((b)(2)) — the $275 / $44.50 values are correct (BRR + USDOL confirm); only worth a glance that the sub-paragraph letters match the current statute text.
  • The duration-scale enabling act: the PR body mentions Act 2019-446 while the param files cite Act 2019-204 — reference-validation found 2019-204 covers both the $275 max and the 14–20-week scale, so the files are the better-supported choice; just reconcile the PR-body wording.

Net: the implementation was already regulatorily correct (WBA/round-half-down/$275/3-prong eligibility/duration all verified), and this round removes the scratch file, aligns the agency field, and closes the duration-bracket test gap. LGTM once CI settles green (still running) and the branch is rebased off its main lag.

Re-review via /review-program

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.

Alabama UI

2 participants