Skip to content

cathedralai/cathedral

Repository files navigation

Cathedral

Known Vulnerabilities CodeQL

A Bittensor subnet running a verifiable AI workforce.

The subnet publishes jobs - standing work with a source pool, task templates, and a public scoring rubric. Miners bring agents that submit cards answering those jobs. Cathedral runs every agent's instruction set inside a sealed runtime, scores the card on six dimensions, signs the result, and weekly-anchors it on chain. Best-performing agents earn TAO.

Runtime depth — what's verified today vs. v2. Today the sealed runtime decrypts the bundle, reads soul.md as the system prompt, fetches the job's source pool, calls Chutes inference, and returns a card. The agent's skills and AGENTS.md ship with the bundle for inspection (and future execution), but they are not executed by the v1 runtime. The 1.10x verified multiplier attests that the LLM call happened inside the Polaris-deployed runtime against the miner's soul.md — not full Hermes execution with tool routing. v2 (tracked in OBSERVABILITY_V1.md) embeds Hermes and captures tool calls, model calls, memory reads/writes, sub-agent invocations, and host metrics. We're shipping the loop first and deepening the runtime next.

First vertical: regulatory intelligence (EU AI Act, US AI Executive Order, UK AI Whitepaper, Singapore PDPC, Japan METI/MIC). The mechanism generalizes to any domain where expert agent output needs to be checked against ground truth.

Latest release: v1.0.7 — Polaris-native v2 runtime, two-tier mining · 2026-05-12

Vocabulary note. This README and the public site use jobs for the standing work the subnet asks for, and cards for miner submissions. The publisher's database column is still card_id (it keys on the job identifier). External-facing copy is being renamed first; the schema rename will follow with a signed-payload version bump.

What a miner ships

Cathedral does not accept a hand-written report. It accepts an agent. Two tiers — same Card JSON, same scoring rubric, same TAO emissions. The difference is where the agent runs.

Tier How it works Multiplier You pay for
A — Polaris-hosted Cathedral asks Polaris to deploy your bundle as a Hermes agent inside an attested runtime 1.10x verified-runtime Polaris compute + (today) Cathedral's inference
B — BYO box (SSH probe) You run Hermes yourself on your own hardware; Cathedral SSHs in to query it 1.00x Your own compute + your own LLM key

Tier A is the easy on-ramp. Tier B is for miners who already run agents locally and want full control over the runtime + LLM provider. Full step-by-step for both lives in docs/miner/QUICKSTART.md.

The submission flow:

  1. Run Hermes on your own box. Build a ~/.hermes/profile/default/ with a soul.md (the agent's identity — system prompt + role + output style), an AGENTS.md index, any skills the agentic loop will execute, and optionally memories. Zip the profile up to 10 MiB as your bundle.
  2. Sign the canonical submission payload {bundle_hash, card_id, miner_hotkey, submitted_at} with your sr25519 hotkey. (Here card_id is the job identifier.) The signature goes in the X-Cathedral-Signature header and the hotkey ss58 in X-Cathedral-Hotkey.
  3. POST /v1/agents/submit with the bundle, card_id (the job you're answering), display_name, attestation_mode=ssh-probe, and your SSH coordinates (ssh_host, ssh_port, ssh_user). The publisher computes bundle_hash = BLAKE3(zip_bytes), encrypts the bundle with AES-256-GCM under a per-bundle data key wrapped by CATHEDRAL_KEK_HEX, and stores the ciphertext in the cathedral-bundles object-store bucket. Production storage runs on Cloudflare R2 via a path-style S3 client. (Tier A / attestation_mode=polaris-deploy ships in code but is gated off for v1 — see RELEASES.md.)
  4. Cathedral SSHs into your declared host as ssh_user, snapshots your ~/.hermes/ into an isolated cathedral-eval-<round> profile, runs hermes chat -q "<task>" (full agentic loop with tool calls + skill execution) against that profile, captures the full forensic trail (state.db slice, sessions JSON, request dumps, skills, memories, logs), SCPs the trace bundle back, and tears down the eval profile. Your primary ~/.hermes/ is never modified. The returned card is treated as the agent's output for scoring.
  5. Cathedral re-derives task_hash from the prompt bytes and output_hash from the produced card bytes, runs preflight + the six-dimension scorer, applies the first-mover delta, signs the resulting EvalRun projection with the Cathedral key, and persists it. Validator-side signature verification dispatches on eval_output_schema_version via _SIGNED_KEYS_BY_VERSION — v1 today, v2 (card excerpt + artifact manifest hash) ships gated behind CATHEDRAL_EMIT_V2_SIGNED_PAYLOAD.

The quickest way to start mining is to point an AI agent at the canonical skill doc:

Read https://api.cathedral.computer/skill.md and follow it.

The skill doc carries the exact card schema, signing payload format, endpoints, and error codes. There is no client library; an agent that can curl and sign sr25519 can mine.

What a validator does

The validator binary in this repo (cathedral-validator) runs three asyncio loops on the same sqlite database:

  1. The verification worker drains claims rows, fetches Polaris records, verifies signatures, scores the card, and writes scores. This is the legacy /v1/claim flow that pre-dates the agent-bundle pipeline; it still drives the on-chain side.
  2. The pull loop (cathedral.validator.pull_loop) reads GET /v1/leaderboard/recent from the publisher, verifies every EvalRun projection against the Cathedral public key, and upserts a row keyed by miner_hotkey.
  3. The weight loop joins the latest score per hotkey to the metagraph's uids, normalizes, and calls subtensor.set_weights.

For v1, the producer side (miner submits, Cathedral runtime evaluates, publisher signs) is live. The validator pull loop verifies signatures today; on-chain weight setting and weekly Merkle anchoring are wired in code but not yet running against the live publisher signature stream. See Status.

Full procedure for someone running a validator: docs/VALIDATOR.md.

Jobs live

The publisher's card_definitions table is seeded from cathedralai/cathedral-eval-spec. Five jobs are live and accept submissions today:

Job ID Jurisdiction Topic
eu-ai-act EU EU AI Act enforcement and guidance
us-ai-eo US US executive orders and federal AI guidance
uk-ai-whitepaper UK UK pro-innovation AI regulation framework
singapore-pdpc SG Singapore PDPC enforcement and guidance
japan-meti-mic JP Japan METI / MIC AI and data guidance

In-process source-class requirements and refresh cadences live in src/cathedral/cards/registry.py. Full per-job eval-specs (source_pool, task_templates, scoring_rubric) live in card_definitions and are queryable at GET /v1/cards/{card_id}/eval-spec.

Africa is tracked in cathedralai/cathedral#24. Scope is open: pan-AU vs. country-specific.

Architecture

miner ── POST /v1/agents/submit ──▶ publisher (Railway, FastAPI)
                                       │
                                       ├─ encrypt + put cathedral-bundles (S3/R2)
                                       ├─ INSERT agent_submissions (status=queued)
                                       └─ orchestrator picks up
                                              │
                                              ▼
                                       PolarisRuntimeRunner
                                       (Tier A path; Cathedral's resolver
                                        hands Polaris a presigned URL)
                                              │
                                              ▼
                              Polaris marketplace eval (api.polaris.computer)
                              ── deploys ghcr.io/cathedralai/cathedral-runtime
                                              │
                                              ▼
                              runtime container
                              ├─ GET presigned URL, decrypt with KEK + key_id
                              ├─ read soul.md as system prompt
                              ├─ fetch each source_pool URL, BLAKE3 each body
                              ├─ call Chutes LLM (default DeepSeek V3.1)
                              └─ emit Card JSON
                                              │
                                              ▼
                              Polaris signs Ed25519 over
                              {submission_id, task_id, task_hash,
                               output_hash, deployment_id, completed_at}
                                              │
                                              ▼
                              Cathedral re-derives task_hash + output_hash,
                              verifies signature against pinned public key,
                              runs preflight + score_card,
                              applies first-mover delta + 1.10x multiplier,
                              signs the public EvalRun projection,
                              INSERTs eval_runs + updates agent_submissions.
                                              │
                                              ▼
                              GET /v1/leaderboard/recent (signed projections)
                                              │
                                              ▼
                              cathedral.computer frontend hydrates every 30s
                              validator pull loop verifies + writes scores

Attestation tiers

Tier Mode Verified by Earns emissions Ranks on leaderboard Live today
A polaris Polaris Ed25519 attestation; Cathedral re-derives task and output hashes yes yes yes
B+ tee AWS Nitro / Intel TDX / AMD SEV-SNP attestation; runtime measurement matched against approved-runtime registry yes yes spec-only; Nitro verifier wired, no live TEE miners
B unverified nothing no no (discovery surface only) yes

The submit endpoint takes attestation_mode as a form field. unverified submissions are stored encrypted, get a status='discovery' row, never enter the eval queue, and never appear on the leaderboard. They show up on the discovery surface so research material is not lost.

Full attestation contract: docs/ATTESTATION_CONTRACT.md.

Status

Verified live, 2026-05-11:

  • Five job definitions seeded, eval-specs served at /v1/cards/{card_id}/eval-spec.
  • End-to-end Tier A pipeline: submit -> encrypt to R2 -> Polaris runtime-evaluate -> Chutes LLM -> attestation -> Cathedral re-verification -> score -> sign -> publish.
  • Cathedral runtime image: ghcr.io/cathedralai/cathedral-runtime:v1.0.7 with probe-mode endpoints (/probe/run, /probe/health, /probe/reload) for long-lived miner-owned probes.
  • Publisher: Railway, auto-deploy on push to main. TLS via Cloudflare.
  • Validator binary running on SN292 testnet (uid 32), pulling signed eval-runs from the publisher, verifying the cathedral signature locally, and dispatching set_weights every 600 seconds with a 98% burn floor to the subnet owner uid.
  • Provisioning: scripts/provision_validator.sh and scripts/provision_miner.sh stand up a validator or miner-probe from scratch on Ubuntu 22.04+; PM2 supervises both apps with systemd boot persistence; bin/updater.sh watches for signed git tags and reloads on release.

Wired in code, not yet running against live signatures:

  • On-chain Merkle anchoring (weekly system.remarkWithEvent). Merkle code path exists in cathedral.publisher.merkle and cathedral.chain.anchor; not running on a schedule yet.
  • SN39 mainnet validator. Code path proven on SN292 testnet; needs a registered SN39 hotkey with stake + permit to set weights on mainnet.

Not yet built:

  • Live TEE miners. Nitro verifier exists in cathedral.attestation.nitro; TDX and SEV-SNP return 501 from the submit endpoint.
  • Africa job (#24).

Repo layout

cathedral/
├── src/cathedral/
│   ├── types.py            # Polaris-facing wire types (PolarisAgentClaim, Card, ScoreParts)
│   ├── v1_types.py         # publisher-side types (AgentSubmission, EvalRun, EvalTask, Merkle)
│   ├── config.py           # ValidatorSettings, MinerSettings
│   ├── auth/               # sr25519 hotkey signature verification
│   ├── attestation/        # Tier B+ verifiers (Nitro live, TDX + SEV-SNP stubs)
│   ├── cards/              # registry, preflight, six-dimension score
│   ├── chain/              # Bittensor metagraph + weight setting + Merkle anchor
│   ├── evidence/           # Polaris evidence fetch + Ed25519 verify (legacy /v1/claim path)
│   ├── eval/               # task generator, orchestrator, polaris_runner, scoring_pipeline
│   ├── publisher/          # FastAPI: /v1/agents/submit, reads, skill.md
│   ├── storage/            # R2 client + bundle encryption + Hermes bundle validator
│   ├── validator/          # sqlite queue, worker, pull loop, weight loop, watchdog, health
│   ├── miner/              # claim submission client (legacy path)
│   └── cli/                # `cathedral`, `cathedral-validator`, `cathedral-miner`, `cathedral-publisher`
├── docker/cathedral-runtime/   # Tier A runtime image (built and pushed by GH Actions)
├── docs/                       # Architecture, attestation contract, validator runbook
├── config/                     # TOML defaults for testnet, mainnet, miner
├── scripts/                    # Systemd unit, install, dev helpers, stub Polaris
└── tests/                      # pytest, real Ed25519 keypair in conftest

Quick start: miner

The fast path is to let an agent do it. Paste this into your AI agent:

Read https://api.cathedral.computer/skill.md and follow it. Mine the eu-ai-act card under the display name "<your-name>".

The skill doc carries everything: card schema, canonical signing payload, attestation modes, error codes. If you prefer to drive the legacy /v1/claim path from a CLI (for the existing Polaris-evidence flow, not the new agent-bundle pipeline):

git clone https://github.com/cathedralai/cathedral
cd cathedral
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e .

# Edit config/miner.toml: miner_hotkey, owner_wallet, validator_url
export CATHEDRAL_VALIDATOR_BEARER=<token>

cathedral-miner submit \
  --work-unit "card:eu-ai-act" \
  --polaris-agent-id agt_01H... \
  --polaris-run-ids run_01H... \
  --polaris-artifact-ids art_01H...

Full miner walkthrough: docs/miner/QUICKSTART.md.

Quick start: validator

git clone https://github.com/cathedralai/cathedral
cd cathedral
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e .[dev]

# Copy and edit config/testnet.toml (or mainnet.toml):
#   - network.validator_hotkey  -- your registered hotkey ss58
#   - polaris.public_key_hex    -- Polaris Ed25519 public key
#   - http.bearer_token_env     -- env var holding your bearer token

export CATHEDRAL_BEARER=<token>
export CATHEDRAL_PUBLIC_KEY_HEX=<cathedral publisher public key, hex>

cathedral-validator migrate --config config/testnet.toml
cathedral-validator serve   --config config/testnet.toml

In another terminal:

cathedral chain-check --config config/testnet.toml   # confirm hotkey + subtensor
cathedral health                                     # full snapshot
cathedral weights                                    # weight-set status word
cathedral registration                               # is the validator on the metagraph

Full validator procedure (mechanism, anti-cheating, requirements, known limits, how to verify a specific eval): docs/VALIDATOR.md. Operational runbook (systemd, logs, recovery): docs/validator/RUNBOOK.md. v1.1.0 upgrade notes: docs/validator/UPGRADING_TO_V1_1_0.md.

You can confirm a validator is running v1.1.0 by querying https://api.taostats.io/api/validator/weights/latest/v1?netuid=39 and checking version_key=1001000 on their last weight-set.

Documentation map

Future enhancements

  • On-chain weekly Merkle anchoring of EvalRun projections.
  • Validator pull-loop running in production against the live publisher signature stream.
  • TDX and SEV-SNP TEE verifiers wired (live miners attest with hardware roots, not Polaris).
  • Per-domain rubric profiles (legal vs. finance vs. science).
  • Layer-2 audit replay: validators re-run a random sample of bundles on a different task and compare structural similarity to the submitted card.
  • Approved-runtime registry moved on-chain (currently a git JSON file, see docs/ATTESTATION_CONTRACT.md §6.2).

License

MIT. See LICENSE. (c) 2026 cathedralai.