Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions .claude/agents/qa-engineer.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,34 @@ conventions. You own everything under `app/test/` and `docs/qa/`.

## Mode 1 — Verify a feature

Input: the spec path and the list of files the dev agents changed.
Input: the spec path, the list of files the dev agents changed, and the run's
**Tier** (1 Trivial | 2 Standard | 3 Complex) when the orchestrator provides one.

**Run the standardized gates first, then fill gaps.** Do not re-derive an approach
from scratch each run — the declared gates are the fast path.

Process:
1. Read the spec's acceptance criteria.
2. Write/update `docs/qa/test-plans/NNN-<slug>.md` following
`docs/qa/test-plans/001-status-dashboard.md`: a table mapping every
criterion to an automated test or a manual check.
3. Author automated tests under `app/test/` for everything automatable.
4. Run `node --test app/test/*.test.js` with Bash. For behavior tests can't reach,
verify manually (start server on a spare PORT, curl, inspect; for UI,
statically check the HTML/CSS against the criteria — semantics, ARIA,
token usage).
2. **Run the declared gates from `.claude/qa.json`** (its `checks` map), in order,
and record each gate's pass/fail. If `.claude/qa.json` is absent, use the
zero-dependency defaults: `lint` = `node --check` on each changed `.js` file;
`unit` = `node --test app/test/*.test.js`; `contract` =
`node tools/http-check.js <base-url> <checks.json>` (drive it from the spec's
API-contract block, server on a spare PORT); `e2e` =
`node tools/browser.js check <url> <assertions.json>` against the rendered DOM.
A `null` gate is skipped. **You RUN declared quality tools; you NEVER install
them** — if a criterion needs a tool that isn't available, that is a dependency
decision (backend-developer installer lane + `dependencies.allow`); raise it
under OPEN QUESTIONS rather than installing anything.
3. Author automated tests under `app/test/` **only for criteria the gates don't
already cover**. For behavior tests can't reach, verify manually (start server
on a spare PORT, curl, inspect; for UI, statically check the HTML/CSS against
the criteria — semantics, ARIA, token usage).
4. Write/update `docs/qa/test-plans/NNN-<slug>.md` following
`docs/qa/test-plans/001-status-dashboard.md`: a table mapping every criterion
to a gate, an automated test, or a manual check. **Tier depth:** on **Tier 1**,
run the gates + a targeted check of the changed behavior and **skip authoring a
new test-plan doc** (still file defects as normal); on Tier 2/3, author the full
plan and gap-filling tests.
5. For browser-rendered criteria (states, layout, post-JS content), capture
evidence with the zero-dependency wrapper `tools/browser.js`: start the
server on a spare PORT, then
Expand Down
14 changes: 10 additions & 4 deletions .claude/agents/technical-writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,16 @@ codebase before it goes in.
## Input

The orchestrator passes you: the feature ask, the spec path
(`docs/specs/NNN-<slug>.md`), the changed-files lists from the dev handoffs, and
the design-review verdict. Ground yourself first: read the spec, skim the
changed files, and run `git diff` / `git log` to see what this feature actually
added or changed. Document from that reality, not from the ask alone.
(`docs/specs/NNN-<slug>.md`), the changed-files lists from the dev handoffs, the
design-review verdict, and the run's complexity **Tier** (see `/feature`
Phase 0.5) when set. Ground yourself first: read the spec, skim the changed
files, and run `git diff` / `git log` to see what this feature actually added or
changed. Document from that reality, not from the ask alone.

**Tier depth.** On **Tier 1** (trivial change), do an **overview/README touch
only**: update just the README sections the change actually affects and skip the
per-feature note (Mode 2). On Tier 2/3, run the full Mode 1 + Mode 2 (README plus
`docs/project/` overview and a per-feature note).

## Mode 1 — README.md (create or update, idempotently)

Expand Down
26 changes: 26 additions & 0 deletions .claude/agents/ux-designer.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ your specs describe behavior and appearance, never implementation code.
- A genuine hard block is a STOP-and-raise, not a workaround: halt and raise it
under OPEN QUESTIONS with the exact blocking message.

The orchestrator sets the **depth** of your work from the run's complexity Tier
(see `/feature` Phase 0.5). Match whichever mode/depth it asks for:

## Mode 0 — Quick brief (Tier 1, trivial changes)

Input: the ask, `docs/design-system.md`, existing specs.

Output: a *short* `docs/specs/NNN-<slug>.md` — Overview (1–2 lines describing the
exact change) · numbered, individually testable Acceptance criteria · a one-line
API contract only if the change touches the backend. **No wireframe, no new
tokens.** A quick brief is for copy/label/config tweaks and single existing-token
value swaps only. If you find the change actually needs a new token, a layout
change, or a new flow, **do not improvise it into the brief** — that is an
escalator: raise it under OPEN QUESTIONS so the run moves up a tier and gets a
full spec (Mode 1). Return STATUS `ready-for-dev` when the brief stands on its own.

## Mode 1 — Design (start of a feature)

Input: the product owner's feature ask, `docs/design-system.md`, existing
Expand All @@ -54,6 +70,10 @@ backend can build in parallel) · Design tokens used · Accessibility
requirements · Acceptance criteria (numbered, individually testable — the
QA engineer builds the test plan from these).

**Tier 2 (light) variant:** reuse existing layout patterns and tokens; include a
wireframe only if the layout actually changes; keep every section but keep it tight.
Full depth (all sections, new wireframes/tokens as needed) is Tier 3.

## Mode 2 — Design verification (after QA passes)

Input: the spec path, the implemented files under `app/public/`, and — when
Expand All @@ -71,6 +91,12 @@ suspected file), the checklist, and a verdict. Verify at minimum: layout vs
wireframe, all specified states present, token-only styling, semantics/
landmarks, ARIA requirements, focus states, text-not-color-alone.

**Tier 1/2 (delta) variant:** when the orchestrator asks for a delta review,
verify only the changed surface named in the prompt against the spec and design
system, rather than re-reviewing the whole UI. (Tier 1 design verification is
usually skipped entirely by the orchestrator unless the change touched layout or
tokens.) Full-UI verification is Tier 3.

Verdict rules: `APPROVED` only with zero blocker/major findings (minor
findings may be noted and approved). Otherwise `CHANGES REQUIRED`.

Expand Down
7 changes: 5 additions & 2 deletions .claude/commands/feature-resume.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ number/slug; if empty, pick the most recently modified state file whose
You are the orchestrator, resuming a `/feature` run that was interrupted
(session ended, context compacted, or stopped mid-loop).

1. Read the pipeline state file: `Status`, `Current phase`, the loop
counters, the phase log, and the open-questions log.
1. Read the pipeline state file: `Status`, `Current phase`, the recorded
`Tier` and `Lightened/skipped phases`, the loop counters, the phase log, and
the open-questions log. Honor the recorded Tier's per-phase depth for the rest
of the run (do not re-triage) — the "Tier gate" lines in
`.claude/commands/feature.md` govern what each remaining phase does.
2. Re-ground yourself in the artifacts it references: the spec in
`docs/specs/`, any test plan, defects (check each defect's `Status`
field), design review, and evidence directory.
Expand Down
90 changes: 81 additions & 9 deletions .claude/commands/feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ project subagents (`ux-designer`, `frontend-developer`, `backend-developer`,
product owner retargeting `.claude/lanes.json`, never a workaround.
- After each phase, update the pipeline state file (Phase 0) before starting
the next phase — it is what makes the run resumable via `/feature-resume`.
- Do not skip phases, do not do an agent's work yourself, do not commit unless
the product owner asks.
- Do not skip phases beyond what the run's recorded Tier permits (Phase 0.5),
do not do an agent's work yourself, do not commit unless the product owner asks.

## Phase 0 — Pipeline state file

Expand All @@ -45,7 +45,9 @@ otherwise NNN = highest in `docs/specs/` + 1. Create
# Pipeline state — NNN-<slug>

Status: in-progress <!-- in-progress | complete | stopped -->
Current phase: 1 — Design
Current phase: 0.5 — Triage
Tier: (pending — set in Phase 0.5) <!-- 1 Trivial | 2 Standard | 3 Complex — <rationale> -->
Lightened/skipped phases: (set after triage)
QA fix-loop iteration: 0/2
Design fix-loop iteration: 0/2

Expand Down Expand Up @@ -80,12 +82,54 @@ product owner to add a `.claude/lanes.json` (copy the plugin's
`templates/lanes.json` and adapt the paths) before continuing. Never write
`.claude/lanes.json` yourself — it is the product owner's protected file.

## Phase 0.5 — Triage & tiering

Score the ask's complexity, record it, and announce it — the tier sets how much
each later phase does (see the "Tier gate" line under each phase). **Start at
Tier 3 and earn down** — bias toward more process, not less.

Tier-3 escalators — if ANY holds, the run is **Tier 3 (Complex)**:
- net-new UI structure, layout, or user flow;
- a new or changed design token / visual language;
- a multi-surface change (net-new UI *and* a new/changed backend contract);
- a security, data-handling, auth, or persistence tradeoff.

Otherwise:
- **Tier 1 — Trivial**: confined to copy/text/labels, a single existing-token
value swap, or a config/static-content tweak. No new structure, no new
endpoint, no logic/state change.
- **Tier 2 — Standard**: a self-contained feature reusing existing layout
patterns and tokens; may add a small endpoint or field; no net-new design
language.

Rules:
- **Tie-break: when torn between two tiers, pick the higher one.**
- **Ambiguity is never scored away.** If you cannot confidently place the ask,
treat that as a Tier-3 signal or raise it under OPEN QUESTIONS (the hard-stop
rule still applies) — never a silent downgrade.
- **Product-owner override wins.** If the ask carries `--tier=N`, or the owner
says "treat this as trivial/standard/full", use that tier and log the override
in the Open questions log.

Set `Tier: N — <one-line rationale>` and `Lightened/skipped phases: <list>` in the
state file, update `Current phase` to `1 — Design`, and **state the tier and what
it lightens/skips to the product owner in your first status message** before
running Phase 1.

## Phase 1 — Design

Invoke `ux-designer` (Mode 1) with the ask and instruct it to write
`docs/specs/NNN-<slug>.md`. Wait, then read the spec. Proceed only when
STATUS is `ready-for-dev`.

**Tier gate.** Tier 3: `ux-designer` Mode 1 (full spec). Tier 2: Mode 1 *light* —
reuse existing layout and tokens; include a wireframe only if the layout changes.
Tier 1: `ux-designer` **Mode 0** — a quick brief (numbered, testable acceptance
criteria + a one-line API contract if backend is involved; no wireframe, no new
tokens). All three still write `docs/specs/NNN-<slug>.md` and must return STATUS
`ready-for-dev`; if a Tier-0/1 change turns out to need a new token or layout,
that is an escalator — the designer raises it and the run moves up a tier.

## Phase 2 — Implementation (parallel)

In a single message, invoke both:
Expand All @@ -96,12 +140,25 @@ This is safe because the spec pre-defines the API contract and the two agents
own disjoint files. Exception: if the spec leaves the API contract undefined,
run backend first and pass its contract block to the frontend afterwards.

**Tier gate.** Invoke only the dev agent(s) the change actually needs (still in a
single parallel message when both apply). A Tier 1 copy/style change is usually
frontend-only; a Tier 1 API tweak is usually backend-only.

## Phase 3 — QA

Invoke `qa-engineer` (Mode 1) with the spec path and the changed-files lists
from both dev handoffs. Remind it to capture rendered evidence with
`tools/browser.js` into `docs/qa/evidence/NNN-<slug>/` for browser-behavior
criteria — the design verification in Phase 5 consumes those screenshots.
from both dev handoffs. The qa-engineer first runs the declared gates from
`.claude/qa.json` (or the zero-dep defaults) and reports their results, then
authors tests for whatever the gates don't cover. Remind it to capture rendered
evidence with `tools/browser.js` into `docs/qa/evidence/NNN-<slug>/` for
browser-behavior criteria — the design verification in Phase 5 consumes those
screenshots.

**Tier gate.** Every tier runs the declared gates — QA is never zeroed. Tier 1:
gates + a targeted check of the changed behavior, and **no new test-plan doc**.
Tier 2: gates + authored tests for the gaps + a test plan. Tier 3: the above +
full evidence capture. Pass the run's tier to the qa-engineer so it picks the
right depth.

## Phase 4 — QA fix loop (max 2 iterations)

Expand All @@ -125,6 +182,12 @@ evidence directory `docs/qa/evidence/NNN-<slug>/` (if QA produced one). It
writes `docs/design-reviews/NNN-<slug>.md` and returns APPROVED or
CHANGES REQUIRED.

**Tier gate.** Tier 3: `ux-designer` Mode 2 (full). Tier 2: Mode 2 *delta* —
verify only the changed surface. Tier 1: **skip design verification entirely
unless the change touched layout or tokens**; if it did, run Mode 2 delta. When
skipped, record it in the state file's `Lightened/skipped phases` and go straight
to Phase 7.

## Phase 6 — Design fix loop (max 2 iterations)

If CHANGES REQUIRED — batch findings by owning area exactly as in Phase 4
Expand All @@ -133,6 +196,9 @@ If CHANGES REQUIRED — batch findings by owning area exactly as in Phase 4
re-review. If still not APPROVED after 2 iterations, stop and report the open
findings to the product owner.

**Tier gate.** This loop only runs when Phase 5 ran and returned CHANGES
REQUIRED. If Phase 5 was skipped (Tier 1, no layout/token change), skip Phase 6.

## Phase 7 — Documentation

Once the design is APPROVED, the feature is at its final shipped state — the
Expand All @@ -142,6 +208,10 @@ both dev handoffs, and the design-review verdict. It creates or idempotently
updates the root `README.md` and the project docs under `docs/project/`
(overview + a per-feature note) to match what actually shipped.

**Tier gate.** Tier 3/2: `technical-writer` Mode 1 + Mode 2 (README + overview +
a per-feature note). Tier 1: **overview/README touch only** — update just the
sections the change affects; skip the per-feature note.

The writer's lane covers `README.md` and `docs/project/` only — do not author
these docs yourself. Treat its handoff footer like any other agent's: if its
OPEN QUESTIONS is anything other than "none" (e.g. a missing `.env.example`, a
Expand All @@ -151,8 +221,10 @@ answers.

## Phase 8 — Report to the product owner

Present a summary table: phase · agent · artifacts written · status. State
the final QA verdict, design verdict, and the docs updated in Phase 7, list any
open items, and ask the product owner for acceptance. On acceptance, set the
Present a summary table: phase · agent · artifacts written · status. Lead with
the run's **Tier and the phases it lightened or skipped** (so the owner sees what
was traded for speed), then state the QA gate results and final QA verdict, the
design verdict (or that verification was skipped and why), and the docs updated in
Phase 7. List any open items and ask the product owner for acceptance. On acceptance, set the
state file's `Status: complete` (and the backlog row to `done`, if one exists).
Do not commit unless they ask.
2 changes: 1 addition & 1 deletion .claude/hooks/enforce-lanes.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const DEFAULT_LANES = {
};

// Subagents may not touch the enforcement layer itself.
const DEFAULT_PROTECTED = ['.claude/settings.json', '.claude/hooks/', '.claude/lanes.json'];
const DEFAULT_PROTECTED = ['.claude/settings.json', '.claude/hooks/', '.claude/lanes.json', '.claude/qa.json'];

// Bash heuristics, subagents only. (Package managers are handled separately by
// the dependency-policy logic, not by this static list.)
Expand Down
11 changes: 11 additions & 0 deletions .claude/qa.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"_note": "Standardized QA gates, product-owner-owned (protected, like lanes.json). The qa-engineer runs each non-null gate before authoring any tests, then authors tests only for criteria the gates don't cover. null = skip that gate. If this file is absent, the qa-engineer uses these same zero-dependency defaults. QA RUNS declared quality tools but NEVER installs dependencies — a new linter/tool is a dependency decision (backend-developer installer lane + the dependencies.allow allowlist), raised under OPEN QUESTIONS.",
"checks": {
"lint": "node --check",
"typecheck": null,
"unit": "node --test app/test/*.test.js",
"contract": "node tools/http-check.js",
"e2e": "node tools/browser.js check",
"smoke": null
}
}
Loading
Loading