Skip to content
Back to skills

Add Qa Spec

ASecurity

Generate a code-free QA/E2E specification (reachability intent, UX acceptance criteria, functional E2E scenarios, capture states, target viewports, a11y expectations) from about.md + design.md + plan-*.md, and author the _tests/screens.json catalog (design: path only — no expect). Loaded by add-plan's qa-pipeline QA-Spec step.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
developmentgodatabasefrontendbackend

Works with

  • cli

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add brabos-ai/code-addiction --skill add--qa-spec --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Qa Spec?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add  Qa Spec
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/brabos-ai-add-qa-spec/badge)](https://www.skillsdirectory.com/skills/brabos-ai-add-qa-spec)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add--qa-spec
description: Generate a code-free QA/E2E specification (reachability intent, UX acceptance criteria, functional E2E scenarios, capture states, target viewports, a11y expectations) from about.md + design.md + plan-*.md, and author the _tests/screens.json catalog (design: path only — no expect). Loaded by add-plan's qa-pipeline QA-Spec step.
---

# QA/E2E Specification — Case Generation Rubric

<!-- uses:
- skill: add--doc-schemas
- skill: add--doc-schemas/references/new-feature.md
- mention: add--qa
- mention: add--test-specification
- agent: e2e-agent
- agent: qa-agent
-->

> **LANG:** Respond in user's native language. Tech terms in English.

## When to Use

- `add-plan`'s `qa-pipeline`-gated QA-Spec step (STEP qa-pipeline.qa-spec), to produce `plan-qa-spec.md` AND author `_tests/screens.json` before consolidation.

## When NOT to Use

- Contract test cases (input/output pairs from RFs/RNs) — that's `add--test-specification`.
- Judging/scoring an implementation against a rubric — that's `add--qa`.

## Inputs

- `about.md` — RF/RN + acceptance criteria.
- `design.md` — UX contract (layout/hierarchy/spacing/tokens/state). Resolve it per the `feature-design` **Location** rule in `{{skill:add--doc-schemas/references/new-feature.md}}` (SF-level first, feature-level fallback).
- Area `plan-*.md` (plan-database.md, plan-backend.md, plan-frontend.md) — technical contracts, if they exist.
- `FEATURE_DIR/_tests/screens.json` — the existing catalog (scaffolded by `add-qa-setup`, or written by a previous plan run). Absent on a first run.
- `docs/qa/config.json` — default viewport set (required to resolve the viewports column).

## QA/E2E Case Generation

Emit **one row per surface/subfeature that `design.md` declares** — never skip a declared screen (the run's coverage gate treats a declared-but-unspecced screen as a blocker). Per surface, derive:

- **Reachability intent** — route (`path`) OR non-route open-recipe intent (e.g. "opened via the New-entry button on /entries"). Record the intent only — real selectors are finalized post-implementation by `@e2e-agent`, which merges this intent with the rendered DOM. You DO write the intent into `screens.json` (see Screen Catalog below); you do NOT invent selectors.
- **UX acceptance criteria** — tied to `design.md` (layout/hierarchy/spacing/tokens/state).
- **Functional E2E scenarios** — given/when/then per acceptance criterion. **CRUD heuristic:** when a surface manages a data entity (a form that persists, or a listing), enumerate create / read / update / delete / list as distinct scenarios. Where `about.md` has no acceptance criterion for an operation, still list it and mark the row a **gap** — never invent the criterion.
- **Capture states** — the UI states to screenshot for the surface, from the canonical vocabulary: `default`, `empty`, `filled`, `submitted`, `list`, `detail`, `created`, `updated`, `deleted`, `error`, `success`. A data-entity surface typically yields `empty,filled,list`. A single-state surface uses `default`. These map 1:1 to the screenshot files `<screen>.<state>.<viewport>.png`.
- **Target viewports** — default from `docs/qa/config.json`; per-surface override when the design demands it.
- **a11y expectations** — which surfaces carry explicit a11y acceptance (labels, focus trap, contrast, keyboard nav, etc.).

## Output 1 — `plan-qa-spec.md`

Write to `docs/features/${FEATURE_ID}/plan-qa-spec.md` under a `## QA/E2E Specification` heading:

| ID | surface | SF | reachability | viewports | capture states | UX acceptance | functional scenario | a11y |
|----|---------|----|--------------|-----------|----------------|---------------|---------------------|------|
| QA01 | entry-form | SF01 | modal (open via New-entry) | mobile,desktop | empty,filled,list | fields render + width rule | submit persists entry + list shows it | labels + focus trap |

## Output 2 — Screen Catalog (`_tests/screens.json`)

You OWN this file when dispatched by `add-plan` STEP qa-pipeline.qa-spec. (`add-qa-setup` STEP add-qa-setup.catalog only scaffolds it at setup time, before any plan exists.) One catalog entry per row of the table above.

### Entry shape

```json
{
  "feature": "<feature-id>",
  "screens": [
    { "id": "login", "sf": "SF02", "name": "Login", "kind": "route",
      "path": "/login", "auth": false,
      "design": "docs/features/<id>-.../subfeatures/SF02-.../design.md" },
    { "id": "entry-form", "sf": "SF01", "name": "Entry form", "kind": "modal",
      "open": [{ "goto": "/entries" }, { "click": "role=button[name=New entry]" }],
      "auth": true,
      "design": "docs/features/<id>-.../subfeatures/SF01-.../design.md" }
  ]
}
```

| Field | Rule |
|-------|------|
| `id` | stable kebab surface id — matches the `surface` column of your table |
| `sf` | the subfeature the surface belongs to (`SF01`, …); the merge key together with `id` |
| `name` | human label |
| `kind` | `route` \| `modal` \| `overlay` \| `portal` |
| `path` | route surfaces only |
| `open` | non-route surfaces only — ordered recipe, each step exactly one of `{"goto":"<path>"}`, `{"click":"<selector>"}`, `{"fill":["<selector>","<value>"]}`, `{"select":["<selector>","<value>"]}`, `{"wait":"<selector \| ms>"}`. Playwright role/testid syntax — never brittle CSS |
| `auth` | true when the surface requires an authenticated session |
| `design` | the `design.md` path actually used for that screen (SF-level when it exists, feature-level fallback). The only contract pointer — visual values live in that file's `## Design Contract`. There is no `expect` key |

Route surfaces keep `path`; non-route surfaces declare `kind` + `open`. Both forms coexist in one catalog.

### Read-merge-write (MANDATORY)

The catalog is **feature-wide** while a plan run is scoped to **one SF** — so it is NEVER rewritten from scratch. Merge by `sf` + `id`:

1. Read the existing file. Absent → start from `{"feature":"<feature-id>","screens":[]}`.
2. Entries whose `sf` is OUT of this run's scope are preserved **byte-identically** — never reorder, reformat, or "clean up" them.
3. An in-scope entry (same `sf` AND same `id`) is **replaced** by the newly derived one.
4. A newly derived in-scope entry with no match is **appended**.
5. An in-scope entry whose screen no longer exists in the consolidated design.md is **removed** (out-of-scope entries stay untouchable — rule 2 above).

Store reachability INTENT only. If a design doc is missing or thin, list the screen with a note rather than inventing a route — flag it as a gap for the user.

## Rules

- Code-free only — no implementation code, no test scripts. The `screens.json` `open` recipe is reachability intent, not a test: never hand-write selectors you have not observed; `@e2e-agent` finalizes them post-implementation.
- Keep `plan-qa-spec.md` under ~15 lines (tabular). `screens.json` has no line budget — it carries one entry per declared screen.
- Flag missing UX acceptance / thin design as **gaps** — never invent content.
- Each row maps to one surface/subfeature; do not merge unrelated surfaces into one row.
- Emit a row for **every** screen `design.md` declares — an omitted declared screen becomes a coverage `blocker` at run time.
- `capture states` uses the canonical vocabulary only; single-state screens use `default`. Do not invent a passing CRUD scenario for an operation `about.md` does not cover — mark it a gap.
- Every `plan-qa-spec.md` row has a matching `screens.json` entry (same `sf` + `id`) and vice versa for in-scope surfaces — the two outputs are one specification in two shapes.
- NEVER rewrite `screens.json` wholesale — out-of-scope SF entries survive byte-identically.
- NEVER write an `expect` key. `@qa-agent` reads `DESIGN_FILE` for declared values.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.