RiskOracle

March 23, 2026 · View on GitHub

"Fast pre-action risk oracle. Should I execute this right now?"

Python License: MIT ACP Live

RiskOracle is a standalone pre-action risk oracle for autonomous AI agents. Before any agent executes a swap, trade, hire, or intent — RiskOracle aggregates four independent risk signals into one normalized score and tells the agent whether to proceed, delay, or abort.

RiskOracle is not EP. Not NoLeak. Not MemGuard. It is a risk aggregation layer — the single score before execution.


The Problem

Autonomous agents fail in four distinct ways before any action fires:

Failure ModeRoot CauseSilent?
Policy violationAction not authorized by policyOften
Wallet overexposureToo much capital at risk for current balanceYes
Memory driftState the agent is acting on is stale or corruptedAlways
Execution leakTiming is wrong — signal is valid but conditions aren'tYes

Each failure mode has its own detection service. Without aggregation, an agent must call four services, interpret four responses, and write custom gating logic. RiskOracle does all of that in a single call and returns one number.


Architecture

Agent Action Request


  ┌──────────────┐
  │  RiskOracle   │
  │  /risk/check  │
  └──────┬───────┘

   ┌─────┼──────┬──────────┐
   ▼     ▼      ▼          ▼
  EP    NoLeak  MemGuard  Wallet
 Guard  Check    Check    Check
 (35%)  (15%)   (20%)    (30%)
   │     │      │          │
   └─────┼──────┴──────────┘

   Weighted Score
    (0.0 → 1.0)

  ┌──────┴───────┐
  │  < 0.30      │ → proceed
  │ 0.30 – 0.60  │ → delay
  │  > 0.60      │ → abort
  └──────────────┘

How It Works

  1. Agent sends a proposed action + context to /risk/check
  2. RiskOracle calls four scoring components in parallel — each with a 3s hard timeout
  3. Scores are weighted and aggregated into a single riskScore (0.0 – 1.0)
  4. A recommendedAction is returned: proceed, delay, or abort
  5. A cryptographic proofHash is generated as an immutable record
  6. Everything is logged to Postgres asynchronously (never blocks the response)

Fail-Open Guarantee

RiskOracle never blocks the trading loop. If any dependency times out or errors:

  • That component returns a low-risk fallback score
  • The agent still gets a valid response
  • The fallback is logged for audit
  • proofHash is always generated — never null, even on full failure

Scoring Weights

ComponentWeightSourceWhat It Measures
policyViolation35%EP /ep/validateIs this action authorized by policy?
walletRisk30%Internal calculationCapital-to-balance exposure ratio
memoryDrift20%MemGuard /memguard/checkIs the agent's state fresh or stale?
executionLeak15%NoLeak /noleak/checkIs the timing right for execution?

Weights reflect impact severity: policy violations and capital exposure are weighted higher than timing or drift.


API

POST /risk/check

Request:

{
  "agentId": "achilles",
  "action": {
    "type": "swap",
    "capital": 50
  },
  "context": {
    "walletBalance": 500,
    "memoryState": {
      "price": 2000,
      "ts": 1711234567
    }
  }
}

Response:

{
  "riskScore": 0.068,
  "confidence": 0.978,
  "breakdown": {
    "policyViolation": 0.0,
    "walletRisk": 0.05,
    "memoryDrift": 0.0,
    "executionLeak": 0.35
  },
  "recommendedAction": "proceed",
  "proofHash": "0x9ccb0773102e40130781ed90ba0af08e40fe5454dfcbd4d275b79d9c7416312b",
  "receipt": "riskoracle-v1-0x9ccb07731...",
  "latencyMs": 377,
  "timestamp": "2026-03-23T13:50:17.637554+00:00",
  "schemaVersion": "v1"
}

GET /health

{
  "status": "ok",
  "service": "riskoracle",
  "port": 5090
}

Error Handling

StatusConditionBehavior
200Normal checkFull risk assessment returned
200Dependency timeoutFallback scores used, recommendedAction: "proceed"
400Missing action fieldError message, never 500
200Complete engine failureStub response with low risk — never blocks agent

RiskOracle never returns 500. The catch-all fallback always returns a valid response with recommendedAction: "proceed".


Risk Thresholds

riskScorerecommendedActionMeaning
0.00 – 0.30proceedSafe to execute
0.30 – 0.60delayElevated risk — wait or reduce size
0.60 – 1.00abortHigh risk — do not execute

Running

Prerequisites

pip install flask requests psycopg2-binary

Start the Server

python3 riskoracle_server.py
# → Serving on port 5090

Smoke Test (Engine Only)

python3 riskoracle_engine.py

Curl Test

curl -s -X POST http://localhost:5090/risk/check \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "achilles",
    "action": {"type": "swap", "capital": 50},
    "context": {"walletBalance": 500}
  }' | python3 -m json.tool

systemd Service

sudo systemctl start riskoracle
sudo systemctl status riskoracle
# Runs on port 5090 with Restart=always

Environment Variables

VariableDefaultDescription
EP_GUARD_URLhttps://achillesalpha.onrender.com/ep/validateEP Guard endpoint
NOLEAK_URLhttp://localhost:5070/noleak/checkNoLeak endpoint
MEMGUARD_URLhttp://localhost:5080/memguard/checkMemGuard endpoint

All endpoints are configurable. Zero hardcoded credentials.


Postgres Schema

CREATE TABLE riskoracle_calls (
  id SERIAL PRIMARY KEY,
  timestamp TIMESTAMPTZ DEFAULT NOW(),
  caller_agent_id TEXT,
  action_type TEXT,
  risk_score FLOAT,
  recommended_action TEXT,
  payment_protocol TEXT,
  payment_amount TEXT,
  proof_hash TEXT,
  latency_ms INTEGER,
  classified_as TEXT,
  schema_version TEXT DEFAULT 'v1'
);

CREATE INDEX idx_riskoracle_ts ON riskoracle_calls(timestamp);
CREATE INDEX idx_riskoracle_agent ON riskoracle_calls(caller_agent_id);
CREATE INDEX idx_riskoracle_score ON riskoracle_calls(risk_score);

Pricing (ACP)

TierPriceOutput
Basic$0.005/callriskScore only
Standard$0.01/callFull breakdown + confidence
Advanced$0.02/callrecommendedAction + cross-check

Available as pre-risk-check on Virtuals ACP — agent-to-agent.


Agent Loop Position

RiskOracle sits as the final aggregation layer in the Achilles pre-execution loop:

RiskOracle (overall risk?) → MemGuard (state valid?) → NoLeak (should I execute?) → EP Guard (authorized?) → Execute
RiskOracleMemGuardNoLeakEP Guard
QuestionWhat is the overall risk?Is my state valid?Should I execute now?Is this authorized?
Endpoint/risk/check/memguard/check/noleak/check/ep/validate
OutputriskScore + actiondriftScore + actionGER + confidenceproof_hash + policy
ConnectionAggregates the other threeIndependentIndependentIndependent

Each service is fully independent. RiskOracle calls the other three but never modifies them.


Design Principles

  1. Always fail open — dependency timeout = low-risk stub. Never block the trading loop.
  2. Proof on every responseproofHash is generated on success AND failure. Never null.
  3. Weighted aggregation — components are weighted by impact severity, not equally.
  4. Dependency isolation — each component has its own 3s timeout. One service down doesn't affect others.
  5. Fire-and-forget logging — Postgres writes are async. Log failures never affect response latency.
  6. Never 500 — catch-all returns valid JSON with recommendedAction: "proceed".


License

MIT