Protocol Specifications
The 4 foundational protocol blueprints define how every component communicates — wire format, cryptographic identity, canonical data types, and federation. Everything else in the platform depends on these contracts.
Protocol blueprints are the lowest layer. They define what goes on the wire between agents, orchestrators, gateways, and federated hubs. A system that implements these 4 specs correctly can participate in any Weblisk network — regardless of implementation language or hosting platform.
Wire Format
The wire format defines the HTTP + JSON communication contract between all Weblisk components. Every request and response in the system follows these rules — no exceptions, no alternative encodings, no negotiation required.
Transport Rules
| Rule | Value |
|---|---|
| Transport | HTTP/1.1, HTTP/2, or HTTP/3 — all supported equally |
| Content type | application/json — always, for both requests and responses |
| Path prefix | /v1 — all endpoints versioned |
| Timestamps | Unix epoch seconds (int64) — no timezone ambiguity |
| IDs | 32-character hex strings (16 random bytes) |
| Body limit | 1 MB default; 10 MB for task execution |
| Unknown fields | MUST be ignored — forward compatibility guaranteed |
Request Envelope
Every authenticated request carries identity context:
POST /v1/execute HTTP/1.1
Authorization: Bearer <WLT token>
Content-Type: application/json
X-Trace-Id: <32-char hex>
X-Request-Id: <32-char hex>
{
"id": "<task-id>",
"token": "<WLT token>",
"context": {
"workspace_root": "/path/to/project",
"services": { ... },
"entity": { ... },
"trace_id": "<32-char hex>"
},
...
}
Response Envelope
All responses follow one of two shapes — success (2xx) or error (4xx/5xx):
{
"error": "forwarding to agent failed — connection refused",
"code": "AGENT_UNREACHABLE",
"category": "transient",
"retryable": true
}
Error Categories
- transient — temporary failure; retry is safe (network timeout, agent overloaded)
- permanent — will not succeed on retry (invalid input, capability not available)
- partial — request partially succeeded; detail includes completed and failed sub-results
Standard Error Codes
| Code | HTTP | Category | Meaning |
|---|---|---|---|
INVALID_REQUEST | 400 | permanent | Missing or malformed fields |
INVALID_SIGNATURE | 401 | permanent | Ed25519 signature verification failed |
TOKEN_EXPIRED | 401 | transient | Token past expiry — re-register |
FORBIDDEN | 403 | permanent | Missing required capability |
NOT_FOUND | 404 | permanent | Unknown agent or resource |
AGENT_UNREACHABLE | 502 | transient | Agent connection failed |
RATE_LIMITED | 429 | transient | Too many requests — retry after backoff |
Identity — Ed25519 Cryptographic Signing
Every agent, orchestrator, and hub has a unique cryptographic identity. No usernames, no passwords, no shared secrets — identity is proven mathematically via Ed25519 (RFC 8032) digital signatures.
Key Generation
# Keys generated on first startup
.weblisk/keys/
├── private.key # 64 bytes, file permissions 0600
└── public.key # 32 bytes, shared freely
# Public key format: 64-character hex string
# Signature format: 128-character hex string (64 bytes)
What Gets Signed
| Operation | Signed Payload | Purpose |
|---|---|---|
| Registration | JSON.stringify(manifest) | Prove ownership of claimed identity |
| Task results | JSON.stringify({task_id, status, output}) | Non-repudiation — agent cannot deny producing a result |
| Messages | JSON.stringify({from, to, action, payload}) | Verify sender identity without trusting the transport |
| Channel grants | JSON.stringify({channel_id, agents, expires}) | Orchestrator authorizes direct communication |
| Federation handshake | JSON.stringify({hub_id, capabilities, timestamp}) | Mutual authentication between hubs |
WLT Token Format
Weblisk tokens (WLT) are structured as base64url(header).base64url(payload).base64url(signature):
// Header
{ "alg": "Ed25519", "typ": "WLT" }
// Payload
{
"sub": "seo-analyzer", // Agent name
"iss": "orchestrator", // Issuer
"iat": 1713264000, // Issued at (epoch seconds)
"exp": 1713350400, // Expiry (epoch seconds)
"cap": ["file:read", "llm:chat"], // Granted capabilities
"cid": "" // Channel ID (empty = not channel-scoped)
}
Token Lifetimes
- Agent auth tokens: 24-hour TTL — issued on registration, re-register to renew
- Channel tokens: 1-hour TTL — issued per channel grant, auto-expire
- Federation tokens: 72-hour TTL — negotiated during hub peering
Replay Protection
Registration requests include a timestamp. The orchestrator rejects any request where |now - timestamp| > 300 seconds (5-minute window). This prevents intercepted registrations from being replayed.
Algorithm Agility
The alg field in the WLT header enables future migration to post-quantum algorithms (ML-DSA / FIPS 204) with zero protocol-level changes. Implementations MUST check the alg field and reject unknown algorithms.
Canonical Types
Every data structure that crosses a wire boundary is defined as a canonical type. These are the shared vocabulary — when an agent says "TaskResult", every other component knows the exact shape, field types, and constraints.
Core Types
| Type | Fields | Used By |
|---|---|---|
| AgentManifest | name, type, version, description, url, public_key, capabilities, inputs, outputs, collaborators, approval, max_concurrent |
Registration, discovery |
| TaskRequest | id, token, context, inputs, priority, deadline |
Task submission |
| TaskResult | task_id, status, output, changes, observations, recommendations, signature, duration_ms |
Task completion |
| ServiceDirectory | agents[] (name, url, type, public_key, capabilities, status) |
Discovery, routing |
| ChannelGrant | channel_id, agents[], token, expires, signature |
Agent-to-agent messaging |
| ErrorResponse | error, code, category, retryable, detail |
All error responses |
| HealthStatus | name, version, status, uptime_seconds, metrics |
Health checks |
Type Rules
- All fields use
snake_case— no camelCase, no PascalCase on the wire - Optional fields are omitted entirely (not
null) — reduces payload size and simplifies parsing - Arrays are never
null— empty arrays are[] - Enums are lowercase strings —
"success","failed","pending_approval" - Unknown fields MUST be preserved during passthrough (orchestrator forwarding) and ignored during processing
Capability Format
// Capability = namespace:action + optional resource scoping
{
"name": "file:read",
"resources": ["app/**/*.html", "content/**/*.md"]
}
// Standard namespaces:
// file:read, file:write — filesystem access
// llm:chat — LLM inference
// agent:message — inter-agent communication
// workflow:execute — multi-agent orchestration
// http:get, http:send — outbound HTTP
// http:receive — inbound HTTP (webhook handling)
// database:read, database:write — data store access
// realtime:publish — real-time channel publishing
Status Enum
Task results carry a status field with exactly 3 values:
success— task completed, output is availablefailed— task failed, error is in outputpending_approval— task produced recommendations that require human approval before execution
Federation
Federation is the protocol that allows independent hubs to collaborate without trusting each other's internal state. Each hub maintains sovereignty over its agents, data, and policies — federation provides controlled, cryptographically verified interaction between hubs.
Federation Model
Hub A (acme.weblisk.dev) Hub B (partner.weblisk.dev)
├── Orchestrator A ├── Orchestrator B
├── Agents [internal] ├── Agents [internal]
├── Federation Gateway ◄────────► Federation Gateway
│ ├── Peer registry │ ├── Peer registry
│ ├── Data boundary rules │ ├── Data boundary rules
│ └── Trust tier: verified │ └── Trust tier: verified
└── Shared capabilities: └── Shared capabilities:
- seo:analyze - content:translate
- perf:audit - legal:review
Trust Tiers
| Tier | Access Level | Verification |
|---|---|---|
| anonymous | Public endpoints only (health, capability listing) | None — any hub can query |
| known | Can request tasks on shared capabilities | Ed25519 handshake successful |
| verified | Full collaboration — shared channels, workflow participation | Mutual authentication + behavioural fingerprint match |
| trusted | Can act as delegate — execute on behalf of the other hub | Verified + explicit trust grant by admin |
Peering Handshake
- Hub A sends a signed peering request:
{hub_id, url, public_key, capabilities, timestamp} - Hub B verifies the signature and checks the timestamp (5-minute window)
- Hub B responds with its own signed capabilities declaration
- Both hubs store each other in their peer registry at known tier
- Behavioural fingerprinting begins — response patterns, capability stability, error rates
- After threshold met (configurable), tier elevates to verified
Data Boundary Contracts
Federation enforces data sovereignty through explicit boundary rules:
federation:
peers:
partner.weblisk.dev:
trust_tier: verified
shared_capabilities:
- content:translate
- legal:review
data_boundary:
allow_fields: [title, description, url, language]
deny_fields: [email, api_key, internal_id, password]
max_payload_size: 64KB
retention: none # Partner must not persist our data
rate_limit: 100/hour
Federation Security
- Cryptographic isolation: Each hub's internal agents are invisible to federated peers — only explicitly shared capabilities are exposed
- Data minimisation: Boundary rules strip fields before cross-hub transmission
- Audit trail: Every federated request is logged with peer identity, capability used, and data fields transmitted
- Revocation: Trust can be revoked instantly — removes peer from registry and terminates active channels
- No transitive trust: If Hub A trusts Hub B, and Hub B trusts Hub C, Hub A does NOT automatically trust Hub C