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

# Repository and modules

> Four Python modules, canonical schemas locked, multi-provider AI council operational. What's in the repo right now.

<Warning>
  This page reflects the actual state of the codebase as of the current build. Every claim below is traceable to a file in the repository.
</Warning>

## The repo

Pelion protocol code lives in a Python monorepo (this repo). Contracts, when built, will live in a separate Foundry repo (`pelion-contracts`). The two deployment cadences are different enough that one monorepo is more friction than it's worth.

Current layout.

```
pelion/
├── pyproject.toml            package config, optional extras
├── pelion/
│   ├── schemas/              canonical Question / Verdict / Synapse types
│   ├── judgment/             frontier AI council (Claude, GPT, Gemini)
│   ├── miner/                Bittensor Axon wrapping FrontierModelClient
│   └── validator/            Dendrite dispatch with accuracy scoring
└── tests/                    Python test suite
```

## Module by module

### `pelion.schemas`. Built.

The canonical data types for every message the protocol touches. Locked. Not subject to addition without coordinated miner, validator, and router updates.

| Type                              | Purpose                                                                              |
| --------------------------------- | ------------------------------------------------------------------------------------ |
| `Question`                        | Off-chain canonical question format (§4.2 of the spec)                               |
| `EvidencePolicy`                  | Source category, domain, and recency rules                                           |
| `Verdict`                         | Consensus outcome, confidence, nested evidence and reasoning                         |
| `Evidence` and `EvidenceSource`   | Structured evidence bundle                                                           |
| `Reasoning` and `MinerProvenance` | Per-miner reasoning plus the consensus rationale                                     |
| `SubnetMetadata`                  | Which subnet produced the verdict, at what block height                              |
| `Outcome`                         | Sentinel values. `UNRESOLVABLE = -1`, `NO = 0`, `YES = 1`. Multi-outcome values ≥ 2. |
| `PelionSynapse`                   | Bittensor wire envelope (subclass of `bt.Synapse`)                                   |

All schemas are Pydantic v2, frozen once constructed, with strict validation (`extra="forbid"`). Canonical JSON uses camelCase (matching spec §4.2). Python attributes are snake\_case via `alias_generator=to_camel`.

Ambiguities in the spec have been resolved and documented. The `subnet_routing` field is a `list[int]` off-chain and a `uint256` bitmap on-chain. Evidence and reasoning hashes are computed at the router-to-adapter boundary as `sha256(canonical_json_bytes(...))`, not stored on canonical Verdict. `UNRESOLVABLE = -1`. Adapter-only fields (`callback_contract`, `callback_selector`) are omitted from canonical Question.

### `pelion.judgment`. Built.

The synthetic frontier council. Takes a `Question`, fans it out to multiple LLM providers in parallel via `asyncio.gather`, and aggregates responses into a canonical `Verdict`.

| Component             | Purpose                                                                                                |
| --------------------- | ------------------------------------------------------------------------------------------------------ |
| `FrontierModelClient` | Main entrypoint. Fans queries, enforces per-provider timeout, aggregates.                              |
| `ModelProvider`       | Protocol (duck-typed). Any `async def judge(q) -> ModelResponse`.                                      |
| `ModelResponse`       | One provider's answer (outcome, confidence, reasoning, cited URLs).                                    |
| `aggregate()`         | Pure function. Majority vote on outcome, mean confidence over the majority camp, tie → `UNRESOLVABLE`. |
| `AnthropicProvider`   | Claude via the Anthropic SDK. Uses prompt caching on the system prompt.                                |
| `OpenAIProvider`      | GPT via the OpenAI SDK. Uses JSON response mode.                                                       |
| `GeminiProvider`      | Gemini via `google-genai`. Uses JSON response MIME type.                                               |

Key design properties.

No retrieval in v0. Providers are asked to reason from training data and cite URLs they would consult. Cited URLs are carried into reasoning text but not fetched. Retrieval will be added as a separate module (shared between the frontier council and real Bittensor miners) when it's needed.

`UNRESOLVABLE` is never a silent error handler. A provider timeout or error raises `InsufficientResponsesError` if the remaining responses drop below the `min_responses` threshold. Council disagreement (tie) is a legitimate `UNRESOLVABLE`. Infrastructure failure is not.

Per-provider timeout is independent. A slow provider does not cancel its siblings (verified via test).

### `pelion.miner`. Built.

A runnable Bittensor miner that wraps `FrontierModelClient` behind an Axon.

| Component                                         | Purpose                                                                        |
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
| `Miner`                                           | Lifecycle. `start()`, `run_forever()`, `stop()`. Owns wallet, Axon, Subtensor. |
| `MinerConfig`                                     | Env-driven or YAML-driven runtime config. Frozen Pydantic model.               |
| `forward(synapse, client)`                        | Pure async handler. Axon-independent, testable in isolation.                   |
| `synapse_to_question`, `apply_verdict_to_synapse` | Conversion layer between bt.Synapse and canonical types.                       |
| `build_providers(config)`                         | Lazy-instantiates enabled frontier providers.                                  |

Key design properties.

No judgment logic in the miner. The miner is transport glue. All resolution happens in `pelion.judgment`, imported through the public package (not via `.client` submodule).

bt.Synapse isolation. The conversion layer is the only place `PelionSynapse` meets canonical types. If Pydantic-version or field-shape coupling between Bittensor and Pelion ever fights, the fix lives in `conversion.py`, not in the schemas.

Bittensor import only at runtime. `Miner.start()` is the only place `import bittensor` fires. Unit tests run without the bittensor extra via a conftest stub.

Entrypoint. `pelion-miner --config path/to/miner.yaml` (or `python -m pelion.miner`).

### `pelion.validator`. Built.

A runnable Bittensor validator that queries miners, scores them against known-answer questions, and sets weights.

| Component                      | Purpose                                                                                       |
| ------------------------------ | --------------------------------------------------------------------------------------------- |
| `Validator`                    | Lifecycle. `start()`, `run_forever()`, `stop()`. Owns wallet, Dendrite, Subtensor, metagraph. |
| `ValidatorConfig`              | Env-driven or YAML-driven config.                                                             |
| `query_and_score()`            | Pure async function. Dispatch one entry to all miners, return `{hotkey: score}`.              |
| `BacktestSet`, `BacktestEntry` | Round-robin iterator over known-answer questions. YAML loadable.                              |
| `default_v0_backtest()`        | Bundled toy backtest. Stable facts only, no time-sensitive items.                             |
| `score_accuracy()`             | v0 scoring function. Exact-match accuracy. 1.0 or 0.0.                                        |
| `ScoreAccumulator`             | Per-hotkey cumulative accuracy → normalized weight vector.                                    |

Key design properties.

v0 scoring is intentionally simple. The spec's richer scoring (evidence quality and calibration) is not implemented in v0 and lands in Task 7 against live-subnet data. v0 is accuracy only, and the code makes that explicit.

Cumulative accuracy, no decay. Stale hotkeys sit in the accumulator but never receive weight (filtered by current metagraph membership at weight-setting time).

Liveness over silence. If no miner has produced any signal, the validator sets uniform weights rather than abstaining. Production may prefer stricter behavior.

Entrypoint. `pelion-validator --config path/to/validator.yaml`.

## Test properties

No real API calls. Every LLM provider test uses mock providers with canned responses.

No real Bittensor runtime. A `conftest.py` stub installs a minimal `bittensor.Synapse` so tests exercise the Pydantic-model side of the wire types without needing the bittensor SDK installed.

Fast. Full suite runs in under one second locally.

## Not yet built

<CardGroup cols={2}>
  <Card title="Local subtensor (Task 5)" icon="docker">
    Docker Compose, wallet and register scripts, `make dev-up`. End-to-end miner and validator loop on a local Bittensor instance.
  </Card>

  <Card title="Benchmark harness (Priority 1)" icon="chart-column">
    18 months of Polymarket historical markets, frontier-council evaluation, published accuracy and calibration report. Pure Python on top of `pelion.judgment`.
  </Card>

  <Card title="Router service" icon="route">
    Phase 2 work. Listens to mainnet adapter events, dispatches to Bittensor subnets, aggregates responses, posts back via relay.
  </Card>

  <Card title="SN6 subnet client" icon="plug">
    Be a customer of an existing Bittensor subnet (Numinous, Infinite Games). Normalizes SN6 responses to canonical `Verdict` format.
  </Card>

  <Card title="Adapter contract" icon="file-contract">
    `PelionAdapter.sol`. The public contract surface on mainnet. Submission, verdict intake, challenge window, finalization, callback. Lives in the future `pelion-contracts` repo.
  </Card>

  <Card title="Token and treasury" icon="coins">
    ERC-20 with tax hooks. Treasury with buyback function. Also in `pelion-contracts`.
  </Card>

  <Card title="Reference market" icon="store">
    `PelionMarket.sol`. The showcase consumer. Conditional-token prediction market that calls the adapter for resolution.
  </Card>

  <Card title="Cross-chain relay" icon="bridge">
    v1 bonded federated committee. v2 light-client bridge. Bridges Bittensor-side consensus to mainnet-side adapter.
  </Card>
</CardGroup>

## Source links

The protocol Python core lives at [github.com/peliondev/pelion-protocol](https://github.com/peliondev/pelion-protocol). All paths below are relative to that repository.

* [`pelion/schemas/`](https://github.com/peliondev/pelion-protocol/tree/main/pelion/schemas). Canonical schemas and synapse definition.
* [`pelion/judgment/`](https://github.com/peliondev/pelion-protocol/tree/main/pelion/judgment). Frontier council and providers.
* [`pelion/miner/`](https://github.com/peliondev/pelion-protocol/tree/main/pelion/miner). Axon wiring and forward handler.
* [`pelion/validator/`](https://github.com/peliondev/pelion-protocol/tree/main/pelion/validator). Dendrite dispatch and scoring.

Each directory has a detailed `README.md` with the component's design, invariants, and known limitations. Those READMEs are the authoritative engineering reference. This documentation is their external-audience framing.

## Further reading

<CardGroup cols={2}>
  <Card title="Live example" icon="play" href="/whats-built/live-example">
    A copy-pasteable Python snippet that produces a real verdict.
  </Card>

  <Card title="Benchmark methodology" icon="flask" href="/whats-built/benchmark-methodology">
    What Priority 1 will measure, how, and what "good" looks like.
  </Card>
</CardGroup>
