Usability Review
A usability review asks whether the user got the job done and where the experience got in the way. Every finding is a claim code verified: a model never decides on its own that something is a problem, and never writes the finding's text. It is advisory — a finding never sets a non-zero exit or gates a run.
usability strategy
(--strategy usability), matching the CLI. "UX review" is the same feature — you may
see it used informally elsewhere on this site — but the canonical name to search and script
against is usability.
Two ways to run it
Live, as an exploration strategy against a running app:
jevitate explore --url http://localhost:3000 \
--strategy usability --goal "check out with a saved card" \
--app-class consumer --real
# optional: independent checks decide whether the job was done, as on a goal run
jevitate explore --url http://localhost:3000 --strategy usability \
--goal "check out with a saved card" --app-class consumer \
--success urlIncludes:/order/confirmed --real
# opt in to the fail-safe destructive-control probe (prefer staging), with product facts
jevitate explore --url https://staging.example.com/settings --strategy usability \
--goal "manage team members" --app-class admin \
--product .jevitate/product.json --probe-guards --real Offline, over a Recording you already captured (jevitate record or a goal run's output):
jevitate ux ./checkout.recording.json --app-class consumer --real
# optional persona + the job the flow pursues, for sharper relevance
jevitate ux ./checkout.recording.json --app-class admin \
--persona "first-time buyer" --job "check out with a saved card" --real
The offline review reads the live run's evidence sidecar (<stem>.evidence.json)
when it is there, so it reproduces the live run's findings.
How a finding is made
- A claim starts from what the run observed: a guard probe, your product facts, or friction the run hit (a retry, a long wait, a dead end, an error, a backtrack, an abandoned form, an unfinished job).
- Jev categorizes friction: a claim type from a closed list (or
not-a-problem) and the control it is about, picked from the page's real controls. - Code verifies every claim. One that fails is dropped and counted in
report.claims, never shown. - Duplicates merge by claim type, page and control.
- Two yes/no questions grade it: "Do we need this?" and "Do we need this to ship this feature?". Code maps the answers to
actionable,relevant-minor,genericorwrong. - The text comes from a template over the verified fields (control, page, blocked request, quoted text, expected fact).
--polish(opt-in) rewrites the recommendation with one generation call.
Claim types: destructive-unguarded, fact-conflict,
next-step-unclear, no-feedback, blocked-action and
error-unrecoverable. Each is cited under the heuristic it violates
(Report Schema). On a live run each verified finding gets a
cropped, secret-masked screenshot with the cited control boxed.
Guard probes: --probe-guards
Clicking destructive controls is off by default. Without the flag nothing is
clicked, and a "this deletes without asking" claim is reported unverifiable (in
coverage.skipped), never a finding. With it, after the run each destructive control
("Delete", "Remove", "Revoke"…) is clicked once on a fresh page to see whether a confirm dialog,
page dialog or confirmation page comes first. The probe is fail-safe:
- It aborts every write and every destructive-looking request, whatever the method (URL, query, RPC name or body).
- It refuses pages with an open WebSocket or EventSource, or a service worker.
- It never answers a dialog, and never clicks a control matching
--deny.
A server that destroys data on a harmless-looking GET can't be recognized: probe a staging environment.
Product facts: .jevitate/product.json
State what the product is, and the review checks the screens against it in code: a wrong price or
trial is a fact-conflict, a missing or disabled intended next step is
next-step-unclear. Pass --product <file> or keep it at
.jevitate/product.json.
{
"version": 1,
"currency": "USD",
"plans": [
{ "name": "Starter", "prices": [{ "amount": 29, "interval": "month" }], "trialDays": 14 },
{ "name": "Pro", "prices": [{ "amount": 149, "interval": "month" }], "trialDays": 14 }
],
"journeys": [{ "name": "Set up a workspace", "routes": ["/onboarding", "/projects/:id"] }],
"pages": [{ "route": "/onboarding", "nextStep": "Create project" }]
}
The file is validated strictly; every problem is listed in one refusal
(E_UX_PRODUCT_INPUT, exit 64) before a browser opens. Without it, the report says that
prices and next steps went unchecked.
What --app-class actually controls
--app-class is required for both paths. It is a calibration signal:
it tells Jev what kind of app this is (consumer, admin,
internal, etc.) so it judges friction sensibly for that context.
--app-class does not select or imply a
user persona; it only calibrates the review for the kind of app. The live review is
calibrated against a default persona, "first-time user". The offline path
(jevitate ux <recording>) accepts an explicit usability --persona.
Don't confuse it with explore --persona name=storageState, which runs the same mission
once per signed-in session and diffs them (see Flags Reference).
Viewport and device
By default every run, the usability review included, uses Playwright's default viewport:
1280×720, desktop, no touch. --viewport <W>x<H> (e.g.
--viewport 375x812) or --device "<name>" (e.g.
--device "iPhone 13") change it; they are mutually exclusive. Below 1024px the
horizontal-overflow and vertical-clipping checks run too (text cut off by a fixed-height box or
above the page top): pure DOM geometry, reported as a signal finding in the usability review.
--check-overflow turns them on at any width; --ignore-overflow
<selector> excludes intentional cases.
--show), and the report says so in calibrationCaveats.
Expect far fewer findings than in 0.2.0: a finding exists only when code verified its claim.
Going deeper
- Report Schema —
claims,grade,coverage,suppressed, and whatcleandoes and doesn't guarantee. - Flags Reference — every flag per strategy.
- MCP & CLI — full command syntax for both the live and offline paths.
- Testing Modes — how usability fits among the other five
jevitate exploremodes.
Coming soon: Journeeze adds what people think of the same journeys: likes, dislikes and what they don't understand, clustered into GitHub issues. Get early access.