/nw-test-design-mandates
Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion,
Claude Code
$ npx -y skills add nWave-ai/nWave --skill nw-test-design-mandates --agent claude-code
Codex
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a codex -y
Cursor
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a cursor -y
Gemini CLI
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a gemini-cli -y
GitHub Copilot
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a github-copilot -y
OpenCode
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a opencode -y
Windsurf
$ npx skills add nWave-ai/nWave --skill nw-test-design-mandates -a windsurf -y
SKILL.md
nw-test-design-mandates.SKILL.mdname: nw-test-design-mandates
description: Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion, layer-dependent PBT mode, two-tier acceptance, example-based sad paths). Lean recomposing core - routes to three narrow mandate modules.
user-invocable: false
Acceptance Test Design Mandates (recomposing core)
This skill is the Single Source of Truth (SSOT) for every acceptance-test-design mandate. All mandates are enforced during peer review and must pass before handoff to software-crafter.
This core holds the cross-cutting concerns (numbering, registry, language-convention frame, compliance-verification handoff) and COMPOSES three narrow mandate modules. The canonical mandate definitions live in the modules — this core does not re-inline them.
Load `nw-cross-cutting-invariants` and apply `flow:findings-go-to-the-owner-directly` when exchanging findings or questions between roles.
Assertion failure messages state WHAT / WHY / HOW (STANDING)
Every AT assertion's failure message MUST state **WHAT** observable failed (the specific expected-vs-actual), **WHY** it matters (the contract it breaks), and **HOW** to fix (what the implementation must make true / the concrete remediation). A bare `assert x == y` with no message — or a message that only restates the code — is itself a defect: a RED must TEACH the crafter exactly what to make true, not force them to reverse-engineer the intent. Same what/why/how rule the product's own error surfaces obey.
Then/Assert steps own these business-named assertions and carry WHAT/WHY/HOW internally; scenario bodies call clean domain steps, not wordy assertion-message builders.
Test time (STANDING)
Test time is a critical responsibility of the acceptance designer and its reviewer (`test:feedback-loop-budget` in `nw-cross-cutting-invariants`). Keep every test within the design's per-test and property budgets, and the default CI suite within its ceiling (300 s unless a repository ADR sets another). Give each formal law a fast executable projection on the pure core in the default suite. Put real adapter fault injection (storage down, interrupted or double write, crash, concurrent writers) only in the infrastructure suite of a feature whose derogation the human granted. Measure per-test time over at least nine sequential runs and report n, median, maximum and load; a test meets its budget on the median with at most one run over it. Never write a test above the budgets: propose the feature's derogation request, with one risk/value record per test, and ask for the human's decision instead.
Three cost laws complete this budget (Ale 2026-10-30): (1) RED default — a test covering a declared-not-yet-deployed obligation is RED by default in its natural committed state; pass/xfail bridging is not a substitute and synthetic RED by removing markers is not an observed FAIL. (2) Mutation is nightly — text-flip and similar belong to the nightly delta on implemented code, never to review gating. (3) End-to-end installer cycles are an integration concern — rare, and always reusing an existing prepared setup, never reinstalling per case; an oracle case never executes a full lifecycle subprocess.
Durable outcome naming (STANDING)
Every acceptance-test identifier must name the durable observable value it protects. Delivery bookkeeping is not value: never put `slice_NN` or `slice-NN` in a test file/function name. Do not create a ledger, delivery narrative or execution plan to preserve that bookkeeping; Git owns change provenance. Before RED, derive the identifier from the charter's value statement; a reader must understand what is protected without opening delivery bookkeeping. Scenario titles and parametrization IDs follow the same naming rule. The acceptance designer and reviewer validate the observable meaning at authoring time; no language-specific post-hoc naming gate is part of the delivery spine.
Closure obligations — COUNT / PARTITION / SILENCE (STANDING)
Three generative obligations. They fire at AUTHORING time, on the shape of what an AT (or the artifact it certifies) asserts — not as a gate that fires after the error. They are domain-agnostic: a validator checks the obligation is DISCHARGED without understanding the subject. Whenever a scenario, a charter oracle, or a design artifact emits one of these shapes, the matching cell is filled inline while writing:
- **Emit a COUNT → name the POPULATION.** A number ("3 consumers wired", "0 findings", "5
slices") is meaningless without its denominator: 3 of WHAT total, 0 out of a set that was actually enumerated. An AT asserting a count MUST also pin the population it was drawn from, and assert the count against that population — never a bare integer.
- **Emit a PARTITION → assert CONSERVATION.** When a whole is split into parts (buckets,
statuses, refused/accepted halves, per-category verdicts), the parts MUST sum back to the whole. Assert the conservation law, not just the individual buckets — a partition whose pieces silently drop members is the exact defect this catches.
- **Declare SILENCE/ABSENCE → name the DISCRIMINATOR.** A "clean / nothing found / no-op /
not-applicable" result MUST carry what distinguishes **looked-and-genuinely-absent** from **never-actually-looked** (no capable tier, unparseable input, swallowed error). The AT proves the discriminator by constructing the empty case AND a broken/incapable case and asserting their outputs DIFFER — the negative test no positive test can replace (Vera's absence ≠ incapacity, `nw-user-examiner` §8). A silence indistinguishable from a swallowed error is a false negative wearing a degraded alibi, never a PASS.
Why here, why inline: the obligation is SEEDED mechanically from what the design already
Read more
name: nw-test-design-mandates description: Design mandates for acceptance tests - hexagonal boundary, business language abstraction, user journey completeness, pure function extraction, 3 Pillars (domain language / chained narrative / production composition), and the layered ATD discipline (Universe-bound assertion, layer-dependent PBT mode, two-tier acceptance, example-based sad paths). Lean recomposing core - routes to three narrow mandate modules. user-invocable: false
Acceptance Test Design Mandates (recomposing core)
This skill is the Single Source of Truth (SSOT) for every acceptance-test-design mandate. All mandates are enforced during peer review and must pass before handoff to software-crafter.
This core holds the cross-cutting concerns (numbering, registry, language-convention frame, compliance-verification handoff) and COMPOSES three narrow mandate modules. The canonical mandate definitions live in the modules — this core does not re-inline them.
Load `nw-cross-cutting-invariants` and apply `flow:findings-go-to-the-owner-directly` when exchanging findings or questions between roles.
Assertion failure messages state WHAT / WHY / HOW (STANDING)
Every AT assertion's failure message MUST state **WHAT** observable failed (the specific expected-vs-actual), **WHY** it matters (the contract it breaks), and **HOW** to fix (what the implementation must make true / the concrete remediation). A bare `assert x == y` with no message — or a message that only restates the code — is itself a defect: a RED must TEACH the crafter exactly what to make true, not force them to reverse-engineer the intent. Same what/why/how rule the product's own error surfaces obey.
Then/Assert steps own these business-named assertions and carry WHAT/WHY/HOW internally; scenario bodies call clean domain steps, not wordy assertion-message builders.
Test time (STANDING)
Test time is a critical responsibility of the acceptance designer and its reviewer (`test:feedback-loop-budget` in `nw-cross-cutting-invariants`). Keep every test within the design's per-test and property budgets, and the default CI suite within its ceiling (300 s unless a repository ADR sets another). Give each formal law a fast executable projection on the pure core in the default suite. Put real adapter fault injection (storage down, interrupted or double write, crash, concurrent writers) only in the infrastructure suite of a feature whose derogation the human granted. Measure per-test time over at least nine sequential runs and report n, median, maximum and load; a test meets its budget on the median with at most one run over it. Never write a test above the budgets: propose the feature's derogation request, with one risk/value record per test, and ask for the human's decision instead.
Three cost laws complete this budget (Ale 2026-10-30): (1) RED default — a test covering a declared-not-yet-deployed obligation is RED by default in its natural committed state; pass/xfail bridging is not a substitute and synthetic RED by removing markers is not an observed FAIL. (2) Mutation is nightly — text-flip and similar belong to the nightly delta on implemented code, never to review gating. (3) End-to-end installer cycles are an integration concern — rare, and always reusing an existing prepared setup, never reinstalling per case; an oracle case never executes a full lifecycle subprocess.
Durable outcome naming (STANDING)
Every acceptance-test identifier must name the durable observable value it protects. Delivery bookkeeping is not value: never put `slice_NN` or `slice-NN` in a test file/function name. Do not create a ledger, delivery narrative or execution plan to preserve that bookkeeping; Git owns change provenance. Before RED, derive the identifier from the charter's value statement; a reader must understand what is protected without opening delivery bookkeeping. Scenario titles and parametrization IDs follow the same naming rule. The acceptance designer and reviewer validate the observable meaning at authoring time; no language-specific post-hoc naming gate is part of the delivery spine.
Closure obligations — COUNT / PARTITION / SILENCE (STANDING)
Three generative obligations. They fire at AUTHORING time, on the shape of what an AT (or the artifact it certifies) asserts — not as a gate that fires after the error. They are domain-agnostic: a validator checks the obligation is DISCHARGED without understanding the subject. Whenever a scenario, a charter oracle, or a design artifact emits one of these shapes, the matching cell is filled inline while writing:
- **Emit a COUNT → name the POPULATION.** A number ("3 consumers wired", "0 findings", "5
slices") is meaningless without its denominator: 3 of WHAT total, 0 out of a set that was actually enumerated. An AT asserting a count MUST also pin the population it was drawn from, and assert the count against that population — never a bare integer.
- **Emit a PARTITION → assert CONSERVATION.** When a whole is split into parts (buckets,
statuses, refused/accepted halves, per-category verdicts), the parts MUST sum back to the whole. Assert the conservation law, not just the individual buckets — a partition whose pieces silently drop members is the exact defect this catches.
- **Declare SILENCE/ABSENCE → name the DISCRIMINATOR.** A "clean / nothing found / no-op /
not-applicable" result MUST carry what distinguishes **looked-and-genuinely-absent** from **never-actually-looked** (no capable tier, unparseable input, swallowed error). The AT proves the discriminator by constructing the empty case AND a broken/incapable case and asserting their outputs DIFFER — the negative test no positive test can replace (Vera's absence ≠ incapacity, `nw-user-examiner` §8). A silence indistinguishable from a swallowed error is a false negative wearing a degraded alibi, never a PASS.
Why here, why inline: the obligation is SEEDED mechanically from what the design already
AI agents that guide you from idea to working code, with human judgment at every gate. nWave runs inside Claude Code. It breaks feature delivery into seven waves (discover, diverge, discuss, design, devops, distill, deliver).
Other skills on nwave.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about nw-test-design-mandates.
- Which coding agents can use nw-test-design-mandates?
- nw-test-design-mandates installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

