/nw-tdd-cross-language
Port the state-delta + property-based testing paradigm to languages other than Python. DIY recipes per language; canonical Python ref shipped in nwave_ai.state_delta.
Claude Code
$ npx -y skills add nWave-ai/nWave --skill nw-tdd-cross-language --agent claude-code
Codex
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a codex -y
Cursor
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a cursor -y
Gemini CLI
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a gemini-cli -y
GitHub Copilot
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a github-copilot -y
OpenCode
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a opencode -y
Windsurf
$ npx skills add nWave-ai/nWave --skill nw-tdd-cross-language -a windsurf -y
SKILL.md
nw-tdd-cross-language.SKILL.mdname: nw-tdd-cross-language
description: Port the state-delta + property-based testing paradigm to languages other than Python. DIY recipes per language; canonical Python ref shipped in nwave_ai.state_delta.
user-invocable: false
disable-model-invocation: true
Cross-Language State-Delta Porting Guide
This optional implementation guide is not a requirement to port an nWave API. Native discovery and applicability live in `nw-test-design-mandates`; its layered-mechanics module owns observation laws. Use incumbent native assertions, generators, shrinking/replay and helpers first. Matching `nw-pbt-*` guidance loads on need; unlisted languages use their real native tooling, not an `EVIDENCE_GAP` merely because no adapter is shipped. Never borrow Python as a substitute. The recipes below illustrate one optional helper implementation.
Unlisted languages (C, C++, OCaml, etc.) use their own native test, generator, shrinker and replay libraries; no Python-derived shim is imposed.
---
Canonical Python reference
**Illustrative Python API contract** (semantics reference only; not a required API, file path or predicate count; see `nwave_ai.state_delta.matcher`):
def assert_state_delta(
before: Mapping[str, Any],
after: Mapping[str, Any],
universe: set[str],
expected: Mapping[str, Predicate],
*,
strict: bool = False,
) -> None: ...
Predicate = Callable[[Any, Any], bool]
# Illustrative predicate factories (not a required set or count):
def prepended_with(prefix: str, sep: str = ":") -> Predicate: ...
def appended_with(suffix: str, sep: str = ":") -> Predicate: ...
def unchanged() -> Predicate: ...
def set_to(value: Any) -> Predicate: ...
def containing(substring: str) -> Predicate: ...
def normalized_to(normalizer: Callable[[Any], Any]) -> Predicate: ...
def idempotent_after(prefix: str, sep: str = ":") -> Predicate: ...
def legacy_healed(detector: Callable[[Any], bool], healed_check: Callable[[Any], bool]) -> Predicate: ...**Semantics**:
- For each key in `universe`:
- If in `expected`: predicate must return True
- If NOT in `expected`: implicit-unchanged (`before[k] == after[k]`)
- `strict=True`: keys in `(before|after) - universe` raise `kind=strict_universe_mismatch`
- Multi-violation: ALL violations collected, ONE AssertionError raised
---
Porting recipe (conditional, language-agnostic)
Only when an existing native assertion/helper cannot express a needed public-state preservation observation, consider a small project-idiomatic helper. Translate the semantics needed by actual consumers, not a mandatory eight-predicate API or fixed path. Do not create a shim or additional allocations merely to match this illustrative Python reference.
Step 1 — Translate the semantics, only if a helper is needed
Adapt the function signatures using language-idiomatic types:
- Universe = set/list of strings (`Set<String>`, `string[]`, `&[String]`, etc.)
- Expected = map of string → predicate (`Map<String, Predicate>`, `{[key: string]: Predicate}`, `HashMap<String, Box<dyn Fn>>`)
- Predicate = callable taking `(old, new) → bool`
Step 2 — Multi-violation collector (illustrative)
function assert_state_delta(before, after, universe, expected, strict=false):
violations = []
for key in universe:
if key in expected:
predicate = expected[key]
if not predicate(before[key], after[key]):
violations.append(predicate_failed_violation(key, before[key], after[key]))
else:
if before[key] != after[key]:
violations.append(undeclared_change_violation(key, before[key], after[key]))
if strict:
for key in (before.keys ∪ after.keys) - universe:
violations.append(strict_universe_mismatch_violation(key, before.get(key), after.get(key)))
if violations:
raise AssertionError(format_multiline_message(violations))Step 3 — Predicates (only those consumers need)
Include only the predicates actual tests need; the Python eight are illustrative, not a required count. If added, each closes over its parameters using the language's idiom (illustrative: TypeScript arrow functions, Rust `move` closures, F# partial application, Java lambdas, Go returned funcs).
Step 4 — Compose with the native PBT library (if any)
If the project already has a generator/shrinker/replay library, it generates inputs and the native assertion or helper validates post-action state. Illustrative sketch:
property "installer preserves user PATH":
forall(path: gen_realistic_path):
before = capture_state()
installer.install(path)
after = capture_state()
assert_state_delta(before, after,
universe={"PATH", "permissions", "hooks"},
expected={"PATH": prepended_with(app_bin)},
strict=true)---
Illustrative mini-examples per language (not required APIs, paths or LOC)
TypeScript / fast-check
import { fc } from 'fast-check';
import { assertStateDelta, prependedWith } from './state-delta'; // hypothetical helper
fc.assert(
fc.property(pathStrategy(), (userPath) => {
const before = captureState();
installShims(userPath);
const after = captureState();
assertStateDelta(before, after, {
universe: ['PATH', 'permissions', 'hooks'],
expected: { PATH: prependedWith('/app/bin') },
strict: true,
});
})
);Rust / proptest
use proptest::prelude::*;
use crate::state_delta::{assert_state_delta, prepended_with}; // hypothetical helper
proptest! {
#[test]
fn installer_preserves_user_path(user_path in path_strategy()) {
let before = capture_state();
install_shims(&user_path);
let after = capture_state();
assert_state_delta(
&before, &after,
&["PATH", "permissions", "hooks"],
&[("PATHRead more
name: nw-tdd-cross-language description: Port the state-delta + property-based testing paradigm to languages other than Python. DIY recipes per language; canonical Python ref shipped in nwave_ai.state_delta. user-invocable: false disable-model-invocation: true
Cross-Language State-Delta Porting Guide
This optional implementation guide is not a requirement to port an nWave API. Native discovery and applicability live in `nw-test-design-mandates`; its layered-mechanics module owns observation laws. Use incumbent native assertions, generators, shrinking/replay and helpers first. Matching `nw-pbt-*` guidance loads on need; unlisted languages use their real native tooling, not an `EVIDENCE_GAP` merely because no adapter is shipped. Never borrow Python as a substitute. The recipes below illustrate one optional helper implementation.
Unlisted languages (C, C++, OCaml, etc.) use their own native test, generator, shrinker and replay libraries; no Python-derived shim is imposed.
---
Canonical Python reference
**Illustrative Python API contract** (semantics reference only; not a required API, file path or predicate count; see `nwave_ai.state_delta.matcher`):
def assert_state_delta(
before: Mapping[str, Any],
after: Mapping[str, Any],
universe: set[str],
expected: Mapping[str, Predicate],
*,
strict: bool = False,
) -> None: ...
Predicate = Callable[[Any, Any], bool]
# Illustrative predicate factories (not a required set or count):
def prepended_with(prefix: str, sep: str = ":") -> Predicate: ...
def appended_with(suffix: str, sep: str = ":") -> Predicate: ...
def unchanged() -> Predicate: ...
def set_to(value: Any) -> Predicate: ...
def containing(substring: str) -> Predicate: ...
def normalized_to(normalizer: Callable[[Any], Any]) -> Predicate: ...
def idempotent_after(prefix: str, sep: str = ":") -> Predicate: ...
def legacy_healed(detector: Callable[[Any], bool], healed_check: Callable[[Any], bool]) -> Predicate: ...**Semantics**:
- For each key in `universe`:
- If in `expected`: predicate must return True
- If NOT in `expected`: implicit-unchanged (`before[k] == after[k]`)
- `strict=True`: keys in `(before|after) - universe` raise `kind=strict_universe_mismatch`
- Multi-violation: ALL violations collected, ONE AssertionError raised
---
Porting recipe (conditional, language-agnostic)
Only when an existing native assertion/helper cannot express a needed public-state preservation observation, consider a small project-idiomatic helper. Translate the semantics needed by actual consumers, not a mandatory eight-predicate API or fixed path. Do not create a shim or additional allocations merely to match this illustrative Python reference.
Step 1 — Translate the semantics, only if a helper is needed
Adapt the function signatures using language-idiomatic types:
- Universe = set/list of strings (`Set<String>`, `string[]`, `&[String]`, etc.)
- Expected = map of string → predicate (`Map<String, Predicate>`, `{[key: string]: Predicate}`, `HashMap<String, Box<dyn Fn>>`)
- Predicate = callable taking `(old, new) → bool`
Step 2 — Multi-violation collector (illustrative)
function assert_state_delta(before, after, universe, expected, strict=false):
violations = []
for key in universe:
if key in expected:
predicate = expected[key]
if not predicate(before[key], after[key]):
violations.append(predicate_failed_violation(key, before[key], after[key]))
else:
if before[key] != after[key]:
violations.append(undeclared_change_violation(key, before[key], after[key]))
if strict:
for key in (before.keys ∪ after.keys) - universe:
violations.append(strict_universe_mismatch_violation(key, before.get(key), after.get(key)))
if violations:
raise AssertionError(format_multiline_message(violations))Step 3 — Predicates (only those consumers need)
Include only the predicates actual tests need; the Python eight are illustrative, not a required count. If added, each closes over its parameters using the language's idiom (illustrative: TypeScript arrow functions, Rust `move` closures, F# partial application, Java lambdas, Go returned funcs).
Step 4 — Compose with the native PBT library (if any)
If the project already has a generator/shrinker/replay library, it generates inputs and the native assertion or helper validates post-action state. Illustrative sketch:
property "installer preserves user PATH":
forall(path: gen_realistic_path):
before = capture_state()
installer.install(path)
after = capture_state()
assert_state_delta(before, after,
universe={"PATH", "permissions", "hooks"},
expected={"PATH": prepended_with(app_bin)},
strict=true)---
Illustrative mini-examples per language (not required APIs, paths or LOC)
TypeScript / fast-check
import { fc } from 'fast-check';
import { assertStateDelta, prependedWith } from './state-delta'; // hypothetical helper
fc.assert(
fc.property(pathStrategy(), (userPath) => {
const before = captureState();
installShims(userPath);
const after = captureState();
assertStateDelta(before, after, {
universe: ['PATH', 'permissions', 'hooks'],
expected: { PATH: prependedWith('/app/bin') },
strict: true,
});
})
);Rust / proptest
use proptest::prelude::*;
use crate::state_delta::{assert_state_delta, prepended_with}; // hypothetical helper
proptest! {
#[test]
fn installer_preserves_user_path(user_path in path_strategy()) {
let before = capture_state();
install_shims(&user_path);
let after = capture_state();
assert_state_delta(
&before, &after,
&["PATH", "permissions", "hooks"],
&[("PATHAI 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-tdd-cross-language.
- Which coding agents can use nw-tdd-cross-language?
- nw-tdd-cross-language 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.

