/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,
$ npx -y skills add nWave-ai/nWave --skill nw-test-design-mandates --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/nw-test-design-mandates
Context preview
The summary Claude sees to decide when to auto-load this skill.
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,
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)
user-invocable: false
disable-model-invocation: true
Acceptance Test Design Mandates
Four mandates enforced during peer review. All must pass before handoff to software-crafter.
LANGUAGE CONVENTION FRAME (read FIRST — overrides all examples below)
**Code examples in this skill use Python syntax for illustration only.** They are NOT prescriptive about target language. nWave is language-agnostic per the "genericity and agnosticism" mandate (2026-05-24).
**Before applying mandates**, detect the target project's language from manifest files: `package.json` → TypeScript/JS; `Cargo.toml` → Rust; `go.mod` → Go; `pyproject.toml`/`setup.py`/`Pipfile` → Python; `pom.xml`/`build.gradle` → Java/Kotlin; `*.csproj`/`*.fsproj` → C#/F#; `Gemfile` → Ruby; `Package.swift` → Swift.
**When the target language is NOT Python**: adapt EVERY code example — replace Python imports (`from pytest_bdd import ...`, `from hypothesis import ...`), type hints, class/function syntax, test-framework idioms, directory conventions (`tests/` vs `test/` vs `__tests__/`) with target equivalents. Project conventions ALWAYS WIN over skill examples — if the user's repo has 50 TS files and zero Python files, mandates apply via TypeScript test framework, never Python pytest.
**Empirical anchor**: 5 of 5 Python code blocks in this skill, zero TS/Go/Rust — root-cause for language-leak per F-SKILL-EXAMPLES-LANGUAGE-LEAK. Connects [[feedback_language_adapter_plugin_architecture_2026_05_24]] (genericity mandate).
Mandate 1: Hexagonal Boundary Enforcement
Tests invoke through driving ports (entry points), never internal components.
Driving Ports (Test Through These)
Application services/orchestrators | API controllers/CLI handlers | Message consumers/event handlers | Public API facade classes
Not Entry Points (Never Test Directly)
Internal validators, parsers, formatters | Domain entities/value objects | Repository implementations | Internal service components
Correct Pattern
# Invoke through system entry point (driving port)
from myapp.orchestrator import AppOrchestrator
def when_user_performs_action(self):
orchestrator = AppOrchestrator()
self.result = orchestrator.perform_action(
context=self.context
)Violation Pattern
# Invoking internal component directly
from myapp.validator import InputValidator # INTERNAL
def when_user_validates_input(self):
validator = InputValidator() # WRONG BOUNDARY
self.result = validator.validate(self.input)Testing internal components creates Testing Theater: tests pass but users cannot access feature through actual entry point. Integration wiring bugs remain hidden.
Mandate 2: Business Language Abstraction
Step methods speak business language, abstract all technical details.
Three Abstraction Layers
**Layer 1 - Gherkin**: Pure business language, all stakeholders. Domain terms from ubiquitous language | Zero technical jargon | Describe WHAT user does, not HOW system does it
Scenario: Customer places order for available product
Given customer has items in shopping cart
When customer submits order
Then order is confirmed
And customer receives confirmation email
**Layer 2 - Step Methods**: Business service delegation. Method names use domain terms | Delegate to business service layer (OrderService, not HTTP client) | Assert business outcomes (order.is_confirmed()), not technical state (status_code == 201)
def when_customer_submits_order(self):
self.result = self.order_service.place_order(
customer=self.customer, items=self.cart_items
)
def then_order_is_confirmed(self):
assert self.result.is_confirmed()
assert self.result.has_order_number()**Layer 3 - Business Services**: Production services handle technical implementation. HTTP calls, DB transactions, SMTP hidden inside service layer.
Test Smell Indicators
`requests.post()` in step method | `db.execute()` in step method | `assert response.status_code` | Technical terms in Gherkin
Mandate 3: User Journey Completeness
Tests validate complete user journeys with business value, not isolated technical operations.
Complete Journey Structure
Every scenario includes: **User trigger** (Given/When) | **Business logic** (When - system processes rules) | **Observable outcome** (Then - user sees result) | **Business value** (Then - value delivered)
Correct Example
Scenario: Customer successfully completes purchase
Given customer has selected products worth $150
And customer has valid payment method
When customer submits order
Then order is confirmed with order number
And customer receives email confirmation
And order appears in customer's order history
Violation Example
Scenario: Order validator accepts valid order data
Given valid order JSON exists
When validator.validate() is called
Then validation passes
# Tests isolated validation, not user journey
Scenario Name Test
Does name express user value or technical operation? "Customer completes purchase" = correct. "Validator accepts JSON" = violation.
Walking Skeleton Strategy
Balance user-centric E2E integration tests with focused boundary tests.
Walking Skeletons (2-5 per feature)
Trace thin vertical slice delivering observable user value E2E | Each answers: "Can a user accomplish this goal and see the result?" | Express simplest complete user journey | Validate system delivers demo-able stakeholder value | Touch all layers as consequence of journey, not as design g
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) user-invocable: false disable-model-invocation: true
Acceptance Test Design Mandates
Four mandates enforced during peer review. All must pass before handoff to software-crafter.
LANGUAGE CONVENTION FRAME (read FIRST — overrides all examples below)
**Code examples in this skill use Python syntax for illustration only.** They are NOT prescriptive about target language. nWave is language-agnostic per the "genericity and agnosticism" mandate (2026-05-24).
**Before applying mandates**, detect the target project's language from manifest files: `package.json` → TypeScript/JS; `Cargo.toml` → Rust; `go.mod` → Go; `pyproject.toml`/`setup.py`/`Pipfile` → Python; `pom.xml`/`build.gradle` → Java/Kotlin; `*.csproj`/`*.fsproj` → C#/F#; `Gemfile` → Ruby; `Package.swift` → Swift.
**When the target language is NOT Python**: adapt EVERY code example — replace Python imports (`from pytest_bdd import ...`, `from hypothesis import ...`), type hints, class/function syntax, test-framework idioms, directory conventions (`tests/` vs `test/` vs `__tests__/`) with target equivalents. Project conventions ALWAYS WIN over skill examples — if the user's repo has 50 TS files and zero Python files, mandates apply via TypeScript test framework, never Python pytest.
**Empirical anchor**: 5 of 5 Python code blocks in this skill, zero TS/Go/Rust — root-cause for language-leak per F-SKILL-EXAMPLES-LANGUAGE-LEAK. Connects [[feedback_language_adapter_plugin_architecture_2026_05_24]] (genericity mandate).
Mandate 1: Hexagonal Boundary Enforcement
Tests invoke through driving ports (entry points), never internal components.
Driving Ports (Test Through These)
Application services/orchestrators | API controllers/CLI handlers | Message consumers/event handlers | Public API facade classes
Not Entry Points (Never Test Directly)
Internal validators, parsers, formatters | Domain entities/value objects | Repository implementations | Internal service components
Correct Pattern
# Invoke through system entry point (driving port)
from myapp.orchestrator import AppOrchestrator
def when_user_performs_action(self):
orchestrator = AppOrchestrator()
self.result = orchestrator.perform_action(
context=self.context
)Violation Pattern
# Invoking internal component directly
from myapp.validator import InputValidator # INTERNAL
def when_user_validates_input(self):
validator = InputValidator() # WRONG BOUNDARY
self.result = validator.validate(self.input)Testing internal components creates Testing Theater: tests pass but users cannot access feature through actual entry point. Integration wiring bugs remain hidden.
Mandate 2: Business Language Abstraction
Step methods speak business language, abstract all technical details.
Three Abstraction Layers
**Layer 1 - Gherkin**: Pure business language, all stakeholders. Domain terms from ubiquitous language | Zero technical jargon | Describe WHAT user does, not HOW system does it
Scenario: Customer places order for available product Given customer has items in shopping cart When customer submits order Then order is confirmed And customer receives confirmation email
**Layer 2 - Step Methods**: Business service delegation. Method names use domain terms | Delegate to business service layer (OrderService, not HTTP client) | Assert business outcomes (order.is_confirmed()), not technical state (status_code == 201)
def when_customer_submits_order(self):
self.result = self.order_service.place_order(
customer=self.customer, items=self.cart_items
)
def then_order_is_confirmed(self):
assert self.result.is_confirmed()
assert self.result.has_order_number()**Layer 3 - Business Services**: Production services handle technical implementation. HTTP calls, DB transactions, SMTP hidden inside service layer.
Test Smell Indicators
`requests.post()` in step method | `db.execute()` in step method | `assert response.status_code` | Technical terms in Gherkin
Mandate 3: User Journey Completeness
Tests validate complete user journeys with business value, not isolated technical operations.
Complete Journey Structure
Every scenario includes: **User trigger** (Given/When) | **Business logic** (When - system processes rules) | **Observable outcome** (Then - user sees result) | **Business value** (Then - value delivered)
Correct Example
Scenario: Customer successfully completes purchase Given customer has selected products worth $150 And customer has valid payment method When customer submits order Then order is confirmed with order number And customer receives email confirmation And order appears in customer's order history
Violation Example
Scenario: Order validator accepts valid order data Given valid order JSON exists When validator.validate() is called Then validation passes # Tests isolated validation, not user journey
Scenario Name Test
Does name express user value or technical operation? "Customer completes purchase" = correct. "Validator accepts JSON" = violation.
Walking Skeleton Strategy
Balance user-centric E2E integration tests with focused boundary tests.
Walking Skeletons (2-5 per feature)
Trace thin vertical slice delivering observable user value E2E | Each answers: "Can a user accomplish this goal and see the result?" | Express simplest complete user journey | Validate system delivers demo-able stakeholder value | Touch all layers as consequence of journey, not as design g
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).
Repo: nWave-ai/nWave
Other skills on nwave.
- /nw-ab-critique-dimensions
Review dimensions for validating agent quality - template compliance, safety, testing, and priority validation
Open skill - /nw-abr-critique-dimensions
Review dimensions for validating agent quality - template compliance, safety, testing, and priority validation
Open skill - /nw-ad-critique-dimensions
Review dimensions for acceptance test quality - happy path bias, GWT compliance, business language purity, coverage completeness, walking skeleton user-centricity, priority validation, observable behavior assertions, traceability coverage, and walking skeleton boundary proof
Open skill - /nw-agent-creation-workflow
Detailed 5-phase workflow for creating agents - from requirements analysis through validation and iterative refinement
Open skill - /nw-agent-testing
5-layer testing approach for agent validation including adversarial testing, security validation, and prompt injection resistance
Open skill - /nw-architectural-styles-tradeoffs
Architectural style selection decision matrices, trade-off analysis, structural enforcement rules, and combination patterns. Load when choosing or evaluating architecture styles.
Open skill

