plugins/lisa-expo-copilot/skills/exploratory-qa/SKILL.md
First-time-user exploratory QA walkthrough for web apps that FEEDS THE LIFECYCLE. Use when asked to experience an app the way a brand-new human user would — landing cold on the home page and clicking through to find anything confusing, broken, or hard to understand (unclear purpose or audience, human-facing jargon, contextless extracted data, machine-style labels, raw dates/enums, sparse data with no explanation, wrong control semantics, slow or unclear loads, late meaningful content, cramped or cut-off UI, inconsistent/non-standard UX, awkward scroll behavior, unclear affordances, dead-end flows that strand a user — e.g. a login page with no way to register or recover a password, or a primary action that drops the user into an incomplete/unsatisfiable state with no way to finish) across all breakpoints. Instead of writing a report file, it files every finding as a tracked work item via lisa:tracker-write (bugs and usability/UX issues). A `ready` parameter controls whether those tickets are created build-ready (auto-picked-up by lisa:intake) or left in the backlog for human triage (default). For gaps in the automated Playwright test suite, use the e2e-coverage-gaps skill instead.
npx skillsauth add codyswanngt/lisa exploratory-qaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Experience the app the way a brand-new human user would: land cold on the home page with no prior knowledge, then click through and actually try to use it — just like a real person. The goal is to surface anything confusing, broken, or hard to understand, and to do so at every breakpoint.
This is a usability/experience pass, not a test-coverage audit. It does not look at the Playwright
suite or hunt for coverage gaps — for that, use the e2e-coverage-gaps skill. Here, every finding is
filed as a tracked work item so it enters the Lisa lifecycle — no static report file.
target-url | env (first positional) — what to explore.ready=true|false — the build-ready state for the tickets this pass creates.
ready=true → created build-ready, so lisa:intake / the build-intake scanner auto-picks them up.ready=false (default) → created in the backlog (not build-ready) for a human to review and
promote into the queue.ready flag
(default false).tracker from
.lisa.config.json (local overrides global). If it is unset, stop and report that the tracker must
be configured (via /lisa:setup:jira / :github / :linear) before exploratory QA can file
findings — do not silently fall back to a report file.Click through the visible paths and actually attempt real tasks — a first-time user explores, makes mistakes, and tries the obvious thing. Cover at least these dimensions unless the user narrows scope:
snake_case, null/undefined, untranslated i18n keys), admin/database terms such as
"metadata", "rows", "bucket", "record", "entity", or "loaded rows", implementation identifiers such
as slugs, unexplained domain jargon, unclear button/menu names, and icons with no discernible
meaning. Flag all-caps enum/source labels, raw timestamps, and typo-like machine strings. If a
heading, label, or field would make a non-technical user ask "what does that mean?", file a
usability/clarity ticket with plainer wording.Money Mention, Entity, Record) paired with values but no sentence,
source, category, or explanation of why the value matters. If a user cannot tell what a number,
fact, or field refers to without rereading the raw source, file a usability/clarity ticket to hide it
from the default UI or add context such as excerpts, labels, grouping, or provenance.Bug; otherwise file a usability Improvement.Bug; when it eventually
works but the path is confusing or roundabout, file a usability Improvement.Loading... / Connecting... with no progress, anything that feels slow or janky. Flag pages
where the browser reports loaded / complete but meaningful content arrives much later, or where
the visible shell appears quickly while the real task content remains missing. Capture user-perceived
timings: shell visible, first meaningful content, and stable/complete content. If the delay is
noticeable, file a usability/performance ticket even if the eventual content is correct.A screenshot glance misses controls clipped by a few pixels or pushed just past a container edge. At every width, in addition to looking, take DOM measurements via the browser automation tool (Playwright, Chrome MCP, etc.) and treat any of these as a finding:
document.documentElement.scrollWidth > clientWidth, or a
horizontal scrollbar on a container that should not scroll → accidental horizontal overflow.getBoundingClientRect() against the viewport and against each ancestor
that has overflow: hidden | clip | auto | scroll. If any edge of the control falls outside those
bounds, it is partially or fully clipped / unreachable — even when the page looks fine in a thumbnail.
This is exactly the case that gets missed: a submit/apply button whose right edge is cut off by its
filter card.scrollWidth > clientWidth (or that renders an
ellipsis) where the hidden text carries meaning — e.g. a select showing "Any CRD state" jammed into
its chevron, a label cut mid-word.Record which width(s) trigger each, the offending element, and a screenshot. A primary or
interactive control that is clipped, offscreen, or unreachable is a Bug, not merely an
Improvement — a user literally cannot see or click all of it.
document.readyState, first meaningful
route-specific content, and visually stable/full route content.A real first-time user creates, edits, and deletes things — exercise those flows when the environment is safe.
qa- or codex-.This skill does not write a report file. Every finding becomes a leaf work item created via
lisa:tracker-write (the vendor-neutral writer — it dispatches to the configured tracker and runs the
validation gate; never call a vendor *-write-* skill directly). Map each finding to a type:
| Finding | issue_type | build_ready |
|---------|--------------|---------------|
| User-visible bug (broken behavior) | Bug | the ready flag (default false) |
| Usability / UX / clarity issue | Improvement | the ready flag (default false) |
A control that is clipped, offscreen, or otherwise unreachable (per §5) counts as broken behavior
→ file it as a Bug, not an Improvement. Pure crowding/clarity with the control still fully usable
is an Improvement.
Each finding is a flat leaf (no children), so build_ready applies directly — pass it explicitly on
every create. Each ticket MUST be a complete spec (the validator rejects thin tickets):
Re-running a pass must not refile the same finding. Before creating a ticket, search the tracker for an
open ticket carrying a stable marker [lisa-exploratory-qa] <finding-key> in its body (the
<finding-key> is a stable slug of surface + symptom, e.g. settings-modal/horizontal-overflow@tablet).
If one exists, reference/update it instead of creating a duplicate; only create when none exists.
Match by the marker, never by title (titles get edited). A closed prior ticket does not suppress a
new one — a recurrence after a fix is a genuine regression.
No report file. Emit a concise in-session summary:
ready vs triage/backlog).ready flag (default: backlog for human triage).e2e-coverage-gaps.tools
--- name: harper-realtime description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy. --- # Harper Realtime ## Overview Harper exposes live data through the same Resource model used for REST and
tools
--- name: harper-realtime description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy. --- # Harper Realtime ## Overview Harper exposes live data through the same Resource model used for REST and
tools
--- name: harper-realtime description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy. --- # Harper Realtime ## Overview Harper exposes live data through the same Resource model used for REST and
tools
--- name: harper-realtime description: This skill should be used when adding or troubleshooting Harper (HarperDB/Fabric) real-time behavior: MQTT topics, WebSocket resource subscriptions, resource publish/subscribe handlers, SSE-style streaming routes, and local subscriber verification. Pairs with harper-resources, harper-config-yaml, harper-schema-graphql, and harper-build-and-deploy. --- # Harper Realtime ## Overview Harper exposes live data through the same Resource model used for REST and