Chaos Engineering skill for Codex
Break it on purpose, with a hypothesis. Codex designs fault-injection experiments around a written hypothesis tied to SLIs, with the smallest blast radius that answers it and an abort command ready before the fault starts. It runs latency and outage experiments locally with Toxiproxy, prepares Chaos Mesh or AWS FIS manifests for approved staging or production windows, and turns results into fixes and automated resilience tests.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- chaos-engineering Installs to ~/.agents/skills/chaos-engineering/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install chaos-engineering The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project chaos-engineering Installs to .agents/skills/chaos-engineering/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/chaos-engineering.zipunzip -o chaos-engineering.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) chaos-engineering PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $chaos-engineering, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Plans and runs fault-injection experiments and game days - steady-state hypotheses tied to SLIs, blast radius and abort conditions, faults injected with Toxiproxy, tc netem, Chaos Mesh, LitmusChaos or AWS Fault Injection Service, observation through existing dashboards, and written findings that turn into resilience fixes. Starts locally and in staging, and requires explicit owner approval before touching shared or production systems. Use when asked to test resilience to dependency outages, latency, pod or node loss, to plan a game day, or to verify timeouts, retries, circuit breakers and failover actually work.
Use it when
- Verifying that timeouts, retries, circuit breakers and fallbacks really work
- Planning a game day or failover drill
- Recreating the conditions of a past outage to confirm the fix
- Adding automated resilience tests to an integration suite
Use something else when
- You need to design timeouts, retries and circuit breakers in code: use resilience-patterns
- You need to measure throughput and latency under traffic: use load-testing
- An incident is happening right now: use incident-command
How to check the result
The fault is confirmed active in dependency metrics during the window, steady state is restored afterwards with no residual chaos resources, and each finding has an owner and a fix.
The mistake it prevents
Injecting a fault whose selector or port never matched, then recording a false 'hypothesis held' because nothing actually broke.
An experiment is worth running when it tests a specific hypothesis about steady-state behaviour, its blast radius is the smallest that can answer the question, a named person can abort it in seconds, and the result becomes a fix or a confirmed guarantee. Breaking things without a hypothesis is an outage, not an experiment.
Safety gate (do this before anything else)
- Identify the target environment. Local and ephemeral environments: proceed. Shared staging, pre-production or production: stop and get explicit written approval from the system owner in chat, including time window, scope and abort criteria.
- Confirm monitoring exists for the steady-state metrics; no dashboards means no experiment.
- Confirm an abort mechanism that works even if the tooling fails (delete the chaos
resource, stop the FIS experiment, remove the
tcrule, scale back up). - Confirm on-call knows, and no incident or release is in progress.
- Never run experiments that can destroy data (deleting volumes, dropping tables, corrupting backups) outside disposable environments.
Codex must not apply faults to shared clusters, cloud accounts or production on its own initiative. Prepare the manifests, runbook and commands; let the approved operator execute or confirm each step.
Inspect first
- Read
AGENTS.md, architecture docs, and the dependency map: which services, databases, caches, queues and third-party APIs each request path touches. - Read the resilience code that the experiment will exercise: timeouts, retries with backoff, circuit breakers, bulkheads, fallbacks, health checks, PodDisruptionBudgets, autoscaling, multi-AZ settings.
- Read SLOs and the dashboards for the relevant SLIs (success rate, latency p99, queue
depth, error budget). See
slo-error-budgets. - Review recent incidents; the best experiments re-create the conditions of past outages.
Write the hypothesis
### Experiment: Redis latency on cart service
Hypothesis: When Redis p99 latency rises to 500 ms for 5 minutes, cart API success rate stays
>= 99.5% and p99 latency stays < 800 ms, because the cache client times out at 100 ms and
falls back to Postgres.
Steady state (measured 30 min before): success 99.95%, p99 210 ms.
Fault: +500 ms latency, 100 ms jitter on traffic to redis-cart; 5 minutes.
Blast radius: staging namespace `cart`, 1 of 3 Redis replicas' clients via Toxiproxy.
Abort if: success < 98% for 60 s, or p99 > 2 s, or any alert pages on-call.
Abort action: `toxiproxy-cli toxic remove -n redis_latency redis-cart`.
Owner / operator / observer: <names>. Window: <date, time, timezone>.
Choose the fault and the tool
| Question | Fault | Tool |
|---|---|---|
| Do timeouts and fallbacks work for one dependency? | Latency, connection refused, reset, slow close | Toxiproxy (local, CI, staging) |
| How does a host or container behave on a bad network? | Delay, loss, corruption, bandwidth limit | tc netem (Linux, needs root) |
| Does the service survive pod loss and rescheduling? | Pod kill, container kill | Chaos Mesh PodChaos, LitmusChaos |
| Kubernetes network partitions and DNS failures | Partition, delay, DNS errors | Chaos Mesh NetworkChaos, DNSChaos |
| Resource exhaustion | CPU, memory stress, disk fill | Chaos Mesh StressChaos, stress-ng |
| AWS instance, AZ or managed-service disruption | Stop instances, throttle APIs, AZ power interruption scenario | AWS Fault Injection Service with stop conditions on CloudWatch alarms |
| Multi-step failover (region, database primary) | Orchestrated sequence | Game day with a runbook, tool per step |
Start with the smallest fault that tests the hypothesis: one dependency, one replica, a few minutes. Increase scope only after a clean result.
Local and CI experiments (no approval needed)
# Toxiproxy in front of Redis for an integration test or docker compose stack
toxiproxy-server &
toxiproxy-cli create -l 0.0.0.0:26379 -u redis:6379 redis-cart
toxiproxy-cli toxic add -t latency -a latency=500 -a jitter=100 -n redis_latency redis-cart
# point the app at :26379, run the scenario, then
toxiproxy-cli toxic remove -n redis_latency redis-cart
Automate the important ones as resilience tests in the integration suite (Toxiproxy has clients for Go, Java, Python, Node and a Testcontainers module), so the guarantee is checked on every change rather than once a year.
# Linux host or privileged container: 200 ms delay, 1% loss on eth0 (needs root)
tc qdisc add dev eth0 root netem delay 200ms 50ms loss 1%
tc qdisc del dev eth0 root # abort / cleanup
Kubernetes (staging, with approval)
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: cart-to-redis-latency
namespace: cart
spec:
action: delay
mode: all
selector:
namespaces: ["cart"]
labelSelectors: { app: cart-api }
direction: to
target:
mode: all
selector:
namespaces: ["cart"]
labelSelectors: { app: redis-cart }
delay:
latency: "500ms"
jitter: "100ms"
duration: "5m"
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: kill-one-cart-pod
namespace: cart
spec:
action: pod-kill
mode: one
selector:
namespaces: ["cart"]
labelSelectors: { app: cart-api }
Abort: kubectl delete networkchaos cart-to-redis-latency -n cart. Verify with kubectl get networkchaos -A that nothing is left running after the window.
Running the experiment or game day
- Announce start in the agreed channel (the operator does this; Codex drafts the message).
- Record steady state for at least 15-30 minutes beforehand.
- Inject the fault; note the exact start time.
- Observe the SLIs and the specific mechanism (did the circuit breaker open? did the fallback query run? did autoscaling trigger?). Collect traces and logs.
- Abort immediately on any abort condition. Aborting is a valid result.
- Remove the fault; confirm return to steady state and that no residual faults remain.
- Debrief within a day while details are fresh.
Reading results
| Outcome | Meaning | Next step |
|---|---|---|
| Hypothesis held, mechanism observed | Guarantee confirmed | Automate as a recurring test; widen scope next time |
| Hypothesis held, mechanism not observed | Passed by luck (fault did not apply, traffic too low) | Fix the experiment, rerun |
| Hypothesis failed | Found a weakness before customers did | File fixes with owners; rerun after the fix |
| Aborted | Blast radius larger than expected | Treat as an incident review; shrink scope |
Output template
## Chaos experiment report: <name> (<date>)
Environment: <staging/prod> | Approved by: <owner> | Operator: <name>
Hypothesis: <...>
Result: held | failed | aborted at <time> because <condition>
Timeline: <start, fault injected, observations, removed, steady state restored>
Observations: <SLIs with numbers, mechanism evidence (traces, logs, dashboard links)>
Findings:
1. <weakness> - impact - fix - owner - due
Follow-ups: <automated resilience test added? next experiment?>
Gotchas
- Retries without backoff and jitter turn a latency fault into a retry storm; watch the dependency’s request rate, not only the caller’s errors.
- Health checks that call dependencies make every pod fail readiness together when the dependency slows. Liveness checks must not depend on downstream services.
- A fault that does not apply (wrong selector, wrong port) produces a false “held”. Always confirm the fault is active (latency visible in dependency metrics) before judging.
- Chaos tooling with cluster-wide permissions is itself a risk; scope its RBAC to target namespaces.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Chaos Engineering"
short_description: "Break it on purpose, with a hypothesis"
default_prompt: "$chaos-engineering Test whether our cart service survives Redis getting slow" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.