> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orica.markets/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolution

> How market outcomes are determined and finalized by multi-agent AI.

Resolution is the process of determining the correct outcome of a market after the event has occurred. Orica employs a sophisticated **multi-agent AI resolution system** with hierarchical workers, intelligent sub-crawlers, and built-in dispute mechanisms for human oversight.

> [!NOTE]
>
> Markets are resolved by a multi-layer AI architecture powered by [Claude 4.5 Sonnet](https://openrouter.ai/anthropic/claude-sonnet-4.5) via [OpenRouter](https://openrouter.ai/), with autonomous research agents backed by [Firecrawl](https://www.firecrawl.dev/).

***

## Multi-Agent Resolution Architecture

The resolution system operates as a **hierarchical multi-agent pipeline** where a primary orchestrator delegates to specialized sub-workers for evidence gathering and analysis.

```mermaid theme={"dark"}
flowchart TB
    subgraph Orchestrator["Primary Resolution Agent"]
        MainAI["Claude 4.5 Sonnet<br/>Orchestrator"]
        Tools["Tool Registry"]
    end

    subgraph Workers["Sub-Agent Workers"]
        SearchWorker["Search Worker"]
        ScrapeWorker["Intelligent Scrape Agent"]
        SubAI["Sub-AI Analyzer"]
    end

    subgraph Crawlers["Sub-Crawlers"]
        MDCrawler["Markdown Extractor"]
        JSONCrawler["Schema-Based JSON Extractor"]
        ScreenshotCrawler["Visual Capture Agent"]
        LinkCrawler["Link Discovery Crawler"]
    end

    MainAI -->|"search()"| SearchWorker
    MainAI -->|"scrape()"| ScrapeWorker
    ScrapeWorker --> SubAI
    SubAI -->|"sub_scrape()"| MDCrawler
    SubAI -->|"json_extraction"| JSONCrawler
    SubAI -->|"screenshot"| ScreenshotCrawler
    SubAI -->|"links"| LinkCrawler
    SubAI -->|"summarize_content()"| MainAI
    MainAI -->|"resolve()"| Chain["On-Chain Submission"]
```

***

## Resolution Pipeline

**1. Market Closure Detection**

The auto-resolver daemon continuously monitors the database for markets where `close_time` has elapsed. Markets are processed in parallel batches with semaphore-controlled concurrency (up to 100 simultaneous resolutions).

**2. Orchestrator Initialization**

For each closed market, a primary **Claude 4.5 Sonnet orchestrator** is instantiated with:

* Market question and options
* Creation and close timestamps
* Resolution criteria from metadata
* Tool registry (search, scrape, resolve)

**3. Agentic Research Loop**

The orchestrator enters an **iterative reasoning loop** (up to 20 iterations) where it autonomously:

1. Formulates search queries based on the market question
2. Dispatches sub-workers to gather evidence
3. Analyzes returned data against resolution criteria
4. Decides whether more research is needed or resolution can proceed

**4. Intelligent Sub-Scraping**

When the orchestrator invokes `scrape()`, a **sub-AI agent** takes over:

* Performs initial content extraction
* Spawns a nested reasoning loop (up to 5 iterations)
* Dynamically selects extraction strategies based on content type
* Can invoke sub-crawlers for specialized extraction (JSON schemas, screenshots, link graphs)

**5. Evidence Synthesis**

Once sufficient evidence is gathered, the orchestrator synthesizes findings and invokes the `resolve()` tool with:

* Outcome index
* Human-readable outcome name
* Evidence summary
* Source URLs
* Chain-of-thought reasoning

**6. Proof Persistence**

Resolution proof is uploaded to **IPFS via Pinata**, creating an immutable record containing the full reasoning chain, evidence, and source citations.

**7. On-Chain Submission**

The resolved outcome and IPFS metadata URI are submitted to Solana via the Orica SDK, transitioning the market to `resolved` status.

**8. Dispute Window**

After resolution, a window opens for participants to challenge the AI's determination.

* If no dispute: Resolution becomes final
* If disputed: Weighted voting begins among stakeholders

***

## Sub-Agent Architecture

### Primary Orchestrator

The main resolution agent operates with three core tools:

| Tool | Purpose |
| - | - |
| `search` | Web search via Firecrawl to discover relevant sources |
| `scrape` | Intelligent URL scraping with sub-AI delegation |
| `resolve` | Final outcome submission with evidence |

### Intelligent Scrape Agent

When `scrape()` is invoked, a specialized sub-AI takes control:

```mermaid theme={"dark"}
flowchart LR
    Initial["Initial Scrape<br/>(markdown/JSON)"] --> SubAI["Sub-AI<br/>Analyzer"]
    SubAI --> Decision{Sufficient<br/>Data?}
    Decision -->|Yes| Summary["summarize_content()"]
    Decision -->|No| SubScrape["sub_scrape()"]
    SubScrape --> Formats["Format Selection"]
    Formats --> MDCrawler["markdown"]
    Formats --> JSONCrawler["json_extraction"]
    Formats --> ScreenCrawler["screenshot"]
    Formats --> HTMLCrawler["html/rawHtml"]
    Formats --> LinkCrawler["links"]
    MDCrawler & JSONCrawler & ScreenCrawler & HTMLCrawler & LinkCrawler --> SubAI
```

The sub-AI automatically detects query intent and selects optimal extraction strategies:

| Query Type | Detection Keywords | Extraction Strategy |
| - | - | - |
| Metrics/Stats | `count`, `number`, `commits`, `stars`, `price` | JSON schema extraction |
| Visual Data | `chart`, `graph`, `image`, `UI` | Screenshot capture |
| Navigation | `find`, `explore`, `subpages` | Link discovery |
| Text Content | General queries | Markdown extraction |

### Schema-Based JSON Extraction

For structured data extraction, the sub-AI constructs dynamic JSON schemas:

```json theme={"dark"}
{
  "type": "json",
  "schema": {
    "type": "object",
    "properties": {
      "commits": { "type": "number" },
      "last_commit_date": { "type": "string" },
      "contributors": { "type": "number" }
    }
  },
  "prompt": "Extract repository statistics from this GitHub page"
}
```

This enables precise extraction of numbers, dates, and metrics that would be difficult to parse from raw markdown.

***

## Resolution Infrastructure

> [card] [Claude 4.5 Sonnet](https://openrouter.ai/anthropic/claude-sonnet-4.5)
>
> Primary orchestrator and sub-AI reasoning engine. Handles multi-step reasoning, tool selection, and evidence synthesis.

> [card] [OpenRouter](https://openrouter.ai/)
>
> API gateway providing low-latency access to Claude models with automatic failover and load balancing.

> [card] [Firecrawl](https://www.firecrawl.dev/)
>
> Intelligent web scraping infrastructure supporting markdown, HTML, JSON extraction, and visual capture.

> [card] [IPFS / Pinata](https://pinata.cloud/)
>
> Decentralized storage for immutable resolution proofs with full reasoning chains.

***

## Concurrency Model

The resolver operates with **parallel market processing**:

```
┌─────────────────────────────────────────────────────────────┐
│                    Auto-Resolver Daemon                      │
├─────────────────────────────────────────────────────────────┤
│  Semaphore: max_concurrent = 100                            │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────┐ ┌─────────┐ ┌─────────┐       ┌─────────┐     │
│  │Market A │ │Market B │ │Market C │  ...  │Market N │     │
│  │ Agent   │ │ Agent   │ │ Agent   │       │ Agent   │     │
│  └────┬────┘ └────┬────┘ └────┬────┘       └────┬────┘     │
│       │           │           │                  │          │
│       ▼           ▼           ▼                  ▼          │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐       ┌─────────┐     │
│  │Sub-AIs  │ │Sub-AIs  │ │Sub-AIs  │       │Sub-AIs  │     │
│  └─────────┘ └─────────┘ └─────────┘       └─────────┘     │
└─────────────────────────────────────────────────────────────┘
```

Each market resolution operates independently with its own agent hierarchy, enabling throughput scaling while preventing resource exhaustion.

***

## Iteration Limits & Safeguards

The system operates with strict iteration bounds to prevent runaway execution:

| Component | Max Iterations | Timeout |
| - | - | - |
| Primary Orchestrator | 20 | 120s per API call |
| Sub-AI Scrape Agent | 5 | 20s per sub-scrape |
| Search Queries | Unlimited (within orchestrator loop) | 30s |
| Image Search | 3 candidates checked | 30s |

If the orchestrator exhausts iterations without reaching resolution, the market is marked as **Unresolvable** (outcome 255) with timeout reasoning.

***

## Resolution Metadata

When the AI resolves a market, it generates a comprehensive IPFS metadata document containing the full audit trail:

```json theme={"dark"}
{
  "outcome": 0,
  "outcome_name": "Yes",
  "evidence": "Bitcoin reached $100,000.00 on CoinGecko at 23:45 UTC on December 30, 2025.",
  "sources": [
    "https://www.coingecko.com/en/coins/bitcoin",
    "https://www.coinmarketcap.com/currencies/bitcoin/"
  ],
  "reasoning": "The daily close price exceeded the threshold before the market close time. Multiple sources confirmed the price action via schema-based JSON extraction.",
  "model": "claude-sonnet-4.5",
  "timestamp": 1735603500,
  "market_address": "ABC123...",
  "is_dispute_resolution": false
}
```

> [accordion] Metadata Fields
>
> | Field | Description |
> | - | - |
> | `outcome` | The outcome index being reported (0-254) |
> | `outcome_name` | Human-readable outcome name |
> | `evidence` | Synthesized evidence from all sub-agent findings |
> | `sources` | URLs scraped by sub-crawlers and verified by sub-AI |
> | `reasoning` | Full chain-of-thought from orchestrator's final synthesis |
> | `model` | The AI model used for resolution |
> | `timestamp` | When the resolution was submitted |
> | `is_dispute_resolution` | True if this came from a dispute override |

> [!NOTE]
>
> The full conversation log (including all sub-agent tool calls and responses) is stored in the database for auditing purposes, but only the synthesized proof is persisted to IPFS.

***

## Special Outcomes

| Value | Meaning |
| - | - |
| 0-254 | Valid outcome index |
| 255 | **Unresolvable** - All participants receive refunds |

> [!NOTE]
>
> "Unresolvable" is used when the AI determines the market question cannot be definitively answered (e.g., source data unavailable, ambiguous criteria, event did not occur in a measurable way).

***

## Dispute Mechanism

If participants believe the AI's resolution is incorrect, they can initiate a dispute:

1. **Challenge Period**: Any stakeholder can open a dispute within the dispute window
2. **Evidence Submission**: Disputants provide evidence via dispute messages
3. **Weighted Voting**: Token holders vote on the correct outcome
4. **Override**: If the vote contradicts the AI resolution, the outcome is corrected

> [!WARNING]
>
> Disputes require staking tokens. Frivolous disputes that fail result in stake forfeiture.

***

## Redemption

After finalization, holders of winning shares can redeem them for USDC:

```typescript theme={"dark"}
// Check if user has already redeemed
const response = await fetch(
  `https://api.orica.markets/markets/${marketAddress}/redemptions/${userAddress}`
);
const { has_redeemed, redemption } = await response.json();

if (!has_redeemed) {
  const redeemIx = await sdk.orica.buildRedeem(
    userPubkey,
    userUsdcAccount,
    marketAddress
  );
  
  const tx = new Transaction().add(redeemIx);
  await sendAndConfirmTransaction(connection, tx, [wallet]);
}
```

***

## Fetching Resolution Data

Resolution data is included in the market response from the API:

```json theme={"dark"}
{
  "address": "ABC123...",
  "question": "Will Bitcoin hit $100k by 2025?",
  "status": "resolved",
  "resolution_outcome": 0,
  "resolution_metadata_uri": "ipfs://Qm...",
  "resolved_at": 1735689600,
  "resolver": "AI_RESOLVER"
}
```

***

## Next Steps

> [card] [Disputes](https://docs.orica.markets/guides/disputes.md)
>
> Learn how to challenge AI resolutions.

> [card] [Architecture](https://docs.orica.markets/guides/architecture.md)
>
> Understand how components interact.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.