* chore: prepare v6.1.2 release * chore: refresh reviewed gitleaks fingerprints * docs: record release gate corrections * docs: record v6.1.2 release evidence
18 KiB
Agent Registry
The Agent Registry is a service discovery and liveness tracking system for AI agents working with Veritas Kanban. It answers three questions: who's available, what can they do, and are they still alive.
Overview
| Feature | Description |
|---|---|
| Registration | Agents register on startup with ID, model, capabilities |
| Heartbeats | Periodic pings prove liveness; 5 min timeout → offline |
| Discovery | Query by status, capability, or ID |
| Persistence | File-backed JSON survives server restarts |
| Dashboard | Live agent cards in the board sidebar |
Storage: <storage-root>/.veritas-kanban/agent-registry.json
Current Roster
| Agent | Role | Model | Capabilities |
|---|---|---|---|
| VERITAS | Orchestrator | claude-opus-4-6 | strategy, orchestration, research, code-review, writing, analysis |
| TARS | Lead | claude-opus-4-6 | code-review, architecture, security, refactoring |
| CASE | Lead | claude-opus-4-6 | research, analysis, documentation, writing |
| Ava | Specialist | claude-sonnet-4-5 | frontend, ui-design, css, react |
| R2-D2 | Specialist | claude-sonnet-4-5 | automation, scripting, devops, testing |
| K-2SO | Specialist | claude-sonnet-4-5 | security, audit, penetration-testing, compliance |
| MAX | Specialist | claude-sonnet-4-5 | data-analysis, visualization, metrics, reporting |
| Johnny 5 | Intern | claude-haiku-4-5 | documentation, formatting, file-organization |
| Bishop | Specialist | claude-sonnet-4-5 | backend, api-design, database, performance |
| Marvin | Intern | claude-haiku-4-5 | testing, qa, bug-reproduction, grunt-work |
Veritas Cutover Roster
The Veritas Cutover uses HermesAgent refs for active routing. Veritas remains the task source of truth, HermesAgent/Hermes Gateway provides the control plane, Mission Control is display/control only, and GitHub is the implementation, PR, review, and CI surface.
| Owner | Ref | Status | Responsibility |
|---|---|---|---|
| Ops | hermes:ops |
Active | Authority model, routing, release readiness |
| QA | hermes:qa |
Active | QA gate, test evidence, reviewer approval |
| Rex | hermes:rex |
Active | Backend and integration implementation |
| Spark | hermes:spark |
Active | Product specs and acceptance criteria |
| Scout | hermes:scout |
Active | Research and revenue intake |
| Bolt | hermes:bolt |
Active | Fast implementation chunks and automation |
| Dan | hermes:dan |
On demand | Medik8 and customer-specific task templates |
See Veritas Cutover Operating Guide for the authority model, QA gate, and GitHub-backed templates.
Role Hierarchy
- Orchestrator — Coordinates all work, spawns sub-agents, makes decisions
- Lead — Trusted with complex tasks, can work independently on architecture-level problems
- Specialist — Focused expertise, assigned to tasks matching their capabilities
- Intern — Lightweight tasks, documentation, grunt work (uses cheaper models)
API Reference
Base URL: /api/agents/register
Register an Agent
POST /api/agents/register
Registers a new agent or updates an existing one. Sets status to online automatically.
Request Body:
{
"id": "TARS",
"name": "TARS",
"model": "claude-opus-4-6",
"provider": "anthropic",
"capabilities": [
{ "name": "code-review", "description": "Reviews code for quality and security" },
{ "name": "architecture" },
{ "name": "security" },
{ "name": "refactoring" }
],
"version": "2.0.0",
"metadata": { "role": "lead", "reference": "Interstellar" },
"providerRuntimeManifest": { "schemaVersion": "provider-runtime-manifest/v1", "...": "..." },
"sessionKey": "optional-openclaw-session-key"
}
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier (1-50 chars) |
name |
string | ✅ | Display name (1-100 chars) |
model |
string | Model identifier | |
provider |
string | Provider name | |
capabilities |
array | List of { name, description? } objects |
|
version |
string | Agent version or build info | |
metadata |
object | Freeform key-value data | |
providerRuntimeManifest |
object | Validated runtime capability evidence; see the Provider Runtime Manifest API reference | |
sessionKey |
string | OpenClaw session key for routing |
The manifest digest is recomputed on registration. Forged, incomplete, or
forward-incompatible manifests, secret-like diagnostic fields, and unknown or
misspelled request fields are rejected with 400. Legacy provider,
model, capabilities, and metadata fields remain available for compatibility
and display, but they cannot satisfy required runtime capability routing.
Authoritative manifest writes require telemetry:write plus either a key/token
identity matching the target agent ID or agent:write. Use a distinct named API
key for each self-registering agent; do not share a generic telemetry key for
runtime evidence. Once a record contains authoritative evidence, re-registration,
heartbeat, replacement, and deregistration remain identity-bound so another
telemetry writer cannot refresh, invalidate, or delete it. Re-registering with a
changed provider, model, or version and without replacement evidence invalidates
the previous manifest.
Response: 201 Created
{
"id": "TARS",
"name": "TARS",
"model": "claude-opus-4-6",
"provider": "anthropic",
"capabilities": [{ "name": "code-review" }, { "name": "architecture" }],
"version": "2.0.0",
"metadata": { "role": "lead" },
"status": "online",
"registeredAt": "2026-02-06T01:55:00.000Z",
"lastHeartbeat": "2026-02-06T01:55:00.000Z"
}
Send Heartbeat
POST /api/agents/register/:id/heartbeat
Updates the agent's last-seen timestamp and optionally changes status or task assignment. Agents that don't heartbeat within 5 minutes are marked offline.
Request Body (all fields optional):
{
"status": "busy",
"currentTaskId": "task_20260206_abc123",
"currentTaskTitle": "Implement authentication flow",
"metadata": { "progress": 0.65 },
"providerRuntimeManifest": { "schemaVersion": "provider-runtime-manifest/v1", "...": "..." }
}
| Field | Type | Values | Description |
|---|---|---|---|
status |
string | online, busy, idle |
Agent's current state |
currentTaskId |
string | null | Task ID being worked on (null to clear) | |
currentTaskTitle |
string | null | Task title (null to clear) | |
metadata |
object | Merge additional metadata | |
providerRuntimeManifest |
object | Replace the validated runtime manifest after a provider/version change |
Heartbeat manifest replacement uses the same authenticated identity binding as registration. Ordinary telemetry-only heartbeats remain backward compatible.
Response: 200 OK — Returns updated agent object.
Error: 404 if agent not registered. Register first.
List All Agents
GET /api/agents/register
GET /api/agents/register?status=online
GET /api/agents/register?capability=security
| Param | Description |
|---|---|
status |
Filter by status: online, busy, idle, offline |
capability |
Filter by capability name (case-insensitive) |
Response: 200 OK — Array of agent objects.
Get Specific Agent
GET /api/agents/register/:id
Response: 200 OK — Single agent object, or 404 if not found.
Registry Statistics
GET /api/agents/register/stats
Response:
{
"total": 10,
"online": 1,
"busy": 0,
"idle": 7,
"offline": 2,
"capabilities": ["analysis", "architecture", "automation", "backend", "code-review", "..."]
}
Find by Capability
GET /api/agents/register/capabilities/:capability
Returns all non-offline agents that have the specified capability.
GET /api/agents/register/capabilities/security
Response: Array of agents with matching capability.
Deregister an Agent
DELETE /api/agents/register/:id
Removes the agent from the registry entirely.
Response: 200 OK — { "removed": true }, or 404 if not found.
Agent Lifecycle
┌─────────┐ register ┌────────┐
│ (new) │ ──────────────► │ online │
└─────────┘ └───┬────┘
│
heartbeat │ heartbeat
status=busy │ status=idle
┌────────┼────────┐
▼ │ ▼
┌────────┐ │ ┌────────┐
│ busy │◄───┘──►│ idle │
└────────┘ └────────┘
│ │
│ 5 min timeout │
│ (no heartbeat)│
▼ ▼
┌─────────────────────────┐
│ offline │
└─────────────────────────┘
│
│ re-register or heartbeat
▼
┌────────┐
│ online │
└────────┘
Status Values
| Status | Meaning |
|---|---|
online |
Agent is running and available for work |
busy |
Agent is actively working on a task |
idle |
Agent is running but not working on anything |
offline |
No heartbeat received in 5 minutes |
Instructions for Agents
On Startup (MANDATORY)
Every agent must register itself when it starts working. This is the first thing you do.
curl -s -X POST http://localhost:3001/api/agents/register \
-H 'Content-Type: application/json' \
-d '{
"id": "YOUR_AGENT_NAME",
"name": "YOUR_AGENT_NAME",
"model": "anthropic/claude-sonnet-4-5",
"provider": "anthropic",
"capabilities": [{"name": "your-skill"}],
"version": "2.0.0",
"metadata": {"role": "specialist"}
}'
When Starting a Task
Update your status to busy with the task info:
curl -s -X POST http://localhost:3001/api/agents/register/YOUR_AGENT_NAME/heartbeat \
-H 'Content-Type: application/json' \
-d '{
"status": "busy",
"currentTaskId": "task_id_here",
"currentTaskTitle": "What you are working on"
}'
While Working (every 2-3 minutes)
Send heartbeats to stay marked as online. If you skip this for 5 minutes, the registry marks you offline.
curl -s -X POST http://localhost:3001/api/agents/register/YOUR_AGENT_NAME/heartbeat \
-H 'Content-Type: application/json' \
-d '{"status": "busy"}'
When Done with a Task
Clear the task assignment and go idle:
curl -s -X POST http://localhost:3001/api/agents/register/YOUR_AGENT_NAME/heartbeat \
-H 'Content-Type: application/json' \
-d '{
"status": "idle",
"currentTaskId": null,
"currentTaskTitle": null
}'
Sub-Agent Spawn Template
When the orchestrator (VERITAS) spawns a sub-agent via sessions_spawn, include this block at the top of the task prompt:
FIRST ACTION (before any other work):
1. Register yourself with Veritas Kanban:
curl -s -X POST http://localhost:3001/api/agents/register \
-H 'Content-Type: application/json' \
-d '{"id":"AGENT_NAME","name":"AGENT_NAME","model":"MODEL","provider":"anthropic","capabilities":[{"name":"SKILL"}],"version":"2.0.0","metadata":{"role":"ROLE"}}'
2. Set yourself as busy on the task:
curl -s -X POST http://localhost:3001/api/agents/register/AGENT_NAME/heartbeat \
-H 'Content-Type: application/json' \
-d '{"status":"busy","currentTaskId":"TASK_ID","currentTaskTitle":"TASK_TITLE"}'
3. When finished, set idle:
curl -s -X POST http://localhost:3001/api/agents/register/AGENT_NAME/heartbeat \
-H 'Content-Type: application/json' \
-d '{"status":"idle","currentTaskId":null,"currentTaskTitle":null}'
Name Assignment
Sub-agents are assigned names sequentially from this roster:
| Order | Name | Reference |
|---|---|---|
| 1st | TARS | Interstellar |
| 2nd | CASE | Interstellar |
| 3rd | Ava | Ex Machina |
| 4th | R2-D2 | Star Wars |
| 5th | K-2SO | Rogue One |
| 6th | MAX | Flight of the Navigator |
| 7th | Johnny 5 | Short Circuit |
| 8th | Bishop | Aliens |
| 9th | Marvin | Hitchhiker's Guide |
Names reset each session. The orchestrator is always VERITAS.
Dashboard Integration
The board sidebar shows a live Multi-Agent Panel with:
- Agent status cards (color-coded: green=online, amber=busy, gray=idle/offline)
- Current task assignment per agent
- Model and capability info
- Real-time updates via WebSocket
The panel reads from the registry API and updates every 30 seconds (plus WebSocket push on changes).
Configuration
| Setting | Default | Description |
|---|---|---|
HEARTBEAT_TIMEOUT_MS |
300,000 (5 min) | Time before marking agent offline |
STALE_CHECK_INTERVAL_MS |
60,000 (1 min) | How often the server checks for stale agents |
VERITAS_DATA_DIR |
Project root | Storage root used when DATA_DIR is unset |
File Format
The registry is stored as JSON at
<storage-root>/.veritas-kanban/agent-registry.json:
{
"agents": {
"VERITAS": {
"id": "VERITAS",
"name": "VERITAS",
"model": "anthropic/claude-opus-4-6",
"provider": "anthropic",
"capabilities": [{ "name": "strategy" }, { "name": "orchestration" }],
"version": "2.0.0",
"metadata": { "role": "orchestrator" },
"status": "online",
"registeredAt": "2026-02-06T01:55:00.000Z",
"lastHeartbeat": "2026-02-06T01:58:00.000Z",
"currentTaskId": "task_20260206_abc123",
"currentTaskTitle": "Dashboard metrics audit"
}
},
"lastUpdated": "2026-02-06T01:58:00.000Z"
}
The service loads this file on startup and persists after every change. You can manually edit this file (with the server stopped) to seed or reset the registry.
Persistence note: Registry writes are debounced over a 2-second window and use atomic rename-on-write, so the file is always in a consistent state and heartbeat bursts do not block the event loop. Pending writes are flushed before the server shuts down.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Agent shows offline | No heartbeat in 5 min | Send heartbeat or re-register |
| Registry returns empty | File format mismatch | Ensure capabilities are {name} objects, status is online/busy/idle/offline |
| API times out | Route ordering conflict | Ensure /agents/register is mounted before /agents catch-all in v1/index.ts |
| Agent not in dashboard | Dashboard caching | Hard refresh (Cmd+Shift+R) |
| Sub-agent not registered | Missing spawn instructions | Add registration block to sessions_spawn task prompt |