Journey: A retroactive income correction recomputes a SNAP overpayment
On this page
A SNAP household is approved; the system auto-enrolls it (#1014) and the settlement pass issues the current benefit month. A retroactive income correction then comes to light — the household was over-income as of its determination date. The caseworker recomputes the frozen determination snapshot against the corrected facts; the replay denies, so the benefits already paid are clawed back into an overpayment claim, and an overpayment notice is generated. The caseworker beats — authoring the correction and running the recompute — are followable click-by-click in the worker portal; enrollment and issuance are the system’s own production behavior, observed on the case.
Reproducibility tier: Harness. The aged precondition this journey needs — an
approved SNAP determination backdated ~3 months — is constructed by a
one-command harness bring-up (the paired
spec’s SnapCaseBuilder), not by hand and not through the applicant portal. For a
live demo, run the paired spec (or its harness) to build the aged case, then walk the
caseworker steps below against it.
This walkthrough is paired with the automated spec
tests/e2e/specs/journey-snap-overpayment-recompute.spec.ts, covering scenario
snap.integrity.claim-calculation-lookback. The screenshots below are captured by
that spec (Test 1). See Verifying the journey to run it.
Personas & credentials
| Persona | Credentials / identity | Role in the journey |
|---|---|---|
Applicant |
N/A for this journey. The aged case is built by the test harness — a
determination backdated ~3 months is not portal-fileable (there is no worker
"backdate-determination" action) — so no application is filed through |
The household exists only as harness-constructed facts (a single working-age adult, reported wages) — the case the system enrolls + pays and the journey then recoups from. |
Caseworker |
Worker portal, Keycloak login |
Observes the system’s auto-enrollment on the case, authors the retroactive income correction, and recomputes the overpayment. |
Bring-up & reset
cargo xtask dev start --profile full # full devstack (SNAP + applications + enrollment + notices)
cargo xtask seed --seed 42 # deterministic fixtures
Reset between runs with cargo xtask migrate rollback (and a fresh browser /
incognito window for the worker session). The
Demo Runbook owns the full bring-up + reset detail;
this page owns the click-by-click steps.
Concrete precondition
The paired spec’s harness builds exactly this aged case (all records backdated together to the determination date):
-
Household composition — a single working-age adult, head of household, no dependents (
headMember, date of birth 1985-06-15). -
Initial reported income — $600/month in wages. That clears the SNAP gross-income test, so the application determines Approved — the starting point for the enrollment and issuances.
-
Backdated determination — the household, application, and determination are dated as of the first of the month ~3 months ago (
asOf), so the paid months precede today. -
Enrollment + paid benefits — approval auto-enrolls the household (#1014) and the settlement pass issues + settles the current benefit month at the determination’s net monthly benefit. That settled issuance is exactly the paid row the claim sizes against: the recompute window is pinned to the current month at both ends (the determination’s
effective_dateis the decision day), so backdated months could never contribute. A mailing address is also seeded so the overpayment notice can resolve its postal recipient (the #1091 gate). -
Retroactive correction — $9,000/month in wages, effective as of the determination date. This is a construction extreme (well over any SNAP gross-income limit), so the corrected replay denies and the overpayment is positive.
-
Recompute inputs — correction-as-of = the determination date; claim basis = Agency error.
The walkthrough, step by step
| # | Screen | Action | Expected | Screenshot |
|---|---|---|---|---|
01 |
Caseworker |
Open the approved case ( |
The SNAP program shows Approved, and the SNAP enrollment section shows the auto-enrollment (#1014) with the current benefit month issued — no worker action; this is production behavior on approval. |
|
02 |
Caseworker |
Open the Income tab → + Add income, record the corrected (higher) wages effective ~3 months ago. |
The retroactive over-income fact is recorded, effective as of the determination date. |
|
03 |
Caseworker |
Determination → Actions → Recompute overpayment; enter the correction date + claim basis (Agency error). |
The snapshot replays against the corrected facts; the corrected verdict denies, sizing an overpayment over the paid month. |
|
04 |
Caseworker |
Open the Notices tab. |
The overpayment notice is listed (matched by its subject, not a bare count) — the human-visible consequence of the recompute (the claim opens in the SNAP ledger). |
|
Expected outcome / oracle
The recompute replays the frozen determination snapshot against the corrected
facts. Because the retroactive income is over the limit, the corrected verdict
denies, so the benefits the system already paid (the settled current-month
auto-issuance) are clawed back into an open overpayment claim in the SNAP ledger
(agency_error basis, positive amount), and an overpayment notice is generated on
the Notices tab.
The oracle is relational, never a literal policy dollar:
-
A claim opens with a positive amount (the construction extreme guarantees > 0) that equals the settled auto-issuance — the clawback is exactly what was paid.
-
Its overpayment notice surfaces on the Notices tab, matched by subject identity.
-
The replay is write-free — it mints no new determination.
-
The recompute is idempotent — re-running it returns the same claim (same amount, same id), never a second claim.
No policy dollar figure or threshold is asserted, so the journey holds under any jurisdiction’s values.
Honest scope
-
The aged case is a documented one-command harness bring-up. A determination backdated ~3 months with prior issuances the claim looks back on is neither hand-buildable nor portal-fileable (there is no worker "backdate-determination" action; the signed, snapshotted determination of ADR-002/028 is only reachable through the harness’s live apply→determine path). The paired spec constructs it; the caseworker beats after it are the human-followable part. A worker backdate-determination affordance (#999) would let this journey be filed at the portal front door and gain an applicant view — until then it is worker-only.
-
The applicant
/lookupview is N/A. The given-library case files no portal application, so it carries no ADR-026 reference + passcode — there is no applicant view-back to demo (honest scope, not a portal gap). -
Enrollment + issuance are the system’s own production path. Approval auto-enrolls the household (#1014) and the settlement pass issues + settles the current month; the journey waits for that instead of constructing it — a manual backdated enrollment cannot coexist with the auto-enrollment (#1130 one-live-enrollment), and the recompute window is pinned to the current month, so the auto-issuance is exactly the countable paid row.
-
Issued amounts equal the household’s net monthly benefit. The determination exposes only the household’s net benefit (not a gross maximum allotment), and the auto-enrollment issues that amount — the correct real-world issuance for a household with income.
-
The overpayment claim has no per-case worker screen. Its human-visible consequence is the overpayment notice on the Notices tab (the last step); the claim itself is verified programmatically in the paired spec.
Verifying the journey
cargo xtask e2e --devstack-profile full -- \
specs/journey-snap-overpayment-recompute.spec.ts --project journey
Test 1 builds the approved, backdated SNAP household through the real
apply→determine endpoints, waits for the system’s auto-enrollment to settle the
current benefit month, then drives the worker arc through the portal — authoring
the retroactive income correction and recomputing the overpayment — capturing the step screenshots
into test-results/e2e/walkthroughs/… for commit into
docs/modules/ROOT/assets/images/walkthroughs/…. The correctness oracle is
relational: the recompute opens an overpayment claim in the SNAP ledger with a
positive amount and generates an overpayment notice, while minting no new
determination (the replay is write-free) and returning the same claim on re-run
(idempotent) — no policy dollar figure is asserted, so it holds under any
jurisdiction’s values. (Tests 2–3 exercise the recompute endpoint directly for the
forward-effective rejection + the no-over-issuance case.)
See also
-
Demo Runbook (bring-up + reset + credentials)
-
Journey Walkthroughs (the pairing overview)
-
Scenario Inventory & Human-Fidelity E2E (epic &61) </content> </invoke>



