The Onboarding Smoke

One end-to-end click-through — the main scenario, from a buyer's chair — run at the end of every build.

HomeZero · 2026-06-23 · live target www.homezero.md · authored by walking the real app · market under test: North Fork Valley (Paonia) · run owner: Claude, via Claude-in-Chrome

What this is. A single happy-path test that proves the product still works the way a real buyer meets it: open the site, onboard into the North Fork Valley, watch the team read the market back to you, land on a board full of real homes, and zero in on one. Not a unit test (we have 74 of those) and not the everything-at-once stress test — the spine. If this run is green, the funnel is alive. If any UI assertion fails, a buyer hit the same wall.

How it's run. At the end of every build I click through it in the browser (~2 min) and report green/red. Each step is UI (what the buyer sees) or DATA (the Convex/Turso row behind the glass — so we know the cards are real public record, not rendered fiction). The STOP step is the account boundary — automation never creates the account; the signed-in half uses the dev identity instead.

The two-half shape — and why

Act 1 · Anonymous onboarding — the funnel a stranger walks

1 Landing UI

Do Go to https://www.homezero.md.

✓ Hero reads "Search like you do today. Go deeper than anyone ever has." and a "Get started — free" CTA is present. Nav has How it works / The ladder / Pricing / Log in.

2 Enter the wizard UI

Do Click "Get started — free" → lands /start → click "Get started" on the intro card.

✓ /start shows the intro card "HomeZero keeps you on top of every home you're watching." with a sample briefing card, then Step 1 opens.

3 Step 1 — "Where are you looking?" → the reflection UI DATA

Do Type name Pete; type place Paonia; pick budget $500–750k; click Next.

★ KEYSTONE. After the place is typed, the inline reflection appears: "We read North Fork Valley." + the Gunnison/organic-heart blurb + a live count "43 homes on the market here, read through 34 layers of public record" + ≥1 sample card.
A wrong town, a zero count, or no reflection = the resolver or the market data broke. Stop and triage.
DATA The count matches Convex: listings:list filtered to the North Fork Valley market returns ~that many active homes.

4 Step 2 — "What matters to you" UI

Do Select "Good value or underpriced"; click Next.

✓ The chip checks (green ✓) and expands inline to an elaboration field ("Flag homes that look underpriced for what they are."). The list of yearnings is intact (Water rights, Room for animals, Single-level, Garage/shop, Stretch budget, Just exploring, Share anything else).

5 Step 3 — the Finish button STOP

Do Read the screen. Do not click the CTA.

✓ Step 3 reads "Want your advisor to text you?" with an optional WhatsApp field and a terminal CTA labelled "Create account & build my team."
Boundary. Clicking it creates a real account + births the advisor and market agent. The smoke ends Act 1 here. To exercise what's past Finish, switch to the dev identity (Act 2) — never real signup.

Act 2 · Signed in — what the buyer gets for finishing

6 The launchpad UI

Do (dev identity active) Go to /home.

✓ "Welcome back, <name>." + a "Your board" panel reading "N homes on your board" with a CARRY/footing preview of real addresses, and the roster both ONLINE: "Your advisor — ONLINE" and "… market agent — ONLINE". An "Open your board →" button.
Watch: the roster currently labels the market agent "Delta County market agent" while the reflection says "North Fork Valley." Same agent, two names — note it; not a fail.

7 The board UI DATA

Do Click "Open your board →" (or go to /board).

✓ Kanban renders four columns — INBOX · WORTH SEEING · SCHEDULED · SEEN — with counts. ≥1 real NFV card carrying: a $ price, a street address (e.g. 57 Cedar Drive, 41014 Beaver Trail Lane), a market blurb, a score (e.g. 66 "solid, with a catch"), an advisor question with answer chips, and 👍/👎 + "Worth seeing →"/"Pass". A "FOOTING $…" affordability slider sits on top ("every home re-checks live").
DATA Each visible card's address + price matches a listings row in Convex (the sweep wrote it; the board reads it live via useQuery).

8 Zero in — the interaction loop UI

Do On an INBOX card, click "Worth seeing →" (or 👍).

✓ The card moves to WORTH SEEING and both column counts update. The board is a live, co-curated thread — the move persists on reload.

Act 3 · The bloom — lazy briefing (wire-up pending)

9 Briefing authors on a zero DATA

Do Zero a home that has no full briefing yet (a resting card from the sweep), then wait.

✓ Within a few minutes the card upgrades from resting ("Not yet briefed") to a full briefing — a real verdict (category + headline + confidence) and a deepDive that has started reading layers — authored by the market agent, surfaced by the advisor.
No-clobber invariant: the ~46 NFV homes that already had Briefs keep them. A sweep or a zero must never blank an existing verdict/deepDive. (Backed by patchListingFactsBatch — facts-only — + upsert-only-for-new in publish.ts.)
Not live yet. The star→ringMarket→drain hop isn't wired into the live savedListings insert. Until it is, trigger the drain by hand (POST {kind:'drain'} to the market agent) and watch the same bloom. Wiring this is the step that makes Act 3 click-only.

What green looks like

Known gaps this test surfaces

GapEffect on the runFix
Account boundary at FinishAct 1 can't complete signup in automationUse dev identity for Act 2; keep Act 1 anonymous (by design)
star→ring not wired into live savedListingsAct 3 bloom is manual (hand-POST the drain)Wire ringMarket on the saved-listing insert → Act 3 becomes click-only
Market agent named "Delta County" on the rosterCosmetic mismatch vs "North Fork Valley"Reconcile the label (market = NFV within Delta County)

Later: codify for CI

This doc is the script I run by hand each build. When it stabilises, the same steps drop into a Playwright spec (homezero/e2e/onboarding-smoke.spec.ts) — Act 1 headless against a preview deploy, Act 2 behind the dev-identity cookie, Act 3 asserting the Convex bloom — so it can also run in CI without a human in the chair. Until then, the human/agent click-through is the gate.