# Evolution 18 — performance

**Synthetic, local, single process.** One small write per iteration, 200 iterations after 20 warm-up, in a temporary
directory on this host (6 vCPU, Linux 7.0.0-38, Python 3.14.4). Not a deployment measurement. Raw data:
`performance_results.json`; command: `python3 scripts/evolution18/run_evidence.py`.

Each row measures decision + enforcement + execution + evidence for one action (authorize, execute, receipt).

| Configuration | p50 ms | p95 ms | p99 ms | actions/s | level reached | verdict |
|---|---|---|---|---|---|---|
| Evolution 17 `RuntimeBridge` (path executor, observer = a function in the same process) | 0.56 | 0.59 | 0.69 | 1,778 | — | — |
| Evolution 18, no sensor | 3.50 | 3.62 | 3.81 | 285 | INSTRUMENTED | INCOMPLETE |
| Evolution 18, snapshot sensor only | 4.15 | 4.68 | 5.22 | 237 | EXTERNALLY_OBSERVED | INCOMPLETE |
| Evolution 18, both sensors, 11 files under the root | 10.59 | 12.99 | 14.78 | 97 | INDEPENDENTLY_CORROBORATED | VERIFIED |
| Evolution 18, both sensors, 1,001 files under the root | 29.33 | 39.32 | 43.31 | 33 | INDEPENDENTLY_CORROBORATED | VERIFIED |

Errors: 0 in every configuration (every iteration completed).

| Other cost | Value |
|---|---|
| receipt size (median, both sensors) | ~19 KB JSON, 12 graph nodes |
| clean-room verification of one receipt | p50 2.5 ms, p99 5.5 ms |
| sensor process memory (RSS) | 19–32 MB each |
| enforcer process peak RSS during the whole run | 113 MB |
| enforcer CPU for 220 actions | 1.3–1.5 s (≈ 6–7 ms CPU per action, mostly Ed25519 signing of ~9 nodes and JSON canonicalization in pure Python) |
| restart recovery with one ambiguous intent | 1.2 ms |

## Reading the numbers

- The evidence is not free: the verified configuration is about **20× slower** than Evolution 17's unobserved path on
  a small tree and about **52× slower** on a 1,000-file tree. Evolution 17's figure is fast because it observes
  nothing real.
- The snapshot sensor's cost grows with the size of the tree (it hashes everything twice). At 1,000 small files that is
  ~20 ms of the 30 ms. It will not scale to a large working directory; a production design needs a smaller root per
  action, a content-addressed cache, or a kernel-side sensor.
- The event sensor costs ~6–7 ms per action here, most of it re-adding a watch per directory at every arm.
- No security check was removed or sampled to get these numbers. No optimization was attempted.
- Behaviour with incomplete observation is not faster or slower in a way that matters; it changes the verdict
  (rows 2 and 3), which is the point.

## What a customer would have to accept

One action at a time per root (the lock refuses concurrency), tens of milliseconds per governed file action,
~20 KB of evidence per action, and two extra processes per enforcer. For low-rate consequential actions (a deploy,
a config change, a payment file) that is cheap. For high-rate tool calls it is not.
