Demo Runbook: driving the SNAP journey walkthroughs live

On this page

How to stand up the devstack once and drive any published SNAP journey walkthrough on demand — side by side, applicant portal + caseworker portal — and how to reset cleanly between journeys. Pair this with the individual journey walkthroughs: this page owns bring-up
reset + credentials; each walkthrough owns its click-by-click steps.

IMPORTANT

Do not git push during a live demo. The pre-push battery reseeds the running devstack, which wipes the golden snapshot mid-session. If you must push, re-run cargo xtask migrate snapshot afterward.

One-time bring-up

cargo xtask dev start --profile full        # every service + the applicant portal (cross-program journeys need --profile full)
cargo xtask seed --seed 42 --households 50  # deterministic fixtures + the login-capable applicant cast
cargo xtask migrate snapshot                # OPTIONAL — only if you plan to use the full snapshot restore below
cargo xtask dev status                      # read the EPHEMERAL host ports (they change every bring-up — never hardcode)

cargo xtask dev status prints the worker portal + applicant portal URLs with their host-mapped ports. Open the worker URL for the caseworker and the canopy-portal URL for the applicant (two browser windows, side by side).

Reset between journeys

A reset is usually NOT required. Every journey files (or the harness builds) its own household, and each live /apply filing mints a fresh HH-… credential — so you can run journeys back-to-back without resetting. Reset only when you want to re-run the same journey or clear accumulated cases from the worker queue.

cargo xtask seed --seed 42 --reset          # TRUNCATE the seeded tables + reload the deterministic seed

This is the quickest, safest reset: --reset TRUNCATEs and reloads, which preserves the table structure, so the running services keep working — no service restart needed. It restores the seed cast (HH-ca570001…04) and clears the journey applications you filed. Then open a fresh browser context / incognito window so the applicant + worker start from clean sessions (the Redis session store + cookies are not touched by a DB reset).

Full restore from a snapshot (thorough)

If you took a cargo xtask migrate snapshot and want a byte-identical restore of every database:

cargo xtask migrate rollback                                          # pg_restore --clean per database
docker ps --format '{{.Names}}' | grep -E '^canopy-canopy-.*-1$' | xargs docker restart   # REQUIRED after rollback
IMPORTANT
migrate rollback uses pg_restore --clean, which drops and recreates each table. The running services hold pooled prepared statements that then reference the old tables, so the first request after a rollback fails with a 500 (cached plan must not change result type) until the services reconnect. You must restart the application services after a rollback (the docker restart line above; a plain container restart, ~30s, no rebuild). migrate rollback restores Postgres only — RabbitMQ, Redis, Garage, and Keycloak stay live, and the ephemeral ports are unchanged. Prefer the fast reset above unless you specifically need a full snapshot restore.

Cold, pristine start (rarely needed — e.g. a wedged stack)

cargo xtask dev clean --confirm
cargo xtask dev start --profile full
cargo xtask seed --seed 42
cargo xtask migrate snapshot                # optional: capture a golden snapshot to roll back to

Credentials

Caseworker (worker portal). Keycloak login jane.caseworker / password (see UAT Facilitator Guide for the full worker roster).

Applicant — live front door. When you file a fresh application through /apply, the portal shows an Application ID (HH-…) + a 12-digit passcode on submit (and again at the start screen). Write them down: they are how the applicant signs back in at /lookup to view /home and /letters. They are minted per run — there is no fixed value.

Applicant — pre-filed seed cast. If you want a case that already exists (rather than filing live), sign in with a cast member from Applicant Portal Seed Credentials (HH-ca570001…04 + their passcodes).

Per-journey index

Each journey’s reproducibility tier tells you how the case is built:

  • Fully manual — the applicant files the whole case live through /apply; the caseworker records every fact + acts; the applicant signs back in to view the outcome. The richest side-by-side demo.

  • Worker-driven — the applicant files the SNAP front door live and can view /home//letters, but the substantive mid-journey beats (appeals, filing a second program, decisions) are caseworker-only (no applicant self-service UI for them yet — honest scope).

  • Harness — the case cannot be hand-built live (it needs an aged determination / prior issuances). A one-command harness builds it; you demo the caseworker beats live. No applicant /lookup view (a harness-built case carries no portal credential).

Journey Tier Start here

Intake → determination → NOA

Fully manual

Applicant files SNAP at /apply; worker determines → NOA.

Lottery winnings → adverse action

Fully manual

Applicant files; worker approves + certifies, records winnings → denial.

Material income change → recert nudge

Fully manual

Applicant files; worker approves + certifies, records a material increase → recert nudge.

Address change → shelter cascade

Fully manual

Applicant files (size-3); worker records the move + higher rent → benefit rises.

ELE consent grants children Medicaid

Fully manual

Applicant files (2 children, no ELE opt-in); worker approves (defers) → records ELE consent → re-determines.

Change during a pending hearing

Worker-driven

Applicant files (size-3); worker files two hearings around a shelter change.

Cross-program report (TANF → SNAP)

Worker-driven

Applicant files SNAP; worker files TANF + records a shared change → both deny.

TANF closure → transitional SNAP

Worker-driven

Applicant files SNAP (2 children); worker files + closes TANF for earnings → TSNAP freeze.

Upheld hearing → overpayment

Worker-driven

Applicant files; worker enrolls + issues continued benefits, files a timely appeal, records Upheld.

Lapsed certification churns back

Worker-driven

Applicant files SNAP; worker approves, backdates a certification to lapse it, reapplies + recertifies forward. Applicant signs back in to view home.

Retroactive correction recomputes an overpayment

Harness

Harness builds an aged determination + prior issuances; worker records a retroactive correction + recomputes the claim.

Gotchas

  • Ephemeral ports — always read them from cargo xtask dev status; never hardcode :8080 / :8090.

  • Cross-program journeys REQUIRE --profile full — a snap-only stack has no TANF / Medicaid services, so the cross-program + ELE + TSNAP journeys will not run.

  • First login after a cold start — Keycloak has a ~30s JWKS debounce; if the first sign-in stalls, wait and retry (or prefer cargo xtask dev refresh over a cold start if the stack was previously up).

  • Do not git push during the demo (see the note at the top) — re-snapshot afterward if you do.

Edit this page · default