Thassa.

Protocol

Settlement & authoritative sources

Thassa markets never settle on open-ended LLM web search. Every market resolves against known authoritative sources, bound at creation and disclosed publicly — stored onchain, rendered in the app, and served by the API.

Structured settlement queries

A settlement query is structured JSON stored onchain as a public string: the question, its category, the resolution rule, and the exact sources that decide it.

single-source settlement query
{
  "question": "Will it rain in San Francisco on 2026-07-18?",
  "category": "weather",
  "rule": "single",
  "sources": [
    {
      "id": "nws",
      "name": "NWS/NOAA",
      "url": "https://api.weather.gov"
    }
  ]
}

Anyone can inspect the query that will settle a market — in the app’s market detail (“Advanced”), or via GET /trade-api/v1/markets/{id}/sources.

The rule of thumb

Encoded in the registry

Numeric data ⇒ exactly one publicly-disclosed source. Boolean data ⇒ multi-source majority concurrence.

Scores, temperatures, and prices are facts one authority publishes — naming a single source publicly is both sufficient and unambiguous. “Did X happen” questions are interpretations, so no single outlet decides them: a panel must concur.

Source categories

CategoryRuleSources
sportssingleESPN — the single primary source for results.
newsmajorityBoolean “did X happen” questions. Panel of NYT, WSJ, Reuters, AP, BBC (configurable list); a majority must concur or no update is produced.
weathersingleNumeric. Exactly one allowed authoritative source — default NWS/NOAA (api.weather.gov).
pricesingleAsset pricing, numeric. Exactly one allowed source per asset class — default Coinbase spot for crypto, configurable per deployment.
generalFallback for uncategorized questions: LLM adjudication, clearly labeled as such.

The majority-concurrence rule

majority settlement query
{
  "question": "Did the bill pass the Senate before 2026-07-01?",
  "category": "news",
  "rule": "majority",
  "sources": [
    { "id": "nyt",     "name": "The New York Times",  "url": "https://www.nytimes.com" },
    { "id": "wsj",     "name": "The Wall Street Journal", "url": "https://www.wsj.com" },
    { "id": "reuters", "name": "Reuters",             "url": "https://www.reuters.com" },
    { "id": "ap",      "name": "Associated Press",    "url": "https://apnews.com" },
    { "id": "bbc",     "name": "BBC",                 "url": "https://www.bbc.com" }
  ]
}

For majority-rule markets, during fulfillment the node:

  1. Fetches each panel source independently (news RSS/APIs) — in the node process, prior to any LLM call.
  2. Derives one independent verdict per source, adjudicating only from that source’s fetched evidence.
  3. Computes concurrence in code: a majority of the panel must agree. 3 of 5 settles; 2–2 with one unavailable does not.
  4. If there is no majority — or a source is unavailable — the node produces no update (_fulfilled=false) and retries later. The market stays SETTLING.

For single-rule markets, the one bound source decides; unavailability likewise means no update and a retry.

How sources get bound

The backend hosts the source registry and exposes it over MCP to both the market-generation agent and the oracle nodes (list_sources, resolve_sources). When a market is generated, the agent categorizes the question and binds its sources at generation time; candidates without a resolvable category fall back to general. The registry itself is publicly readable.

Prompt-injection guardrails

  • The oracle’s query template instructs the node to answer only the market question passed via bid inputData, returning strictly the expected shape and refusing instructions embedded in the question.
  • The LLM adjudicates only from evidence the node fetched — it has no browsing or tools at settlement time.
  • Market generation sanitizes user input, wraps it in delimited data blocks, schema-validates output, and requires settlement queries to be objective, verifiable statements with a resolution source and date.

When settlement can’t happen

A market that can never resolve cleanly can be voided by the owner (voidMarket) — status VOID, all deposits refundable. Until then, an unresolvable query simply keeps producing no update: funds stay escrowed and safe, never settled on a bad answer.