Skip to content

Implement Oklahoma Unemployment Insurance (ref #8264) - #8265

Open
daphnehanse11 wants to merge 10 commits into
PolicyEngine:mainfrom
daphnehanse11:ok-ui
Open

Implement Oklahoma Unemployment Insurance (ref #8264)#8265
daphnehanse11 wants to merge 10 commits into
PolicyEngine:mainfrom
daphnehanse11:ok-ui

Conversation

@daphnehanse11

@daphnehanse11 daphnehanse11 commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements Oklahoma Unemployment Insurance (administered by the Oklahoma Employment Security Commission, OESC).

Closes #8264

Regulatory authority

Monetary eligibility (§2-207)

A claimant is monetarily eligible if EITHER:

  • Test A: base-period taxable wages >= $1,500 AND base-period total wages >= 1.5 × high quarter wages
  • Test B: base-period taxable wages > 0 AND base-period total wages >= the annual taxable wage base

Annual taxable wage base

Year Amount
2025 $28,200
2026 $25,000
(Pre-2025 default: $27,000)

Weekly benefit amount (§2-104)

  • WBA = floor(high quarter taxable wages / 23)
  • Clamped to [$16, max_amount]
  • Max amount (OESC Board determination):
    Year Max WBA
    2024 $519
    2025 $541
    2026 $649

Maximum benefit amount (§2-106, HB 1933)

  • MBA = WBA × max_weeks
  • max_weeks = 26 before 2023, 16 from 2023-01-01

Partial benefits (§2-105)

  • Weekly payable = max(0, WBA - max(0, weekly_earnings - $100))

Annual benefit

  • ok_ui = min(weekly_payable × weeks_unemployed, MBA)
  • Gated by ok_ui_monetarily_eligible and Oklahoma state code

Requirements coverage

REQ Description Param Variable Test
001 Base period - ok_ui_base_period_, ok_ui_high_quarter_ -
004 Test A eligibility/min_taxable_wages, min_total_wages_multiplier ok_ui_meets_high_quarter_test ok_ui_meets_high_quarter_test.yaml
005 Test B tax/payroll/unemployment/taxable_wage_base ok_ui_meets_alternate_wages_test ok_ui_meets_alternate_wages_test.yaml
006 A OR B - ok_ui_monetarily_eligible ok_ui_monetarily_eligible.yaml
011 WBA formula wba/divisor ok_ui_weekly_benefit_rate ok_ui_weekly_benefit_rate.yaml
012 WBA clamp wba/min_amount, wba/max_amount ok_ui_weekly_benefit_rate ok_ui_weekly_benefit_rate.yaml
015 MBA - ok_ui_maximum_benefit_amount ok_ui_maximum_benefit_amount.yaml
016 max_weeks mba/max_weeks ok_ui_maximum_benefit_amount ok_ui_maximum_benefit_amount.yaml
018 Partial partial/disregard ok_ui_weekly_payable ok_ui_weekly_payable.yaml
021 Annual - ok_ui ok_ui.yaml + integration.yaml
022 Eligibility gate - ok_ui (defined_for) ok_ui.yaml + edge_cases.yaml
013 Handbook example - - ok_ui_weekly_benefit_rate.yaml Case 1 ($14,000 → $519)

Not modeled

30 NOT-MODELED items, listed in the scope decision. The most notable:

  • Able/available/seeking-work tests (§2-202, §2-205.1)
  • One-week waiting period (§2-206)
  • Disqualifications (voluntary quit, misconduct, drug/alcohol, suitable-work refusal, labor disputes, pension offset, seasonal, back-pay)
  • §1-231 16→20→26 week claim-volume escalation (treated as fixed 16 weeks per issue OK unemployment insurance #8264)
  • Alternative/extended base periods (§1-202.1, §1-202.2)
  • Alien-status rules (§2-208)
  • Extended Benefits (§§2-701 et seq.)

Historical notes

  • Maximum duration was reduced from 26 to 16 weeks by HB 1933, effective 2023-01-01.
  • $1,500 minimum taxable wage threshold has been in statute since 1980.
  • $100 partial-benefit disregard has been in statute since 1994.
  • Maximum WBA is reset annually by the OESC Board (§2-104(B)).

Files added

policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/
├── eligibility/
│   ├── min_taxable_wages.yaml
│   └── min_total_wages_multiplier.yaml
├── wba/
│   ├── divisor.yaml
│   ├── min_amount.yaml
│   └── max_amount.yaml
├── mba/
│   └── max_weeks.yaml
├── partial/
│   └── disregard.yaml
└── index.yaml

policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/
├── ok_ui.py
├── ok_ui_base_period_taxable_wages.py
├── ok_ui_base_period_total_wages.py
├── ok_ui_gross_weekly_earnings.py
├── ok_ui_high_quarter_taxable_wages.py
├── ok_ui_maximum_benefit_amount.py
├── ok_ui_meets_alternate_wages_test.py
├── ok_ui_meets_high_quarter_test.py
├── ok_ui_monetarily_eligible.py
├── ok_ui_weekly_benefit_rate.py
└── ok_ui_weekly_payable.py

policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/
├── edge_cases.yaml
├── integration.yaml
├── ok_ui.yaml
├── ok_ui_maximum_benefit_amount.yaml
├── ok_ui_meets_alternate_wages_test.yaml
├── ok_ui_meets_high_quarter_test.yaml
├── ok_ui_monetarily_eligible.yaml
├── ok_ui_weekly_benefit_rate.yaml
└── ok_ui_weekly_payable.yaml

policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/
└── taxable_wage_base.yaml (extended with 2025/2026 values)

changelog.d/
└── ok-ui.added.md

@codecov

codecov Bot commented May 12, 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 (68139b5).
⚠️ Report is 44 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #8265   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3        11    +8     
  Lines           49       142   +93     
=========================================
+ Hits            49       142   +93     
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 6 commits July 28, 2026 10:59
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace broken 2025 OESC PDF URL with working OMES PDF + OESC homepage
- Fix section citation: §1-218 → §1-201(48) + §1-223 in taxable_wage_base
- Add subsection specificity: §2-207(A) → §2-207(A)(1)/(A)(2)
- Correct PDF page anchors: divisor/min_amount/max_amount #page=49→50;
  disregard #page=50→51
- Update stale $27,400 test comments to match actual $27,000 param
- Replace 0000-01-01 sentinel with 1980-07-01 in mba/max_weeks
- Add trailing comma to make single-element reference tuples valid

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Change 0000-01-01 sentinel to 2024-01-01 in taxable_wage_base
- Replace repealed §1-202 with current §1-201(4) in base-period docstrings
- Add §2-207 reference to ok_ui_base_period_total_wages (where "total
  wages" qualifier comes from)
- Update §2-104(B) title in max_amount to clarify OESC Board determination

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@daphnehanse11
daphnehanse11 requested a review from hua7450 July 28, 2026 16:12
@daphnehanse11
daphnehanse11 marked this pull request as ready for review July 28, 2026 17:06
Remove the adds wiring into unemployment_compensation (newer core
rejects adds combined with uprating, and the integration is deferred
to PolicyEngine#8303 pending policyengine-us-data support) and the coupled
integration assertion.

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

Copy link
Copy Markdown
Collaborator Author

Rebased onto current main (branch is now main + 6 commits). One substantive change during the rebase: the adds = ["ok_ui"] wiring into the federal unemployment_compensation variable was removed — newer policyengine-core rejects adds combined with uprating, and that income-flow integration is deferred to the umbrella PR #8303 pending policyengine-us-data support (per @MaxGhenis's guidance there). The PR now implements ok_ui as a standalone program. Oklahoma suite passes 56/56 locally.

@DTrim99

DTrim99 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Program Review — via /review-program (multi-agent audit)

PR: #8265 — Oklahoma Unemployment Insurance (new program, OK, 2022–2026)
Scope: 11 variables, 10 new + 1 modified parameter YAMLs, 9 test files, programs.yaml entry (verified_years: "2022-2026"), changelog fragment.
Validators: regulatory review, reference validation, code-pattern audit, test-coverage review, PDF source audit (statute + yearly numbers), 2 independent code-path verifiers.

Source Documents

# Document Link
1 Title 40 O.S. (Employment Security Act) — §§1-201, 1-217, 1-223, 1-231, 2-102, 2-104, 2-105, 2-106, 2-207 https://www.oklegislature.gov/OK_Statutes/CompleteTitles/os40.pdf
2 HB 1933 (2022), enrolled — 26→16 week duration cut, eff. 2023-01-01 https://www.oklegislature.gov/cf_pdf/2021-22%20ENR/hB/HB1933%20ENR.PDF
3 OESC Employer Important Numbers 2023 https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2023.pdf
4 OESC Employer Important Numbers 2024 https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2024.pdf
5 OESC Employer Important Numbers 2025 https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Important-Numbers-2025.pdf
6 OESC Employer Important Numbers 2026 — note the official URL carries the "Improtant" typo; it resolves to a real PDF, so the PR's hrefs are correct as-is https://oklahoma.gov/content/dam/ok/en/oesc/images/misc/Employer-Improtant-Numbers-2026.pdf
7 OESC "Oklahoma UI Tax Rates by Industry, Establishment Size and County" (Feb 2022 report; Table 1 covers 2011–2022 wage base / max WBA / MBA / conditional factors) cited in PR (oklahoma-ui-tax-rates-industry-size-county-2021.pdf)
8 OES-339 Claimant Handbook (Rev. 05-2025) cited in PR
9 USDOL Significant Measures of State UI Tax Systems, CY2024 (OK page — corroborates 2024 wage base $27,000) https://oui.doleta.gov/unemploy/pdf/sigmeasures/sigmeasuitaxsys24.pdf

All five primary PDFs were fetched and text-extracted; every 2022–2026 dollar value was checked against them (see Source Audit Summary).

Branch Status

⚠ PR branch is 41 commit(s) behind main. Consider rebasing before merge. Review scoped to merge-base diff; staleness did not affect findings.

Critical (Must Fix)

  1. 2022 base_period_wages_share = 1 (no cap) contradicts the statute — 2022 MBA overstated by up to ~88%. (CONFIRMED by code-path verification)
    File: policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/base_period_wages_share.yaml (1980-07-01: 1, first real cap at 2023-01-01: 0.4).
    Citation: 40 O.S. §2-106(3); HB 1933 enrolled text; OESC Feb-2022 tax-rates report, Table 1.
    HB 1933 rewrote only §2-106 paragraph (1) (the weeks multiple) — paragraphs (2)/(3), the conditional-factor percentage caps, are pre-existing law carried forward unchanged. There was never a year with a 100% share; the statutory range is 40–50%. Table 1 of the PR's own cited source shows the conditional factor was D in 2021–2022, so the 2022 base-period-wages cap was 40%. The PR's own mba/max_amount.yaml 2022 value ($9,900 = 20% of average annual wage) already encodes factor D for §2-106(2) in 2022 — the two parameters are internally contradictory. The wrong value is load-bearing: ok_ui_maximum_benefit_amount.py computes min(26×WBA, $9,900, 1×BPW) instead of min(26×WBA, $9,900, 0.4×BPW); the cap binds for any claimant with base-period wages < ~2.83× high-quarter wages (a broad, realistic band — Test A only requires 1.5×). Example: HQW $8,000 / BPW $12,000 → repo MBA $9,022 vs statutory $4,800. 2022 is claimed (programs.yaml verified_years: "2022-2026") and tested — the existing 2022 tests just happen to sit outside the binding band.
    Fix: 2022-01-01: 0.4 (or, if backdating is kept, use Table 1's factor history: 0.5 for no-factor years, 0.4 for 2021–2022 — never 1). Add a 2022 test in the binding band (e.g. HQW $6,900 / BPW $12,000 → MBA $4,800).

  2. taxable_wage_base.yaml history replacement silently changes/breaks pre-2022 OK payroll tax.
    File: policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml.
    This pre-existing parameter is consumed outside the new program by policyengine_us/variables/gov/states/tax/payroll/unemployment/taxable_earnings_for_state_unemployment_tax.py (generic state selector; OK registered in _jurisdictions.py). The PR deletes the old 0000-01-01: 27_000 anchor and starts the series at 2022-01-01: 24_800. The new 2022–2026 values are the correct OESC figures (the old flat $27,000 was only right for 2024), but pre-2022 is now undefined: simulations of years ≤ 2021 touching OK state unemployment payroll tax will backward-extrapolate to $24,800 (or error), instead of the previous $27,000 behavior.
    Fix: keep a pre-2022 anchor (e.g. 2021-01-01: 24_000 per the Feb-2022 report's Table 1, which lists 2011–2022 values if fuller backdating is wanted). Expect OK payroll-tax diffs for 2022/2023/2025/2026 in any regression comparison — an intended accuracy improvement, but worth stating in the PR body.

  3. os40.pdf#page=XX statute anchors are internally inconsistent — the same section is cited at different pages in different files.
    Files: wba/divisor.yaml, wba/min_amount.yaml, wba/max_amount.yaml (§2-104 at #page=50) vs ok_ui_weekly_benefit_rate.py (§2-104 at #page=49); partial/disregard.yaml (§2-105 at #page=51) vs ok_ui_weekly_payable.py (§2-105 at #page=50); ok_ui_base_period_total_wages.py (§2-207 at #page=56 mixed with #page=42).
    A section cannot be on two pages; printed-page vs file-page offsets into the 340-page consolidated Title 40 PDF are the likely cause. Render os40.pdf and confirm the file page for each of §1-201(48), §1-223, §1-231, §2-104, §2-105, §2-106, §2-207, then make every citation of a given section use the same #page. A wrong statute anchor is worse than none.

  4. taxable_wage_base.yaml re-hosted statute anchors unverified.
    File: policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml.
    The PR replaces the old oksenate.gov citation (#page=32, §1-223) with oklegislature.gov anchors: §1-201(48) at #page=23, §1-223 at #page=44. The statutory content is correct (verified against OSCN HTML), but the host/edition changed and the page numbers were not carried over reliably — confirm both file pages as part of item 3.

  5. edge_cases.yaml is a forbidden aggregate test file — merge into the per-variable test files.
    File: policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/edge_cases.yaml (530 lines, Cases 1–23).
    Repo/skill convention: edge cases are appended to the existing {variable}.yaml files, never collected in a new file. Redistribute: Cases 1–6 → ok_ui_meets_high_quarter_test.yaml / ok_ui_meets_alternate_wages_test.yaml / ok_ui_monetarily_eligible.yaml; 7–12 → ok_ui_weekly_benefit_rate.yaml; 15–18 → ok_ui_weekly_payable.yaml; 19–20 → ok_ui_maximum_benefit_amount.yaml; 13–14, 21–23 → ok_ui.yaml. The cases themselves are mostly good — this is structural, not functional.

Should Address

  1. §2-207(A)(2): the 1.5× monetary-eligibility prong is applied to taxable high-quarter wages; the statute and all OESC public guidance use unqualified "wages." (CONFIRMED by code-path verification; LOW practical severity — narrow affected population)
    File: policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py (multiplies min_total_wages_multiplier by ok_ui_high_quarter_taxable_wages).
    Citation: 40 O.S. §2-207(A)(2) ("one and one-half (1 1/2) times the amount of wages ... in which the wages were highest" — unqualified, contrast prong (1)'s "Taxable wages"); §1-218 ("wages" = uncapped remuneration); OES-339 handbook and the OESC website both phrase the test with plain "wages," so the ambiguity defense fails. The model also has no ok_ui_high_quarter_total_wages variable, so the statutory quantity is unrepresentable and the high quarter is implicitly identified by taxable rather than total wages. Verified impact: for all inputs consistent with the PR's own variable semantics, only the intermediate boolean can flip — final ok_ui_monetarily_eligible is rescued by Test B (any claimant with a quarter above the wage base necessarily passes Test B), and no PR test changes outcome; a final-outcome divergence is constructible only under exotic annual-cap wage timing. Fix: add an ok_ui_high_quarter_total_wages input and use it in the 1.5× comparison; at minimum document the taxable-wage proxy and its no-final-effect property.

  2. Post-2025 duration escalation (§2-106(1)(c) / §1-231) held at a fixed 16 weeks; possible 2024 amendment uncited.
    File: policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml (stops at 2023-01-01: 16).
    Citation: 40 O.S. §2-106(1)(c) ("between sixteen (16) and twenty (20) times ... dependent upon the state's average unemployment insurance claims"); §1-231(B) (16 weeks at ≤5,000 average claims, escalating to 26 above 40,000 continued claims). Holding 16 matches the low-claims branch and the Rev. 05-2025 handbook, and the limitation is disclosed in the ok_ui.py docstring — but confirm 16 was operative for 2025/2026, and note OSCN shows §1-231 was amended by HB 3596 (Laws 2024, eff. Nov 1 2024): verify the modeled values survive the amendment and add the HB3596 citation if it governs 2025+.

  3. §2-106(2) average-annual-wage cap is unmodeled and its mba/max_amount proxy is under-documented (and a no-op post-2023).
    Files: policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_amount.yaml; policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py (docstring).
    Citation: 40 O.S. §2-106(2) (applicable % of state average annual wage, rounded to nearest $100). The 2023–2026 published values (7,888/8,304/8,656/10,384) equal exactly 16 × max WBA and are not $100 multiples, so they cannot be the §2-106(2) statutory quantity — arithmetically the parameter never binds post-2023 (min(WBA×16, maxWBA×16) = WBA×16). The omission appears benign (the §2-106(2) leg should never bind under any conditional-factor pairing), but neither ok_ui.py's "Not modeled" inventory nor max_amount.yaml's description says the parameter is an OESC-published proxy. Document both.

  4. Docstring corrections.
    Files: ok_ui_high_quarter_taxable_wages.py, ok_ui_base_period_taxable_wages.py, ok_ui.py.
    (a) The input docstrings say taxable wages are "capped at the Oklahoma taxable wage base per quarter"; §1-201(48) caps taxable wages per calendar year. (b) The ok_ui.py "Not modeled" inventory omits §2-106(2) (see item 3) and the §1-217(B)(2) 15% wage/hour-loss prong of the deemed-unemployed test — add both.

  5. Missing boundary tests for parameter year-steps and cap interactions (no formula variable is untested, but several parameter values are never exercised):
    Files: policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/*.yaml.

    • 2026 Test-B wage-base boundary (the only downward step, $28,200 → $25,000): add total_wages 25_000 → true / 24_999 → false to ok_ui_meets_alternate_wages_test.yaml.
    • WBA max clamp for 2023 ($493) and 2025 ($541) in ok_ui_weekly_benefit_rate.yaml (only 2022/2024/2026 clamps are pinned there).
    • A case where the statewide mba/max_amount is the sole binding cap (e.g. 2025: HQW $20,000 → WBR 541, 541×16 = $8,656 = max_amount; total wages $100,000).
    • The 2026 base_period_wages_share step (0.4 → 0.475) binding (e.g. 2026: HQW $10,000, total $12,000 → MBA $5,700).
    • Share cap binding while weeks_unemployed < max_weeks (confirms min() ordering in ok_ui.py).
    • A 2023 case confirming the 16-week regime took effect exactly at 2023-01-01 (no 2023 test exists at all).
    • Per Critical 1's fix, a 2022 case where the 40% share cap binds.
  6. Negative-input guard: negative ok_ui_base_period_total_wages yields a negative MBA and negative ok_ui (latent bug).
    Files: ok_ui_maximum_benefit_amount.py, ok_ui.py, ok_ui_weekly_benefit_rate.py.
    min_(min_(WBR×weeks, max_amount), total_wages×share) with negative total wages returns the negative product, which then propagates through ok_ui = min(payable×weeks, MBA). Also, no test proves the $16 WBA floor holds against a negative HQW (floor(−5,000/23) = −218 → max(−218, 16) = 16). Add both cases; guard with max_(..., 0) if the negative-MBA probe confirms the bug.

  7. Zero-default wage inputs — add a microsimulation documentation note.
    Files: ok_ui_base_period_taxable_wages.py, ok_ui_base_period_total_wages.py, ok_ui_high_quarter_taxable_wages.py, ok_ui_gross_weekly_earnings.py.
    These are direct inputs (default_value = 0; quarterly wages are not derivable from annual microdata), so in microsimulation ok_ui is 0 for the entire population — a household-calculator-only estimate by design (the entry is economy: false / household: true, mirroring AL UI). No prescriptive default is warranted; document the zero-default consequence in the variable docstrings/PR body so reviewers don't expect aggregate or net-income effects.

  8. Reference formatting: page numbers embedded in title: strings.
    Files: mba/max_amount.yaml ("... 2021, page 2"), wba/max_amount.yaml (two instances, incl. "OES-339 ... page 4"), taxable_wage_base.yaml ("... 2021, page 2").
    Page numbers belong in href: (#page=XX, already present) — drop them from the titles.

  9. Description wording: value 1.5 described as a "share."
    File: policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/eligibility/min_total_wages_multiplier.yaml ("this share of high quarter wages"). A value > 1 is a multiple, not a share — reword to "this multiple of high quarter wages" (the label already says "multiplier").

Suggestions

  1. Add OSCN per-section HTML mirrors alongside the monolithic PDF. Deep #page links into the 340-page os40.pdf break on re-pagination. Verified stable per-section URLs: §2-104 oscn.net/...CiteID=77164, §2-105 77165, §2-106 77166, §2-207 77177, §1-201 77132, §1-223 77157, §1-231 492632.
  2. Subsection precision in reference titles. mba/max_amount.yaml and mba/max_weeks.yaml cite bare "§2-106"; add the paragraph (e.g. "§2-106(1)") to match the pattern used elsewhere ("§2-207(A)(1)", "§2-104(B)").
  3. Surface the "Not modeled" inventory in app-facing metadata, not just the ok_ui.py source docstring, so users see the disqualification/waiting-week/alternative-base-period limitations.
  4. ok_ui_gross_weekly_earnings naming: label says "weekly" but definition_period = YEAR (intentional, documented); a caveat in the label/app docs would reduce confusion since the partial-benefit math treats it as one week's earnings.
  5. PR-body note that ok_ui is intentionally not wired into unemployment_compensation or household net income (standalone modeled estimate, consistent with the AL UI pattern) so reviewers don't expect a net-income effect. Minor test idiom note: several edge cases attach absolute_error_margin: 0.01 to outputs that include booleans — harmless (margin < 1 does not void a boolean) and needed for the co-checked currency outputs; no action.

Source Audit Summary

Audit Checked Matches Mismatches Notes
Statute audit (§§2-102, 2-104, 2-105, 2-106, 2-207, 1-217, 1-231; HB1933; OES-339) 18 17 1 Mismatch: §2-207(A)(2) taxable vs plain wages → verified CONFIRMED, low severity (Should Address 1)
Yearly numbers audit (wage base, max WBA, max MBA, share, $1,500 floor, effective dates; 2022–2026) 21 20 1 Mismatch: 2022 share = 1 vs statutory 0.4 → verified CONFIRMED, critical (Critical 1). All dollar values incl. 2022 corroborated from the PR's own cited sources
Total 39 37 2 Both mismatches independently CONFIRMED by dedicated code-path verifiers

The reference validator's inability to machine-read the OESC bulletins (S1 in its report) was superseded by the PDF audit, which fetched and read all of them — every 2022–2026 dollar value is now source-corroborated. Remaining open reference risks are the page anchors (Critical 3–4) and the HB3596 question (Should Address 2).

Validation Summary

Check Result
CI ✅ All 33 checks pass
Regulatory review (Validator 1) ✅ Core formulas (WBA, partial, MBA lesser-of, A/B tests) match statute; 0 critical
Reference validation (Validator 2) ⚠ 2 critical (page-anchor inconsistencies; re-hosted anchors)
Code-pattern audit (Validator 3) ⚠ 1 critical (taxable_wage_base history), 4 should-address
Test coverage (Validator 4) ⚠ 1 critical (edge_cases.yaml), 7 should-address; all 7 formula variables have dedicated tests, integration test present
PDF source audit ✅ 37/39 values match; 2 confirmed mismatches (above)
Code-path verification ✅ Both mismatches traced end-to-end; severities assigned (LOW / CRITICAL)
Changelog fragment changelog.d/ok-ui.added.md
programs.yaml entry verified_years: "2022-2026" claim is undermined by Critical 1 for 2022

Review Severity: REQUEST_CHANGES

Five critical findings — one confirmed regulatory value error active in a claimed/tested year (2022 MBA cap), one cross-program parameter-history regression, two citation-integrity blockers, and one test-structure violation — require changes before merge. The core program logic is otherwise sound and thoroughly source-verified.

Next Steps

  1. Run /fix-pr 8265 to apply the fixes above (start with Criticals 1–2, then the anchor reconciliation, then redistribute edge_cases.yaml).
  2. Rebase onto main (branch is 41 commits behind) and re-run CI.
  3. Render os40.pdf locally (poppler) to pin the true file pages for each cited section before updating anchors.
  4. After Critical 1's fix, re-confirm the programs.yaml verified_years: "2022-2026" claim (or drop 2022).

🤖 Generated by /review-program (Claude Code multi-agent review)

…tests

- Set 2022 base-period wages share to 0.4 (conditional factor D per
  40 O.S. 2-106(3) and the OESC table); pre-2023 uncapped value was
  incorrect and overstated 2022 MBAs
- Restore the pre-existing 0000-01-01: 27,000 taxable wage base anchor
  the PR had dropped, keeping pre-2022 OK payroll tax identical to main
- Reconcile every os40.pdf page anchor to verified file pages; add
  stable OSCN per-section HTML references and HB 3596 citation for the
  16-week duration; strip page numbers from reference titles
- Document the taxable-wage proxy in the 1.5x eligibility test, the
  16x-max-WBA proxy for the 2-106(2) cap, the calendar-year wage-base
  cap, the unmodeled duration escalator, and microsim-inert inputs
- Guard maximum benefit amount against negative wages with max_(.., 0)
- Dissolve the aggregate edge_cases.yaml into per-variable test files
  and add boundary tests (2026 wage-base step, WBA clamps, binding MBA
  caps by year, 16-week seam, negative wages)

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

DTrim99 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Fixes Applied (from Program Review)

Commit 68139b5 addresses all actionable findings from the review above.

Critical

  • 2022 MBA cap corrected: mba/base_period_wages_share.yaml now applies 0.4 in 2022 (conditional factor D per 40 O.S. § 2-106(3) and the OESC table) instead of an uncapped 1 — the percentage caps pre-existed HB 1933, which only rewrote the weeks multiple. A 2022 binding-band test was added (HQW $6,900 / BPW $12,000 → MBA $4,800).
  • Restored the wage-base anchor: the PR had deleted the pre-existing 0000-01-01: 27_000 value from taxable_wage_base.yaml, silently changing pre-2022 OK payroll tax. The anchor is restored ahead of the new 2022–2026 series; the payroll consumer test passes unchanged.
  • Every os40.pdf page anchor reconciled to verified file pages (§ 1-201(48) p23, § 1-223 p44, § 1-231 p48, § 2-104 p50, § 2-105 p51, § 2-106 p51, § 2-207 p56) — the previously inconsistent § 2-104/§ 2-105 cites now agree everywhere.
  • Aggregate edge_cases.yaml dissolved: its 23 cases were redistributed into the per-variable test files (eligibility, WBA, payable, MBA, ok_ui) with titles preserved, then the file was removed.

Should Address

  • § 2-207(A)(2) wage-basis deviation documented: the statute applies the 1.5× test to unqualified (total) wages; the implementation uses taxable high-quarter wages as a proxy. Documented in the docstring rather than adding a new zero-default input — the verifier confirmed the deviation affects only capped high-quarter earners and Test B rescues final eligibility in modeled cases.
  • HB 3596 (Laws 2024) verified and cited for the 16-week duration floor from 2025; the § 2-106(1)(c)/§ 1-231 16–26-week escalator documented as unmodeled.
  • Corrected docstrings: the wage-base cap is per calendar year (§ 1-201(48)), not per quarter; the 2023–26 mba/max_amount values documented as OESC-published 16×max-WBA proxies for the § 2-106(2) cap; not-modeled inventory (disqualifications, waiting week, alternative base period, 15% wage-loss prong) surfaced in the app-facing documentation string.
  • Negative-wages guard: ok_ui_maximum_benefit_amount now floors base-period wages at 0 (negative inputs previously produced a negative MBA and negative ok_ui); the $16 WBA floor already covered negative high-quarter wages. Tests added.
  • New boundary tests: 2026 Test-B wage-base step ($24,999/$25,000), WBA max clamps for 2023 ($493) and 2025 ($541), MBA max_amount sole-binding case, 2025 share-binding case, 2023 16-week seam.
  • Zero-default microsim notes on the four wage inputs; "share" → "multiple" wording; page numbers stripped from reference titles.

Suggestions

  • Stable OSCN per-section HTML references added beside the monolithic os40.pdf; subsection precision in § 2-106 titles; gross_weekly_earnings label now flags the YEAR-period/weekly-figure convention.

Skipped (deliberate)

Verification

  • All 67 OK UI YAML tests pass locally, plus the OK payroll wage-base consumer test (1/1) confirming pre-2022 behavior is identical to main.
  • ruff format + check clean.

🤖 Applied via /fix-pr (Claude Code)

@DTrim99
DTrim99 requested a review from PavelMakarchuk August 4, 2026 17:22
@hua7450

hua7450 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Program Review

PR #8265 — "Implement Oklahoma Unemployment Insurance (ref #8264)", author daphnehanse11, base main, head branch ok-ui.

Source Documents

Branch Status

The branch is 8 commits ahead and 325 commits behind PolicyEngine/policyengine-us main (merge-base f7018a5ddc266b46eb6f2422cfee2afdc0f54f2a). A rebase or merge from main before merge is recommended so CI runs against current base behaviour and any parameter-tree or programs.yaml drift surfaces now rather than after merge.

Staleness did not affect any finding in this review: the review was scoped to the merge-base diff, every file examined is either new in this PR or was read at PR head, and all three parameter-value verifications were run against external primary sources rather than against base-branch state. This note is informational only and is not a finding.


Critical (Must Fix)

  1. [C1] § 2-207(A)(2) applies the 1.5× multiplier to taxable high-quarter wages; the statute says total wages. This flips monetary eligibility from ineligible to a paid claim.policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.py:29-33 — PDF p.56

    Verbatim statutory text, transcribed from a 600-DPI render of file page 56 (printed footer reads "Page 56", so the anchor is directly checkable):

    §40-2-207. Wage requirement during base period.
    WAGE REQUIREMENT DURING BASE PERIOD.
    A. The unemployed individual, during the individual's base
    period, shall have been paid:
    1. Taxable wages of not less than One Thousand Five Hundred
    Dollars ($1,500.00); and
    2. Total wages of not less than one and one-half (1 1/2) times
    the amount of wages during that quarter of the individual's base
    period in which the wages were highest.

    The right-hand operand is bare "wages" — twice. The drafter used the defined term "Taxable wages" in (A)(1), in (B)(1), and again in (B)(2) ("the annual amount of taxable wages"), and deliberately did not use it in (A)(2). § 2-104(A) on p.50 is the control: a sentence of identical grammatical shape says "taxable wages" twice where it means taxable wages. § 1-201(48) defines "Taxable wages" as wages capped per calendar year at the wage base; § 1-201(49)/§ 1-218 define "Wages" as uncapped gross remuneration. Since taxable ≤ total, substituting the capped figure can only lower the threshold — the error is strictly one-directional and always more generous than the statute.

    The code:

    high_quarter_taxable_wages = person("ok_ui_high_quarter_taxable_wages", period)
    meets_multiplier = base_period_total_wages >= (
        p.min_total_wages_multiplier * high_quarter_taxable_wages
    )

    Worked failing case (2025 parameters), executed against the model — not hand arithmetic. Single employer, 2025 claim, base period 2024 Q4 + 2025 Q1–Q3. The 2024 wage base is $27,000 and $18,200 of it was consumed in 2024 Q1–Q3, before the base period opened, leaving $8,800 of headroom:

    Quarter Total wages Taxable wages
    2024 Q4 $22,000 $8,800
    2025 Q1 $2,000 $2,000
    2025 Q2–Q3 $0 $0
    Base period $24,000 $10,800

    High quarter is 2024 Q4 under both selection rules: total $22,000, taxable $8,800.

    Statute § 2-207(A)(2) Code
    1.5× threshold 1.5 × $22,000 = $33,000 1.5 × $8,800 = $13,200
    Test A, prong 1 ($1,500) $10,800 ≥ $1,500 ✓
    Test A, prong 2 $24,000 ≥ $33,000 → FAIL $24,000 ≥ $13,200 → PASS
    Test B (§ 2-207(B)) $24,000 ≥ $28,200 → FAIL same → FAIL
    ok_ui_monetarily_eligible False True
    ok_ui (20 weeks unemployed) $0 $6,112

    The model was run on these inputs and paid $6,112 to a claimant § 2-207 denies entirely (WBR = floor(8,800/23) = $382; MBA = min(min(382×16, 8,656), 24,000×0.40) = $6,112).

    The docstring's justification is false and must be removed, not retained. ok_ui_meets_high_quarter_test.py:5-13 says "in the cases PolicyEngine models, the alternate wages test (Test B) rescues final eligibility, so the proxy does not change the modeled monetary-eligibility outcome." That holds only when high-quarter total wages exceed the full annual wage base, in which case base-period total wages also exceed it and Test B passes. But § 1-201(48)'s cap is a calendar-year cap and an Oklahoma base period straddles two calendar years, so earnings paid before the base period can exhaust the cap — exactly the case above. Test B does not rescue it, and nothing else does.

    Fix shape. A reference swap is not sufficient: no ok_ui_high_quarter_total_wages variable exists anywhere in the model (repo-wide grep of variables/ for high_quarter returns only ok_ui_high_quarter_taxable_wages, its two consumers, and unrelated PA variables). Add a new Person/YEAR/USD input ok_ui_high_quarter_total_wages (default_value = 0, defined_for = StateCode.OK, referencing § 2-207(A)(2)), use it at ok_ui_meets_high_quarter_test.py:29,32, and leave ok_ui_high_quarter_taxable_wages serving ok_ui_weekly_benefit_rate where § 2-104(A) genuinely wants the taxable figure. Note the two provisions also select the high quarter on different bases (§ 2-104(A) picks the highest taxable quarter, § 2-207(A)(2) the highest total quarter), which can be different quarters — so a rescaling of the existing input would not be faithful either.

    Also correct the test file: policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_meets_high_quarter_test.yaml:3-5 restates the substituted rule as the statute ("Total base-period wages >= 1.5 x high-quarter taxable wages. Reference: 40 O.S. §2-207(A)"), and all four cases hold ok_ui_high_quarter_taxable_wages: 10_000 (lines 13, 33, 52, 72) with no case in the divergence zone. When the new input is added, all four existing cases must supply it explicitly — otherwise it defaults to 0, prong (2) becomes trivially satisfied, and every assertion silently inverts.

    Corroborating reports: regulatory C1; pdf-audit-mba MISMATCH 3; code-validator SA-3; verifier-codepath-1 (CONFIRMED, four refutation attempts all failed); verifier-mismatch-1 (CONFIRMED MISMATCH at 600 DPI, severity CRITICAL).

  2. [C2] Ten of 49 added #page= anchors land on a page that does not carry the cited text — including the only citation for every 2022 value and three load-bearing § 2-106 values. — see table — PDF p.52

    A reference that points at a cover page or a bare section heading corroborates nothing. Every wrong anchor below was verified by rendering the target page; os40.pdf has offset 0 (printed page == file page), and the 2021 OESC report has offset +4 (four unnumbered front-matter pages), which the PDF manifest did not cover because that document was not in the downloaded set.

    File:line Cited Actual What is on the cited page
    parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml:23 os40.pdf#page=51 52 Only the trailing heading §40-2-106. Maximum benefit amount. / MAXIMUM BENEFIT AMOUNT. The 26× and 16× multipliers are on p.52
    .../mba/max_amount.yaml:22 os40.pdf#page=51 52 Same heading-only page; § 2-106(2)'s 25%/23.75%/22.5%/21.25%/20% ladder is on p.52
    .../mba/base_period_wages_share.yaml:16 os40.pdf#page=51 53 Same; the two encoded rungs — (3)(b) 47.5% and (3)(e) 40% — are on p.53
    variables/.../ok_ui_maximum_benefit_amount.py:13 os40.pdf#page=51 52 Same; the three-prong lesser-of the formula implements is on p.52
    .../wba/max_amount.yaml:20 …-2021.pdf#page=2 6 Report cover page. Table 1 (2022 Maximum Weekly Benefit $476) is on file p.6
    .../mba/max_amount.yaml:26 …-2021.pdf#page=2 6 Cover page. Table 1 (2022 MBA $9,900) is on file p.6
    parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml:29 …-2021.pdf#page=2 6 Cover page. Table 1 (2022 wage base $24,800) is on file p.6
    variables/.../ok_ui_base_period_taxable_wages.py:23 os40.pdf#page=19 23 p.19 ends with the bare heading §40-1-201. General definitions. § 1-201(48) "Taxable wages" is on p.23 — and this PR's own taxable_wage_base.yaml:17 cites p.23 correctly, so the two files contradict each other
    variables/.../ok_ui_base_period_total_wages.py:22 os40.pdf#page=19 20 Same heading-only page; § 1-201(4) "Base period" is on p.20
    variables/.../ok_ui_high_quarter_taxable_wages.py:23 os40.pdf#page=44 23 Wrong section, not just wrong page. p.44 prints § 1-221 and § 1-223; the docstring cites only § 1-201(48) (p.23) and § 2-104(A) (p.50)

    The three #page=2 sites are the most consequential: that mis-anchored citation is the sole source the PR offers for the entire 2022 vintage of wba/max_amount, mba/max_amount, and taxable_wage_base. All three values are correct (see [A4] and Investigated and Cleared), but as cited they are unverifiable.

    Corroborating reports: reference-checker C-1, C-2, C-3, SA-2, SA-3; verifier-pages (independent 49-reference audit: 39 correct, 10 wrong); regulatory G2; verifier-codepath-3 §7(i); verifier-codepath-6 §7; verifier-mismatch-4 §6; verifier-ext-1 §C.2; verifier-ext-3 defect 3; pdf-audit-mba (manifest flag).

  3. [C3] mba/max_amount is not load-bearing in any of the 67 test cases, and the case named for it asserts a binding that never occurs.policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.yaml (Case 7); policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/integration.yaml (Cases 3, 6)

    ok_ui_maximum_benefit_amount is min(min(WBR × max_weeks, max_amount), share × total_wages). The max_amount leg was evaluated against every case in the suite that asserts an MBA (10 in ok_ui_maximum_benefit_amount.yaml, 4 in ok_ui.yaml, 4 in integration.yaml). It never uniquely binds. It either loses to the duration cap or the share cap, or — in the three 2025 cases with WBR clamped to $541 — it ties the duration cap at exactly $541 × 16 = $8,656.

    The case explicitly named for it is the tie:

    - name: Case 7, 2025 - statewide max amount binds against a large share cap.
      # min(min($541 * 16 = $8,656, $8,656 max_amount), 0.4 * $100,000 = $40,000) = $8,656.

    $8,656 comes out whether max_amount is 8,656, 9,000, or 50,000. The name and comment assert a binding the case does not demonstrate; the same is true of integration.yaml Cases 3 and 6.

    Net effect: raise any of the five published values — 9,900 / 7,888 / 8,304 / 8,656 / 10,384 — to an arbitrary number and every test still passes. The suite pins only a one-sided lower bound per year (2022 ≥ 7,800; 2023 ≥ 4,800; 2024 ≥ 8,000; 2025 ≥ 8,656; 2026 ≥ 5,700).

    The fix is available and cheap. 2022 is the one year where max_amount demonstrably binds, because the 26-week regime lets WBR × weeks exceed it: period 2022, ok_ui_high_quarter_taxable_wages: 20_000, ok_ui_base_period_taxable_wages: 20_000, ok_ui_base_period_total_wages: 100_000, state_code: OK → WBR $476 (2022 cap); duration $476 × 26 = $12,376; share 0.4 × $100,000 = $40,000; max_amount $9,900 is the least → ok_ui_maximum_benefit_amount: 9_900. Add the matching ok_ui: 9_900 with weeks_unemployed: 26.

    For 2023–2026 the parameter genuinely cannot bind by construction (the encoded values are exactly 16 × the maximum WBA, and any individual's WBR × 16 ≤ max_WBA × 16), which two independent verifications confirmed. The honest fix there is a comment stating that those values are unfalsifiable by the suite — not a case name implying otherwise.

    Corroborating reports: edge-case-checker CRIT-1; pdf-audit-mba MISMATCH 2; verifier-ext-2 §7 cross-check; verifier-mismatch-4 §3c; code-validator SUG-6.

  4. [C4] 2023 and 2026 have zero end-to-end ok_ui coverage, contradicting the published verified_years: "2022-2026".policyengine_us/programs.yaml:1356; policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/ok_ui.yaml, .../integration.yaml

    programs.yaml publishes verified_years: "2022-2026" with status: complete. Years in which ok_ui itself is asserted: 2022 (integration.yaml Case 5), 2024, 2025. 2023 and 2026: none. ok_ui_monetarily_eligible is likewise never asserted at 2023 or 2026.

    Year ok_ui ok_ui_monetarily_eligible ok_ui_weekly_benefit_rate ok_ui_maximum_benefit_amount
    2022 × × × ×
    2023 × ×
    2024 × × × ×
    2025 × × × ×
    2026 × ×

    Both missing years are exactly the transition years. 2023 is where mba/max_weeks steps 26 → 16, and where taxable_wage_base = $25,700 and mba/max_amount = $7,888 first apply. 2026 is where mba/base_period_wages_share steps 0.4 → 0.475 and wba/max_amount jumps to $649.

    Two ready cases:

    • period 2023, HQW 6_900, taxable 6_900, total 20_700, ok_ui_gross_weekly_earnings: 0, weeks_unemployed: 16, state_code: OKok_ui_monetarily_eligible: true, ok_ui_weekly_benefit_rate: 300, ok_ui_maximum_benefit_amount: 4_800, ok_ui: 4_800.
    • period 2026, HQW 20_000, taxable 20_000, total 60_000, ok_ui_gross_weekly_earnings: 0, weeks_unemployed: 16ok_ui_weekly_benefit_rate: 649 (2026 cap load-bearing), ok_ui_maximum_benefit_amount: 10_384, ok_ui: 10_384.

    One structural note the author should know: the 0.475 share can never bind for a monetarily eligible 2026 claimant. Test A requires total ≥ 1.5 × HQW, and 0.475 × 1.5 × HQW = 0.7125 × HQW always exceeds the duration cap 16 × HQW/23 = 0.6957 × HQW; Test B requires total ≥ $25,000 while the share would need total < $10,384/0.475 = $21,861. This was independently reconfirmed by a 22,470-combination brute-force scan that found zero fractional 2026 MBAs for eligible claimants. So ok_ui_maximum_benefit_amount.yaml Case 8 (the only 0.475 case) describes a claimant who can never be paid — legitimate for the standalone variable, but it means the 0.475 value never reaches ok_ui under any input.

    Corroborating reports: edge-case-checker CRIT-2; verifier-mismatch-3 §4a.


Should Address

  1. [A1] § 2-102 whole-dollar truncation is applied to the WBA but not to the maximum benefit amount or the weekly payable, which § 2-102 names by their exact statutory nouns.policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_maximum_benefit_amount.py:27-30 and .../ok_ui_weekly_payable.py:22-23 — PDF p.49

    § 40-2-102, verbatim at 600 DPI: "ROUNDING PROVISION. Any benefit amount, any maximum benefit amount, or any payment amount computed under the provisions of this article that is not a multiple of One Dollar ($1.00) shall be computed to the next lower multiple of One Dollar ($1.00)." The three nouns map 1:1 onto § 2-104 ("Computation of benefit amount"), § 2-105 (the paid partial amount), and § 2-106 (whose heading is literally "Maximum benefit amount"). A scope refutation was tried and failed: § 2-102 says "this article", which is strictly broader than § 2-101's "this part" (Title 40 elsewhere refers to "Part 6 of Article 2", "Part 1 of Article 2").

    ok_ui_weekly_benefit_rate.py:22 applies np.floor correctly and its own comment cites § 2-102 by name — so this is an internal inconsistency, not a difference of legal reading.

    Model-executed magnitudes: MBA 2025, base-period total wages $15,002.45 → model $6,000.98 vs statutory $6,000 ($0.98, propagates verbatim to ok_ui). Weekly payable 2025, WBR $400, weekly earnings $150.01 → model $349.99 vs $349, amplified by ok_ui.py:49's multiplication by weeks_unemployed to $15.84 at 16 weeks and $25.74 at the pre-2023 26-week duration. The per-case error is a roughly uniform draw on [$0, $1.00), so ~70% of cents inputs clear the 0.3 reporting threshold. The error is systematically one-directional — the model can only over-state the Oklahoma benefit, never under-state it.

    Classified SHOULD ADDRESS under the rounding rule: both formulas are structurally correct — right prongs, right parameters, right min_/max_ ordering — and an exhaustive categorical-flip hunt found no flip with downstream consequences. (The $16 WBA minimum cannot flip, because flooring happens before a whole-dollar clamp; the min() branch selection cannot flip; eligibility does not read either variable; the MBA-to-zero flip requires taxable > total, which is economically impossible. The one real flip — payable $0.50 truncating to $0 — terminates at ok_ui, which no variable consumes, and is worth at most $13.)

    Live-year detail: the MBA path is live 2022–2025 via the § 2-106(3) share prong and provably inert in 2026 (see [C4]); the payable path is live in all years but only on the household-calculator/API surface, since ok_ui_gross_weekly_earnings is a bare input defaulting to 0. Suggested fix: np.floor the min_() result at ok_ui_maximum_benefit_amount.py:27-30 and the payable at ok_ui_weekly_payable.py:23. No floor is needed at ok_ui.py:49 — § 2-102 governs the weekly payment and the benefit-year maximum, not the annual roll-up. Regression tests should use cents-valued inputs; the existing absolute_error_margin: 0.01 will catch them.

    Corroborating reports: regulatory S1, S2; pdf-audit-wba M5; verifier-codepath-5 (CONFIRMED, SHOULD ADDRESS); verifier-mismatch-3 (CONFIRMED MISMATCH, SHOULD ADDRESS; also recorded a FALSE POSITIVE on ok_ui_weekly_benefit_rate, which floors correctly).

  2. [A2] The § 2-206 one-week unpaid waiting period is not modeled, and it overstates the benefit by one full WBA on the majority of spell lengths.policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui.py:45-50 — PDF p.56

    § 40-2-206, verbatim at 600 DPI: "WAITING PERIOD. The unemployed individual must have been unemployed for a waiting period of one (1) week. No week shall be counted as a week of unemployment for the purposes of this section: (1) Unless it occurs within the benefit year …; (2) If benefits have been paid with respect thereto; (3) Unless the individual was eligible for benefits with respect thereto." Clause (2) makes the week unpaid by construction; clause (1) makes it one per benefit year, which is exactly the period ok_ui is defined over.

    In force for the whole modeled window, established four ways: the section carries no amendment history at all (contrast § 2-205.1 immediately above it, amended by Laws 2022, c. 360); it is byte-identical in the independent Oklahoma Senate May-2022 compilation; a full-title sweep for "waiting" finds no suspension provision (the only other hit, § 2-714, excludes waiting-period provisions from extended benefits, which presupposes regular benefits carry one); and the live handbook OES-339 p.4 says a debit card is mailed "after the waiting period, or first week of benefits, is served."

    ok_ui pays weekly_payable × weeks_unemployed capped at the MBA, with no deduction anywhere in the chain. weeks_unemployed is CPS unemployment duration ("weeks spent looking for work"), not weeks claimed, so deducting does not double-count. Let K = MBA / weekly_payable: the overstatement is one full weekly payable for 1 ≤ n ≤ K, a partial amount for K < n < K+1, and $0 only at n ≥ K+1. Against the PR's own asserted test values: Case 1 (2025, 10 weeks) $4,000 vs $3,600 — $400 overstated, 11.1%; Case 7 (2024, 16 weeks, at the cap) $8,000 vs $7,500 — $500, 6.7%; Case 9 (2025, share cap binding, K = 13.8) $358 in the partial band; Case 2 (2025, 20 weeks) $0 — absorbed. Per-claimant upper bound is each year's maximum WBA: $476 / $493 / $519 / $541 / $649.

    Fix is one line plus a one-value parameter: payable_weeks = max_(weeks_unemployed - p.waiting_weeks, 0) inside the existing min_, with waiting_weeks.yaml 1980-07-01: 1. Do not instead lower mba/max_weeks to 15 — OESC's published MBA equals published max WBA × 16 exactly in every year (493×16=7,888; 519×16=8,304; 541×16=8,656; 649×16=10,384), which proves those 16 are payable weeks with the waiting week on top. Do not subtract one WBA after the cap — that would wrongly strip a week from an already-capped long spell.

    Fair framing, and the reason this is not CRITICAL: the omission is explicitly disclosed in both the class docstring (ok_ui.py:17-18) and the documentation field (ok_ui.py:32-35); the only in-repo precedent, pa_uc.py:10-11, omits it identically under status: complete; and the dollar error reaches no microsim, budget, or poverty aggregate (ok_ui is $0 population-wide because all four wage inputs default to 0, and no variable consumes ok_ui). Best handled as a non-blocking change or one tracking issue covering both ok_ui and pa_uc — framing it as an OK regression would be inaccurate.

    Corroborating reports: regulatory S3; pdf-audit-annual (MISSING FROM REPO); verifier-codepath-2 (CONFIRMED, medium); verifier-mismatch-2 (CONFIRMED MISMATCH, medium, and corrected the absorption model from a fixed 17-week threshold to K-dependent — which widens the biting range).

  3. [A3] ok_ui_weekly_benefit_rate returns $16 for every Oklahoman with no UI wages, and nothing in the suite pins it.policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_weekly_benefit_rate.py:10,23

    The variable is gated only on defined_for = StateCode.OK and applies the § 2-104(A) $16 floor unconditionally: min_(max_(np.floor(0/23), 16), max_amount) = 16. Verified live — an OK person with no wage inputs returns ok_ui_weekly_benefit_rate = 16.0 while ok_ui_monetarily_eligible = False and ok_ui = 0.

    Direction and magnitude, reported without prescribing a default: no benefit leaks (ok_ui and ok_ui_weekly_payable are both defined_for = "ok_ui_monetarily_eligible", and the MBA share prong drives MBA to 0), so the population-level dollar effect is exactly zero and no eligibility outcome flips. The exposure is presentational: the Household API and web app will publish a non-zero weekly benefit rate for every Oklahoma household — children, retirees, everyone — in the variable tree. § 2-104(A)'s floor presupposes a claimant with a computed benefit ("if the amount is less than Sixteen Dollars … it shall be increased"), not the general population. Gating on ok_ui_monetarily_eligible, as ok_ui_weekly_payable.py:10 already does, would make it consistent; PA differs here only incidentally, because pa_uc_weekly_benefit_rate reads a rate table that returns 0 at 0 wages.

    No test exposes it: ok_ui.yaml Case 4 sets all wages to zero and asserts only ok_ui_monetarily_eligible: false and ok_ui: 0. Pinning case: period 2025, age: 35, no OK UI inputs, state_code: OKok_ui_weekly_benefit_rate: 16, ok_ui_maximum_benefit_amount: 0, ok_ui_monetarily_eligible: false, ok_ui: 0.

    Corroborating reports: edge-case-checker CRIT-3 (rated CRITICAL); code-validator SA-1; regulatory G1. Placed at SHOULD ADDRESS under the microsim-default rule — it neither flips eligibility for any population share nor shifts aggregate cost.

  4. [A4] The 2022 vintage has no cited source of 2022 vintage, though an authoritative one exists and resolves.policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml:14-32, .../mba/max_amount.yaml:20-34, .../mba/base_period_wages_share.yaml:14-26, policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml:28-29 — PDF p.1

    Every 2022 value is correct — this is a provenance defect, not a value defect. All four were read visually off a 600-DPI render of the 2022 OESC sheet (sha256 642cc67c…, 70,137 bytes, HTTP 200, CreationDate 2022-12-07): Conditional Factor "D" and State Experience Factor "50%" · Taxable Wage Base $24,800 · Maximum Weekly Benefit $476 · Maximum Benefit Amount $9,900 · Average Annual Wage $49,560 · Average Weekly Wage $953. base_period_wages_share 0.4 follows from factor "D" via § 2-106(3)(e). As a bonus the same sheet corroborates the pre-existing default_rate 0.015 ("New Employer Tax Rate 1.50%").

    Today the only 2022 citation is the mis-anchored 2021 tax-rates report (see [C2]), and mba/base_period_wages_share.yaml cites no 2022-vintage document at all — its four OESC sheets are 2023, 2024, 2025 and 2026. A repo-wide grep for Numbers-2022 returns zero hits, against 4 / 4 / 3 / 4 for 2023–2026: 2022 is the single gap in an otherwise complete annual-sheet citation set. Adding one reference line to the four files closes it.

    Corroborating reports: reference-checker C-5, SA-11 (rated CRITICAL on text extraction); pdf-audit-annual Task 3 (two EXTERNAL PDF NEEDED flags); regulatory G4; verifier-ext-2 (CORROBORATED at 600 DPI, severity LOW — Phase 5 verdict governs, so this is not CRITICAL).

  5. [A5] taxable_wage_base.yaml cites a vintage of § 1-223 whose printed percentages reproduce none of the encoded values, and carries no explanatory comment.policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml:21 — PDF p.44

    § 1-223 was rewritten by Laws 2025, c. 140, § 1, eff. Nov. 1, 2025. The currently-printed ladder is 40 / 41.25 / 42.5 / 43.75 / 45%. Applying it to the published average annual wages gives 2023 $23,100, 2024 $24,300, 2025 $25,400, 2026 $24,200 — matching none of the encoded 25,700 / 27,000 / 28,200 / 25,000. The ladder that actually produced them is the pre-2025 one (40 / 42.5 / 45 / 47.5 / 50%), retrieved from the Oklahoma Senate's May-2022 Title 40 compilation and independently corroborated by OESC's own Employment Security Act compilation.

    Every encoded value is right: all nine years 2014–2026 reproduce exactly under the correct-vintage ladders (wage base rounds to the nearest $100 per § 1-201(48); max WBA truncates per § 2-102). But a reviewer who follows the citation and does the arithmetic will conclude the whole file is wrong. Add a comment naming the pre-2025 ladder, the current ladder and its Nov. 1 2025 effective date, and the conditional factors (D for 2022–2025, A for 2026) that select the rungs — with the note that CY2026's $25,000 reflects a determination made under the prior percentages, consistent with OESC setting next-year rates before the amendment took effect.

    Corroborating reports: verifier-ext-3 defect 1 (called this "the single most useful thing this verification produced"); pdf-audit-wba (EXTERNAL PDF NEEDED flag, now closed).

  6. [A6] Three reference titles state something the source does not say.policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/wba/max_amount.yaml:15,19,27-28; .../mba/max_amount.yaml:25; .../tax/payroll/unemployment/taxable_wage_base.yaml:28

    • wba/max_amount.yaml:15"40 O.S. §2-104(B) (OESC Board determines maximum weekly benefit annually)". § 2-104(B) confers no board discretion: it fixes the maximum by statute as 60% / 57.5% / 55% / 52.5% / 50% of the second preceding year's average weekly wage, selected by the § 3-113 conditional factor. It is § 2-104(C) that assigns the Commission (not a "Board") the ministerial task of computing the average weekly wage. The parenthetical actively misleads about the mechanism.
    • wba/max_amount.yaml:27-28 — titled "OESC Claimant Handbook OES-339 (Rev. 05-2025)". The live document at that unversioned URL is Rev. 06-3-2026; its page 4 now names only "For 2026, the maximum WBA is capped at $649.00" and quotes no 2025 figure. The page anchor is correct and still corroborates the 2026 value and the 16-week duration — only the revision label is stale, and it will drift again. Retitle or drop the revision suffix. The same stale label appears in the ok_ui_weekly_benefit_rate.yaml test comment and at diff line 342.
    • The 2021 report is titled "Oklahoma UI Tax Rates by Industry, Size, and County, 2021" in three files; its actual title is "Oklahoma Unemployment Insurance Tax Rates by Industry, Establishment Size and County", covering 1Q2016–1Q2021 and published February 2022 — and the values being cited are Table 1's 2022 column. A reader cannot tell from the title that the 2022 values are traceable there.

    Corroborating reports: reference-checker SA-5, SA-6, SA-13; verifier-ext-3 defect 2; pdf-audit-annual M1; verifier-pages §D.

  7. [A7] mba/max_weeks.yaml's comment misattributes § 1-231 to the wrong session law and describes the escalator as an unmodeled gap when it verifiably does not bind.policyengine_us/parameters/gov/states/ok/oesc/unemployment_insurance/mba/max_weeks.yaml:4-9,26,28

    The values are correct1980-07-01: 26 and 2023-01-01: 16 are both right for every covered year, confirmed independently (see Investigated and Cleared). The defects are in the comment:

    • It reads "§1-231 sets the duration floor at 16 weeks from Jan. 1, 2025 (Laws 2024, c. 114 / HB 3596)", which does not match the file's own 2023-01-01 key and misnames the enacting law. § 1-231's history line reads "Added by Laws 2022, c. 287, § 3, eff. Jan. 1, 2023. Amended by Laws 2024, c. 114, § 3, eff. Nov. 1, 2024." HB 3596 SECTION 3 was diffed against HB 1933 SECTION 3 and against the codified text: word-for-word identical — the only underlined (added) matter in HB 3596 is the section catchline. HB 3596 changed nothing about max_weeks. The 2023-01-01: 16 key rests on § 2-106(1)(b) ("If between January 1, 2023, and January 1, 2025, sixteen (16) times the weekly benefit amount") plus HB 1933 SECTION 4 ("This act shall become effective January 1, 2023").
    • It frames the § 1-231 escalator as "not modeled", which reads as an admitted gap. It is stronger than that: the escalator does not bind in any covered year. Suggested replacement wording, verified: "The §1-231 escalator (+2 weeks per 15,000-claim increment above 5,000, capped at 20; 26 weeks if weekly continued claims exceed 40,000) is operative from Jan. 1, 2025 but does not bind: the 13-week averages beginning the first July file week were 10,266 (governs CY2025) and 11,393 (governs CY2026), below the first increment. OESC's published maxima confirm 16x — 2025: $8,656 = 16 x $541; 2026: $10,384 = 16 x $649."
    • Title style: :28 gives HB 3596 its session-law identifier ("Laws 2024, c. 114") while :26 titles HB 1933 as just "Oklahoma House Bill 1933 (2022)". HB 1933 is Laws 2022, c. 287, eff. 2023-01-01; matching the two titles would make the misattribution self-evident.

    A forward-looking watch item worth recording alongside it: the CY2026 window ran 11,393, about 57% of the 20,000 threshold that would step the multiplier to 18, and is trending up (11% above the CY2025 window). And § 1-231(B)(2)'s 26-week trigger reads on weekly continued claims exceeding 40,000 and applies mid-year — a year-keyed parameter cannot express it at all.

    Corroborating reports: code-validator C-2 (rated CRITICAL on the theory the value might be wrong — refuted in Phase 5); reference-checker SA-8, S-4; pdf-audit-mba MISMATCH 5; pdf-audit-wba M1, M3; verifier-ext-1 §C (REJECTED the value mismatch, confirmed the documentation defects).

  8. [A8] The PR silently changes a pre-existing employer payroll-tax output in four of five years, and the changelog does not mention it.policyengine_us/parameters/gov/states/ok/tax/payroll/unemployment/taxable_wage_base.yaml:5-9; changelog.d/ok-ui.added.md:1

    Converting a flat 0000-01-01: 27_000 into a dated 2022–2026 series moves ok_employer_state_unemployment_tax, which reaches households through employer_state_unemployment_taxemployer_state_payroll_taxemployer_payroll_taxemployer_cost_of_employment. Verified live for a $60k OK earner (rate 1.5%, unchanged):

    Year Pre-PR base Post-PR base Pre-PR tax Post-PR tax Δ
    2022 27,000 24,800 $405.00 $372.00 −$33.00
    2023 27,000 25,700 $405.00 $385.50 −$19.50
    2024 27,000 27,000 $405.00 $405.00 $0.00
    2025 27,000 28,200 $405.00 $423.00 +$18.00
    2026 27,000 25,000 $405.00 $375.00 −$30.00

    Every one of these moves is a correction — the direction reported by the Phase 4 validators was backwards, and pre-2022 years are bit-identical before and after the PR (see Pre-existing). The finding is one of scope disclosure, not of value: changelog.d/ok-ui.added.md says only "Add Oklahoma Unemployment Insurance", so an employer-tax change is invisible to reviewers and to release notes, and no test in the PR exercises the tax-side consumer at any changed year. Add a line to the changelog fragment (one fragment per PR remains correct) and, ideally, a boundary test on the employer-tax path.

    Corroborating reports: code-validator C-1 (rated CRITICAL); verifier-codepath-3 §4 (confirmed the substance, refuted the direction).

  9. [A9] Test-suite gaps beyond [C3] and [C4].policyengine_us/tests/policy/baseline/gov/states/ok/oesc/unemployment_insurance/

    Discriminating cases that are missing, ordered by value:

    • Negative weeks_unemployed produces a negative benefit, unguarded and untested. ok_ui.py:45-50 has no zero floor: with weeks_unemployed: -5 and WBR $400, min(-2000, 6400) = -2000. Every other negative path in this program is guarded (ok_ui_maximum_benefit_amount.py:24 wraps base-period wages in max_(…, 0); ok_ui_weekly_payable.py:23 floors at 0) — this one was missed. Needs a max_(…, 0) in the formula plus a case asserting ok_ui: 0.
    • ok_ui_weekly_payable's defined_for gate has zero coverage — all 8 cases use taxable $9,200 / total $30,000 and are eligible. A case with taxable 1_000 / total 12_000ok_ui_weekly_payable: 0 is discriminating (without the gate it would be 400).
    • 2022 ($24,800) and 2023 ($25,700) wage-base boundaries are never load-bearing in ok_ui_meets_alternate_wages_test.yaml — only 2025 and 2026 have boundary cases, and both 2022 and 2023 genuinely differ from the $27,000 that would otherwise apply.
    • No clean same-inputs A/B across either parameter seam. Cases 4 (2022) and 5 (2024) skip 2023, the 26→16 transition year itself; Cases 6 (2022) and 8 (2026) differ in both HQW and max_weeks, so neither isolates the 0.4→0.475 share change.
    • "Both monetary tests pass" is reached but never asserted (integration.yaml Cases 1 and 3 reach it; neither asserts both component flags).
    • The $16 floor is never combined with partial earnings — all 8 payable cases run at WBR $400.
    • No multi-person household anywhere in the suite. All 67 cases are single-person. The repo's entity-wide-input trap cannot fire here (every OK UI input is Person-entity with explicit per-person slots), but nothing proves one claimant's wages don't leak into a spouse's benefit.
    • ok_ui_gross_weekly_earnings is disconnected from employment_income and nothing documents it — a household with employment_income: 60_000 and no OK-specific earnings input gets the full WBA, disregard never engaging.
    • Hygiene: three byte-duplicate cases inflate the count to 67 from an effective 64 (ok_ui_meets_high_quarter_test.yaml Case 4 ≡ Case 1; ok_ui_weekly_payable.yaml Case 5 ≡ Case 2; ok_ui_maximum_benefit_amount.yaml Case 4 ≡ Case 2); ok_ui_monetarily_eligible.yaml reuses "Case 1/2/3" twice each (lines 7/80, 30/104, 53/126), making a failure report ambiguous; integration.yaml Case 7's comment claims intermediates "may still compute" in a TX household, but all five carry defined_for = StateCode.OK and are masked; and integration.yaml's 7 cases are unit tests with extra assertions — single adults in a bare households block with no spm_units, tax_units, spouse, child, or employment_income.

    Worth recording as not defects: the four formula-less wage inputs correctly need no eponymous test files; the out-of-state gate is paired with an in-state twin, which is a genuinely discriminating defined_for test and is rare; and ok_ui being unwired from household_benefits/spm_unit_benefits matches pa_uc and nj_unemployment_insurance precedent.

    Corroborating report: edge-case-checker SA-1 through SA-13, SUG-1 through SUG-8.

  10. [A10] Reference hygiene: same URL at multiple #page= anchors, a bare landing page, and an uncited load-bearing section. — seven reference lists; .../wba/max_amount.yaml:29-30; .../ok_ui_weekly_benefit_rate.py:16-19

    • Seven reference lists cite os40.pdf at two or three different anchors, against the standing one-page-per-URL rule: mba/max_weeks.yaml (48, 51), taxable_wage_base.yaml (23, 44, 56), ok_ui.py:41-42 (50, 51), ok_ui_base_period_taxable_wages.py:23-24 (19, 44), ok_ui_base_period_total_wages.py:22-24 (19, 42, 56), ok_ui_high_quarter_taxable_wages.py:23-24 (44, 50), ok_ui_maximum_benefit_amount.py:12-13 (48, 51). In each case the anchors point at genuinely different sections that jointly support the variable — the most defensible form of the pattern — but the rule is one page per URL. Recommended single pages after the [C2] corrections: max_weeks → 52; taxable_wage_base → 23; ok_ui.py → 52; ok_ui_base_period_taxable_wages → 23; ok_ui_base_period_total_wages → 42; ok_ui_high_quarter_taxable_wages → 50; ok_ui_maximum_benefit_amount → 52. Every os40.pdf citation is additionally paired with an OSCN DeliverDocument.asp?CiteID=… link to the same section — promoting the OSCN link to first position for secondary sections would make the citations self-maintaining and would have prevented three of the four wrong-page findings.
    • wba/max_amount.yaml:29-30 cites https://oklahoma.gov/oesc.html with the generic title "Oklahoma Employment Security Commission". It is the agency home page: HTTP 200, but it states no weekly benefit maximum for any year and corroborates nothing. Remove it — the four Important Numbers sheets already carry the values.
    • § 2-102 is load-bearing but cited nowhere. ok_ui_weekly_benefit_rate.py:16-19 invokes it in a bare code comment to justify np.floor, a rule that changes the payable by up to $1/week; the variable's only reference is os40.pdf#page=50 (§ 2-104). Add § 2-102 (p.49) to the reference tuple. Related: ok_ui.py says it implements the "§ 2-106 / § 1-231" duration cap but neither section is reachable from its reference tuple, and ok_ui_high_quarter_taxable_wages.py names § 1-201(48) in prose but not in its tuple.

    Corroborating reports: reference-checker SA-4, SA-7, SA-9, S-1, S-2, S-3; regulatory G3; code-validator SUG-2, SUG-3, SUG-4; verifier-pages §A.

  11. [A11] A variable label leaks an implementation caveat into user-facing text.policyengine_us/variables/gov/states/ok/oesc/unemployment_insurance/ok_ui_gross_weekly_earnings.py:14

    label = "Oklahoma UI average weekly earnings (year-period input)". Labels render in the web app and in API metadata; the storage-period caveat belongs in documentation. Compare pa_uc_gross_weekly_earnings, whose label is clean and whose caveat lives in the docstring.

    Corroborating report: code-validator SA-6.


Suggestions

  1. [S1] ok_ui.py's "not modeled" list miscites the alternative/extended base period authorities in three ways and lists the item twice under mutually inconsistent citations. ok_ui.py:10-11 names "§ 1-201(48) / § 1-217(B)"; § 1-201(48) is "Taxable wages" (p.23) and § 1-217 is "Unemployed" — neither concerns base periods. ok_ui.py:19-20 and the documentation field at :32-33 name "§ 1-202.1 / § 1-202.2"; § 1-202.2 was repealed by Laws 2022, c. 360, § 23, eff. Nov. 1, 2022, before the coverage window opens. The correct citations are § 1-201(2) (definition) and § 2-207(C) (the substitution rule) for the alternative base period, and § 1-202.1 for the extended base period. De-duplicate the entry and re-cite it. (Phase 5 rated this SUGGESTION; it is a documentation defect, not a formula defect — see Investigated and Cleared.)
  2. [S2] mba/base_period_wages_share.yaml:4-6's comment is substantively correct but reads as self-contradictory and misled three separate reviewers. Its (a) 50%, (b) 47.5%, (c) 45%, (d) 42.5%, (e) 40% list gives § 2-106(3) subparagraph letters, while "condition 'd' (40%)" gives a § 3-113 condition letter; the two alphabets are offset by one, because subparagraph (a) is the no-conditional-factor case. Both encoded values are right (condition "d" → subpara (e) → 40%; condition "a" → subpara (b) → 47.5%). Add "(note: subparagraph letters are offset one from the § 3-113 condition letters)". The same offset risk applies to the § 2-106(2) discussion in mba/max_amount.yaml.
  3. [S3] ok_ui_meets_alternate_wages_test.py has no docstring, and its > 0 prong at :20 carries no comment, no parameter, and no subsection reference — unlike every other non-trivial variable in the folder. The prong is genuinely "Taxable wages of any amount" (§ 2-207(B)(1), p.57); saying so would also close the naming ambiguity that made two auditors read "alternate wages test" as "alternative base period". A one-line docstring on ok_ui_monetarily_eligible.py noting that § 2-207(C) substitutes alternative-base-period wages into these same inputs would close the residual caller-side exposure.
  4. [S4] Pre-2022 values on three new parameters are backdated to 2015 by the repo-wide backdate_parameters(first_instant="2015-01-01") at policyengine_us/system.py:116, silently returning 2022 figures for 2015–2021 (pre-2015 raises ParameterNotFoundError). Verified errors run from −$1,800 (2020 MBA, −15.4%) to +$300 (2021 MBA); the sign changes because 2015–2020 ran at the 60%/25% fund-in-excess rates. base_period_wages_share is correct for 2021 (conditional factor D in both 2021 and 2022) and wrong only for 2015–2020. The window sits outside verified_years: "2022-2026", microsim exposure is nil, and the two merged siblings do the same (NJ's max_weekly_benefit returns $854 for 2021 against a true $731, under status: complete). Not a blocker. It is unusually cheap to fix, though: the complete corrected 2011–2022 series is printed in Table 1 of a document the PR already cites — 1980-07-01-style keys are not needed, just 2015-01-01 entries plus 2015-01-01: 0.5 on the share.
  5. [S5] status: complete at policyengine_us/programs.yaml:1352 overstates a program that computes $0 for every household in microsimulation. All four wage inputs are formula-less with default_value = 0 and no imputation, and ok_ui is not consumed by unemployment_compensation or any aggregate (repo-wide grep finds only programs.yaml:1347,1354), so it never reaches household net income. partial would be more accurate. Recorded as a family-wide consistency decision rather than an OK slip: nj_unemployment_insurance (:1331) and pa_uc (:1373) both carry status: complete under the identical design, and index.yaml's economy: false / household: true already disclose the intent correctly.
  6. [S6] Five values are dated to 1980-07-01 (and the disregard to 1994-07-01) on the strength of the section's enactment clause, not of a source establishing the figure held from that date — wba/divisor.yaml:4, wba/min_amount.yaml:4, eligibility/min_taxable_wages.yaml:4, eligibility/min_total_wages_multiplier.yaml:4, mba/max_weeks.yaml:10. Every cited section was amended repeatedly after 1980 (§ 2-104 in 1983/1998/2017; § 2-207 in 1983/1995/2002/2009/2010/2012/2018; § 2-106 in 1983/1986/1998/2022). All five values are corroborated as current law. Either date them to the amendment that set them or note in a comment that 1980-07-01 is the section's enactment date and earlier values were not researched. partial/disregard.yaml's 1994-07-01 is the one date fully corroborated, because § 2-105's own text recites "any week ending after July 1, 1994".
  7. [S7] ok_ui.py's docstring omits the approximation most likely to matter to a reader: § 2-106 caps benefits per benefit year (§ 1-201(5): a rolling year anchored to the claim date), while the model applies min_(annual_benefit, maximum_benefit_amount) per calendar year — so a benefit year straddling December can draw up to a full MBA in each of two calendar years. This is inherent to PolicyEngine's annual periods and should not be modeled, but the docstring enumerates nine other exclusions in detail and should list this one. Worth one more line: the omitted § 1-217(B)(2) and § 2-202/§ 2-205.1/§ 2-404–2-422 provisions only restrict eligibility (making the model over-inclusive) while § 1-201(2)/§ 1-202.1 only expand it (conservative) — the net direction is not obvious from the current list.
  8. [S8] ok_ui.py:5-21 carries both a class docstring and a documentation= block at :26-36 with overlapping but non-identical "not modeled" lists; they will drift. Keep one. Repo-wide, 1,176 variable files use documentation= and only 15 of 5,706 use a class docstring — six of those 15 are this PR, following the pa_uc template. Docstrings are not surfaced in API metadata.
  9. [S9] The handbook worked-example test comment overstates its source. ok_ui_weekly_benefit_rate.yaml Case 1 says "Matches OES-339 Rev. 05-2025 page 4 worked example", but the handbook stops at "the weekly benefit amount would be adjusted to the maximum allowed" — deliberately year-agnostic. The $519 comes from the 2024 Important Numbers sheet, not the handbook, whose own stated maximum is $649. The comment also writes $608.69 where the handbook prints $608.70 (a $0.01 misquote of a number presented as a quotation; it does not change the floored $608).
  10. [S10] mba/max_amount is a semantically mixed series: 2022 encodes the § 2-106(2) percentage-of-average-annual-wage cap (20% × $49,560 → $9,900, which genuinely binds against 26 × $476 = $12,376), while 2023–2026 encode 16 × the maximum WBA, i.e. the § 2-106(1) duration product. It is numerically harmless — the encoded values match what OESC itself publishes, and the term can never bind for 2023+ since any individual's WBR × 16 ≤ max_WBA × 16 — and the file's comment discloses it. But the parameter's description, label and reference all present it as the § 2-106(2) statutory cap, which it is not for 2023+. Worth a sentence in the comment; style.md's "drop a min_ that can never bind" would apply the moment pre-2023 coverage is dropped.
  11. [S11] Metadata and naming polish: programs.yaml:320 uses name: Oklahoma UI where the sibling UI entries spell out ("New Jersey Unemployment Insurance", "Pennsylvania Unemployment Compensation"); programs.yaml:1351 uses agency: Oklahoma Employment Security Commission where the siblings use a state-abbreviation prefix; parameters/.../unemployment_insurance/index.yaml omits the program-level reference block that PA's index carries; and the 2021 report is cited as https://www.oklahoma.gov/… while every other oklahoma.gov reference in the PR uses the bare https://oklahoma.gov/….
  12. [S12] ok_ui_weekly_benefit_rate, ok_ui_weekly_payable and ok_ui_gross_weekly_earnings store weekly dollars in YEAR-period USD variables. Consistent with pa_uc, so not a defect against repo convention, but the app and API will render and uprate them as annual amounts, and any future MONTH-period reader or uprating rule would silently divide by 12. Worth a documentation line on each (only ok_ui_gross_weekly_earnings has one today).
  13. [S13] ok_ui_gross_weekly_earnings / ok_ui_high_quarter_taxable_wages / ok_ui_base_period_{taxable,total}_wages mirror pa_uc_gross_weekly_earnings / pa_uc_highest_quarter_wages / pa_uc_base_year_wages and NJ's equivalents. These are not state-specific rules — they are the same household facts, and a household now needs three parallel copies. Worth considering a shared person-level input set before a fourth state lands. (CLAUDE.md's "state programs should be self-contained" is about income calculations, not raw inputs.)
  14. [S14] The parameter files should carry a maintenance note: max WBA moves 15–20% in a single year when the conditional factor changes, in either direction (2020→2021 dropped $539 → $461; 2025→2026 rose $541 → $649). There is no silent-drift mechanism — these parameters have no uprating, so a year with no entry visibly holds the last value — but a "refresh from the OESC Important Numbers sheet each January" note is warranted. Also warn against extrapolating a future wage base as 52 × max WBA: that identity holds only in condition-"d" years, and the § 1-223 ladder itself changed in 2025.

Investigated and Cleared

Nine reported mismatches were escalated to Phase 5 verification and rejected. None appears as a finding.

  1. § 2-207(C) as a third eligibility route — REJECTED (verifier-codepath-4). (C)(1) expressly routes alternative-base-period wages back into "subsection A or B of this section" — it is a conditional wage-substitution rule, not a qualifying test, and none of (C)(1)–(5) states a threshold, rate, or amount. ok_ui_monetarily_eligible.py:17's high_quarter | alternate implements both tests the section contains. There is also nothing to write: the substitution is already satisfiable through the existing input contract, since all three base-period wage figures are pure caller-supplied inputs, and (C)(2)–(5) (affidavit acceptance, redetermination, employer protest, second-benefit-year bar) are administrative procedure PolicyEngine models for no program. The residual defect is the miscitation at [S1]. The regulatory reviewer's "reasonable, documented exclusion" verdict is sustained over the MBA auditor's "largest un-modeled eligibility rule".
  2. § 1-231 sliding duration ladder for CY2025/CY2026 — REJECTED (verifier-ext-1). The flat 16 is the legally correct value for every year 2023–2026. 2023–2024 are fixed at 16 by § 2-106(1)(b) with no data lookup ("If between January 1, 2023, and January 1, 2025, sixteen (16) times"); § 1-231(B) does not reach them by its own terms ("On January 1, 2025…"). For 2025 and 2026 the statutory 13-week averages of Continued UI Claims were computed from US DOL/ETA form 539 and independently corroborated week-for-week against FRED OKCCLAIMS: 10,265.5 (window 2024-07-06 to 2024-09-28, governs CY2025) and 11,393.3 (window 2025-07-05 to 2025-09-27, governs CY2026) — both far below the first 15,000-claim increment above 5,000, and nowhere near the 40,000 emergency trigger. Decisively, OESC's own published maximum benefit amounts equal exactly 16 × the maximum WBA in all four years (7,888 = 16×493; 8,304 = 16×519; 8,656 = 16×541; 10,384 = 16×649), and the live handbook states 16 weeks "as established by state law". Downgraded to the documentation items at [A7].
  3. mba/max_weeks stepping at 2023-01-01 rather than 2025-01-01 — CLEARED. The step date matches § 2-106(1)(b), the § 2-106 amendment credit ("Laws 2022, c. 287, § 2, eff. Jan. 1, 2023"), and HB 1933 SECTION 4. Only the accompanying comment is wrong ([A7]).
  4. mba/base_period_wages_share values 0.4 / 0.475 possibly off by one rung — CLEARED by four independent lines of evidence (verifier-ext-2, verifier-ext-3, verifier-codepath-6, verifier-mismatch-4). The comment's (a)…(e) are § 2-106(3) subparagraph letters and the quoted letters are § 3-113 conditions, offset by one. § 2-106(3)(e) reads verbatim "forty percent (40%) during calendar years in which condition 'd' exists" and (3)(b) "forty-seven and one-half percent (47.5%) … condition 'a'". OESC published factor "D" for 2022–2025 and "A" for 2026. Both encoded values are right; the code-validator's C-3 was premised on the values possibly being wrong, and that premise is refuted. Wording clarification only ([S2]).
  5. The 2026 pair — wage base $25,000 alongside max WBA $649 — CLEARED (verifier-ext-3). The pdf-audit-wba finding that these "cannot both hold" used the post-Laws-2025 § 1-223 ladder. Under the pre-2025 ladder that governed the determination, condition "a" gives 42.5% × $58,765.95 = $24,975.53 → $25,000 for the wage base and § 2-104(B)(2)'s 57.5% × ($58,765.95/52) = $649.82 → $649 for the max WBA. All nine years 2014–2026, across three different conditional factors and both ladders, reproduce exactly. The apparent wage_base / 52 ≈ max WBA identity the auditors saw in 2021–2025 is an artifact of both ladders landing on 50% at condition "d" — it breaks in 2014, 2015–2020 and 2026. A rising max WBA alongside a falling wage base is the statute working as designed. Documentation item at [A5].
  6. The 2026 taxable wage base decrease $28,200 → $25,000 — CLEARED as REAL, read verbatim off the published 2026 sheet at 300 and 600 DPI. The whole page moves together: conditional factor D → A, state factor 50% → 30%, rate range 0.3–9.2% → 0.2–5.8%. Not a digit swap.
  7. ok_ui_weekly_benefit_rate missing § 2-102 flooring — FALSE POSITIVE (verifier-mismatch-3). np.floor is present at :22 and runs before a whole-dollar clamp, so the output is always integral. Only the other two variables are affected ([A1]).
  8. A missing § 2-106 prong — NOT PRESENT. This was the review's feared critical. ok_ui_maximum_benefit_amount.py:27-30 computes all three prongs correctly nested: min_(min_(wbr * p.max_weeks, p.max_amount), base_period_total_wages * p.base_period_wages_share). Using uncapped ok_ui_base_period_total_wages for prong 3 is right — "wages for insured work" (§ 1-201(37)) is not § 1-201(48) taxable wages. The max_(…, 0) guard at :24-26 is defensive and correct.
  9. The Employer-Improtant-Numbers-2026.pdf filename — CORRECT as encoded. The typo is genuinely upstream: the "Improtant" spelling returns 200 and the "Important" spelling 404 for 2026; the reverse holds for 2023–2025, which the diff also spells correctly. (The PR body misspells 2025; the diff is right.)

Additional clean results worth recording, so they are not re-flagged:

  • No hard-coded policy values in any formula. Every threshold, rate, divisor, floor, cap and week count comes from a parameter; the only literals are 0 floors and one > 0 prong.
  • No reinvented variables. weeks_unemployed (variables/household/demographic/person/weeks_unemployed.py) and the pre-existing gov.states.ok.tax.payroll.unemployment.taxable_wage_base are both correctly reused rather than duplicated; the remaining 11 variables are genuinely state-specific and mirror the PA UC naming one-for-one.
  • No zero-coverage formula variables. The four variables without eponymous test files have no formula at all, so none is required; every formula-bearing variable has at least one asserting test.
  • Boundary operators are correct throughout — "not less than" → >=, "equal to or more than" → >=, the § 2-104(A) clamp, Test A joined by & and Test A-or-B by | per "Notwithstanding the provisions in subsection A".
  • Partial benefits (§ 2-105) are exactly right, including the coincidence that the payable reaches $0 precisely at the § 1-217(B)(1) unemployment cutoff (WBA + $100), which is why no separate gate is needed here as it was for PA.
  • A dependents' allowance is correctly absent — unlike NJ and PA, Oklahoma has none.
  • Parameter metadata is complete and correct on all 11 files: unit/period/label/description/reference, period: week on weekly dollar amounts, unit: /1 on the dimensionless parameters, ISO date keys, no scale/bracket parameters. index.yaml's economy: false / household: true is right.
  • Entity and period usage are clean: all 11 variables Person/YEAR, every parameter read with the bare period, no period.this_year, no / MONTHS_IN_YEAR, no cross-entity aggregation, no division by a data-derived denominator, no enum inputs, no _before_lsr readers.
  • All 15 distinct cited URLs resolve (HTTP 200; no dead links). Three of seven OSCN mirror links were verified verbatim; four were blocked by Cloudflare Turnstile and are recorded as unverified rather than verified — none is load-bearing, since each duplicates an os40.pdf citation of the same section.
  • The changelog fragment is correctly formedchangelog.d/ok-ui.added.md, top-level, valid added type, one fragment for the PR. Only its content is incomplete ([A8]).

Pre-existing Issues

Not introduced by this PR; excluded from the critical count and from the severity recommendation.

  1. taxable_wage_base.yaml:4 0000-01-01: 27_000 is wrong for every pre-2022 year — but the PR improves the file. Confirmed against the merge base: the pre-PR file was that single value and nothing else, so every year through 2026 previously evaluated to $27,000. The sentinel is a diff context line; this PR is the first thing that has ever made the parameter year-accurate for any year, narrowing the wrong-value window from "all years" to "pre-2022". True bases were $17,000–$24,000 for 2011–2021, so the residual overstatement runs from +12.5% (2021) to +58.8% (2015) on ok_employer_state_unemployment_tax — the one place in this cluster that is genuinely live in microsimulation. All 50 sibling state taxable_wage_base.yaml files use the same bare 0000-01-01 sentinel; OK is now the only year-accurate file in the family. Deleting the sentinel is not a fix: backdate_parameters would then backfill 2015–2021 with $24,800, still wrong for all seven years. If the author wants to close it, the eleven 2011–2021 values are printed in Table 1 of a document the file already cites.
  2. default_rate.yaml:3 0000-01-01: 0.015 is wrong before 2016. Table 1 gives new-employer rates of 1.0% / 1.0% / 2.0% / 2.4% / 2.2% for 2011–2015; 1.5% holds only from 2016. Outside this PR's scope entirely — the file is untouched — and noted only for completeness.
  3. The § 2-206 waiting week is omitted in pa_uc identically ([A2]), under status: complete at programs.yaml:1373.
  4. status: complete on a program that is $0 in microsimulation is the family pattern ([S5]) — nj_unemployment_insurance and pa_uc both carry it under the identical formula-less-input design.
  5. No state UI benefit variable is wired into any aggregate. ok_ui, pa_uc and nj_unemployment_insurance are all unconsumed leaves; variables/gov/states/unemployment_compensation.py is a formula-less uprated input, not an aggregator.
  6. Backdating of first parameter values to 2015 is produced by policyengine_us/system.py:116, a repo-wide mechanism this PR did not opt into ([S4]); the merged NJ UI program exhibits the identical pattern.

PDF Audit Summary

Category Count
Confirmed correct 53 (14 WBA + 14 MBA + 20 annual auditor matches, + 5 corroborated 2022 values)
Mismatches (code-path confirmed + visually verified) 5 (§ 2-207(A)(2) operand; § 2-102 truncation ×2 variables; § 2-206 waiting week; pre-2022 phantom values; pre-2022 wage-base sentinel)
Mismatches rejected (code-path cleared) 9
Unmodeled items 16 (2 genuine gaps, 1 reasonable-but-undocumented, 12 reasonable documented exclusions, 1 correctly absent)
Pre-existing issues 6

Reference-checker corroboration table, all 25 in-scope parameter values: 19 CORROBORATED (6 of them through a mis-anchored citation — [C2]), 5 corroborated-value / uncorroborated-date ([S6]), 1 uncorroborated by cited sources (2022 share — closed by [A4]), 1 CONTRADICTED (the pre-existing pre-2022 sentinel). Anchor audit: 49 added #page= references checked, 39 correct, 10 wrong.

Validation Summary

Check Result
Regulatory Accuracy 4 issues (1 critical, 3 should-address); 2 escalated mismatches rejected on verification
Reference Quality 8 issues (1 critical cluster of 10 wrong anchors, 5 should-address, 2 suggestions); all 15 URLs resolve
Code Patterns 5 issues; 8 of 10 audit categories PASS, no hard-coded values, no reinvented variables
Formatting (params & vars) 2 issues (both YAML comments; all metadata fields complete and correct)
Test Coverage 2 critical + 13 gaps; 0 zero-coverage formula variables
PDF Value Audit 5 mismatches / 53 confirmed
CI Status Passing (run 30927284280 — changelog check and all Full Suite baseline/contrib shards)

Review Severity: REQUEST_CHANGES

This is a well-built implementation and much of it verified clean: all three § 2-106 prongs are correctly nested, the § 2-105 partial-benefit formula is exact, every 2022–2026 annual value matches an OESC publication to the dollar, no legal value is hard-coded, no variable is reinvented, every formula-bearing variable has tests, and CI is green. Four of the five reported "value mismatches" that reached verification were rejected on the evidence, including both of the two that would have been most damaging.

The blocking item is [C1]: § 2-207(A)(2)'s multiplicand is the capped taxable figure where the statute says bare "wages", which flips ok_ui_monetarily_eligible from False to True and pays $6,112 to a claimant the statute denies — verified verbatim at 600 DPI, traced through a fully live code path, and reproduced by running the model. [C2] leaves the entire 2022 vintage and three § 2-106 values citing pages that carry no such text, and [C3]/[C4] mean the suite cannot falsify five published dollar values or two of the five claimed verified_years.

Next Steps

To auto-fix issues: run the fix-pr workflow for this PR.

…on citations

Correct the base_period_wages_share comment so 40% maps to factor (e)
and 47.5% to (b) (was 'd'/'a'); the 0.4/0.475 values are unchanged.
Add section labels (§1-201/§1-218/§2-207, §1-223) to the previously
bare os40.pdf page anchors on the two base-period wage variables.
Documentation only, no value or logic change — OK suite 328/328 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DTrim99

DTrim99 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Fixes Applied — remaining review items

Following up on the earlier fix round (commit 68139b5), which resolved all 5 criticals, 8 of 9 should-address, and 4 of 5 suggestions. Re-checked every review item against the current tree; only two documentation-grade items remained open, both now fixed with no value or logic change.

Fixed

  • Conditional-factor legend (mba/base_period_wages_share.yaml) — the era comment mislabeled the factor letters ("condition 'd' (40%)" / "'a' (47.5%)") against the legend, which actually maps 40% → factor (e) and 47.5% → factor (b). Corrected the comment to "(e) (40%)" / "(b) (47.5%)". The 0.4 / 0.475 values are unchanged (this was the C1 fix).
  • Bare citation anchors (ok_ui_base_period_total_wages.py, ok_ui_base_period_taxable_wages.py) — the previously unlabeled os40.pdf#page=… references now carry section labels (§1-201(4)/§1-218/§2-207 for total wages; §1-201(48)/§1-223 for taxable wages). All page anchors and citations retained.

Verification

  • OK UI suite: 328/328 pass.
  • Scope: 3 files, +6/−1 — a comment correction and two reference labels only. No parameters, formulas, or tests touched.

Everything from the program review is now addressed.

🤖 Generated with Claude Code

…x citations

- C1 (behavioral): the §2-207(A)(2) high-quarter eligibility multiplier read
  capped TAXABLE wages, wrongly passing an ineligible claimant. Add a
  ok_ui_high_quarter_total_wages input and apply the 1.5x prong to total wages
  per the statute; remove the false Test-B-rescue docstring. Add a divergence
  test that inverts if reverted, plus MBA-binding and 2023/2026 end-to-end cases.
- C2: correct the os40.pdf #page anchors across the MBA/WBA/wage-base refs and
  the base-period wage variables (values were already right).
- A5-A10: taxable_wage_base §1-223 vintage note; drop the stale handbook
  Rev-05-2025 label and the 'OESC Board determines' phrasing; correct max_weeks'
  §1-231 attribution (Laws 2022 c.287) and reframe the escalator as operative-
  but-non-binding; disclose the employer payroll-tax effect in the changelog;
  guard weeks_unemployed with max_(...,0); reference cleanups.

No parameter value changed. OK UI suite 335/335 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DTrim99

DTrim99 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Fixes applied from @hua7450's review

Incorporated the review above (pushed just now, OK UI suite 335/335 pass). Unlike the NY PR's C1, this C1 had one correct answer per statute, so it's fixed rather than deferred.

C1 — the real output bug (fixed)

The §2-207(A)(2) high-quarter eligibility prong was reading capped taxable high-quarter wages, but the statute uses total "wages" — which, as you showed, let an ineligible claimant through (~$6,112). Added an ok_ui_high_quarter_total_wages input and applied the 1.5× multiplier to total wages; removed the false Test-B-rescue docstring. The WBR path keeps the taxable measure where that's correct. Added a divergence test (taxable capped below total, so the eligibility result inverts if C1 is reverted) as the regression guard, plus an MBA-binding case and 2023/2026 end-to-end cases so the previously-undemonstrated bindings are pinned.

Citations / comments (values were already correct — no parameter value changed)

  • C2 — corrected the os40.pdf#page= anchors across the MBA/WBA/wage-base params and the base-period wage variables.
  • A5 — added the taxable_wage_base vintage note (pre-2025 §1-223 ladder vs the post-Laws-2025 ladder, conditional factors D/A) so a reader following the citation doesn't conclude the file is wrong.
  • A6 — dropped the stale "Rev. 05-2025" handbook label (live is 06-3-2026) and the "OESC Board determines" phrasing; fixed the truncated County title.
  • A7 — corrected the max_weeks §1-231 attribution to Laws 2022 c.287 / HB 1933 and reframed the escalator as operative-but-non-binding (13-week averages fall below the first increment); the 26/16 values are unchanged.
  • A8 — disclosed the employer payroll-tax effect of the wage-base dating in the changelog.
  • A9 — guarded weeks_unemployed with max_(…, 0); plus the §2-102 reference add, the year-period caveat move, and the §1-201(48)/§1-202.2 mis-cite cleanup.

I left programs.yaml status: complete (family-consistent with NJ/PA, and you'd rated it suggestion-level), and left everything in your "Investigated and cleared" / "Pre-existing" lists untouched.

🤖 Generated with Claude Code

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.

OK unemployment insurance

3 participants