# Smoke Test — Workflow UI + gateway

You are running the **workflow UI** slice of a release smoke test. Prove that the
gateway a fresh `init` ships can boot, serve a workflow's browser UI bundle, and
route its root — the surface a real user sees when they run `smithers ui`. Run
every command yourself with your shell and judge from real HTTP responses.

## Our standard: zero defects, fixed by a patch release

Smithers holds itself to a high bar. **We do not accept failures.** Any issue you
find is a `fail` with exact evidence, even a minor one, a doc inconsistency, an
edge case, an ugly error, or something unrelated to this release. We ship a patch
release to fix it right away. Never downgrade a finding to "pre-existing",
"acceptable", "cosmetic", "expected", or "out of scope". The ONLY legitimate
`skipped` is a real limitation of this test machine (no agent installed, no model
credentials); a product, CLI, doc, or behavior problem is always a `fail`.

## Version under test

The exact version is: {props.version}

Pin it on EVERY `bunx` invocation: run `bunx smithers-orchestrator@VERSION SUBCOMMAND`, substituting VERSION with the version above.

## Setup — a fresh folder

1. Clear the bunx cache (`bun pm cache rm`, then remove any
   `bunx-*smithers-orchestrator*` dir from `$TMPDIR`).
2. `SMOKE_DIR=$(mktemp -d)/smoke-ui && mkdir -p "$SMOKE_DIR" && cd "$SMOKE_DIR"`.
3. Run `init` (pinned to the version above) and confirm `.smithers/gateway.ts`
   and `.smithers/ui/` exist (the gateway + UI sources).

## Boot the gateway and check it serves

Pick a free port (e.g. 7391). Boot the gateway the init pack ships and keep it in
the background, then poll `/health` until ready:

```bash
PORT=7391 HOST=127.0.0.1 bun run .smithers/gateway.ts &
GW=$!
for i in $(seq 1 120); do curl -fsS "http://127.0.0.1:7391/health" && break; sleep 0.5; done
```

Then record `pass | fail | skipped` with the exact curl + status line / body for:

1. **`ui.health`** — `GET /health` returns ok (HTTP 200).
2. **`ui.root-routing`** — `GET /` (use `curl -i`) returns HTTP **302** with a
   `Location` header to the console UI, OR HTTP **200** `text/html` landing page.
   It must NOT return a bare `404` NOT_FOUND JSON (this is the 0.25.2
   gateway-root-routing fix — a regression here is a `fail`).
3. **`ui.workflow-bundle`** — `GET /workflows/plan` (a workflow that ships a UI)
   returns HTTP 200 `text/html` that bundles the React app (an HTML document with
   a root mount element and a script tag — i.e. the bundle built and served). A
   500 / bundle build error is a `fail`. Try another keyed UI (e.g.
   `/workflows/vcs`, `/workflows/grill-me`) to confirm it is not plan-specific.
4. **`ui.boot-config`** — fetching `GET /workflows/plan?runId=does-not-exist`
   should still serve the bundle (the UI handles the empty-run state
   client-side), not 500.

Always kill the gateway at the end: `kill "$GW" 2>/dev/null`.

If `bun` is unavailable or the gateway cannot bind for an environmental reason
(not a Smithers bug), mark the affected checks `skipped` with the reason. A
gateway that boots but 500s on a UI route, or 404s on `/`, is a `fail`.

## Optional — the `ui` command

`ui --help` (pinned to the version above) should describe opening a workflow UI
for a run. Record `ui.command-exists` (`pass` / `fail`).

## Output

Return JSON matching the schema below. `passed` is `true` only if the gateway
boots, `/health` is ok, `/` routes (302 or landing, not 404 JSON), and at least
one workflow UI bundle serves real HTML without a 500. `findings`: one per check,
dotted `area` (e.g. `ui.root-routing`), `status`, `evidence` (the curl + the
status line / key body). `reproSteps` for any failure.

Required output shape (an example of the JSON to return):

{props.schema}
