| leader-crash | 3cp/3h/1e | SIGKILL the raft leader while traffic flows through the edge | a new leader is elected, committed writes survive, new writes succeed, and no workload request fails |
| cp-total-outage | 1cp/2h/1e | SIGKILL every control-plane member for 15s, then restart | hosts enter offline-hold, admitted workloads keep running with the same PIDs, no request fails, buffered observations are delivered after recovery |
| host-crash | 1cp/4h/1e | SIGKILL a host agent and all of its workloads (machine loss) | the edge stops routing to the dead replica without failed requests, the host is marked lost, and the replica is rescheduled and observed running elsewhere |
| agent-restart | 1cp/2h/0e | SIGKILL dh-noded only (workloads keep running) and restart it | the restarted agent re-adopts every workload by PID and kernel start time without restarting it |
| journal-corruption | 1cp/2h/0e | stop a host agent, flip bytes inside one entry of its hash-chained journal, restart it | the host detects the named break, enters ledger-corrupt mode, keeps admitted work, refuses new work, and never appends to the broken chain; after the local operator seals the journal (kept byte-for-byte) the host admits work again and its new chain records the break |
| network-partition | 1cp/4h/1e | drop every WireGuard packet to and from one host at the fault proxies and cut its control-plane channel for 25s, then heal | the isolated host keeps its admitted workload, gossip suspects it, the control plane marks it lost and reschedules, no request fails, and after healing the cluster converges to exactly the desired replicas |
| packet-chaos | 1cp/3h/1e | on every WireGuard path: 5% loss, 10% duplication, 10% reordering, +40ms delay for 20s | WireGuard and TCP absorb the faults: no request fails, the measured mesh RTT reflects the injected delay, and it returns to baseline when faults are cleared |
| clock-skew | 1cp/2h/0e | shift one host's clock +120s, then −120s, then restore | a skewed host detects it from signed bundle timestamps, holds admitted work, refuses new work (CLOCK_SKEW / stale plane), and returns to normal when the clock is corrected |
| stale-generation | 1cp/3h/1e | cut one host from the control plane, roll the app to a new generation, heal | the cut-off host keeps the generation it admitted (never runs an unsigned one), the console shows it as stale, other hosts roll within maxUnavailable, and after healing every replica runs the new generation |
| replay-forgery | 1cp/2h/0e | resend a committed host observation; send one signed by a foreign key; send one with a flipped field | each is rejected with a specific reason and recorded; the host's real state is unchanged |
| revoked-host | 1cp/4h/1e | revoke a host that serves a replica while traffic flows | the revoked host keeps its admitted workload but is removed from the mesh and the edge routing table, the replica is rescheduled, and no request fails |
| storage-replica-loss | 1cp/4h/1e | delete every stored object on one replica host while it runs | anti-entropy detects the missing objects by Merkle comparison, repairs them from peers with signed evidence, and the volume returns to HEALTHY with identical data |
| disk-full | 1cp/4h/1e | make every new write on one replica host fail with ENOSPC (storage-layer injection), write new data, then clear it | the volume is reported DEGRADED — never falsely HEALTHY — while the replica cannot store data; writes still commit on the other replicas; after the disk frees, anti-entropy restores HEALTHY |
| oom | 1cp/1h/0e | run a container limited to 32 MiB that allocates without bound | the container runtime kills it (OOMKilled=true), the host reports oom-killed from runtime evidence, audits it, and restarts it with backoff |
| interrupted-deployment | 3cp/3h/1e | apply a new generation and SIGKILL the raft leader as soon as the first replica has rolled | the new leader resumes the rollout, it completes, and requests keep succeeding (maxUnavailable respected) |
| interrupted-storage-write | 1cp/4h/1e | write 24 MiB, then SIGKILL the primary host (agent and workload) while the new snapshot is still pending | committed data is intact after recovery, and the interrupted write is either fully committed or absent — never partial |
| postgres-outage | 1cp/1h/0e | stop the Postgres evidence mirror, keep operating, restart it | while Postgres is down the console reports JOURNAL ONLY (never DB COMMITTED), writes still commit through raft, and the mirror catches up to DB COMMITTED after recovery |