# Latency profile for trading bots

DoNotAct is a pre-action Risk Gateway, not a co-located matching engine.

Use it where a bot needs an enforceable stop/go decision before an order,
wallet call, paid tool call or capital-release action. Do not put a remote HTTP
check inside a pure HFT quote loop that cannot tolerate network round trips.

## Current live probe

Measured after the 2026-06-22 latency optimization. Local measurements come
from the production VPS against the app port; public measurements include the
network/TLS path to `donotact.com`.

| Surface | Result | Local app | Public path | Notes |
|---|---:|---:|---:|---|
| `GET /health` | 200 | 24.1 ms | usually tens of ms | process health only |
| `GET /v1/preflight/polymarket/540817?...notional_usd=100` with `X-API-Key: demo` | 200 | 119.9 ms first generated hit | p50 273.6 ms / p95 289.8 ms | action-aware gate with live CLOB snapshot |
| Same market, different `notional_usd` within the 5s snapshot window | 200 | 10.4 ms | p50 269.1 ms / p95 280.3 ms | recomputes size decision without refetching upstream |
| Exact repeated preflight request within response cache | 200 | 7.3 ms | included above | response cache hit; `book_age_ms` still ages |
| `GET /v1/dispute/polymarket/580810` with `X-API-Key: demo` | 200 | 127.4 ms sample | variable | updates dispute ledger/alert path |
| `GET /x402/tx/v1/dispute/polymarket/580810` without payment | 402 | challenge only | p50 261.8 ms / p95 268.8 ms | no settlement retry |

These are operational samples, not an SLA. Network path, market freshness,
venue API state, cache state and process restarts can change the number.

The preflight path uses a short Polymarket snapshot cache. This does not make
old book data look fresh: downstream `book_age_ms` continues to age from the
original public fetch time.

For live process-local metrics, use:

```text
https://donotact.com/status
https://donotact.com/status.json
```

## Integration modes

### Inline HTTP gate

Use this for copy-trading, 5-minute/15-minute markets, capital release,
pre-trade checks and paid tool calls where a roughly sub-second remote gate is
acceptable and repeated checks on the same market should stay hot.

Recommended policy:

```text
strategy/copy signal -> intended action -> DoNotAct HTTP check -> submit only if READY
```

Use a client timeout that allows cold samples. A practical starting point is
`connect_timeout=2s`, `read_timeout=5s`, with one retry only for network/5xx
failures. Never retry aggressively on 4xx.

### Cached local guard

For repeated checks on the same market, cache the latest DoNotAct verdict and
respect `as_of`, `cache_hit`, `book_age_ms`, `source_refs` and response
freshness. If the cached evidence is stale for your policy, fail closed or
refresh before the order path.

### WebSocket / watchlist mode

For latency-sensitive bots that monitor the same markets repeatedly, use paid
monitoring streams instead of opening a fresh HTTP request for every loop.

Pattern:

```text
watchlist / stream -> local latest verdict snapshot -> order path checks local snapshot -> submit only if READY
```

This keeps the stop/go state hot near your bot while DoNotAct remains read-only.

## What to block on timeout

If DoNotAct is unreachable and your bot has no fresh local verdict snapshot, the
safe branch is not to submit the action unattended.

Recommended handling:

- timeout before verdict: `INSUFFICIENT_EVIDENCE`;
- stale local snapshot: `INSUFFICIENT_EVIDENCE` unless your policy explicitly
  permits the age;
- `CAUTION`: local policy branch required;
- `DO_NOT_ACT`: block;
- `READY`: continue only under the exact submitted side, size and slippage
  policy.

## Boundary

DoNotAct does not execute orders, custody funds, sign transactions, route
orders, promise fills, promise latency, or guarantee outcomes. It supplies the
diagnostic stop/go contract your bot can enforce before capital moves.
