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.
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.
Fast reset (recommended)
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
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.
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
/lookupview (a harness-built case carries no portal credential).
| Journey | Tier | Start here |
|---|---|---|
Fully manual |
Applicant files SNAP at |
|
Fully manual |
Applicant files; worker approves + certifies, records winnings → denial. |
|
Fully manual |
Applicant files; worker approves + certifies, records a material increase → recert nudge. |
|
Fully manual |
Applicant files (size-3); worker records the move + higher rent → benefit rises. |
|
Fully manual |
Applicant files (2 children, no ELE opt-in); worker approves (defers) → records ELE consent → re-determines. |
|
Worker-driven |
Applicant files (size-3); worker files two hearings around a shelter change. |
|
Worker-driven |
Applicant files SNAP; worker files TANF + records a shared change → both deny. |
|
Worker-driven |
Applicant files SNAP (2 children); worker files + closes TANF for earnings → TSNAP freeze. |
|
Worker-driven |
Applicant files; worker enrolls + issues continued benefits, files a timely appeal, records Upheld. |
|
Worker-driven |
Applicant files SNAP; worker approves, backdates a certification to lapse it, reapplies + recertifies forward. Applicant signs back in to view home. |
|
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 refreshover a coldstartif the stack was previously up). -
Do not
git pushduring the demo (see the note at the top) — re-snapshotafterward if you do.