From 82547e6f8a0c5f9fe3f066e95d48aec1cd7d972c Mon Sep 17 00:00:00 2001 From: Mujtaba Badat <1470881+mujtaba3B@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:17:42 -0500 Subject: [PATCH 1/2] v3.5.0 feat(qa): story-first qa:plan companion artifact The artifact template now opens with three context blocks above the Development section: The story (user story + observed problem), The solution being built, and How this plan proves it (bullets mapping plan rows to the story outcome), each with a FILL marker (STORY / SOLUTION / PROOF). Step 4b documents how to fill them from the Step 2 success criteria. qa plugin 3.4.1 -> 3.5.0. Co-Authored-By: Claude Fable 5 --- qa/.claude-plugin/plugin.json | 2 +- qa/skills/qa-plan/CHANGELOG.md | 13 +++++++ qa/skills/qa-plan/SKILL.md | 11 +++++- .../qa-plan/references/artifact-template.html | 38 ++++++++++++++++++- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/qa/.claude-plugin/plugin.json b/qa/.claude-plugin/plugin.json index b3567aa..156c5e9 100644 --- a/qa/.claude-plugin/plugin.json +++ b/qa/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "qa", - "version": "3.4.1", + "version": "3.5.0", "description": "QA Quincey, the manual-QA persona. Verifies one defined flow against the spec or mockup and records a QA posture. qa:browser drives the real running app through the user's persistent agent-browser session (click/pixel level), walks the spec, seeds and tears down tagged data via the repo's recipe, and ends with the QA_STATUS contract that satisfies the build-time Stop hook and the PR qa-gate CI. qa:headless does the same for backend features with no UI (capturing side effects). qa:qa-plan authors the two-phase QA plan and writes the approval stamp. The plugin also SHIPS Quincey's enforcement hooks (hooks/hooks.json): the QA-plan gates (presentation, build, PR) and the QA-status Stop gate, active in opted-in repos (.qa-plan-gate.json) under ~/dev. Skills: qa:browser, qa:headless, qa:qa-plan.", "author": { "name": "Mujtaba Badat", diff --git a/qa/skills/qa-plan/CHANGELOG.md b/qa/skills/qa-plan/CHANGELOG.md index 6da7466..e7f257b 100644 --- a/qa/skills/qa-plan/CHANGELOG.md +++ b/qa/skills/qa-plan/CHANGELOG.md @@ -1,5 +1,18 @@ # qa:plan CHANGELOG +## v2.1.0 + +Story-first companion artifact. + +- The artifact template now opens with three context blocks above the + Development section: **The story** (the change's user story plus the observed + problem), **The solution being built**, and **How this plan proves it** + (numbered bullets mapping the plan's rows to the story's outcome), each with + its own FILL marker (`STORY` / `SOLUTION` / `PROOF`). Step 4b documents how to + fill them from the Step 2 success criteria (never invented). Driven by + Mujtaba's 2026-07-20 feedback: a QA artifact should say what problem is being + solved and what the solution is before showing any test rows. + ## v2.0.0 Readability overhaul + a pointable companion artifact. diff --git a/qa/skills/qa-plan/SKILL.md b/qa/skills/qa-plan/SKILL.md index 85313bc..0628bbb 100644 --- a/qa/skills/qa-plan/SKILL.md +++ b/qa/skills/qa-plan/SKILL.md @@ -1,6 +1,6 @@ --- name: qa-plan -version: 2.0.0 +version: 2.1.0 description: | QA Quincey's planning skill: turn a change's success criteria into a two-phase QA plan written into the PR body, BEFORE the PR is reviewed or merged. Produces a @@ -160,7 +160,14 @@ Mechanics: Publish a rendered, always-linked view of the same plan as a Claude **artifact**, so there is one pretty page to point at. The artifact is a **companion**, not the source of truth: the gates only ever read the PR-body `## QA` section (Step 4). The artifact can carry the full mechanics that would bloat the table. -1. **Build the HTML.** Copy `references/artifact-template.html` (this skill's base directory) to the session scratchpad and swap the content between the `FILL:` markers: the **title**, the **Development** ELI5 + rows, the **Production** ELI5 + rows, the **Production artifacts**, and the **Definition of Done**. The artifact is the leaner companion view: it deliberately drops the QA-driver line, the `Standard (all green)` line, and the QA-posture line (those live in the PR body, the source of truth). The template is self-contained (inline CSS + data-URI images, theme-aware, no external assets, which the artifact CSP requires) and uses display checkbox glyphs (`☐` / `☑`), NEVER square-bracket checkboxes (the artifact is never gate-parsed, so glyphs are free here). +1. **Build the HTML.** Copy `references/artifact-template.html` (this skill's base directory) to the session scratchpad and swap the content between the `FILL:` markers: the **title**, the story-first **context blocks** (STORY / SOLUTION / PROOF, below), the **Development** ELI5 + rows, the **Production** ELI5 + rows, the **Production artifacts**, and the **Definition of Done**. The artifact is the leaner companion view: it deliberately drops the QA-driver line, the `Standard (all green)` line, and the QA-posture line (those live in the PR body, the source of truth). + + **Story-first context blocks (required).** The page opens with three blocks ABOVE the Development section, so a reader gets what problem is being solved, what is being built, and how the plan proves it before any table: + - `FILL: STORY` - the change's user story in one sentence (`As , when , I want , so `), then the observed problem in a muted line (the incident, gap, or pain that motivated the change, with date/PR when one exists). Derive it from the same success criteria Step 2 pulled (spec, issue, mockup, or the user's own words); never invent it. + - `FILL: SOLUTION` - one paragraph naming what is being built to deliver that outcome, concrete enough that the QA rows below visibly test it. + - `FILL: PROOF` - 2-4 numbered bullets mapping the plan to the story: each states one thing the plan establishes and ends with a muted pointer to the rows that establish it (for example "(Dev rows 1-3.)", "(Prod row 2.)"). This is the bridge that lets the reader see the QA verifies the solution actually solves the story's problem. + + The template is self-contained (inline CSS + data-URI images, theme-aware, no external assets, which the artifact CSP requires) and uses display checkbox glyphs (`☐` / `☑`), NEVER square-bracket checkboxes (the artifact is never gate-parsed, so glyphs are free here). **Driver avatars.** The `Tester` cell shows a logo-only avatar that carries the driver's identity for assistive tech via `role="img"` + `aria-label` (the `title` is the hover tooltip), with the decorative inner `.pic` marked `aria-hidden`: ``, where `` is a roster id with a built-in avatar (`claude` `mutwo` `muthree` `mufour` `mujtaba`). For any driver without one, use the initials fallback: ``. The template's header comment documents how to add a new avatar (inline its `github.com/.png` as a data URI in a new `.pic.` rule; `claude` is a hand-drawn inline-SVG burst on Anthropic clay). diff --git a/qa/skills/qa-plan/references/artifact-template.html b/qa/skills/qa-plan/references/artifact-template.html index 9ec291d..7f9ff59 100644 --- a/qa/skills/qa-plan/references/artifact-template.html +++ b/qa/skills/qa-plan/references/artifact-template.html @@ -2,7 +2,9 @@ +

As Mujtaba, when email-hero's LLM starts failing in production, I want the health check to notice and flag it, so silent LLM breakage surfaces in the mini's triage instead of going unnoticed for days.

+

Observed problem: LLM calls were failing quietly inside the daemon; email-hero health stayed green because nothing recorded the failures where it could see them.

+ +
+

The solution being built

+ +

A per-failure sink records every LLM failure to llm-failures.jsonl, and email-hero health counts the failures inside its window, exiting non-zero past --llm-max-failures so mini check #8 turns red when the LLM is breaking.

+
+
+

How this plan proves it

+ +
    +
  • 1.The counting rules are right in isolation: unit tests cover in-window counting, torn lines, and the cap. (Dev row 1.)
  • +
  • 2.A forced failure on a real copy is noticed end to end: the sink records it and health exits non-zero at the threshold. (Dev row 2.)
  • +
  • 3.The live daemon on the mini behaves the same after deploy, which is the story's outcome verified in production. (Prod row 1.)
  • +
+
+ +

🖥️ Development

From 953b52aa2e0d45db7a94b6c4dfc25612d7725ab2 Mon Sep 17 00:00:00 2001 From: Mujtaba Badat <1470881+mujtaba3B@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:26:01 -0500 Subject: [PATCH 2/2] Address CodeRabbit: use h2 for story-first context headings The context blocks sit directly after the page h1, so h3 skipped a heading level. Promote them to h2 with the same visual style; the aux blocks (after the phase h2s) keep h3. Comment: https://github.com/mujtaba3B/gstack-extensions/pull/61#discussion_r3618491034 --- qa/skills/qa-plan/references/artifact-template.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qa/skills/qa-plan/references/artifact-template.html b/qa/skills/qa-plan/references/artifact-template.html index 7f9ff59..a654cf8 100644 --- a/qa/skills/qa-plan/references/artifact-template.html +++ b/qa/skills/qa-plan/references/artifact-template.html @@ -78,7 +78,7 @@ .pic.generic{background:linear-gradient(135deg,#5b6675,#3d4756);} .aux{margin-top:34px;display:grid;gap:20px;} .block{background:var(--panel);border:1px solid var(--hair);border-radius:14px;box-shadow:var(--shadow);padding:18px 20px;} - .block h3{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 0 12px;font-weight:700;} + .block h3,.context .block h2{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 0 12px;font-weight:700;} .block.artifact{border-left:3px solid var(--live);} .block p{margin:0 0 9px;} .block p:last-child{margin-bottom:0;} @@ -97,18 +97,18 @@

email-hero: LLM-failure health check

-

The story

+

The story

As Mujtaba, when email-hero's LLM starts failing in production, I want the health check to notice and flag it, so silent LLM breakage surfaces in the mini's triage instead of going unnoticed for days.

Observed problem: LLM calls were failing quietly inside the daemon; email-hero health stayed green because nothing recorded the failures where it could see them.

-

The solution being built

+

The solution being built

A per-failure sink records every LLM failure to llm-failures.jsonl, and email-hero health counts the failures inside its window, exiting non-zero past --llm-max-failures so mini check #8 turns red when the LLM is breaking.

-

How this plan proves it

+

How this plan proves it

  • 1.The counting rules are right in isolation: unit tests cover in-window counting, torn lines, and the cap. (Dev row 1.)