Skip to content

achilliesbot/risk-oracle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RiskOracle — Pre-Action Risk Oracle

"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 Mode Root Cause Silent?
Policy violation Action not authorized by policy Often
Wallet overexposure Too much capital at risk for current balance Yes
Memory drift State the agent is acting on is stale or corrupted Always
Execution leak Timing is wrong — signal is valid but conditions aren't Yes

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

Component Weight Source What It Measures
policyViolation 35% EP /ep/validate Is this action authorized by policy?
walletRisk 30% Internal calculation Capital-to-balance exposure ratio
memoryDrift 20% MemGuard /memguard/check Is the agent's state fresh or stale?
executionLeak 15% NoLeak /noleak/check Is 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

Status Condition Behavior
200 Normal check Full risk assessment returned
200 Dependency timeout Fallback scores used, recommendedAction: "proceed"
400 Missing action field Error message, never 500
200 Complete engine failure Stub 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

riskScore recommendedAction Meaning
0.00 – 0.30 proceed Safe to execute
0.30 – 0.60 delay Elevated risk — wait or reduce size
0.60 – 1.00 abort High 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

Variable Default Description
EP_GUARD_URL https://achillesalpha.onrender.com/ep/validate EP Guard endpoint
NOLEAK_URL http://localhost:5070/noleak/check NoLeak endpoint
MEMGUARD_URL http://localhost:5080/memguard/check MemGuard 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)

Tier Price Output
Basic $0.005/call riskScore only
Standard $0.01/call Full breakdown + confidence
Advanced $0.02/call recommendedAction + 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
RiskOracle MemGuard NoLeak EP Guard
Question What is the overall risk? Is my state valid? Should I execute now? Is this authorized?
Endpoint /risk/check /memguard/check /noleak/check /ep/validate
Output riskScore + action driftScore + action GER + confidence proof_hash + policy
Connection Aggregates the other three Independent Independent Independent

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".

Links


License

MIT

About

Pre-action risk oracle for autonomous AI agents. Aggregates EP, NoLeak, MemGuard, and wallet risk into one normalized score.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages