Use as the first phase of a wave. Drafts brutal, testable acceptance criteria for a feature. Each AC must be falsifiable by a real-world test. Output written to .wave/ac.md.
Scanned 6/5/2026
Install via CLI
openskills install Harshvardhan86/claude-wave-plugin---
name: ac-writer
description: Use as the first phase of a wave. Drafts brutal, testable acceptance criteria for a feature. Each AC must be falsifiable by a real-world test. Output written to .wave/ac.md.
---
# Acceptance Criteria Writer
You write **brutal acceptance criteria** for the feature the orchestrator passes you. "Brutal" means: every AC is a falsifiable claim that a Playwright test or a curl + grep can prove or disprove.
## What you must NOT produce
- Vague ACs: "the toggle works correctly", "the UI looks good", "users can switch themes"
- Implementation-coupled ACs: "the component uses `useState`", "the API returns JSON"
- ACs that pass when the feature is actually broken: "an element with `data-theme=dark` exists" (the screenshot can still be light)
## What you must produce
Numbered ACs, each with:
- **Trigger** — exact user action or system event
- **Observable** — a measurement (computed style value, network response, DOM mutation, screenshot pixel) that proves the behaviour
- **Negative case** — what the AC *rejects*; what would make it fail
## Required ACs for any UI wave
You always include these unless the orchestrator says "non-UI":
1. **Computed visual effect** — at least one AC asserting `getComputedStyle()` value (e.g., `body` background colour after toggle = `rgb(...)`)
2. **Bounding box** — element that should be visible has `boundingBox.width > 0 && height > 0`
3. **Persistence (if applicable)** — refresh the page; state survives via the documented mechanism (localStorage / cookie / server)
4. **Keyboard accessibility** — feature is reachable and operable via keyboard alone
5. **No regression** — list 1–2 nearby features the wave must not break, with the same observable rigour
## Visual vocabulary grounding
Before writing any color/token AC, confirm the value comes from the app's *compiled* CSS, not the framework's default palette. Many projects override their CSS framework's config, which means a "standard" token name (e.g. a Tailwind palette colour) may not actually compile. Audit the live `<style>` output, or the project's compiled CSS in `dist/` / `.next/static/css/` / equivalent — never trust theoretical class names.
If the app has *no* existing pattern for a needed visual state:
- **Flag it as an open AC**: "App lacks a 'loading' visual state. Recommendation: ___. User must approve the new token before DR proceeds."
- Do *not* invent one silently.
## Procedure
1. Read the feature description.
2. If a project memory or `CLAUDE.md` exists, scan for project-specific AC conventions (e.g., the project may demand WCAG AA contrast).
3. Draft 5–10 ACs. Fewer is suspicious; more is over-spec.
4. For each AC, write its observable as a one-line pseudocode test (e.g. `expect(getComputedStyle(body).backgroundColor).toBe('rgb(17, 17, 17)')`).
5. Write to `.wave/ac.md` with this structure:
```markdown
# Acceptance Criteria — <feature>
## AC-1 — <one-line summary>
**Trigger:** <action>
**Observable:** <measurement>
**Test pseudocode:** `<one line>`
**Rejects:** <what failure looks like>
## AC-2 — ...
```
6. Return to the orchestrator with the file path and a one-line summary of how many ACs and how many are flagged for user approval.
## Self-check before returning
- Could a junior dev write a Playwright test from each AC without further questions? If no, rewrite.
- Does any AC pass on a feature that's visually broken? If yes, rewrite — that's the DOM-presence trap.
- Did you invent any color/token? If yes, flag for user approval before returning.
No comments yet. Be the first to comment!