> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sudont.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ReAct Error Payload

> The deterministic JSON payload Sudont fires into agentic ReAct loops. Every block is a stable, machine-readable token — never human prose.

## Overview

When the Judge blocks a fatal trade, Sudont emits a **deterministic JSON ReAct error**
straight back into the swarm's reasoning loop. The payload is the hot-path contract between
the firewall and the agent: every field is stable, machine-readable, and consumable without
prose parsing.

<Note>
  The swarm never reads prose. It reads `rule_id`, `simulated_reality`, and `actionable_feedback` —
  three fields, every time, forever. This is the entire integration surface for agentic recovery.
</Note>

This payload shape is emitted by the **DENY**, **INTERROGATE**, and **DIAGNOSE** verdicts.
`ALLOW` returns an EIP-191 signed approval artifact instead. The diagnosis-only path
(`sudont_diagnoseRawTransaction`) always returns the full envelope without forwarding.

***

## Canonical Payload

Every block ships the same JSON-RPC error shape. Multiple violations are emitted in a single
`violations` array so the swarm can reason about the full conflict in one pass.

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32010,
    "message": "Sudont policy violation",
    "data": {
      "sudont": {
        "violations": [
          {
            "rule_id": "MAX_SLIPPAGE_EXCEEDED",
            "simulated_reality": "99.9% loss due to malicious PDA drain",
            "actionable_feedback": "RECALCULATE_ROUTE_OR_SIZE"
          }
        ],
        "latency_us": 122
      }
    }
  }
}
```

<Tip>
  `latency_us` is the full round-trip budget — canonicalisation, bare-metal simulation, Constitution
  evaluation, and payload serialisation. The headline is not the specific number but the shape of
  the error: a stable, machine-readable JSON payload shaped for a ReAct loop, returned at the speed
  of the RPC itself rather than the speed of a cloud dashboard.
</Tip>

***

## Field Reference

<CardGroup cols={2}>
  <Card title="rule_id" icon="fingerprint">
    A stable uppercase token identifying the Constitution rule that fired. Safe to branch on —
    never changes for a given rule, across versions.
  </Card>

  <Card title="simulated_reality" icon="eye">
    A short machine-readable description of what the Cage observed in the sandbox. Not prose —
    a compact signal the swarm can log verbatim for audit.
  </Card>

  <Card title="actionable_feedback" icon="bolt">
    A stable uppercase token the swarm's ReAct loop branches on to pick a recovery strategy.
    The full token set is enumerated below.
  </Card>

  <Card title="hot_path_tier" icon="gauge-high">
    Relative execution tier for the firewall path. **Planned, not yet emitted by the server** —
    swarms should not branch on this field today.
  </Card>
</CardGroup>

***

## Rule IDs

| `rule_id`                   | Fired by                                                          |
| --------------------------- | ----------------------------------------------------------------- |
| `MAX_SLIPPAGE_EXCEEDED`     | Cage State-Diff exceeded `max_slippage_bps`                       |
| `MAX_PRICE_IMPACT_EXCEEDED` | Cage State-Diff exceeded `max_price_impact_bps`                   |
| `MAX_TRADE_SIZE_EXCEEDED`   | Canonical intent exceeded `max_trade_size`                        |
| `UNLISTED_DESTINATION`      | Target address not in `target_allowlist`                          |
| `UNLISTED_TOKEN`            | Token not in `token_allowlist` or present in `token_denylist`     |
| `UNSUPPORTED_CHAIN`         | Chain ID not in `chain_allowlist`                                 |
| `INTENT_OUTCOME_MISMATCH`   | Canonical intent diverges from simulated State-Diff               |
| `UNKNOWN_STATE`             | Cage could not produce a confident simulation under `fail_closed` |

***

## Actionable Feedback Tokens

The swarm's agentic ReAct loop branches on `actionable_feedback` to pick a recovery strategy.
Every token is a directive, not a sentence.

| Token                         | Meaning                                                       |
| ----------------------------- | ------------------------------------------------------------- |
| `RECALCULATE_ROUTE_OR_SIZE`   | Pick a different route or reduce trade size and resubmit      |
| `PROVIDE_ALLOWLISTED_ADDRESS` | Resubmit with a target from the allowlist                     |
| `REDUCE_APPROVAL_AMOUNT`      | Swap unbounded approval for exact trade amount                |
| `SELECT_DIFFERENT_TOKEN`      | Pick a token in the allowlist                                 |
| `HALT_STRATEGY`               | Terminal — the strategy is not recoverable, halt and escalate |
| `RETRY_WITH_PRIVATE_ROUTE`    | Resubmit through a private mempool egress                     |

***

## Consuming in an Agentic ReAct Loop

The payload is designed to be consumed in two lines of loop code. Branch on
`actionable_feedback`, pick a recovery strategy, and resubmit. No prompt engineering, no prose
parsing, no model inference in the hot path.

```javascript title="ReAct Recovery Branch" theme={null}
const sudont = err?.data?.sudont;
if (!sudont) throw err;

for (const v of sudont.violations) {
  switch (v.actionable_feedback) {
    case "RECALCULATE_ROUTE_OR_SIZE": return recalculate(v);
    case "PROVIDE_ALLOWLISTED_ADDRESS": return reroute(v);
    case "REDUCE_APPROVAL_AMOUNT": return shrinkApproval(v);
    case "HALT_STRATEGY": return halt(v);
    default: return halt(v);
  }
}
```

<Tip>
  Swarms running multiple concurrent strategies should key their recovery table on
  `(rule_id, actionable_feedback)` rather than `actionable_feedback` alone — this lets the loop
  distinguish, for example, a slippage-driven recalculation from a liquidity-driven one.
</Tip>

***

<Card title="Constitution Compiler" icon="scroll" href="/policy">
  Learn how every `rule_id` is lowered into a memory-aligned Rust HashSet so Constitution
  evaluation stays line-rate with the RPC.
</Card>
