Journey: a TANF case closing for employment freezes SNAP into a transitional certification
On this page
A public-assistance household is on both SNAP and TANF with no earned income. The applicant files the SNAP application through the real portal front door; the caseworker runs the SNAP determination, files and approves TANF over the shared facts, then records the new earnings when the family gets a job — earnings that close the TANF case for an employment reason. Rather than let the SNAP benefit swing, the agency freezes the SNAP allotment at its pre-closure level for a five-month transitional certification and relieves the household of reporting (7 CFR 273.26-273.29 / PAMMS SNAP 3704). The caseworker reads the frozen transitional certification back on the SNAP Determination tab, and the applicant signs back in to view their home and letters.
Reproducibility tier: Worker-driven. The applicant files an identity-and-composition-only shell at the portal (the wizard captures who is in the household and which income categories apply — never dollar amounts). Every fact that drives the outcome — the new earnings, both determinations, the TANF closure — is recorded by the caseworker in the worker portal. For a live demo that means the story reproduces deterministically from the worker clicks; the only applicant-portal beats are the initial filing and the closing view-back.
This walkthrough is paired with the automated spec
tests/e2e/specs/journey-snap-transitional-benefits-on-tanf-closure.spec.ts,
covering scenario snap.certification.transitional-benefits-on-tanf-closure. The
screenshots below are captured by that spec. See Verifying the journey to run it.
Personas & credentials
| Persona | Credentials / identity | Role in the journey |
|---|---|---|
Applicant |
Files at the portal |
Files the SNAP application (identity + two dependent children, no amounts), then signs back in to view their home + letters. |
Caseworker |
Worker portal (canopy-web, :8080), Keycloak login |
Runs the SNAP determination, files + approves TANF, records the earnings, re-determines TANF (closing it), reads back the frozen cert. |
Bring-up & reset
cargo xtask dev start --profile full # full devstack (SNAP + TANF + applications + eligibility + portal + notices)
cargo xtask seed --seed 42 # deterministic fixtures
Reset between runs (so the applicant files a fresh case each time):
cargo xtask migrate rollback # roll the demo DBs back
# then re-seed, and use a fresh browser / incognito window for the applicant
The full demo procedure and the seeded applicant cast live in Applicant Portal Seed Credentials and the UAT Facilitator Guide.
Concrete precondition
The exact inputs the journey depends on:
-
Applicant filed at
/apply— head of household Tanya Brooks, DOB1985-06-15, no earned income at filing. -
Two dependent children on the application — Miles Brooks (DOB
2016-04-10) and Nora Brooks (DOB2019-08-22), each relationship child. The two dependent children are what make the household TANF-eligible (orchestrator-inferred deprivation) and set the SNAP household size that fixes the frozen allotment. -
Earnings the caseworker records — new Wages of $5,000 / month for the head, effective the day of the demo, recorded once through the Income tab. This is the "got a job" life-event that pushes the household over the TANF ceiling. It is a construction input, not an oracle — no dollar figure is asserted anywhere.
No address or expense facts are needed (this journey does not exercise those editors). The portal-filed case starts with zero income/expense facts by construction.
The walkthrough, step by step
| # | Screen | Action | Expected | Screenshot |
|---|---|---|---|---|
01 |
Applicant |
At |
The confirmation screen reveals the reference number ( |
|
02 |
Caseworker |
Open the portal-filed case ( |
SNAP is Approved at the maximum allotment (zero income) — the pre-closure level that will be frozen. |
|
03 |
Caseworker |
Open the top-bar Action ▾ dropdown → under File application, tick TANF and click File application. |
Redirects to the case’s TANF view — the household now has a pending TANF application. |
|
04 |
Caseworker |
Open Action ▾ → Run Determination on the TANF view. |
TANF is Approved over the shared household facts — the household is on TANF + SNAP. |
|
05 |
Caseworker |
Open the Income tab → the head of household’s + Add income → record the new Wages ($5,000 / month), submit. |
The earnings are recorded once in the shared fact store; the page returns to the Income section. |
|
06 |
Caseworker |
Re-run the TANF determination (Action ▾ → Run Determination on the TANF view). |
TANF flips to Denied for earned income — the case closes, triggering the transitional certification. |
|
07 |
Caseworker |
Return to the SNAP Determination tab ( |
A Transitional SNAP certification card shows the frozen allotment (= the pre-closure allotment), the five-month period, the closure reason, and that reporting is waived. |
|
08 |
Applicant |
Sign back in at |
Lands on the applicant home with the personalised greeting. |
|
09 |
Applicant |
Open the Letters page and click the latest letter. |
The Notice of Action (the SNAP approval) is listed and opens — the portal→worker→portal loop closes. |
|
Expected outcome / oracle
The relations the spec asserts (never a literal policy dollar or threshold):
-
A five-month transitional SNAP certification appears — polled, because the
tanf.case_closedsubscriber opens it asynchronously in canopy-snap’s own DB; its absence would mean the closure→TSNAP pipeline did not fire. -
The freeze holds: the frozen allotment equals the pre-closure SNAP allotment, and both are
> 0(the pre-closure allotment is read back — no dollar asserted). -
Reporting is waived (
reporting_required = false) and the closure reason is an employment trigger (one of employment / earned_income / increased_hours / new_employment) — pinning the closure as employment-driven. -
The window is exactly five whole months (
certification_end - certification_start). -
Every one of those values is displayed on the SNAP Determination tab (the
data-tsnap-*hooks match the polled cert). -
The applicant round-trip: signing back in lands on the home greeting, and at least one letter (the SNAP approval NOA) is present on the Letters page.
Honest scope
-
Closure is modelled as a denying re-determination. There is no dedicated "close TANF case" action — the platform emits
tanf.case_closedon any TANF denial, so the job that pushes income over the TANF ceiling and denies the re-determination is the closure that triggers the transitional certification. -
The applicant portal captures categories, not amounts. The wizard records who is in the household and which income categories apply, never dollar figures, so the portal-filed case starts with zero income/expense facts — the caseworker records every dollar the journey needs (this is why the tier is Worker-driven).
-
The pre-closure SNAP allotment is the max allotment here. The household starts at $0 earned income (living on the TANF grant), and the SNAP determination is computed without the TANF grant in its income stack (a construction simplification), so the frozen figure is the maximum allotment for the household size. The relation that matters — frozen = the pre-closure allotment — holds regardless; no dollar is asserted.
-
The removed-TANF-grant amount is not shown. It is not carried on the closure event, so the display omits it rather than showing a misleading zero.
-
The cert fields are a read-back, not enforced workflow. The five-month reevaluation-before-end and the reporting relief are shown as certification facts; the platform does not yet drive the end-of-period recertification as a workflow.
-
TANF deprivation is orchestrator-inferred (marked provisional), so the TANF leg exercises the demo-grade deprivation path; the income test that drives the closure is real.
-
The display is program-scope gated. The Transitional SNAP certification is SNAP data — a worker not in SNAP program scope does not see it.
Verifying the journey
cargo xtask e2e --devstack-profile full -- \
specs/journey-snap-transitional-benefits-on-tanf-closure.spec.ts --project journey
The spec files the SNAP application through the real /apply wizard (an applicant
context against :8090), runs the SNAP determination, files + approves TANF through
the worker Action ▾ actions, records the new earnings through the Income tab, and
re-runs the TANF determination to close the case — capturing the step screenshots
(step-NN-… worker, app-NN-… applicant) into test-results/walkthroughs/… for
commit into docs/modules/ROOT/assets/images/walkthroughs/…. The correctness oracle
polls the transitional certification and asserts the relational invariants: the
frozen allotment equals the pre-closure allotment (both > 0), reporting is waived,
the closure reason is an employment trigger, and the window is exactly five months —
then confirms every value is displayed on the SNAP Determination tab and that the
applicant can sign back in and read their letter.








