---
description: Author and run an asserted screenshot walkthrough of a Tawa service — for a feature you just built (one-off, `tawa walkthrough`) or as the service's standing tour (`spec.walkthrough`). Use when asked to "show what shipped", "screenshot the new feature", "make a walkthrough", "document this PR with screenshots", "prove the page works in prod", or to add/repair `spec.walkthrough` in a catalog.
---

# Tawa Walkthrough — show what shipped, with proof

A walkthrough is a short flow through a UI where every step **asserts** something on the page and
then screenshots it. The output is a public page with the images, the assertions, and the commit.
Read the `tawa-walkthroughs` rule for the spec format; this command is the procedure.

**Argument:** what to capture — a feature, a PR/issue number, a page, or "the standing tour".

## Step 0 — Decide which kind

- A feature, fix, or PR → **one-off**. Write a spec file, run `tawa walkthrough`, share the link.
  Do **not** touch `catalog-info.yaml`.
- "The tour", "on every deploy", or editing an existing `spec.walkthrough` → **catalog**. Requires
  `insureco.io/catalog-version: "0.7.0"`; it then runs on every deploy of that service.

If unclear, default to one-off and say so.

## Step 1 — Find the truth in the source (never from memory)

For each screen you intend to capture, open the code and write down:

1. **The route.** Next.js: the folder under `app/` (mind dynamic segments — `/orders/failed` can
   match `/orders/[id]`). Express/React Router: the route table. Confirm the path exists.
2. **One structural selector + its exact text** — usually the page's `<h1>`. Open the page
   component and copy the literal string. If the page has no `<h1>`, pick another stable landmark.
3. **One substantive selector** for any page that shows records — a table row, a card, a total —
   and a text you know will be there (a seeded record, a column value). This is what stops a green
   run on an empty page.
4. **Anything sensitive** on screen (names, emails, account numbers) → selectors for `redact`.
5. Whether the screen needs login, and whether it is behind an admin-only check (the platform
   `staff` profile has an org but **no roles** — admin-only screens will 403).

## Step 2 — Write the spec

```yaml
title: "<what this shows, in the reader's words>"
auth: staff            # only if the screens need login
steps:
  - path: /exact/route
    expect:
      h1: "Exact Heading"
      "table tbody tr": "Known record text"
    note: "One or two sentences: what changed and why it matters (#issue)."
    redact: ["td.email"]
```

Keep it to the 2–6 steps that tell the story. Captions are for a human reader: say what is new,
not what the page is. Use `act` for a click that reveals the feature, `shot: { selector }` to frame
one component, `annotate` to point at the new thing.

One-off: save as `walkthrough-<topic>.yaml` (a scratch path is fine; commit it only if the team
wants it kept). Catalog: put the same object under `spec.walkthrough`.

## Step 3 — Run it

```bash
# one-off, against the live service
tawa walkthrough walkthrough-<topic>.yaml --prod -s <service> --label <pr-or-topic>

# catalog block without deploying (uses spec.walkthrough from ./catalog-info.yaml)
tawa walkthrough --prod

# against a local dev server, live-reloading while you edit captions (run in the iec-test repo)
npx tsx src/cli.ts walkthrough --catalog <path>/catalog-info.yaml --target http://localhost:3000 --local --watch
```

Exit code 0 means every step passed. `--json` prints the result for scripting; `--open` opens the page.

## Step 4 — Read failures as information

A red step is the tool working. Each prints the selector, what was expected, and what was actually
there:

| Output | Meaning | Do |
|--------|---------|----|
| `element not found` | Wrong selector, wrong route, or not logged in | Re-check Step 1; add `auth`; look for a redirect to login |
| `"X" does not contain "Y"` | Right element, wrong text — often the **wrong page** rendered fine | Compare the actual text: is this a different route than you think? |
| `none of the N elements it matches contains "Y"` | The selector matches several elements and none has the text | Is the record there? One match with the text is enough to pass |
| `matches N elements, none of them visible` | The element exists and is hidden (`head > title` always is) | Assert on something a person can see |
| `could not be checked: …` | The selector could not be run | Fix the selector's syntax |
| Step passes but the image is empty | You asserted chrome only | Add a record-bearing `expect` entry |
| `navigation … failed` | Path 404s or the service is down | Fix the path / check `tawa status` |
| 403 page in the screenshot | Screen needs a role the `staff` token lacks | Capture a non-admin screen, or run locally with your own session |
| `[warn] redact "…" matched no elements` | Your redaction did nothing — PII may be visible | Fix the selector **before sharing the link** |
| `[warn] annotation "…" dropped` | Anchor selector is wrong | Fix it or remove the marker |

Fix the spec, never the assertion's strictness. Do not delete an `expect` to get green.

## Step 5 — Hand it over

Report the `Walkthrough: <url>` line, the pass count, and anything redacted or skipped. For a PR or
issue, post the link as a comment with one line of context. If the run failed, say which step and
what the page actually showed — do not share a link to a bundle as "the feature working" when a
step on it is a failure card.

For a catalog change: open a PR with the `catalog-info.yaml` edit, note that it will run on every
deploy, and that a failed step blocks sandbox/UAT deploys but is non-blocking in prod.

## Guardrails

- Never put a token, password, or cookie in a spec or a command. `auth` is a profile name.
- Never invent a route, heading, or selector. If you could not confirm it in the source, say so.
- Bundles are public to anyone with the URL. Redact first; prefer seeded data over a real tenant.
- One-off specs stay out of the catalog.
