plugins/lisa-rails-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.
Security scan pending...
This skill is queued for security scanning. Results will appear when the scan completes.
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