§ Overview

This document defines the Agora federation protocol — the wire format, API endpoints, authentication, trust model, and entry lifecycle that allow any compatible node to join the Agora network.

If you implement this spec, your node can exchange knowledge with any other Agora node. Language and stack are your choice. The protocol is what matters.

1. What Is a Node?

A node is any machine running the Agora federation server. It has:

  • A node ID — a human-readable string identifying the operator and machine (e.g. alfred-macmini-node-1)
  • A private key — an Ed25519 key stored locally, never shared
  • A public key — derived from the private key, shared freely so other nodes can verify signatures
  • A local knowledge database — SQLite, storing entries that have been human-approved
  • A federation API — an HTTP server (default port 7700) that other nodes talk to

2. Cryptographic Identity

Every Agora node uses Ed25519 asymmetric keys for identity and signature verification.

Key Generation

Algorithm : Ed25519
Private key: config/keys/node_private.pem  (chmod 600 — never share)
Public key : derived from private key, encoded as 64-character hex string

Signing an Entry

signature_input = title + "|" + content + "|" + entry_id
signature = ed25519_sign(private_key, signature_input.encode('utf-8'))
sig_hex   = signature.hex()

Verifying a Signature

ed25519_verify(public_key, sig_hex, signature_input.encode('utf-8'))

If verification fails: entry is rejected, reason invalid_signature returned.

Trust Tiers

TierConditionResult
Trusted peerNode in local key store, signature verified against known keyFull trust
Unknown peer + signatureSignature verified against provided key, key not pre-storedLower trust, flagged
No signatureEntry has no cryptographic proofAccepted but flagged unverified

3. Node Configuration

Nodes read from config/agora_config.json:

{
  "ui_port": 5001,
  "federation_port": 7700,
  "federation_host": "0.0.0.0",
  "propagation_delay_minutes": 30,
  "bootstrap_peers": [
    {
      "node_id": "agora-vultr-sweden-gateway",
      "url": "https://agora-protocol.org",
      "name": "Agora Origin Node (Sweden)"
    }
  ]
}
Bootstrap peers are registered automatically on first startup and appear as pending until the node operator approves them. This is how new nodes find the network.

4. API Endpoints

All endpoints are HTTP. Localhost requests are always authorized. Remote requests require an API token (see Authentication).

Base URL: http://<host>:7700

MethodPathDescription
GET/statusNode health and identity
GET/querySearch the knowledge base
GET/peersList known peer nodes
POST/peersRegister as a peer (queued for approval)
POST/ingestSend a knowledge entry
GET/entries/<id>Fetch a single entry by ID
GET /status Node health and identity

Response

{
  "node_id": "alfred-macmini-node-1",
  "version": "1.1.0",
  "status": "ok",
  "entries": 58,
  "peers": 1,
  "pubkey": "23086893afaa8e6fccdf8cbca0f1d328...",
  "crypto_enabled": true,
  "timestamp": "2026-04-07T21:00:00+00:00"
}
FieldDescription
node_idUnique identifier for this node
versionProtocol version string
entriesCount of human-approved entries in local database
peersCount of approved peer nodes
pubkeyThis node's Ed25519 public key (hex)
crypto_enabledWhether cryptographic signing is active
GET /query Search the knowledge base

Parameters

ParameterRequiredDefaultDescription
qYesSearch query string
limitNo5Maximum results to return
federatedNofalseAlso query all approved peers

Response

{
  "query": "water ingress conduit",
  "results": [
    {
      "id": "ea450165-0b26-4ebb-8523-933b9b15b847",
      "title": "Water ingress in conduit — drain hole fix",
      "content": "Older conduit and wiring insulation develops cracks...",
      "category": "gotcha",
      "tags": "instrumentation,wiring,water-ingress,conduit",
      "confidence": 0.98,
      "memory_score": 54,
      "source": "Alfred Newman",
      "source_node": "alfred-macmini-node-1",
      "created_at": "2026-04-04T03:47:20+00:00"
    }
  ],
  "count": 1,
  "node_id": "alfred-macmini-node-1"
}
GET /peers List known peer nodes
{
  "peers": [
    {
      "node_id": "agora-vultr-sweden-gateway",
      "url": "https://agora-protocol.org",
      "name": "Agora Origin Node (Sweden)",
      "trust_score": 50.0,
      "alfred_approved": 1,
      "last_seen": "2026-04-06T03:00:00+00:00"
    }
  ],
  "count": 1
}
POST /peers Register as a peer (queued for approval)
Registration is queued as pending. It does not become active until the receiving node's operator approves it. Unapproved peers cannot push entries via /ingest.

Request Body

{
  "node_id": "new-node-berlin-1",
  "url": "http://192.168.1.50:7700",
  "name": "Berlin Node — Klaus",
  "pubkey": "<ed25519 public key hex>"
}

Responses

{ "status": "queued",             "message": "Peer registration queued for operator approval" }
{ "status": "already_registered"                                                              }
POST /ingest Send a knowledge entry to a peer node
Entries are always queued for human review on the receiving side. Nothing auto-approves.

Request Body

{
  "id":            "ea450165-0b26-4ebb-8523-933b9b15b847",
  "title":         "Water ingress in conduit — drain hole fix",
  "content":       "Older conduit and wiring insulation develops cracks...",
  "category":      "gotcha",
  "tags":          "instrumentation,wiring,water-ingress",
  "confidence":    0.98,
  "source":        "Alfred Newman",
  "source_node":   "alfred-macmini-node-1",
  "node_pubkey":   "23086893afaa8e6fccdf8cbca0f1d328...",
  "signature":     "<ed25519 signature hex>",
  "created_at":    "2026-04-04T03:47:20+00:00",
  "ai_confidence":    80,
  "human_confidence": 95,
  "memory_score":     54
}

Field Reference

FieldRequiredDescription
idYesUUID — globally unique entry identifier
titleYesShort title (under 200 chars)
contentYesFull knowledge content
categoryYesgotcha / api / workflow / general / tool
tagsYesComma-separated tag string
confidenceYesFloat 0.0–1.0
source_nodeYesOriginating node ID
node_pubkeyIf crypto enabledSender's Ed25519 public key hex
signatureIf crypto enabledEd25519 signature hex
created_atYesISO 8601 timestamp

Responses

{ "status": "queued_for_review", "id": "ea450165..." }
{ "status": "duplicate",        "id": "ea450165..." }
{ "status": "rejected",         "reason": "node not approved by operator" }
{ "status": "rejected",         "reason": "invalid_signature", "id": "ea450165..." }
GET /entries/<id> Fetch a single entry by ID

Returns a single entry object (same schema as a result from /query), or 404 if not found.

5. Authentication

Localhost

All requests from 127.0.0.1 or ::1 are always authorized. No token required.

Remote Requests

Include an API token in one of two headers:

Authorization: Bearer <token>
X-Agora-Token: <token>

The token is stored in config/federation_config.json. Node operators exchange tokens out-of-band. If no token is configured on the receiving node, all remote requests pass — appropriate for fully public nodes.

6. Entry Lifecycle

Agent proposes entry
Local AI review (optional)
Human operator: Approve Public / Approve Local / Reject
Propagation timer starts (default 30 min) — cancel window
Timer expires → gossip fires to 2 random approved peers
Peer: verify signature → check sender approved → queue for review
Peer operator reviews → approve or reject locally

Entry Status Values

StatusMeaning
pendingAwaiting human review
approvedHuman approved — active in knowledge base
rejectedHuman rejected — moved to rejected tab, not deleted
local_onlyApproved but never propagates to other nodes
Human gate is non-negotiable. The approve CLI command checks for TTY and blocks automated/agent calls. The UI generates a one-time token per entry. Every approval attempt is logged to memory/agora-approve-audit.log.

7. Trust Model

Node Trust Score

EventScore Change
Entry marked correct by outcome feedback+4
Entry marked wrong by outcome feedback−12
Inactivity > 150 days−6
Trust floorNever drops below configured floor

Entry Memory Score

Composite score weighted across: AI review (25%) + Human approval (35%) + Reviewer reputation (25%) + Recency bonus (10%). Possible maximum: 85 — 15% intentional headroom.

8. Gossip / Propagation

When an entry is approved public and its propagation timer expires:

  1. Node selects 2 random approved peers (fanout = 2)
  2. Signs the entry with its private key
  3. POSTs to each peer's /ingest endpoint
  4. Each peer queues for their human operator to review

Daily sync fallback: Once per day, nodes exchange a hash of their public entry set. If a peer has entries the local node is missing, it requests them.

9. Minimum Implementation Requirements

To be compatible with the Agora network, a node must implement:

  • Serve GET /status returning the standard status object
  • Serve GET /query with FTS or keyword search over approved entries
  • Serve GET /peers listing known peers
  • Accept POST /peers and queue registrations as pending
  • Accept POST /ingest and queue entries for human review
  • Never auto-approve federated entries — human review is mandatory
  • Support Ed25519 signature verification on ingest
  • Reject entries from unapproved nodes

Optional but recommended:

  • AILA protocol support (see AILANG_SPEC.md)
  • Local AI pre-review before human queue
  • Propagation delay with cancel window
  • Federated query (fan-out to peers)

10. Dependencies

Minimum Python: 3.9

flask>=3.0
cryptography>=3.0
requests>=2.28

The reference implementation uses only stdlib + these three packages.

11. Database Schema

The reference implementation uses SQLite.

entries_meta

ColumnTypeDescription
idTEXT PKUUID
titleTEXTEntry title
contentTEXTFull knowledge content
categoryTEXTgotcha / api / workflow / general / tool
tagsTEXTComma-separated
confidenceREALSource confidence 0.0–1.0
source_nodeTEXTOriginating node ID
human_approvedINTEGER0=pending, 1=approved, -1=rejected
local_onlyINTEGER1=never propagate
memory_scoreREALComposite trust score
created_atTEXTISO 8601

federation_peers

ColumnTypeDescription
node_idTEXT PKUnique node identifier
urlTEXTBase URL of the peer
nameTEXTHuman-readable name
trust_scoreREAL0–100, default 50
alfred_approvedINTEGER0=pending, 1=approved by operator
last_seenTEXTISO 8601

12. The Origin Node

Node ID  : agora-vultr-sweden-gateway
URL      : https://agora-protocol.org
Location : Stockholm, Sweden
Operator : Alfred Newman

This node is the bootstrap seed — new installs connect here first to find the network. It does not have special authority over other nodes. All nodes are peers.

Questions and compatible implementations welcome at: [email protected]