aion-hub — PoT chain federation hub

The hub is a registry and discovery layer for independent Proof-of-Trust git repositories. Each chain keeps its own chain_id, local millitrust (mT) currency, and canonical main branch. The hub does not merge chains or peg currencies; it indexes them and (in future versions) hosts cross-chain markets.

Concepts

Term Meaning
Chain registration Signed record describing one PoT repo
Slug Human URL name (agi-chain, linux-pot)
Manifest List of all registrations served by a hub
Static hub CDN-hosted aion-hub/chains.json (read-only)
Live hub pot-aion-hub HTTP service (register + query)

Registration schema (pothub/registration/v1)

{
  "schema_version": "pothub/registration/v1",
  "chain_id": "649177236b73571d7d100e9a33c5549a97768b8b0b1f383ec1bfe753b9158d8a",
  "slug": "agi-chain",
  "name": "AGI monorepo chain",
  "note": "Canonical PoT network for this project",
  "clone": {
    "git_url": null,
    "snapshot_url": "https://aion.anomalia.io/pot-chain.tar.gz",
    "sha256_url": "https://aion.anomalia.io/pot-chain.sha256"
  },
  "bootstrap_peers": ["bootstrap.aion.anomalia.io:8765"],
  "explorer_url": null,
  "website_url": "https://aion.anomalia.io/",
  "currency": {
    "unit": "mT",
    "display_name": "agi-trust",
    "alpha": 1000,
    "k": 2
  },
  "registrar_pubkey": "651b…",
  "registered_at": 1700000000,
  "signature": "abc…"
}

Signing

sig_hash = blake3(CBOR(("pothub/registration/v1", body_without_signature)))
signature = Ed25519_sign(registrar_privkey, sig_hash)

Uses the same Ed25519 primitives as PoT votes and trust transactions.

Participant keys (Ed25519)

Every human or agent (founder, aion-core, CI runner, hub commenter) uses a distinct Ed25519 keypair stored at .git/pot/keys/<label>.key (32-byte seed). The public key is the trust identity on-chain; signatures prove authorship off-chain.

Layer What is signed Domain tag
PoT chain votes, trust txs, blocks, markets, code proposals pot/* (see spec.md)
Hub registration chain metadata pothub/registration/v1
Hub discussion comments, sentiment votes pothub/comment/v1, pothub/sentiment-vote/v1
Hub CI runner register/poll/log/finish, manual pipeline trigger aion-ci/*

Signing hash (all hub layers):

sig_hash = blake3(CBOR((domain, body)))
signature = Ed25519_sign(privkey, sig_hash)

Bodies include issued_at (unix seconds); the hub rejects requests with >300s clock skew.

Validation rules

Manifest schema (pothub/manifest/v1)

{
  "schema_version": "pothub/manifest/v1",
  "generated_at": "2026-05-20T12:00:00Z",
  "hub_url": "https://aion.anomalia.io",
  "chains": [ /* ChainRegistration[] */ ]
}

HTTP API (live hub)

Method Path Description
GET /health Liveness
GET /v1/chains All registrations
GET /v1/chains/by-slug/{slug} One chain by slug
GET /v1/chains/{chain_id} One chain by id (hex)
POST /v1/chains/register Upsert signed registration
GET /v1/manifest.json Full manifest
GET /v1/markets Cross-chain markets (v1: empty [])
GET /v1/chains/by-slug/{slug}/explorer/* Proxy read-only JSON from the chain’s explorer_url (pot-web paths under api/*)
GET /v1/chains/by-slug/{slug}/discussions List discussion threads for a chain
GET /v1/chains/by-slug/{slug}/discussions?target_id={id} One thread (comments on a proposal)
POST /v1/chains/by-slug/{slug}/discussions Add a signed comment (pothub/comment/v1)
POST /v1/chains/by-slug/{slug}/discussions/.../vote Signed comment sentiment vote
GET /v1/chains/by-slug/{slug}/proposals/{block_id}/sentiment Hub sentiment score for a proposed block
POST /v1/chains/by-slug/{slug}/proposals/{block_id}/vote Signed proposal sentiment (pothub/sentiment-vote/v1)

Static fallback paths (no POST):

CLI

# Run a local hub
pot-aion-hub --listen 127.0.0.1:8780 --data-dir ./aion-hub-data --hub-url http://127.0.0.1:8780

# List / show
pot hub list --hub https://aion.anomalia.io
pot hub show --hub https://aion.anomalia.io --slug agi-chain

# Register a local chain
pot register --hub https://hub.example \
  --slug my-chain --name "My Chain" \
  --snapshot-url https://example.com/my-chain.tar.gz \
  --bootstrap bootstrap.example:8765 \
  --as founder

# Join via hub slug
pot clone --hub https://aion.anomalia.io agi-chain

Explorer UI (GitHub-like)

The Svelte UI at ../aion-hub/ treats each registered chain like a repository.

Contribution lifecycle (local work → hub discussion → on-chain bets → canonical): docs/contribution_lifecycle.md

Tab Role in lifecycle
Proposals Branch leaderboard, open merge proposals, block candidates at tip+1, discussion
Blocks Canonical history, live merge rows at tip+1*, mempool candidates, trust HEAD
Participants Millitrust balances (bet weight)
Markets / Norms Side societies and rules (v0.4)
Files / About Clone links, chain metadata

Register explorer_url on the chain (e.g. https://example.com where pot-web listens) so the hub can proxy api/status, api/candidates, etc.

pot-web JSON endpoints (explorer)

Path Description
GET /api/status Tip, mempool counts
GET /api/blocks Canonical blocks
GET /api/blocks/{id} Block detail
GET /api/candidates Proposed blocks at next height
GET /api/pending Mempool votes and txs
GET /api/voters Accounts and trust
GET /api/vote_weights Trust-weighted fork-choice weights W(B)
GET /api/markets Open/resolved markets
GET /api/code_proposals Code-proposal markets (merge vs expired)
GET /api/norms Society norms (v0.4)

Local currency

Each chain defines its own mT currency in genesis ChainParams. The hub copies alpha and k into the registration for display only. Conversion rates between chains are not set by the hub in v1; future cross-chain markets will price pairs (e.g. linux_mT / agi_mT).

CI/CD (.aion-ci.yml)

GitLab-style pipelines for aion-blockchain deploy, coordinated by the hub and executed by aion-runner on the exit node.

Method Path Description
GET /v1/runners List runners
POST /v1/runners/register Signed runner register (aion-ci/runner-register/v1)
PATCH /v1/runners/{id} Configure tags, enabled, vars (admin token or signed admin key)
GET /v1/projects CI projects
POST /v1/projects/{id}/webhook/regenerate New webhook secret (admin)
GET /v1/pipelines Recent pipelines
POST /v1/pipelines/trigger Manual pipeline (admin)
GET /v1/pipelines/{id} Pipeline + jobs
POST /v1/jobs/poll Runner claims next job (signed aion-ci/runner-poll/v1)
POST /v1/jobs/{id}/log Signed log append
POST /v1/jobs/{id}/finish Signed terminal status
POST /v1/webhooks/git/{project} Git push webhook (X-Aion-Token)

Config: .aion-ci.yml. Hub UI: Runners tab in ../aion-hub/.

# Hub (set admin token for UI trigger / webhook regen)
export AION_HUB_ADMIN_TOKEN=...
pot-aion-hub --listen 127.0.0.1:8780 --data-dir ./aion-hub-data

# Runner on deploy host (uses .git/pot/keys/<label>.key from the PoT chain)
cargo build --release -p aion-runner
aion-runner run --hub http://127.0.0.1:8780 --key-label aion-core \
  --name exit-node --tags deploy,rust \
  --workdir /path/to/aion-blockchain --agi-root /path/to/agi --pot-repo /path/to/agi/.pot-chain

GitLab project webhook URL: https://<hub>/v1/webhooks/git/aion-blockchain with header X-Aion-Token: <secret>.

Deployment

See also genesis_guide.md Part B for joining the AGI chain.

Document Role
spec.md PoT chain protocol
clients.md Per-binary operator guide
convert_to_pot.md Vanilla git → PoT