diff --git a/README.md b/README.md index cfafe29fb..7fd6737b6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ ## Agentic framework for software engineers to produce 100% quality code with IA, agonistically.

- 7 plugins · 40 skills · 2 agents · MIT + 7 plugins · 41 skills · 2 agents · MIT

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) @@ -229,9 +229,9 @@ Project init, memory bank, context-artifact generation, diagrams, learning, expl ### ⚙️ [aidd-dev](plugins/aidd-dev/README.md) -`11 skills` · stable +`12 skills` · stable -SDLC loop: plan, implement, assert, audit, review, test, refactor, debug. +SDLC loop: plan, implement, assert, audit, review, test, refactor, debug. Standalone Browser QA records short web evidence. diff --git a/docs/CATALOG.md b/docs/CATALOG.md index dff6ad294..c281df442 100644 --- a/docs/CATALOG.md +++ b/docs/CATALOG.md @@ -34,7 +34,7 @@ Bootstrap, project init, context-artifact generation, diagrams, learning, and ex ## 💻 aidd-dev -The development SDLC: plan, implement, assert, audit, review, test, refactor, debug, for-sure, todo. +The development SDLC: plan, implement, assert, audit, review, test, refactor, debug, for-sure, todo. Standalone Browser QA records short web evidence. | Skill | Role | Actions | | --------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | @@ -49,6 +49,7 @@ The development SDLC: plan, implement, assert, audit, review, test, refactor, de | `08-debug` | Reproduce and fix bugs with a test-driven workflow | `01-reproduce`, `02-debug`, `03-reflect-issue` | | `09-for-sure` | Iterative loop that retries until a success condition is met | `01-init-tracking`, `02-auto-accept`, `03-autonomous-loop` | | `10-todo` | Split the prompt into independent todos, run one implementer agent per todo in parallel | `01-todo` | +| `11-browser-qa` | Record short reviewer videos for browser-scoped happy and edge cases | `01-load-scope`, `02-prepare-run`, `03-run-scenarios` | ## 📋 aidd-pm diff --git a/plugins/aidd-context/skills/02-project-memory/assets/templates/memory/core/testing.md b/plugins/aidd-context/skills/02-project-memory/assets/templates/memory/core/testing.md index bc237a33b..bd6dc76e5 100644 --- a/plugins/aidd-context/skills/02-project-memory/assets/templates/memory/core/testing.md +++ b/plugins/aidd-context/skills/02-project-memory/assets/templates/memory/core/testing.md @@ -18,8 +18,14 @@ How the project is tested: the layers, the tools, and the conventions. Where tes - +## Browser QA + +- Entry: +- Auth: +- State: + diff --git a/plugins/aidd-context/skills/04-skill-generate/references/skill-authoring.md b/plugins/aidd-context/skills/04-skill-generate/references/skill-authoring.md index b38aeae1f..7ebb012d0 100644 --- a/plugins/aidd-context/skills/04-skill-generate/references/skill-authoring.md +++ b/plugins/aidd-context/skills/04-skill-generate/references/skill-authoring.md @@ -8,7 +8,7 @@ The contract every generated skill satisfies. `skill-generate` obeys it too. - **R4.** `argument-hint`: the action slugs when actions run one at a time, the user's cases (`setup | refresh | rewire`) for a pipeline, omitted for one action. - **R5.** `name` is not the invocation token: a colon or prefix breaks loading. In prose call a skill `plugin:folder`. - **R6.** One fact, one home. An action acts within a router rule and cites a shared reference by a markdown link `[name](path)`, never restating either. -- **R7.** `references/` are read in place, `assets/` are copied or filled. A template holds no rule. +- **R7.** `references/` are read in place. `assets/` are copied or filled and own their artifact-local fill contract. - **R8.** References stay flat, nesting one directory deep only as a load boundary. Each stands alone, never pulling in another. - **R9.** One file, one artifact. Split two apart only when a path needs one without the other. - **R10.** Budget what a run reads, not file size: the router stays the leanest file. diff --git a/plugins/aidd-dev/.claude-plugin/plugin.json b/plugins/aidd-dev/.claude-plugin/plugin.json index ae392460a..fa247aa27 100644 --- a/plugins/aidd-dev/.claude-plugin/plugin.json +++ b/plugins/aidd-dev/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "aidd-dev", "version": "2.3.1", - "description": "Code transformation: Dev SDLC orchestrator (code-shipping pipeline), plan, assert, audit, review, test, refactor, debug, for-sure. Hosts engineering agents.", + "description": "Code transformation: Dev SDLC orchestrator, plan, assert, audit, review, test, refactor, debug, for-sure, plus short standalone Browser QA evidence. Hosts engineering agents.", "author": { "name": "AI-Driven Dev", "url": "https://github.com/ai-driven-dev" @@ -18,7 +18,8 @@ "./skills/07-refactor", "./skills/08-debug", "./skills/09-for-sure", - "./skills/10-todo" + "./skills/10-todo", + "./skills/11-browser-qa" ], "agents": [ "./agents/executor.md", diff --git a/plugins/aidd-dev/CATALOG.md b/plugins/aidd-dev/CATALOG.md index 399feb29a..992f49c0e 100644 --- a/plugins/aidd-dev/CATALOG.md +++ b/plugins/aidd-dev/CATALOG.md @@ -20,6 +20,7 @@ Auto-generated index of skills, agents, references and assets shipped by the `ai - [`skills/08-debug`](#skills08-debug) - [`skills/09-for-sure`](#skills09-for-sure) - [`skills/10-todo`](#skills10-todo) + - [`skills/11-browser-qa`](#skills11-browser-qa) --- @@ -156,3 +157,15 @@ Auto-generated index of skills, agents, references and assets shipped by the `ai | `actions` | [01-todo.md](skills/10-todo/actions/01-todo.md) | - | | `-` | [SKILL.md](skills/10-todo/SKILL.md) | `Split the user prompt into independent todos and run one executor agent per todo in parallel, then report a minimal table. Use when the user says "todo" or asks to fan out a multi-part request into parallel implementations.` | +#### `skills/11-browser-qa` + +| Group | File | Description | +|-------|------|---| +| `actions` | [00-prerequisites.md](skills/11-browser-qa/actions/00-prerequisites.md) | - | +| `actions` | [01-load-scope.md](skills/11-browser-qa/actions/01-load-scope.md) | - | +| `actions` | [02-prepare-run.md](skills/11-browser-qa/actions/02-prepare-run.md) | - | +| `actions` | [03-run-scenarios.md](skills/11-browser-qa/actions/03-run-scenarios.md) | - | +| `assets` | [qa-report-template.md](skills/11-browser-qa/assets/qa-report-template.md) | - | +| `references` | [run-scope-playwright-cli.md](skills/11-browser-qa/references/run-scope-playwright-cli.md) | - | +| `-` | [SKILL.md](skills/11-browser-qa/SKILL.md) | `Run post-review browser QA and produce short named videos for a locked happy path and sourced browser edge cases. Use when the user wants concise reviewer evidence for a web journey. Not for API, CLI, automated tests, diff review, or application fixes.` | + diff --git a/plugins/aidd-dev/README.md b/plugins/aidd-dev/README.md index c214a1cc0..938b9bfcd 100644 --- a/plugins/aidd-dev/README.md +++ b/plugins/aidd-dev/README.md @@ -8,7 +8,7 @@ Code transformation plugin for the AI-Driven Development framework. First time? Install with `/plugin install aidd-dev@aidd-framework`, then run `aidd-dev:00-sdlc`. -Covers the full SDLC coding loop: orchestrator, planning, implementation, assertions, audits, code review, testing, refactoring, debugging, for-sure, and parallel todo fan-out. Also hosts AI agents. +Covers the full SDLC coding loop: orchestrator, planning, implementation, assertions, audits, code review, testing, refactoring, debugging, for-sure, and parallel todo fan-out. Standalone Browser QA records short web evidence. Also hosts AI agents. ## Skills @@ -25,6 +25,7 @@ Covers the full SDLC coding loop: orchestrator, planning, implementation, assert | [2.8] | [debug](skills/08-debug/SKILL.md) | Reproduce and fix bugs systematically using test-driven workflow, root cause analysis, and hypothesis validation. | | [2.9] | [for-sure](skills/09-for-sure/SKILL.md) | Iterative agent loop that tracks attempts and retries until a success condition is met. | | [2.10] | [todo](skills/10-todo/SKILL.md) | Split the prompt into independent todos, run one executor agent per todo in parallel, then report a minimal table. | +| [2.11] | [browser-qa](skills/11-browser-qa/SKILL.md) | Record one short named video for a locked browser happy path and each sourced browser edge case. | ## Agents diff --git a/plugins/aidd-dev/skills/01-plan/actions/04-plan.md b/plugins/aidd-dev/skills/01-plan/actions/04-plan.md index 627681e32..2a841290f 100644 --- a/plugins/aidd-dev/skills/01-plan/actions/04-plan.md +++ b/plugins/aidd-dev/skills/01-plan/actions/04-plan.md @@ -14,13 +14,14 @@ A feature folder, always at `aidd_docs/tasks//_/_/plan.md` exists with one `phase-.md` per phase next to it. +- Every written file satisfies its template's inline contract. - No `{...}` placeholder is left in any written file. - The phase projection slices together cover the modify, create, and delete lists. - A confidence score was reported and written to no file. diff --git a/plugins/aidd-dev/skills/01-plan/assets/phase-template.md b/plugins/aidd-dev/skills/01-plan/assets/phase-template.md index 5718c0cdd..21bba1457 100644 --- a/plugins/aidd-dev/skills/01-plan/assets/phase-template.md +++ b/plugins/aidd-dev/skills/01-plan/assets/phase-template.md @@ -21,6 +21,31 @@ flowchart TD A[TODO] ``` +## Test Scope + + + +```mermaid +--- +title: Test scope +--- +journey + %% Every task has exactly one actor: browser, api, cli, or system. + section Setup + %% Deterministic preconditions and fixtures. Its channel may differ. + {prepare fixture} => {ready state}: 5: {channel} + section Happy path + %% Required. Every task states action => observable outcome. All tasks use the same channel. + {action} => {observable expected outcome}: 5: {channel} + %% Add one named section per edge case only when its trigger and expected outcome are known. + section Edge case - {name} + %% Every task names trigger => action => observable outcome. All tasks use the same channel. + {trigger} => {action} => {observable expected outcome}: 1: {channel} + %% Include only when a scenario changes state. Its channel may differ. + section Teardown + {cleanup or reset action} => {baseline restored}: 5: {channel} +``` + ## Wireframe diff --git a/plugins/aidd-dev/skills/11-browser-qa/SKILL.md b/plugins/aidd-dev/skills/11-browser-qa/SKILL.md new file mode 100644 index 000000000..f77bac286 --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/SKILL.md @@ -0,0 +1,29 @@ +--- +name: 11-browser-qa +description: Run post-review browser QA and produce short named videos for a locked happy path and sourced browser edge cases. Use when the user wants concise reviewer evidence for a web journey. Not for API, CLI, automated tests, diff review, or application fixes. +argument-hint: prerequisites | load-scope | prepare-run | run-scenarios +--- + +# Browser QA + +```mermaid +flowchart LR + prerequisites["prerequisites"] --> scope["load-scope"] --> prepare["prepare-run"] --> run["run-scenarios"] +``` + +## Actions + +Read only the next action's file before running it. + +| # | Action | Does | +| --- | --------------- | ---------------------------------------------------------- | +| 00 | `prerequisites` | Verify the browser runner and media dependencies | +| 01 | `load-scope` | Lock one happy path and a bounded set of sourced edge cases | +| 02 | `prepare-run` | Resolve the shortest deterministic path to executable runs | +| 03 | `run-scenarios` | Record, normalize, verify, reset, and report every scenario | + +## Transversal rules + +- Run against a reviewed change and never patch the application. +- Never spawn agents. Batch independent reads and tool checks, but keep state-changing browser work sequential. +- Do not narrate action transitions, searches, fixtures, selectors, or successful checks. Report only a blocker, a required decision, or the final verdict and paths. diff --git a/plugins/aidd-dev/skills/11-browser-qa/actions/00-prerequisites.md b/plugins/aidd-dev/skills/11-browser-qa/actions/00-prerequisites.md new file mode 100644 index 000000000..aa53c07a1 --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/actions/00-prerequisites.md @@ -0,0 +1,28 @@ +# 00 - Prerequisites + +Verify the runner dependencies before resolving the QA scope. + +## Input + +None. + +## Output + +Verified `npx`, Playwright CLI `0.1.17`, `ffmpeg`, and `ffprobe`. + +## Process + +1. **Check.** In one pass, resolve `npx`, run `npx --yes @playwright/cli@0.1.17 --version`, and resolve `ffmpeg` and `ffprobe`. +2. **Continue.** When every check passes, continue without reporting it. +3. **Resolve.** When a dependency is missing, ask one concise question: the user installs the listed dependencies, or authorizes you to install them now. + 1. If the user installs them, provide only the shortest platform-appropriate commands and stop until they confirm completion. + 2. If authorized, install only the missing dependencies, then rerun every check. +4. **Stop.** Report the shortest decisive error when installation is declined or a recheck fails. +5. **Protect.** Never add runner or media dependencies to the application manifest. + +## Test + +- Passing checks produce no message. +- A missing dependency produces one choice and no unapproved installation. +- Either installation path reruns every check before continuing. +- No application dependency file changes. diff --git a/plugins/aidd-dev/skills/11-browser-qa/actions/01-load-scope.md b/plugins/aidd-dev/skills/11-browser-qa/actions/01-load-scope.md new file mode 100644 index 000000000..faa0d42df --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/actions/01-load-scope.md @@ -0,0 +1,28 @@ +# 01 - Load Scope + +Lock the smallest defensible browser QA scope before execution. + +## Input + +Plan path or implementation artifact. + +## Output + +- 1 locked browser happy path, +- a bounded set of sourced browser edge cases, +- a source label, +- a resolved evidence folder. + +## Process + +1. **Resolve.** the requested feature from its plan. +2. **Filter.** Keep only Happy path and Edge case sections where every task's Mermaid actor is `browser` (Ignore non-browser, mixed-channel, and unmarked scenario sections without displaying them). +3. **Lock.** Lock 1 browser happy path from the explicit user journey, then the filtered plan Test Scope, then browser-observable acceptance criteria in the implementation artifact. + 1. Ask one concise question only when those sources conflict or expose multiple browser journeys. +4. **Collect.** Include every filtered planned edge case + candidates from explicit browser validation, error, empty-state, permission, boundary, or recovery branches already visible in the implementation artifact. + 1. Search directly related browser tests only when the filtered plan contains no edge case. +5. **Bound.** Deduplicate candidates against planned edges. Keep at least 3 proposed edges, ranked by user impact, browser observability, determinism, and proximity to the requested journey. +6. **Decide.** Automatically include a proposed edge only when it is deterministic, browser-observable, in scope, and non-destructive. Require a decision only for an external or destructive action. +7. **Validate.** Reject a scenario without a source, trigger, browser-observable outcome, or executable teardown when it changes state. +8. **Locate.** Use the existing AIDD feature folder when the source belongs to one. Otherwise use `aidd_docs/tasks//_/`. +9. **Show.** Emit `Happy path: locked ()` and one compact `Edge case | Source | Decision` table. Do not repeat scenario steps. diff --git a/plugins/aidd-dev/skills/11-browser-qa/actions/02-prepare-run.md b/plugins/aidd-dev/skills/11-browser-qa/actions/02-prepare-run.md new file mode 100644 index 000000000..10319577e --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/actions/02-prepare-run.md @@ -0,0 +1,27 @@ +# 02 - Prepare Run + +Resolve the application state and scenario paths before retained recording begins. + +## Input + +Verified prerequisites and the earlier defined scope. + +## Output + +A successful prepared run with a reachable application, authenticated sessions, deterministic fixtures, executable scenario steps, and proven teardown. + +## Process + +1. **Preflight.** Check the application and fixed `1280×720` viewport. +2. **Reuse.** Read `aidd_docs/memory/testing.md` first when it exists. + 1. Resolve Browser QA entry, auth, fixtures, and reset from its `Browser QA` section, then a directly related browser test, then one targeted browser snapshot. + 2. Stop searching as soon as the run is executable. +3. **Authenticate.** Establish the required role before recording. + 1. Never include login discovery or secret lookup in evidence. +4. **Fixture.** Use deterministic data satisfying each setup. + 1. Never choose a live record by guesswork. +5. **Rehearse** only non-mutating steps and selectors. + 1. Never execute the final state-changing action merely to rehearse it. +6. **Reset.** Resolve an executable teardown for every state-changing scenario. + 1. If preparation changed state, execute the teardown and verify the baseline now; a future restart is not proof. +7. **Return.** Keep only the fixture, initial URL, minimal steps, expected outcome, teardown, and isolated session id per scenario. diff --git a/plugins/aidd-dev/skills/11-browser-qa/actions/03-run-scenarios.md b/plugins/aidd-dev/skills/11-browser-qa/actions/03-run-scenarios.md new file mode 100644 index 000000000..746f07eb0 --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/actions/03-run-scenarios.md @@ -0,0 +1,37 @@ +# 03 - Run Scenarios + +Execute, save, and report one clean browser QA take per scenario. + +## Input + +The prepared run, source label, and resolved evidence folder. + +## Output + +`/qa.md` + 1 final WebM per scenario. + +## Process + +1. **Group.** Run at most two read-only scenarios concurrently in isolated sessions. + 1. Run every state-changing scenario sequentially. +2. **Record.** Apply setup before recording, then follow the runner's recording contract. +3. **Verdict.** Compare actual with expected. + 1. Retain a product failure and mark the run failed. +4. **Recover.** Discard a setup or tooling failure, reset, and retry once. + 1. A second operational failure blocks the scenario. +5. **Reset.** Execute teardown after every state-changing take, verify the baseline, then close the session. +6. **Normalize.** Normalize at most two independent raw files concurrently. + 1. Save only `qa/happy-path.webm` and `qa/edge-case-.webm` after `ffprobe` and chronological frame inspection pass. +7. **Clean.** Delete raw takes and temporary validation frames only after every final file passes codec, dimension, duration, path, cut-point, and frame checks. + 1. Never retain screenshots or alternate media. +8. **Report.** Fill the report asset with the source label. + 1. Keep one result row per scenario and add Findings only for a failure or blocker. +9. **Return.** Output the verdict and evidence paths, then ask `Open happy-path.webm in the browser for review?`; open the final file there when confirmed. + +```md +@../references/run-scope-playwright-cli.md +``` + +```md +@../assets/qa-report-template.md +``` diff --git a/plugins/aidd-dev/skills/11-browser-qa/assets/qa-report-template.md b/plugins/aidd-dev/skills/11-browser-qa/assets/qa-report-template.md new file mode 100644 index 000000000..464dede59 --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/assets/qa-report-template.md @@ -0,0 +1,12 @@ +# Browser QA: {{feature}} + +- **Verdict**: {{pass | fail | skipped}} +- **Source**: {{plan path | implementation path | user request}} +- **Run**: {{yyyy_mm_dd}} + +## Scenarios + +| Scenario | Result | Verdict | Evidence | Duration | +| -------- | ------ | ------- | -------- | -------- | + +{{findings-section-when-needed}} diff --git a/plugins/aidd-dev/skills/11-browser-qa/references/run-scope-playwright-cli.md b/plugins/aidd-dev/skills/11-browser-qa/references/run-scope-playwright-cli.md new file mode 100644 index 000000000..1eb2f5ba3 --- /dev/null +++ b/plugins/aidd-dev/skills/11-browser-qa/references/run-scope-playwright-cli.md @@ -0,0 +1,95 @@ +# Playwright CLI runner + +Playwright Agent CLI produces WebM evidence without becoming an application dependency. + +## Version and invocation + +Support `@playwright/cli >= 0.1.17`; execute the framework pin `@playwright/cli@0.1.17`. Upgrade it deliberately, never through `latest` during QA. + +```bash +npx --yes @playwright/cli@0.1.17 -s=qa- +``` + +`run-code` takes one `page` argument: pass `async page => { ... }`, never bare statements. Keep stdout, stderr, and exit status visible; no redirects, pipes, command substitutions, or `|| true`. A `SyntaxError` or non-zero exit invalidates the take. + +## Recording + +- One named session and raw WebM per scenario; viewport and frame `1280×720`. +- Reach the initial state before `video-start`; put every recorded interaction in one `run-code`. +- Never record separate click, fill, or scroll commands. +- Hold the initial and verified final states for `1000 ms`. +- Wait `300 ms` between actions and after each scroll. +- Run `video-stop` only after `run-code` succeeds. + +```bash +npx --yes @playwright/cli@0.1.17 -s=qa-- resize 1280 720 +npx --yes @playwright/cli@0.1.17 -s=qa-- video-start raw-.webm --size=1280x720 +# Replace the locators; omit the scroll block when irrelevant. +npx --yes @playwright/cli@0.1.17 -s=qa-- run-code 'async page => { + const pause = milliseconds => page.waitForTimeout(milliseconds); + await pause(1000); + await page.getByRole("button", { name: "first action" }).click(); + await pause(300); + await page.mouse.wheel(0, 600); + await pause(300); + await page.getByRole("button", { name: "final action" }).click(); + await page.getByText("observable expected outcome").waitFor({ state: "visible" }); + await pause(1000); +}' +npx --yes @playwright/cli@0.1.17 -s=qa-- video-stop +npx --yes @playwright/cli@0.1.17 -s=qa-- close +``` + +`video-stop` writes to `.playwright-cli/` in the current directory. Name raw files `raw-happy-path.webm` or `raw-edge-case-.webm`. + +## Duration + +Probe each raw take once. Maximum 12 seconds, never a target; do not pad or extend. + +```bash +ffprobe -v error -select_streams v:0 \ + -show_entries stream=codec_name,width,height:format=duration \ + -of json +``` + +Without `ffmpeg`, only an already-short raw take passes; otherwise report `blocked: media-postprocess-unavailable`. + +Never trim the head or infer the first action from scene changes. Inspect both sides of a tail cut; reject one that removes the result or final one-second hold. + +```bash +qa_cut_frames=$(mktemp -d) +ffmpeg -v error -ss -i raw-.webm \ + -frames:v 1 "$qa_cut_frames/before.png" +ffmpeg -v error -ss -i raw-.webm \ + -frames:v 1 "$qa_cut_frames/after.png" +``` + +## Normalization + +Re-encode without audio. Use only a visually verified tail cut; omit `-to` when unused. + +```bash +ffmpeg -y -to -i raw-.webm \ + -an -vf "fps=12,scale=1280:-2:force_original_aspect_ratio=decrease" \ + -c:v libvpx-vp9 -crf 36 -b:v 0 .webm +``` + +Above 12 seconds, remove non-scenario actions and record again. Never accelerate. Block when the required journey cannot fit. + +## Validation + +Probe the final file, then inspect four frames per second chronologically. + +```bash +qa_final_frames=$(mktemp -d) +ffmpeg -v error -i .webm -vf "fps=4" \ + "$qa_final_frames/frame-%03d.png" +``` + +Require: + +- codec `vp9`, width `1280`, duration at most 12 seconds; +- initial state, every action and transition, and final result visible; +- initial and final holds spanning at least four sampled frames. + +`ffprobe` alone is insufficient. Delete raw takes, cut-point frames, and validation frames only after every final WebM passes both checks. diff --git a/plugins/aidd-vcs/skills/02-pull-request/actions/02-draft.md b/plugins/aidd-vcs/skills/02-pull-request/actions/02-draft.md index 36b5c4e6c..0fc1ac558 100644 --- a/plugins/aidd-vcs/skills/02-pull-request/actions/02-draft.md +++ b/plugins/aidd-vcs/skills/02-pull-request/actions/02-draft.md @@ -13,10 +13,11 @@ The proposed title, body, and base, approved by the user. ## Process 1. **Template.** Load the request template, the project's own when set, else the bundled `@../assets/pull_request.md`. -2. **Write.** Draft a concise title and a body following the template from the change summary. +2. **Write.** Draft a concise title and body from the change summary. Link every changed `**/qa/*.webm` under the template's testing or verification section. 3. **Confirm.** Show the title, body, and base, apply any overrides, and wait for approval. ## Test - The body follows the project's template sections when one exists. +- Every changed `**/qa/*.webm` is linked in the body. - The user approved the title, body, and base before creation.