fault is a focused network fault-injection engine for explicit TCP and UDP
proxies. It applies chainable transport faults and records what happened.
Payload inspection is limited to DNS faults on UDP proxies.
Read the single-page fault manual for the complete mental
model, examples, and transport semantics. AI agents can use the compact
agent reference or the repository-owned
fault-network-injection skill.
The project deliberately contains no embedded agent, MCP server, eBPF loader, HTTP mutation layer, traffic generator, or cloud deployment runtime.
- Named TCP and UDP proxies with independent fault chains
- Latency, jitter, bandwidth, blackhole, and connection-reset faults
- DNS delay, timeout, truncation, refusal, SERVFAIL, NXDOMAIN, empty answers, and random A records
- Live changes on long-running connections
- One versioned Run model with ordered YAML or JSON phases
- Per-stream and per-exchange transport evidence with bounded streaming
- Coloured CLI dashboards and durable NDJSON journals
- Embeddable Rust and Python APIs
TCP supports latency, jitter, bandwidth, blackhole, and connection reset. UDP supports latency, jitter, and directional blackhole at the datagram boundary; DNS faults additionally manipulate DNS responses. Bandwidth and connection reset are intentionally unavailable for UDP.
Build the executable with current stable Rust:
cargo build --release -p fault-cliRun an indefinite final phase and send traffic through it:
fault run examples/google-proxy.json
curl --connect-to www.google.com:443:127.0.0.1:18080 \
https://www.google.com/Run several timed phases:
fault run examples/timed-run.yamlCLI configuration accepts .json, .yaml, and .yml. Every document uses
the same versioned Run model: routes at the top, fault chains in phases. A
phase without duration remains active until stopped and must be last.
The command accepts --journal FILE for bounded, best-effort NDJSON transport evidence,
--output text|json, and --color auto|always|never.
Install the bundled network-injection skill for a coding agent:
fault skill install --target codex
fault skill install --target claude
fault skill install --target opencodeUse fault skill show to print the bundled SKILL.md. Existing modified
skills are preserved unless installation is repeated with --force. The
installer asks whether the skill belongs to the current workspace or your home
directory; scripts can provide --scope workspace or --scope home.
The Python package requires Python 3.14 or newer. Build the local PyO3 package and run the adaptive example with:
uv sync --project fault-python --python 3.14 --reinstall-package faultlib
uv run --project fault-python --python 3.14 python examples/python_proxy.pyPython receives typed status, transport-record, and phase-transition objects.
Live record delivery is bounded and best effort: a slow Python consumer never
stalls the proxy, and dropped_records reports missed evidence.
Transport evidence never applies backpressure to the engine. A bounded stream
drops records when its consumer falls behind and reports the loss through
dropped_records.
See fault-python/README.md for the API boundary and
development workflow.
Rust applications embed the same engine used by the CLI:
[dependencies]
fault-engine = "1"
fault-model = "1"See fault-engine/README.md for a complete minimal
example.
fault-model: versioned contracts and schemasfault-engine: asynchronous proxy and schedulerfault-cli: command and presentation adapterfaultlib: PyO3 bindings and Python ergonomicsdocs/schemas/run.schema.json: canonical Run contract
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --lockedThe workspace follows current stable Rust and separately checks Rust 1.85 as its minimum supported version.