requestRuling(): ask an AI jury before any contract call
Before a Solidity or Solana program does something risky, it asks a jury to rule on the action against a published ASC. Independent models vote and sign. The contract checks the signed ruling with verifyRuling and runs the action only on allow.
For the how-to, see Enforce a ruling.
1. Why
Most losses come from actions the authors would never have allowed in plain words. Writing those words down, and having independent models check each risky call against them, catches what the code missed. A hypothetical $6B withdrawal to an unknown wallet gets no allow votes, so the call reverts.
2. The interface
Solana: verify_ruling(&asc, &action, &instructions) -> Outcome. The juror signatures ride in the same transaction (Ed25519 precompile). It fails if the ASC id, action hash, juror keys or quorum don't match.
// The on-chain side. The payout fails unless a quorum of listed jurors signed
// "allow" for this exact withdrawal under this exact ASC.
// Illustrative, Anchor-style. Not a deployed program.
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
let action = Action::withdrawal(ctx.accounts.to.key(), amount);
// Juror signatures ride in this transaction (Ed25519 precompile).
// verify_ruling checks the ASC id, action hash, juror keys and quorum.
verify_ruling(&ctx.accounts.asc, &action, &ctx.accounts.instructions)?.require(Outcome::Allow)?;
// Hard caps still apply in code, whatever the jury said.
require!(amount <= ctx.accounts.asc.max_single, AscError::OverCap);
transfer(ctx, amount)
}
EVM: requestRuling(ascId, action, jury) emits an event; then verifyRuling(requestId, attestations) returns the outcome. Two steps, because a contract can't wait for models.
// SPDX-License-Identifier: MIT
// The on-chain side of an ASC on EVM chains. Planned interface, illustrative.
// EVM calls can't wait for models, so it's two steps: requestRuling, then verifyRuling.
pragma solidity ^0.8.24;
interface IAsc {
enum Tier { Fast, Standard, Frontier }
enum Outcome { None, Allow, Deny, Hold, Partial, Release, Stop }
struct Jury { uint8 size; uint8 quorum; Tier tier; }
/// Ask the jury to rule on `action` under the published ASC `ascId`.
/// Emits RulingRequested; the jury answers off chain with signed votes.
function requestRuling(bytes32 ascId, bytes calldata action, Jury calldata jury)
external returns (bytes32 requestId);
/// Check the jurors' signed votes for `requestId` and return the outcome
/// they reached. Reverts if signatures, juror keys, ASC id or quorum don't check out.
function verifyRuling(bytes32 requestId, bytes calldata attestations)
external view returns (Outcome);
event RulingRequested(bytes32 indexed requestId, bytes32 indexed ascId, bytes32 actionHash, Jury jury);
}
Hard caps stay in the contract's own code. The jury can only pick a listed outcome.
3. How the ASC is stored
- Published ASCs are stored on Solana with IQ Labs inscriptions. See Under the hood.
- The contract stores the ASC id and version, so the rules can't change under it.
Status: inscribing and reading back is built; referencing it from an EVM contract isn't.
4. What the contract receives
{
"id": "rul_8fK2c9",
"asc": "asc_hotwallet_v1",
"status": "final",
"outcome": "hold",
"rulesBroken": [
{ "rule": 5, "votes": 5, "note": "Email and 2FA changed 3 hours ago; withdrawal to an address never used by this account." }
],
"jury": { "size": 5, "quorum": 4, "tier": "standard", "answered": 5 },
"votes": [
{ "juror": "gpt", "lab": "OpenAI", "outcome": "hold", "wallet": "J1u...", "sig": "3fa9c1..." },
{ "juror": "claude", "lab": "Anthropic", "outcome": "hold", "wallet": "J2c...", "sig": "b07e42..." },
{ "juror": "gemini", "lab": "Google", "outcome": "hold", "wallet": "J3g...", "sig": "9d21aa..." },
{ "juror": "qwen", "lab": "Alibaba", "outcome": "hold", "wallet": "J4q...", "sig": "51c8e0..." },
{ "juror": "deepseek", "lab": "DeepSeek", "outcome": "hold", "wallet": "J5d...", "sig": "e6f30b..." }
],
"evidence": { "sha256": "4b1e07c2a9d3...", "items": 4 },
"attestations": "<base64: the signed votes, ready to pass to verify_ruling / verifyRuling>",
"dispute": { "open_until": "2026-11-07T16:20:00Z" },
"cost": { "quoted": 25, "charged": 25, "unit": "credits" },
"record": "https://asc.verafy.ai/rulings/rul_8fK2c9",
"illustrative": true
}
Each juror signs from its own wallet. The attestations field carries the signed votes, ready to pass to verify_ruling or verifyRuling.
5. When it fails
- Timeout: the ASC's default outcome, never allow.
- Disagreement: a second jury.
- Bad signature: the transaction fails.
- Compromised juror key: limited by quorum and hard caps.
6. Limits
- Seconds to a minute and a small model cost, so wrap only risky calls.
- Models can be fooled by poisoned evidence.
- Solana transaction size limits a single transaction to about 6 or 7 juror signatures.