"Fast pre-action risk oracle. Should I execute this right now?"
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.
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.
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
└──────────────┘
- Agent sends a proposed action + context to
/risk/check - RiskOracle calls four scoring components in parallel — each with a 3s hard timeout
- Scores are weighted and aggregated into a single
riskScore(0.0 – 1.0) - A
recommendedActionis returned: proceed, delay, or abort - A cryptographic
proofHashis generated as an immutable record - Everything is logged to Postgres asynchronously (never blocks the response)
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
proofHashis always generated — never null, even on full failure
| 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.
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"
}{
"status": "ok",
"service": "riskoracle",
"port": 5090
}| 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".
| 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 |
pip install flask requests psycopg2-binarypython3 riskoracle_server.py
# → Serving on port 5090python3 riskoracle_engine.pycurl -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.toolsudo systemctl start riskoracle
sudo systemctl status riskoracle
# Runs on port 5090 with Restart=always| 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.
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);| 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.
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.
- Always fail open — dependency timeout = low-risk stub. Never block the trading loop.
- Proof on every response —
proofHashis generated on success AND failure. Never null. - Weighted aggregation — components are weighted by impact severity, not equally.
- Dependency isolation — each component has its own 3s timeout. One service down doesn't affect others.
- Fire-and-forget logging — Postgres writes are async. Log failures never affect response latency.
- Never 500 — catch-all returns valid JSON with
recommendedAction: "proceed".
- Live: achillesalpha.onrender.com/riskoracle
- EP Guard: github.com/achilliesbot/execution-protocol
- NoLeak: github.com/achilliesbot/noleak
- MemGuard: github.com/achilliesbot/memguard
- Virtuals ACP: app.virtuals.io/acp/agent/28735
MIT