nw-distill
nw-distill teaches acceptance test creation for the DISTILL wave by teaching the orchestrator's acceptance designer agent how to write tests following port-to-port principles, prior wave reading, wave-decision reconciliation, graceful degradation, and document back-propagation. Use this skill to guide AT authoring in any language by detecting the target project's manifest files first, then adapting all code examples and test-framework idioms to match the project's actual language conventions and file structure rather than assuming Python.
git clone --depth 1 https://github.com/nWave-ai/nWave /tmp/nw-distill && cp -r /tmp/nw-distill/nWave/skills/nw-distill ~/.claude/skills/nw-distillSKILL.md
# DISTILL Methodology: Acceptance Test Creation
This skill provides the acceptance designer's methodology for creating acceptance tests. The orchestrator controls the overall flow (agent dispatch, review gate, handoff) -- this skill focuses on HOW to create good acceptance tests.
## 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 authoring ATs**, detect the target project's language from these manifest files (in order):
- `package.json` → TypeScript / JavaScript (jest, vitest, cucumber-js, playwright)
- `Cargo.toml` → Rust (cargo test, proptest, cucumber-rust)
- `go.mod` → Go (testing, ginkgo, godog)
- `pyproject.toml` / `setup.py` / `Pipfile` → Python (pytest, pytest-bdd, hypothesis)
- `pom.xml` / `build.gradle` → Java / Kotlin (JUnit5, Cucumber-JVM, jqwik)
- `*.csproj` / `*.fsproj` → C# / F# (xUnit, SpecFlow, FsCheck)
- `Gemfile` → Ruby (RSpec, Cucumber-Ruby)
- `Package.swift` → Swift (XCTest, swift-testing)
**When the target language is NOT Python**:
1. Adapt EVERY code example to the target language's conventions (naming, imports, type system, test-framework idioms, file extensions).
2. Replace Python-specific imports (`from pytest_bdd import ...`, `from hypothesis import ...`, `import dataclasses`) with target-language equivalents (`import { Given, When, Then } from '@cucumber/cucumber'`, `import * as fc from 'fast-check'`, etc.).
3. Replace Python type hints (`def f(x: int) -> str`) with target-language type syntax.
4. Replace Python directory conventions (`tests/`, `__init__.py`) with target conventions (`test/`, `__tests__/`, no init files for TS/JS).
5. Replace Python class/function syntax (`class Customer:`, `def given_port():`) with target equivalents.
**Project conventions ALWAYS WIN** over examples below. If the user's repo has 50 TS files using `describe()/it()` blocks and zero Python files, ATs MUST be TypeScript with `describe()/it()` — never Python pytest-bdd regardless of how authoritative this skill's examples look.
**Empirical anchor**: skill examples being Python-only caused LLM to infer Python conventions universal, leading to Python code emitted in greenfield TS project. Connects [[feedback_language_adapter_plugin_architecture_2026_05_24]] (genericity mandate) + F-LANGUAGE-ADAPTER-PLUGIN-INFRASTRUCTURE epic.
## ADR-025 (2026-05-07) — DISTILL is canonical AT author
DISTILL produces ALL acceptance tests as scaffolded RED (skip/pending markers). DELIVER's 3-phase cycle (RED / GREEN / COMMIT, per ADR-025) does NOT re-author ATs in RED — it only unskips the scaffolds and writes PBT unit tests. Wave separation: DISTILL = "what should the system do" (ATs), DELIVER = "how" (PBT unit + impl). The pre-DELIVER fail-for-right-reason gate (described in this skill) becomes the RED phase entry/exit gate in DELIVER per ADR-025 D2.
## Output Tiers (per D2)
Provenance: feature `lean-wave-documentation` — D2 (schema-typed sections), D10 (one-line expansion descriptions). Tier-1 [REF] sections (always emitted) + Tier-2 EXPANSION CATALOG items (lazy, on-demand) are the two output bands. The `.feature` file remains the SSOT for scenarios; the wave-delta sections are pointers + structured summaries. Full contract: `nWave/skills/nw-density-resolution-contract/SKILL.md`.
### Tier-1 [REF] — always emitted
Under `## Wave: DISTILL / [REF] <Section>` headings:
- Scenario list with tags — table of scenario titles + tags (`@walking_skeleton`, `@US-N`, `@real-io`, `@in-memory`, `@error`, `@property`)
- WS strategy — A/B/C/D selection per Mandate 5 with one-line justification
- Adapter coverage table — per Mandate 6, every driven adapter mapped to at least one `@real-io` scenario
- Scaffolds — list of RED-ready scaffold files created (per Mandate 7) with `__SCAFFOLD__` markers
- Test placement — `tests/{path}/` directory choice with one-line precedent justification
- Driving Adapter coverage — every CLI/endpoint/hook in DESIGN mapped to at least one subprocess/HTTP/hook scenario
- Pre-requisites — DESIGN driving ports + DEVOPS environment matrix the scenarios depend on
### Tier-2 EXPANSION CATALOG — lazy, on-demand (per D10)
Rendered under `## Wave: DISTILL / [WHY|HOW] <Section>` only when requested via `--expand <id>` (DDD-2), the wave-end menu (`expansion_prompt = "ask"`), `mode = "full"` auto-expansion, or an ad-hoc user request mid-session.
| Expansion ID | Tier label | One-line description |
|---|---|---|
| `scenario-alternatives-considered` | [WHY] | Alternative scenario phrasings weighed and rejected (Gherkin variants, tag schemes) |
| `fixture-design-discussion` | [WHY] | Why these tmp_path/conftest fixtures, why these scopes, what they cannot model |
| `edge-case-enumeration` | [WHY] | Full edge-case taxonomy: empty/null/boundary/concurrency/timeout/permission |
| `error-path-rationale` | [WHY] | Why each `@error` scenario was chosen and what failure mode it surfaces |
| `tagging-cookbook` | [HOW] | Cookbook for tag application: `@property`, `@requires_external`, `@walking_skeleton` |
| `scaffold-authoring-recipes` | [HOW] | Per-language scaffold recipes (Python, TS, Go, Rust, Java) with marker conventions |
| `pbt-strategy-notes` | [WHY] | Property-based testing strategies for invariants surfaced by the feature |
| `expansion-catalog-rationale` | [WHY] | Why this set of expansions, why these defaults, why D10 enforces one-line descriptions |
| `domain-language-fact-to-step-table` | [HOW] | Soft gate: agent proposes fact→step-name pairs for user review before committing step-method names to code |
| `policy-bootstrap-template` | [HOW] | `docs/architecture/atdd-infrastructure-policy.md` bootstrap snippet emitted on first DISTILL in a project |
| `tier-b-state-machine-template` | [HOW] | State-machine PBT skeleton for Tier B in-memory jouReview dimensions for validating agent quality - template compliance, safety, testing, and priority validation
Review dimensions for validating agent quality - template compliance, safety, testing, and priority validation
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
Detailed 5-phase workflow for creating agents - from requirements analysis through validation and iterative refinement
5-layer testing approach for agent validation including adversarial testing, security validation, and prompt injection resistance
Architectural style selection decision matrices, trade-off analysis, structural enforcement rules, and combination patterns. Load when choosing or evaluating architecture styles.
Comprehensive architecture patterns, methodologies, quality frameworks, and evaluation methods for solution architects. Load when designing system architecture or selecting patterns.
Canonical AT completeness gate — research-anchored 7-category taxonomy (C1-C7) + 15-item mechanical checklist. Paradigm-neutral. Drives acceptance-designer reviewer verdict deterministically.