qa-only
The facts
Its description
Report browser/API/CLI/job/worker/webhook bugs. (gstack) Triggers: qa report only; just report bugs; test but dont fix
The description the agent reads to decide when to use it. Phrases the author says should start it.
When it starts
The agent gets only the name and description, so it picks this skill when someone asks it to test or QA a surface (browser page, API, CLI, job, worker, webhook) and signals they want bugs reported rather than fixed. The report-only framing in the description is what separates it from a general fix-the-bugs QA request.
Things a person might say (the model's guesses)
- “QA the checkout flow and just report what's broken, don't fix anything.”
- “Test our signup API and write up whatever bugs you find — I'll handle the fixes myself.”
- “Check the webhook delivery for problems but leave the code alone.”
A model's summary of when it is used.
Tools it may use, or may not
allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch
Tools it may use while it runs without asking you first.
Runs scripts
bin/gstack-skill-start, scripts/question-registry.ts, bin/gstack-question-preference, bin/gstack-question-log, bin/gstack-paths (first 5 of 7 lines)
Scripts the text names. Found by matching words, so treat them as pointers.
Files it mentions
sections/exploratory.md, sections/reporting.md
Files the text names, such as ones to read or write. Found by matching words, so treat them as pointers.
Stops for a person
6 lines stop to ask a person (first 5 linked)
Lines that stop and wait for a person before going on. Found by matching words, so treat them as pointers.
What it leads to
Other skills this one hands off to, calls, requires or offers instead, as a model read them.
What leads to it
- gstack hands off to this PROACTIVE all, or user names it gstack, line 204
- browse is an alternative to this when you need their rubric browse, line 387
Other skills that hand off to this one, call it, require it or offer it instead, as a model read them.
Licence
MIT, from LICENSE
The terms its author shares it under, which let it be shown here.
Other files in this skill (4) Close
The text
Most marks come from matching words in the file, so treat them as pointers.
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly --> <!-- Regenerate: bun run gen:skill-docs -->
Raw lines 1 to 19Boilerplate, lines 20 to 106. The same text appears in 45 other files here. Close
Telemetry (run last)
After workflow completion, log telemetry with ONE command. OUTCOME is success/error/abort/unknown; SESSION_ID and TEL_START are the values the preamble's skill-start output echoed. It also drains the artifacts-sync queue (the former skill-end sync step — do not run gstack-brain-sync separately).
PLAN MODE EXCEPTION — ALWAYS RUN: This writes telemetry to $GSTACK_STATE_ROOT/analytics/, matching preamble analytics writes.
~/.claude/skills/gstack/bin/gstack-skill-end --skill "qa-only" --outcome OUTCOME \
--session-id "SESSION_ID" --tel-start "TEL_START" --used-browse USED_BROWSE \
--error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null || trueReplace OUTCOME and USED_BROWSE (yes/no) before running; substitute SESSION_ID/TEL_START from the skill-start echoes. ERROR_MESSAGE/FAILED_STEP are "" unless outcome is error. If the command is missing (stale install), skip telemetry — it never blocks the workflow.
/qa-only: Report-Only QA Testing
Explore the selected surfaces and report reproducible behavior with evidence. NEVER fix anything or change product tests. Write only reports, evidence and owned temporary fixtures; the Additional Rules below define these limits.
In shared sections, caller means this /qa-only workflow. The user sets its permissions; an invoking workflow may restrict them further. Owned means created for this run or explicitly assigned to it, not merely writable. Neither term permits repairs.
Raw lines 107 to 137Section index — Read each section when its situation applies
Read sections in full when directed; do not work from memory.
| When | Read this section |
|---|---|
| selecting surfaces, then running report-only probes (one Read covers both) | sections/exploratory.md relative to the installed qa-only/gstack-qa-only SKILL.md directory |
| finalizing the report after probing stops | sections/reporting.md relative to the installed qa-only/gstack-qa-only SKILL.md directory |
Start at Request Parameters, then follow the sections below in order.
Raw lines 138 to 148Request Parameters
Parse the user's request for these parameters:
| Parameter | Default | Override example |
|---|---|---|
| Target | (infer from request/repository or ask) | Browser URL, API route, CLI command, job, worker or webhook |
| Mode | full | --quick, --regression <previous-report-or-baseline> |
| Output dir | .gstack/qa-reports/ | Output to /tmp/qa |
| Scope | Selected target (or diff-scoped) | Focus on duplicate webhook delivery |
Use an isolated synthetic identity for functional probes. For browser sessions, follow Browser Setup; never request credentials in chat.
Parsing records the request; it does not start browser setup. If both --quick and --regression are supplied, ask the user to choose one mode before setup or probes.
On a feature branch without an explicit scope: Use diff-aware testing of changed and adjacent behavior. Do not discover a browser merely because no URL was supplied.
Raw lines 149 to 168Test Plan Context
Look for a test plan in this conversation. If this session already knows the project's state directory, also Read its newest *-test-plan-*.md when permitted. Do not create state or run bookkeeping helpers just to find optional context. Prefer the plan covering more requested contracts; break ties by recency. If neither exists, use git diff analysis.
Prior Learnings
Read this project's existing learnings.jsonl only if its directory is already known and the caller permits that Read. Otherwise skip this optional lookup. Do not run gstack-learnings-search here: its slug helper can update a cache. Do not change configuration, enable cross-project search or create a learning store.
Treat old notes as leads, not proof. When a QA finding matches a past learning, cite it as "Prior learning applied: [key] (confidence N/10, from [date])" and verify the current behavior. Reading old notes never requires writing new ones.
Raw lines 177 to 187Select Surfaces and Isolation
Load the shared preparation gate now (the exploratory STOP just below): complete its scope and selected-method Reads, await their results, and select the surfaces. Defer charters, clocks and probes to Run the Selected Checks; its §1 then reuses the REPORT_DIR resolved under Prepare Report Artifacts.
STOP. Before selecting surfaces, then running report-only probes (one Read covers both), Readsections/exploratory.mdrelative to the installedqa-only/gstack-qa-onlySKILL.md directory in full and follow it. Use this host's installed path, never the product working directory or another host's assets. If missing or unreadable, report a QA setup blocker and its affected probes as blocked; continue other safe probes (independent functional/static checks). Missing/unreadable assets block required QA.
Each surface's method defines Full, Quick and Regression. A mode flag applies to all selected surfaces unless the request names one surface; the others default to Full. For mixed Regression, the argument is the prior combined report. Resolve its functional replay evidence and browser baseline links first, then give each method its own baseline. A missing baseline blocks that surface's regression coverage, not independent checks. In mixed runs, use the user's surface order, defaulting to functional then browser. Each surface's clock starts with its probes; finish one surface before starting the next. A supplied absolute deadline is shared; switching surfaces does not extend it.
Raw lines 188 to 206Prepare Report Artifacts
Resolve and preserve supplied prior report/baseline paths and their evidence links before writing. Select the requested output dir or .gstack/qa-reports; create it if absent. Use that directory as REPORT_DIR only when it is empty; otherwise choose a fresh owned run subdirectory. Use run-YYYYMMDDTHHMMSSZ in UTC, adding a suffix on collision. All local reports, baselines and evidence use this directory. Never overwrite artifacts from earlier runs. Preserve this run's baselines, screenshots and exploration notes when finalizing its report.
A caller's fixed artifact paths and permissions take precedence. An existing empty directory already established as owned by the caller needs no new shell commands to revalidate it; use the caller's supported interface and fixed destinations. If safe preservation is impossible within those permissions, report an output blocker; do not expand write authority or silently redirect required artifacts.
For {target}, use the browser hostname, CLI executable basename, or named API service/job/worker/webhook. Replace characters other than letters, digits and hyphens with hyphens. For mixed targets, use mixed-{project-label}, sanitizing the repository name the same way; use mixed-target when no repository name is available. List the individual targets in the report.
Set REPORT_FILE to the caller's final report filename, otherwise $REPORT_DIR/qa-report-{target}-{YYYY-MM-DD}.md. Charters and final findings use this same file, not a sidecar.
Browser Setup (conditional)
Browser surface only: load its setup; functional-only runs skip this section.
Read sections/browser-setup.md relative to the installed qa/gstack-qa SKILL.md directory in full. Find qa/gstack-qa beside this host's installed caller skill. If missing or unreadable, report a QA setup blocker and its affected probes as blocked; continue other safe probes (independent functional/static checks). Missing/unreadable assets block required QA. No product-directory or cross-host substitutes.
Raw lines 233 to 240
Run the Selected Checks
Use the shared section already loaded above; do not restart its preparation. With its required Reads complete and report ownership resolved, Write the charters into the owned report and wait for the successful Write result before starting any probe clock or baseline. Use REPORT_FILE. State each expected result, risk, entrypoint, isolation and exit condition before probing; never invent the plan later. A failed baseline contract stays failed. Before browser probes, source/diff reads only map changes to pages and flows; read TODOS.md if present to identify known bugs. During browser discovery, observe behavior without reading source to diagnose it.
Raw lines 241 to 253
Output
Raw lines 254 to 255Assemble the report
After probing stops, load the finalization procedure below. Order: exploratory §4 annotations and materialize, then this procedure, then the final report Write. Use retained evidence; this step does not authorize more probes or restart an expired clock. Do not preload reporting. To recover from an accidental early Read: If already read, issue another Read now and await its acknowledgement, even if the tool reports unchanged content. The no-repeat rule covers preparation Reads, not this finalization Read.
STOP. Before finalizing the report after probing stops, Readsections/reporting.mdrelative to the installedqa-only/gstack-qa-onlySKILL.md directory in full and follow it. Use this host's installed path, never the product working directory or another host's assets. If missing or unreadable, report a QA setup blocker and its affected probes as blocked; continue other safe probes (independent functional/static checks). Missing/unreadable assets block required QA.
Use templates from this host's installed QA directory. For mixed runs, use separate browser and functional sections in this same report. Keep common metadata once: date, branch/revision, caller/authority, mode, scope and timing/stop reason. Preserve the initial charters under Charters after that metadata, before findings.
- Browser:
templates/qa-report-template.md: targets, URL, framework, page/screenshot counts, findings, health/category scores and regression comparison. - Functional:
templates/functional-report-template.md: native tools/runtime, fixture ownership, contracts, findings, discoveries/proposed tests and cleanup.
Each proposed test carries a value card; propose it only when it passes this bar:
Test value bar. Before writing or proposing a test, the reproduced bug already answers what it protects and what makes it fail; also answer:
- Why does existing coverage not already catch that? Prefer adding a row to an existing table-driven test or shared fixture over a near-duplicate.
- Does it need a production seam (export, flag, wrapper, injection hook) that no production caller needs? If yes, test at the real boundary instead.
Value card: Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...> (seam: none or its name; no_claim: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. no_claim=provider acceptance (mocked provider; unit only) or no_claim=none beyond protects; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus ...; written JSON keeps full values). Put it under each proposed test. A missing upstream card never blocks: derive it; ignore unknown fields.
Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test.
Nest remaining headings per surface, without duplicating the shared title or metadata. Preserve surface-specific scope, timing and coverage limits. Browser scores apply only to browser coverage; never combine them with functional outcomes. In each section link the current baseline or replay evidence and checkpoints; for functional regression the report plus replay evidence is the baseline. Regression also links the prior input baseline/report; missing required replay inputs block affected coverage. Prior baselines are not applicable to Full/Quick. Report-only repair/test fields contain proposals or not-run status, never claims of edits.
Raw lines 256 to 298Write the checked report
After the reporting procedure's consistency check, write REPORT_FILE and the project copy below. These are the default report destinations; a caller's narrower permissions or fixed paths override them. Do not create a forbidden second copy.
Use this session's existing project slug and state directory for the project copy. If unknown or not writable within the supplied permissions, report that copy as blocked; still write the permitted local report. Do not run state-setup helpers. Write identical content to $GSTACK_STATE_ROOT/projects/{slug}/{user}-{branch}-test-outcome-{datetime}.md (the state root this session resolved). Get {user}/{branch} from git config user.name/git branch --show-current (fallbacks: unknown-user/detached); sanitize like {target}. Use UTC YYYYMMDDTHHMMSSZ. If that destination exists, choose a fresh suffixed filename; never replace a prior report.
Output Structure
REPORT_DIR stays the report root throughout the run. For browser-only and mixed runs, keep screenshots in $REPORT_DIR/screenshots/ and the browser baseline in $REPORT_DIR/baseline.json. The shared loop's mixed-surface split applies only to clocks and checkpoints:
| Run | Clock/checkpoint directory |
|---|---|
| One surface (browser or functional) | $REPORT_DIR |
| Mixed: browser probes | $REPORT_DIR/browser |
| Mixed: functional probes | $REPORT_DIR/functional |
Each probe directory holds its own exploration-NNN.json sequence, annotations.json and materialize step, and, only when timed, deadline.json. Caller-fixed paths override this layout. Do not reassign REPORT_DIR to a surface directory or move the shared browser artifact paths.
Additional Rules (qa-only specific)
- Never fix bugs or write product tests. Find and document only. Necessary read-only source discovery is allowed for functional targets, while browser discovery stays black-box. Do not edit product code, tests, dependencies, config or tracked state through any tool, including shell writes, renames, deletions and edit-then-restore. Never commit, stash or bootstrap. Proposed regressions belong in report artifacts.
- During preflight, check documented native commands and test infrastructure. For browser targets, inspect documentation only for this framework check, before discovery. If absent, report missing coverage and proposed cases without installing anything. An unavailable command/service is not a product defect. Never invoke /qa or another skill from this report-only run. When the browser app's repository is available and no framework is documented, say "No test framework detected. Run
/qato bootstrap in a separate, user-authorized repair session." Functional targets keep the gap without a new framework.
From garrytan/gstack at 3f79d81, 2026-11-01. Skills read by DeepSeek V4.1 Flash on 2026-11-04. Summary and techniques by Claude Opus 5.5 on 2026-11-06.