Skip to main content

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.

Overview

Sudont enforces a four-node decision architecture called The Diamond. Every transaction an AI swarm wants to execute must pass through all four nodes before any value moves on-chain.
          "Intent + Physics + Policy = Verdict"

                  ┌───────────────────────┐
                  │   THE CONSTITUTION    │  ← Layer 1: THE LAW
                  │   user-defined policy │
                  └───────────┬───────────┘

               ┌──────────────┴──────────────┐
               │                             │
        ┌──────▼──────┐               ┌──────▼──────┐
        │ THE CORTEX  │               │  THE CAGE   │  ← Layer 2: THE BODY
        │ intent      │               │  physics    │
        │ extraction  │               │  simulation │
        └──────┬──────┘               └──────┬──────┘
               │                             │
               └──────────────┬──────────────┘

                  ┌───────────▼───────────┐
                  │     THE JUDGE         │  ← Layer 3: THE VERDICT
                  │  ALLOW · DENY         │
                  │  DIAGNOSE_ONLY        │
                  └───────────────────────┘
The Diamond is a fan-out / fan-in shape: it fans out from a single policy source (Constitution) into two parallel verification paths (Cortex and Cage), then converges at a single verdict (Judge). No single node can approve or reject alone.
The Judge requires both the Cortex’s canonical intent and the Cage’s bare-metal simulation results to produce any verdict. When a transaction is fatal, the Judge emits a deterministic JSON ReAct error that the swarm consumes directly. See Agentic ReAct Loop.

Three Pillars

The Diamond is organised around three architectural pillars that together define Sudont’s execution physics.

Zero Integration Friction

No custom SDKs. We are a drop-in RPC proxy. Point your standard Web3 libraries at us, and we handle the rest.

Dual-Engine Physics

We drop every transaction into a local LiteSVM or revm memory sandbox. We simulate the exact mathematical State-Diff of the market before it hits the chain.

Agentic Cybernetics

When a fatal trade is blocked, we don’t output human prose. We fire deterministic JSON ReAct errors back to your AI, allowing it to instantly recalculate its route.

The Four Layers

Layer 1: The Constitution — THE LAW

“The law that governs what is acceptable before a transaction leaves the system.”
Rust crate: sudont-constitutionThe Constitution is the top of the Diamond. It defines rules that every transaction is evaluated against. Operators author policy in JSON or YAML; the Constitution compiles this into an immutable policy object used throughout the hot path.
FieldPurpose
chain_allowlistPermitted chain IDs
protocol_allowlistPermitted protocol identifiers (e.g. uniswap_v3, aerodrome)
target_allowlistPermitted router/contract addresses
token_allowlist / token_denylistPer-token permissions
max_trade_sizeAbsolute size cap in base units
max_slippage_bpsSlippage tolerance in basis points
max_price_impact_bpsPrice impact cap
min_liquidityMinimum pool liquidity threshold
private_route_requiredForce private mempool egress
fail_closedReject any transaction with uncertain state
The PolicySnapshot struct in sudont-types captures the compiled policy at a point in time. All policy decisions are deterministic and auditable.

The Constitution Compiler

The compiler (rust/constitution/src/compiler.rs) transforms operator-facing JSON into an optimised CompiledPolicy:
  • Address lists (target_allowlist, token_allowlist, etc.) → HashSet<[u8; 20]> for O(1) membership checks
  • Program hashes → HashSet<[u8; 32]> for Solana program verification
  • Numeric thresholds (max_slippage_bps, max_trade_size, etc.) → direct U256 comparisons
The compiled policy is wrapped in Arc<CompiledPolicy> for zero-copy sharing across threads. It is loaded once at startup and shared across every Judge evaluation — no runtime modification, no admin override. If fail_closed is set, any unknown state or missing data results in a DENY verdict.

Layer 2a: The Cortex — CANONICAL INTENT

“Canonical intent — what transaction did the swarm actually emit?”
Rust crate: sudont-cortexThe Cortex parses raw signed transactions, unsigned tx requests, and typed trade requests, then normalises them into a CanonicalIntent.
CanonicalIntent
pub struct CanonicalIntent {
    pub vm_type: VmType,       // Evm or Svm — routes to the correct Cage
    pub from: Address,
    pub to: Option<Address>,
    pub value: U256,
    pub data: Bytes,
    pub nonce: u64,
    pub gas_limit: u64,
    // Swap-specific (optional)
    pub token_in: Option<Address>,
    pub token_out: Option<Address>,
    pub amount: Option<U256>,
    pub slippage_bps: Option<U256>,
}
The Cortex is deterministic — no LLM in the hot path. Unknown fields are preserved as explicit nulls; the Cortex never fabricates intent it cannot infer.

Layer 2b: The Cage — DUAL-ENGINE PHYSICS

“Bare-metal physics — drop the transaction into a local sandbox and compute the exact State-Diff.”
Rust crates: sudont-cage (revm), sudont-cage-svm (LiteSVM)The Cage drops the transaction into a local revm or LiteSVM memory sandbox and computes the exact mathematical State-Diff of the market against current chain state. Both cages implement the SimulationEngine trait:
SimulationEngine Trait
pub trait SimulationEngine: Send + Sync {
    fn simulate(&self, intent: &CanonicalIntent) -> Result<SimOutcome, String>;
}
SimOutcome
pub struct SimOutcome {
    pub success: bool,
    pub exit_reason: String,
    pub logs: Vec<SimLog>,
    pub asset_changes: Vec<AssetChange>,
    pub state_diff: Vec<StateDiff>,
}
UniversalStateDiff normalises both engines’ output into a single type — BalanceChange entries, simulated_price_impact_bps, programs_touched, and reverted_on_chain — so the Judge works identically for EVM and SVM. What the Cage produces is fact, not opinion: an auditor can verify the Cage’s output by replaying the same simulation locally. Execution is deterministic. The Cage cannot make allow/veto decisions and cannot see the agent’s intent; it only reports what the physics of the transaction would produce.

Layer 3: The Judge — VERDICT

“The verdict engine — does canonical intent match the simulated State-Diff, and does the State-Diff satisfy mathematical bounds?”
Rust crate: sudont-judgeThe Judge receives the CanonicalIntent from Cortex, the SimOutcome from Cage, and the compiled PolicySnapshot from Constitution, then produces one of four verdicts:
VerdictWhenOutput
ALLOWCanonical intent matches State-Diff, within Constitution boundsEIP-191 signed approval artifact
DENYState-Diff violates bounds, or Constitution hard-violatedDeterministic JSON ReAct error payload
INTERROGATEMedium-risk signal detectedDeterministic JSON ReAct error — swarm recalculates
DIAGNOSEDiagnosis-only request (no forwarding)Full diagnosis envelope; never broadcasts
VerdictDecision Enum
pub enum VerdictDecision {
    Allow,
    Deny,
    Interrogate,
    Diagnose,
}
Reason codes are stable and machine-readable: SUDONT_SLIPPAGE_EXCEEDED, SUDONT_PRICE_IMPACT_EXCEEDED, SUDONT_POLICY_DENY, SUDONT_UNSUPPORTED_TARGET, SUDONT_UNKNOWN_STATE, SUDONT_INTENT_OUTCOME_MISMATCH, SUDONT_UNAUTHORIZED_RECIPIENT.

Decision criteria — Trade pipeline

ALLOW if:
  ├── destination is on allowlist (Constitution)
  ├── amount ≤ constitutional limit
  ├── reality.amount_out ≥ intent.min_out        ← intent matches physics
  └── reality.slippage_bps ≤ intent.max_slippage  ← physics within tolerance

DENY if any of:
  ├── destination not recognized
  ├── amount exceeds constitutional limit
  ├── slippage exceeds intent constraint          ← physics diverges from intent
  └── output below minimum                       ← agent would receive less than claimed

Decision criteria — Raw TX pipeline

ALLOW if:
  ├── destination is valid and allowlisted
  └── amount within constitutional limits

INTERROGATE if:
  └── destination is a contract AND not allowlisted
      → Cortex interrogation protocol activates

DENY if:
  ├── agent fails interrogation (cannot provide allowlisted destination)
  ├── invalid destination
  └── invalid amount

The signed approval artifact

When the Judge issues ALLOW, the approval binds the verdict to the exact parameters evaluated:
{
  "kind": "sudont_approval_v1",
  "issued_at": 1739289600,
  "destination": "0x7a250d...",
  "amount_eth": 0.25,
  "intent_min_out": 500.0,
  "intent_max_slippage_bps": 100,
  "reality_amount_out": 510.5,
  "reality_slippage_bps": 42,
  "pool_id": "0xB4e16d...",
  "execution_engine": "revm-proxy",
  "simulation_time": "sub-millisecond local hot path",
  "gas_used": 152847
}
Signed with EIP-191 (eth_account.sign_message) using a dedicated policy key. The signature is non-repudiable — you cannot fabricate an approval after the fact.

The ReAct Loop

When the Judge blocks a fatal trade, the Diamond fires a deterministic JSON error straight back into the swarm’s ReAct loop:
Judge → JSON ReAct error → Swarm (recalculate_route) → Diamond (re-enter) → Judge
Sudont never emits human prose to an agent. Every block ships with a stable rule_id, a machine-readable simulated_reality, and an actionable_feedback token the swarm consumes directly. The agent recalculates; the firewall stays out of its loop.
See Agentic ReAct Loop for payload structure, trigger conditions, and integration patterns.

The Event Stream — Observable Diamond

Every node in the Diamond emits structured events as it operates. These events form the audit trail.
EventEmitterContent
system_eventAny Diamond nodeComponent-level actions (CORTEX, CAGE, JUDGE, CONSTITUTION, SIGNER)
log_eventCortex pipelineStructured trace lines for the operator console
status_eventCortex orchestrationPipeline state transitions (idle → analyzing → vetoed)
Every event carries:
  • run_id — correlates all events for a single request
  • agent — which AI agent made the request
  • module — which Diamond node acted
  • kind — classification (request, interrogation, verdict, approval, headline, blast_radius)
The HUD (hud/src/App.jsx) consumes this event stream and renders it in real time. The HUD is read-only and passive — it cannot influence the Diamond’s decisions. An operator observes but cannot override.

Why This Holds Up Under Audit

1. The Diamond is deterministic

Every transaction follows the same path through the same four nodes. There are no skip paths, no admin overrides, no manual approvals. The Constitution defines the rules; the Diamond enforces them.

2. No single node can decide alone

Diamond nodeCan doCannot do
ConstitutionDefine rulesExecute transactions
CortexAnalyse intent, interrogateApprove, sign, modify policy
CageSimulate physicsMake judgements, see intent
JudgeCross-validate, sign, denyModify simulations, override policy
The intent path (Cortex) and the physics path (Cage) are independent. Neither can influence the other. The Judge needs both to converge before it can act.

3. Adversarial interrogation record

MEDIUM-risk transactions don’t get a silent pass/fail. The Cortex interrogates the agent, logging its exact responses. Auditors can independently review what the agent claimed versus what the firewall verified — evidence of agent behaviour under scrutiny, not just outcomes.

4. Cryptographic non-repudiation

Every ALLOW verdict produces an EIP-191 signature binding the policy signer to the exact parameters (amount, destination, slippage, simulation results). An auditor can independently verify any approval artifact against the signer’s public address. You cannot forge a historical approval.

5. Fail-secure at every node

FailureDiamond behaviour
revm cache missCage state hydrator fetches missing slots from the configured RPC backend
Local node out-of-syncCage degrades to remote RPC fallback and escalates unknown contracts to Cortex interrogation
CompiledPolicy load failureStartup fails — never runs without a valid policy (fail-closed)
Simulation errorJudge returns DENY with SUDONT_INTERNAL_SIMULATION_ERROR reason code
Every failure mode defaults to the more restrictive path. The Diamond never silently degrades security.

6. Policy is versioned and declarative

The Constitution is tracked in Git:
  • constitution.json — operator-facing policy (readable, diffable)
  • CompiledPolicy — in-memory compiled representation (O(1) lookups, HashSet-backed)
An auditor can diff the JSON to see what the operator changed, verify that the Rust compiler produces the correct CompiledPolicy from any given JSON, and read the JSON without understanding the Rust enforcement code.

7. Risk classification is deterministic

The rules that determine when to interrogate (MEDIUM risk) are compiled math checks in the CompiledPolicy — not external rule engines. Adding a new risk heuristic is a policy JSON change compiled at startup.

8. Complete event lineage

Every step through the Diamond emits a timestamped event with run_id correlation. An auditor can reconstruct the full decision path — from intercept through simulation and interrogation to verdict — using the event stream alone, without access to the code.

Project Structure

rust/
├── types/           ← Shared types (CanonicalIntent, SimOutcome, UniversalStateDiff, Verdict, CompiledPolicy)
├── constitution/    ← Policy compiler (RawConstitution JSON → CompiledPolicy with O(1) HashSet lookups)
├── cortex/          ← Deterministic intent parser (raw tx → CanonicalIntent)
├── cage/            ← EVM simulation engine (revm-backed, implements SimulationEngine trait)
├── cage-svm/        ← SVM simulation engine (LiteSVM-backed, implements SimulationEngine trait)
├── judge/           ← Verdict engine (CanonicalIntent × SimOutcome × PolicySnapshot → Verdict)
├── rpc/             ← JSON-RPC reverse proxy (routes by VmType, catch-all passthrough)
├── cli/             ← CLI tooling
├── bench/           ← Benchmarks
└── tests/           ← Golden tests and integration tests
Dependency direction: all crates depend on sudont-types. The Judge depends on types only — it is completely VM-agnostic. The RPC layer orchestrates the pipeline.