qa-preflight
Skill3 starsChanged 32 days agoMITView on GitHub
The gate between a finished feature and the human QA. Investigates the delivered feature against its spec and the running screen, executes what is automatable, dispatches the existing correctors for defects that are objectively wrong, leaves a permanent guard so each defect cannot return unnoticed, and writes a QA plan (md + csv) plus a findings report carrying only what needs human judgement. Invoked by a HUMAN when the feature is done — never by spec-writer, implement-feature or evaluator.
In this repository19 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- architecture-analyzerSkill
- coupling-mapSkill
- deep-analyzerSkill
- design-systemSkill
- e2e-test-validatorSkill
- e2e-test-writerSkill
- evaluatorSkill
- fix-runnerSkill
- gate-builderSkill
- handoff-writerSkill
- implement-featureSkill
- integration-test-validatorSkill
- integration-test-writerSkill
- playwright-cliSkill
- prd-writerSkill
- spec-writerSkill
- unit-test-validatorSkill
- unit-test-writerSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 13 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
Standalone by decision: No other skill invokes this one.
- Distinctive: line 65
Run these before anything else and stop at the first failure, naming it.
- Distinctive: line 149
Every divergence goes through the fix × escalate rule below.
- Distinctive: line 162
If this skill is ever dispatched non-interactively, it does not skip the checkpoint: it stops and reports that it needs one.
- Distinctive: line 168
Before presenting the lists, ask the person who watched the headed run one question:
- Distinctive: line 195
Re-execute what was corrected: before moving on. The plan must describe the fixed product.
- Very specific: line 244
Write the three artifacts using references/report-template.md verbatim for structure, and derive the cases with references/qa-practices.md.
- Distinctive: line 261
Do not write the files if any of these holds.
- Distinctive: line 303
Run the environment preflight first, and name the failing check.
- Distinctive: line 304
Stop at the checkpoint and wait for approval before any correction.
- Distinctive: line 308
Ask, at the checkpoint, what the watcher saw that the run did not report.
- Very specific: line 312
Leave Status empty — the verdict is the QA's.
- Distinctive: line 314
Write the blocking reason whenever a case cannot be executed.
- Distinctive: line 322
Run the investigation headless — that is the visual gate's job, not this one's.
- Distinctive: line 323
Write an assertion into a visual suite that is not enabled — deliver it ready in the findings report instead.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
QA Preflight
A gate, not a plan generator. A plan generator moves work onto the human; this removes work from the human and uses what remains as the definition of what actually needs a person.
References, loaded on demand:
references/qa-practices.md(how cases are derived) andreferences/report-template.md(the exact output skeletons). Both travel with this skill, so both resolve wherever it is installed.The rationale — why each rule exists and what this skill deliberately does NOT do — is in
docs/Skill_QA_Preflight.mdof the sdd-skills repository, which is where the skill is maintained. That file is not part of an installed copy, and the relative path this note used to give (../../docs/) resolved to nothing outside the source repository. Everything needed to RUN the skill is in the folder you are reading; go to the rationale only to change a rule, and change it there.
Standalone by decision. No other skill invokes this one. It runs when the feature is done, on explicit human request. Running it mid-implementation produces noise about code that is still moving.
It owns no correction logic. Defects are fixed by dispatching the correctors that already exist, with the discipline they already have.
One carve-out, and only one: the visual guard. A permanent guard that is a test goes to
the matching test-writer — a guard for a user flow goes to e2e-test-writer when the
project has an e2e suite (GATES.md lists an e2e gate proven green). A guard that is a gate
rule stays a proposal in the findings report: building gates is gate-builder's job. The
exception is a computed-value assertion (contrast, height, density): no test-writer covers
the visual suite, so when the visual gate is enabled the skill writes that assertion itself.
This is guard code, not product behaviour — it changes what is checked, never what the
application does. Production code stays off-limits under every circumstance, and the guard
still goes through the checkpoint like any other change.
INPUT
- Target feature (ID, e.g.
F08). - Auto-discovers: the feature's
spec.md/plan.md/contract.md, its PRD section,progress.json, the routes and permission blocks it added, and its diff against the integration branch. - Reads the project's design-system doc when one exists, found by the resolution order of the
design-systemskill (../design-system/SKILL.md, Step 1), for the numeric values the accessibility axis asserts. Without a doc, the accessibility axis falls back to the generic WCAG floors inreferences/qa-practices.md; a value that comes only from that skill's bundled baseline is never asserted as a defect.
OUTPUT
docs/qa/QA-<FEATURE>.md— the plan the human QA executes.docs/qa/QA-<FEATURE>.csv— the same matrix, importable as a database.docs/qa/ACHADOS-<FEATURE>.md— what was found, what was fixed, what was escalated, and the permanent guard proposed for each finding.- Zero or more correction commits, made by the dispatched skills, never by this one.
PHASE 1 — Investigation
1.1 Environment preflight
Run these before anything else and stop at the first failure, naming it. A session that dies in timeouts teaches nothing about the product.
| Check | On failure, say |
| Frontend answers on the base URL | "the app is not answering at <url> — bring the stack up" |
| The served bundle is current | "the dev server is serving a stale bundle — its last build failed: <error>" |
| Backend answers | "the API is not answering at <url> — the screen will render empty" |
| Browser runner installed | "@playwright/test is declared but not installed — run the install at the repo root" |
| Automated login works | see below |
| The account's tenant has data for this feature | "the account <login> sees no data for this feature — seed it, or nothing can be measured" |
HTTP 200 does not mean the code under test is the code on disk. A dev server whose
last build failed keeps serving the previous bundle, happily and indefinitely. Read the dev
server's log for a build error before trusting anything measured afterwards — in a real run,
the dev server had been stuck on leftover merge-conflict markers for hours, the preflight passed
it, and a CSS fix appeared not to work because the browser was three hours behind the tree.
On login, and this is not negotiable:
Never seed a session, forge a token, or bypass an anti-bot protection. Check whether the development environment offers a documented non-production escape hatch (a flag that disables verification outside production). If it does, use it and say so in the plan's prerequisites. If it does not, stop and report — an environment that cannot be driven is a finding for the team, not an obstacle to work around.
Log in once and reuse the session. Save the authenticated storage state after the first login and reuse it for every case. Logging in per case throws dozens of attempts at the auth endpoint and trips the rate limiter: a real run produced HTTP 429 midway, and three cases failed in a way that looked exactly like a product defect. When a 429 appears, say so — it is an artefact of how the run was driven, not a finding about the feature.
Reusing a session you obtained legitimately is not forging one. The rule above forbids manufacturing access the application did not grant; it does not require throwing away access it did.
1.2 Read
Spec, plan, contract and the PRD section. The routes the feature added and the permission
required by each. The templates it changed. The tests and gates that already cover it — that
is where the Verificado por column comes from.
1.3 Execute
Always drive the browser headed — playwright-cli open --headed. The default is headless;
passing the flag is not optional here.
This is not a preference about watching a robot work. The human running this skill watches the session live, and what they catch is what the skill did not: a misaligned element, copy that reads wrong, a transition that stutters, a control nobody thought to enumerate. A hidden screen turns that person into a reader of reports; a visible one makes them a second pair of eyes on the product itself. Every gap they spot is a gap in this file, and the way the skill gets better (see 2.1).
A headed run is also why dark theme comes first — someone is looking at the screen, and the light pass is kept as short as possible.
Do not confuse this with the visual gate, which runs headless on purpose: the gate is an unattended check in a pipeline, this is an attended investigation.
Drive the real screen with the playwright-cli skill:
- every control, one at a time — a screen that loads is not a screen that works;
- every filter with a value that returns results — an empty result validates nothing;
- the empty state, and the failure state, which must not look alike;
- both themes, dark first;
- each profile that sees the feature, when more than one does.
Record for each case whether it was executed and what was observed. Anything not exercised is inconclusive — never recorded as working.
Measure only after the value settles. An element that is still animating reports a smaller box: poll the measurement until it repeats, then assert. Waiting on the element's own animations is not enough — a dialog's scale usually lives on an overlay above it, so its subtree reports nothing to wait for. Polling the value is animation-agnostic and measures the thing you care about rather than a proxy for it.
A value that changes with something it cannot depend on is a measurement bug, not a defect. A height that differs between colour themes is the clearest example. Re-measure before classifying: a real run reported a 33px field that did not exist, and the settled value was exactly the 38px the design system specifies.
1.4 Classify
Every divergence goes through the fix × escalate rule below. The output of phase 1 is a short inventory — surfaces, actors, non-obvious rules, risks in order — plus the classified findings. No file is written yet.
PHASE 2 — Checkpoint (mandatory)
Present the inventory and the findings split in two lists: what will be fixed, and what goes to the QA. Then stop.
No correction happens before human approval — including the mechanical ones.
If this skill is ever dispatched non-interactively, it does not skip the checkpoint: it stops and reports that it needs one. Editing already-validated code with nobody looking is the failure mode this phase exists to prevent.
2.1 Ask what the screen showed that the report did not
Before presenting the lists, ask the person who watched the headed run one question:
"What did you see that I did not report?"
Anything they name is treated like any other finding — classified, fixed or escalated. But it carries one extra obligation: a finding that came from the human and not from the run is a gap in this skill. Record it in the findings report under Guardas permanentes propostas with what the derivation would have needed to catch it — a new check in the accessibility axis, a control the enumeration skipped, a state nobody modelled.
This is the loop that makes the skill improve instead of ossify. It only exists because the run is watched, which is why 1.3 is headed and not negotiable.
PHASE 3 — Correction (by dispatch)
For each approved finding, emit an entry in the report schema
(../evaluator/references/evaluation-report-schema.md) and dispatch by kind:
kind | Meaning | Dispatch to |
gate | a declared gate is violated | fix-runner |
observable-criterion | a contract criterion is not met | fix-runner |
qa-finding | a real defect no contract criterion covered — ref is the QA case ID | fix-runner |
test | coverage missing for a rule already in the code — or, for e2e, the guard of a defect about to be fixed | the matching test-writer (unit / integration / e2e) |
Re-execute what was corrected before moving on. The plan must describe the fixed product; writing it first would document the defect as if it were the behaviour.
Confirm every test a writer returns — unit, integration or e2e, written for coverage or as a
guard — with the matching test-validator before trusting it, passing the feature's contract.md
(when it has one) and the writer's checklist.
- PASS or PASS WITH WARNINGS → the test stands and the finding is corrected. The warnings are listed in the findings report, and the test file is left uncommitted and listed there, for the human to commit with the QA artifacts.
- FAIL → the finding moves to the escalated list, with the validator's findings: a test that does not conform guards nothing. Its file stays where the writer left it, uncommitted, and is listed in the findings report as not conforming — not as a guard to commit. The writer is not dispatched again: one finding, one dispatch.
A fix-runner signal can carry "test to correct: <file> — <title>": a test its correction
made stale. Check the claim against the spec, then dispatch the matching test-writer for that
test in correction mode and confirm it like any other; a claim that does not hold escalates
the finding. The fix is committed and the rewritten test is not, so say in the findings report
that the fix's commit passes its tests only together with that file. When the correction came back uncommitted
— a commit hook ran that test — list the correction and the rewritten test together in the
findings report, for the human to commit as one.
One finding per dispatch — except an e2e-guarded defect, which is one sequence of three
(guard, fix, guard re-run). If a correction comes back "not resolved", the finding moves to the
escalated list with that reason — it is never silently dropped. The e2e guard is the one
exception: its expected first answer is "not resolved — product diverges", and that is the
red-before-fix proof, not a failure. The guard re-run is this skill's own: run that one test
headless with the e2e config (GATES.md) — the headed rule is for the investigation, not for
this check — after confirming the dev server rebuilt. Escalate the
finding instead when the guard comes back green before the fix (it does not reproduce the
defect — remove only the guard test from its file — the file itself when it held nothing else — and only its own entry from the writer's checklist and coverage table, it guards nothing), when its validator verdict is FAIL, when it
answers "environment", or when it is still red after the fix-runner reported the correction
applied — unless that re-run is red for an environment reason, which is reported as such. The
guard file is left uncommitted and listed in the findings report, next to the fix's commit, for
the human to commit with the QA artifacts.
A unit or integration writer's done can carry lines that mean the coverage is not what was asked for: "no seam: …" — no test could be written for what it names — and "spec mismatch: …" — the test asserts what the code does, against the spec. Either one moves the finding to the escalated list, with the line: opening a seam changes code that was already validated, and when spec and behaviour disagree, which one is wrong is a product decision (the fix × escalate rule). A test the writer wrote on the way is left uncommitted and listed in the findings report, like a guard file.
PHASE 4 — Delivery
Write the three artifacts using references/report-template.md verbatim for structure, and
derive the cases with references/qa-practices.md.
The matrix carries one block per area. Functional blocks use the feature's own area names
(CT-PEDIDOS, CT-DATAS…). The four cross-cutting axes are always present, with reserved
names and a fixed derivation technique:
| Block | Derived by |
| Functional blocks | state transition + decision table for interacting controls |
CT-FRONTEIRA | equivalence partitioning + boundary values on every input |
CT-PERMISSOES | profile × action matrix, including the disabled state and the reason in its tooltip |
CT-FALHA | per load: success, legitimate empty, error, and the business 409/422 |
CT-ACESSIBILIDADE | the WCAG 2.2 AA checklist, dark theme first, contrast composed over the real background |
Self-audit — refuse your own output
Do not write the files if any of these holds; fix first:
- an acceptance criterion of the feature has no case;
- a case has more than one expected result;
- a case depends on a previous one;
- an expected result requires judgement instead of observation;
- any case was left with an empty
Verificado por; - a case the skill did not execute carries a filled
Resultado Obtido.
The fix × escalate rule
When in doubt, escalate. The cost of escalating something fixable is a few minutes of a human's time. The cost of "fixing" something ambiguous is a silent behaviour change in code that was already validated.
| Fix (mechanical, verifiable, no judgement) | Escalate (always) |
| A deterministic rule a gate already encodes | Spec and behaviour disagree — which one is wrong is a product decision |
| Contrast below the floor when a correct token exists, measured before and after | A business rule that is ambiguous or written nowhere |
| UI copy factually wrong against the implemented behaviour | Any change to an API contract, schema or migration |
| A message key that does not exist falling back to the wrong label | Any file outside the feature — third-party legacy, another line of work |
| Missing coverage for a rule already in the code → dispatch the test-writer | Aesthetics, density, hierarchy — visual judgement |
| Anything the skill could not execute (hardware, telephony, credentials, a second tenant) |
The golden rule
"Nothing to measure" is inconclusive, never passed. A case the skill could not exercise goes to the QA marked as such — screen without data, element that never appeared, assertion that never ran.
This rule exists because a real visual suite reported green while three of its assertions skipped themselves for lack of data, and the contrast assertion — the reason the suite existed — had never executed once. When it finally ran, it found a badge at 4.15:1 against a 4.5 floor.
RULES
Always:
- Run the environment preflight first, and name the failing check.
- Stop at the checkpoint and wait for approval before any correction.
- Dispatch the existing correctors; re-execute what they corrected.
- Confirm every test a writer returns with its test-validator before trusting it.
- Drive the browser headed, so the person running this can see what you see.
- Ask, at the checkpoint, what the watcher saw that the run did not report.
- Log in once and reuse the session across every case.
- Confirm the dev server's last build succeeded before trusting a measurement.
- Let a measured value settle before asserting on it.
- Leave
Statusempty — the verdict is the QA's. - Record provenance in
Verificado porfor every case. - Write the blocking reason whenever a case cannot be executed.
Never:
- Edit production code directly — the only code this skill writes is a visual-suite guard.
- Skip the checkpoint, even when dispatched non-interactively.
- Seed a session, forge a token, or bypass an anti-bot protection.
- Mark an unexecuted case as verified, or fill
Resultado Obtidofor one. - Report a rate-limit or stale-bundle artefact as a product defect.
- Run the investigation headless — that is the visual gate's job, not this one's.
- Write an assertion into a visual suite that is not enabled — deliver it ready in the findings report instead.
- Touch files outside the feature under validation.
- Validate a filter with a value that returns an empty result.
Edge cases
The feature has no contract.md — derive from spec.md and the PRD section, and record
in the plan's non-scope that traceability is partial. Do not invent criteria retroactively.
The screen cannot be reached at all (route missing, permission denied for every test account) — stop after the preflight. A plan derived from code alone would describe intent, not the product.
A finding is fixable but the fix would touch a file outside the feature — escalate. The boundary is the file, not the difficulty.
The correction breaks something else — the dispatched corrector revalidates locally and returns "not resolved"; move the finding to escalated with that reason and continue.
Two profiles disagree about what should be visible and the spec is silent — that is a
CT-PERMISSOES case escalated with both observations, not a defect to fix.
The visual gate is enabled in this project — then, and only then, the proposed assertions are written into the suite and proven to fail before the fix and pass after it.
The guard is a user flow — when the project has an e2e suite, dispatch e2e-test-writer
with a kind: test entry (testSuite: e2e, ref = the QA case id, targetSurface = the
surface and its route when it has one, the QA case's expected result in message, no
testFile): with no existing test to fix, it runs in guard mode and writes the new one,
judging it against that expected result — a qa-finding has no contract line. Order it like
a visual guard: dispatch the guard before the fix — it must come back red ("product
diverges") — then the fix-runner, then re-run the guard green. Confirm the guard with
e2e-test-validator, as Phase 3 says of every test a writer returns: the contract and the
writer's checklist are what let it check the tags. Without an e2e suite, deliver the
flow ready in the findings report, like an assertion for a visual suite that is not enabled.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

