Server Specification
The formal contract that every Weblisk server implementation must fulfil — agent protocol, orchestrator endpoints, identity, and error handling.
Overview
The Weblisk Agent Protocol v1 defines how autonomous agents register with an orchestrator, receive tasks, execute domain-specific logic, communicate with each other, and report results. All communication is HTTP + JSON. Any implementation — regardless of language or platform — that conforms to this specification is compatible with the Weblisk client framework, any blueprint, and any agent.
The specification covers two component types:
- Agents — autonomous processes that expose 5 standard endpoints for describing themselves, executing tasks, reporting health, receiving messages, and accepting service directory updates
- Orchestrator — the central coordination service that manages registration, task routing, channel brokering, service discovery, audit logging, strategies, and approvals
The protocol supports the continuous optimisation lifecycle: strategise → observe → recommend → execute → feedback.
Conventions
- All paths are prefixed with
/v1 - All request/response bodies are
application/json - All timestamps are Unix epoch seconds (
int64) - All signatures are hex-encoded Ed25519 signatures (128 hex chars)
- All public keys are hex-encoded Ed25519 public keys (64 hex chars)
- IDs are 32-character hex strings (16 random bytes)
- Unknown JSON fields MUST be ignored (forward compatibility)
- Request body limits: 1 MB default, 10 MB for task execution
- Errors return
ErrorResponseJSON — at minimum{"error": "message"}
Design Principles
- Minimal surface — only endpoints that every implementation needs
- Transport agnostic — works over HTTP/1.1, HTTP/2, or HTTP/3
- Discovery-based — agents discover each other via the orchestrator's service directory
- Versioned — protocol versions are negotiated at registration; breaking changes only in major versions
- Signed everything — manifests, results, messages, and channel grants are all Ed25519-signed
- Forward compatible — unknown JSON fields are ignored; new optional fields can be added without breaking existing agents
Agent Endpoints
Every agent MUST serve these 5 endpoints on a single HTTP port:
| Path | Method | Auth | Purpose |
|---|---|---|---|
/v1/describe | POST | No | Return the agent's AgentManifest — identity, capabilities, inputs, outputs |
/v1/execute | POST | Yes | Execute a task; accepts TaskRequest, returns signed TaskResult |
/v1/health | GET | No | Health check — returns HealthStatus with name, version, uptime, metrics |
/v1/message | POST | Yes | Agent-to-agent messaging — dispatches to handler by action field |
/v1/services | POST | Yes | Accept service directory updates pushed by the orchestrator |
POST /v1/describe
Returns the agent's full manifest. No auth required — this is how the orchestrator discovers agent capabilities.
{ "name": "seo-analyzer", "type": "agent", "version": "1.0.0", "description": "Scans HTML files and analyzes SEO metadata", "url": "http://localhost:9710", "public_key": "<64-char hex Ed25519 public key>", "capabilities": [ {"name": "file:read", "resources": ["app/**/*.html"]}, {"name": "llm:chat", "resources": []}, {"name": "agent:message", "resources": []} ], "inputs": [ {"name": "html_files", "type": "file_list", "description": "HTML files to analyze"} ], "outputs": [ {"name": "seo_report", "type": "json", "description": "SEO analysis with proposed changes"} ], "collaborators": ["a11y-checker"], "approval": "required", "max_concurrent": 5 }
POST /v1/execute
Executes a task. The agent MUST validate the request has a non-empty id and token,
update its internal service directory from context.services, execute domain-specific logic,
and return a signed TaskResult with task_id matching the request id.
Task results include a status of success, failed, or pending_approval.
Results MAY contain changes (proposed file modifications), observations (measurements),
and recommendations (suggested actions).
POST /v1/message
Direct agent-to-agent messaging. The agent MUST verify the sender's signature against their public key from
the service directory, dispatch to the appropriate handler based on the action field, and sign
the response. Signature covers: JSON.stringify({from, to, action, payload}).
Orchestrator Endpoints
The orchestrator is the central coordination service. It does NOT execute agent logic — it manages registration, routing, security, and discovery.
| Path | Method | Auth | Purpose |
|---|---|---|---|
/v1/register | POST | No | Agent registration — this is how agents get auth tokens |
/v1/register | DELETE | Yes | Agent deregistration — removes from registry and broadcasts |
/v1/task | POST | Yes | Submit a task — routes to target agent via domain or directly |
/v1/channel | POST | Yes | Broker a secure agent-to-agent channel (requires agent:message capability) |
/v1/services | GET | Yes | Current service directory — all registered agents |
/v1/health | GET | No | Orchestrator health with agent/domain/channel counts |
/v1/audit | GET | Yes | Append-only audit log — every operation recorded |
/v1/strategy | GET/POST | Yes | Create, update, and list business strategies |
/v1/context | GET/POST | Yes | Set and retrieve entity context (company, project, site) |
/v1/observations | GET | Yes | Observation history with filtering and pagination |
/v1/approve | GET/POST | Yes | List pending recommendations; approve or reject them |
Registration Flow
Agents register by sending their signed manifest to POST /v1/register:
- Agent builds its
AgentManifestand signs it with its Ed25519 private key - Sends
{manifest, signature, timestamp}to the orchestrator - Orchestrator verifies the signature against
manifest.public_key - Enforces replay protection — rejects if
|now - timestamp| > 300 seconds - Generates a unique
agent_idand issues a WLT auth token (24-hour TTL) - If
manifest.type = "domain": evaluatesrequired_agentsavailability - Logs audit entry and broadcasts updated
ServiceDirectoryto all other agents - Returns
RegisterResponsewith token, service directory, and negotiated protocol version
Task Routing
When a task is submitted to POST /v1/task, the orchestrator routes it based on the target agent's type:
- Domain controller (
type: "domain") — standard path for business tasks; the domain decomposes them into multi-agent workflows - Infrastructure agent (
type: "infrastructure") — routed directly - Work agent (
type: "agent") — direct routing with an advisory log suggesting routing through the domain instead
The orchestrator injects context (workspace_root, service directory, entity context) and a
trace_id for distributed tracing. If the response contains observations or recommendations,
they are stored for the lifecycle loop.
Channel Brokering
Agents that need direct communication request a channel via POST /v1/channel.
The orchestrator verifies the requester has the agent:message capability,
generates a channel ID and a time-limited channel token (1-hour TTL), stores the active channel,
signs the grant, and returns a ChannelGrant with the target agent's URL and public key.
Strategy & Lifecycle Endpoints
The orchestrator manages the continuous optimisation loop through several supporting endpoints:
- POST /v1/strategy — create or update a business strategy with measurable targets
- GET /v1/strategy — list strategies, filterable by status (
active,paused,completed) - POST /v1/context — set or update entity context that grounds agent decisions in business reality
- GET /v1/observations — query observation history with
agent,target,strategy,sincefilters and cursor pagination - POST /v1/approve — accept or reject pending recommendations; accepted recommendations on paused workflows trigger a resume
- GET /v1/approve — list pending recommendations with filters for agent, target, strategy, and priority
Identity & Security
Every agent and orchestrator generates an Ed25519 key pair (RFC 8032) on first startup.
Keys are stored in .weblisk/keys/ with restricted permissions.
See Protocols for the full signing and token specification.
WLT Token Format
Tokens follow the format: base64url(header).base64url(payload).base64url(signature)
| Claim | Type | Description |
|---|---|---|
sub | string | Agent name or identity |
iss | string | Issuer — "orchestrator" or agent name |
iat | int64 | Issued at (Unix epoch seconds) |
exp | int64 | Expiry (Unix epoch seconds); 0 = no expiry |
cap | []string | Granted capabilities (e.g. file:read, llm:chat) |
cid | string | Channel ID — for channel-scoped tokens |
Token lifetimes: agent auth tokens last 24 hours; channel tokens last 1 hour.
The header alg field enables future algorithm agility — e.g. ML-DSA / FIPS 204 (post-quantum)
with zero protocol changes.
Auth Middleware
Applied to ALL orchestrator endpoints except GET /v1/health and POST /v1/register:
- Check
Authorization: Bearer <token>header - If no header, check request body for
tokenfield - Verify token signature against orchestrator's public key
- Check token expiry
- On failure →
401 {"error": "valid token required — register first"} - On success → pass decoded claims to handler
Standard Capabilities
| Capability | Description |
|---|---|
file:read | Read files — scoped by glob patterns in resources |
file:write | Write or modify files |
llm:chat | Use LLM for analysis |
agent:message | Communicate with other agents |
workflow:execute | Execute multi-agent workflows (domain controllers) |
http:get / http:send | Make external HTTP requests |
http:receive | Receive inbound HTTP requests |
database:read / database:write | Read from or write to data stores |
realtime:publish | Publish to real-time channels |
Error Handling
All errors MUST return JSON using the ErrorResponse format. Implementations SHOULD include
code, category, and retryable when available.
{ "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, upstream 503)
- permanent — will not succeed on retry (invalid input, capability not available, unknown action)
- partial — request partially succeeded;
detailSHOULD includecompletedandfailedsub-results
Standard Error Codes
| Code | HTTP | Category | Description |
|---|---|---|---|
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 to get a new one |
FORBIDDEN | 403 | permanent | Missing required capability |
NOT_FOUND | 404 | permanent | Agent or resource not in registry |
RATE_LIMITED | 429 | transient | Too many requests — respect Retry-After header |
INTERNAL_ERROR | 500 | transient | Unexpected server error |
AGENT_UNREACHABLE | 502 | transient | Orchestrator could not reach target agent |
AGENT_TIMEOUT | 504 | transient | Target agent did not respond within timeout |
UNSUPPORTED_VERSION | 400 | permanent | Agent requested an unsupported protocol version |
PHASE_FAILED | 500 | varies | Workflow phase failed — check detail.phase_name |
PARTIAL_FAILURE | 207 | partial | Some phases succeeded, some failed |
Observability
Trace ID Propagation
Every task submission SHOULD include a trace_id in TaskContext.
If the caller does not provide one, the orchestrator MUST generate a unique trace_id
(32 hex chars) and inject it before forwarding. The trace ID is propagated through all downstream calls:
Client → POST /v1/task (trace_id in context)
→ Orchestrator forwards to domain → POST /v1/execute (same trace_id)
→ Domain dispatches to agent → POST /v1/message (same trace_id)
Structured Logging
All components SHOULD emit structured JSON logs to stderr. Required fields:
| Field | Description |
|---|---|
ts | Unix epoch seconds |
level | debug, info, warn, error |
msg | Human-readable message |
component | Component name (e.g. orchestrator, seo, seo-analyzer) |
trace_id | Correlation ID (when available) |
Audit log entries (see GET /v1/audit) are a separate persistent record.
Structured logs are operational and ephemeral — for debugging and monitoring, not compliance.
Audit Logging
Every orchestrator operation creates an AuditEntry with actor, action, target, and status.
Entries are logged to stderr in real-time AND stored in an append-only in-memory log.
| Action | Description |
|---|---|
register | Agent registered |
deregister | Agent deregistered |
task | Task submitted or forwarded |
channel | Channel brokered |
message | Message relayed |
strategy | Strategy created or updated |
approval | Recommendation accepted or rejected |
observation | Observation recorded |
recommendation | Recommendation stored |
feedback | Feedback received |
Version Negotiation
On registration, the orchestrator reads the agent's manifest.protocol_version (default "1"
if omitted). If the orchestrator supports that version, registration succeeds and
RegisterResponse.protocol_version confirms the negotiated version. If the requested version is
not in supported_versions, the orchestrator rejects with 400 and error code
UNSUPPORTED_VERSION.
Server Lifecycle
A compliant orchestrator follows this startup sequence:
- Load Identity — load or generate an Ed25519 key pair (name:
"orchestrator"); keys stored in.weblisk/keys/ - Initialise Stores — empty agent registry, channel registry, audit log, strategy/observation/recommendation stores
- Register Routes — bind HTTP handlers for all protocol endpoints
- Start HTTP Server — listen on configured port (default 9800, configurable via
--portorWL_ORCH_PORT) - Print Startup Info — URL, public key, instructions for registering agents
- Serve — block and handle requests; agents register themselves after startup
On shutdown, the orchestrator drains active connections, deregisters agents, and flushes the audit log.
Verification Checklist
Every compliant implementation MUST pass these checks:
Agent Verification
- Responds to
POST /v1/describewith validAgentManifest - Responds to
GET /v1/healthwith validHealthStatus - Accepts
POST /v1/servicesand updates internal directory - Handles
POST /v1/messagewith signature verification - Returns signed
TaskResultfromPOST /v1/execute - Returns 429 with
RATE_LIMITEDwhen atmax_concurrentcapacity
Orchestrator Verification
GET /v1/healthreturns without authPOST /v1/registervalidates signature and enforces 300s replay windowDELETE /v1/registerremoves agent and broadcastsPOST /v1/taskroutes to correct agent based on typePOST /v1/channelverifiesagent:messagecapabilityPOST /v1/approvetransitions pending → accepted/rejected; rejects empty reason on rejectPOST /v1/strategystores and returns strategyPOST /v1/contextstores entity contextGET /v1/observationsreturns observations with pagination- Generates
trace_idif not provided by caller trace_idpropagated through task forwarding and agent dispatch- Structured logs include
ts,level,msg,componentfields RegisterResponseincludes negotiatedprotocol_version- All error responses use
ErrorResponseformat witherrorfield - All protected endpoints reject requests without valid tokens