Skip to content

Comergence — Domain Registry Protocol

How any constituent registers itself with Comergence.


Design Principles

  • Self-registering — deploy an agent, get a tile. No manual dashboard configuration.
  • Self-describing — the manifest tells the system everything it needs to know
  • Hierarchical — domains contain sub-domains contain constituents, to any depth
  • Ownership — every domain has an agent owner and optionally a human owner
  • Evolvable — manifests can be updated at runtime; the system re-reads and adapts

The Manifest File

Every domain registers by placing an comergence.json file in its workspace root. The signal bus watches for these files. A new file = a new tile. An updated file = the tile morphs. A deleted file = the tile disappears.

{
  "domain": "ai-system.agents.maxrow",
  "name": "Maxrow",
  "description": "Main orchestrator agent. System health, memory, docs, drift.",
  "icon": "🔴",
  "version": "1",

  "owner": {
    "agent": "main",
    "workspace": "/home/clawuser/clawd",
    "human": "jerry"
  },

  "parent": "ai-system.agents",

  "children": [],

  "dataSources": [
    {
      "type": "session-files",
      "path": "~/.openclaw/agents/main/sessions/",
      "watch": true
    },
    {
      "type": "memory-files",
      "path": "/home/clawuser/clawd/memory/",
      "watch": true
    },
    {
      "type": "cron-config",
      "path": "~/.openclaw/cron/",
      "watch": true
    }
  ],

  "healthRules": [
    {
      "id": "heartbeat",
      "description": "Heartbeat received within expected window",
      "check": "last_signal_age < 600",
      "onFail": "amber",
      "code": "agent.heartbeat_missed"
    },
    {
      "id": "cron-health",
      "description": "No consecutive cron failures",
      "check": "cron_consecutive_errors == 0",
      "onFail": "amber",
      "code": "agent.cron_failed"
    },
    {
      "id": "cost-spike",
      "description": "7-day API cost within threshold",
      "check": "cost_7d < 25.00",
      "onFail": "amber",
      "code": "agent.cost_spike"
    }
  ],

  "notifications": {
    "amber": [
      { "target": "human:jerry", "channel": "telegram" }
    ],
    "red": [
      { "target": "human:jerry", "channel": "telegram" },
      { "target": "agent:main", "prompt": "An agent in the AI System domain has gone red. Investigate and report." }
    ]
  },

  "actions": [
    {
      "id": "view-sessions",
      "label": "View Sessions",
      "type": "drill-down",
      "target": "ai-system.agents.maxrow.sessions"
    },
    {
      "id": "view-memory",
      "label": "View Memory",
      "type": "drill-down",
      "target": "ai-system.agents.maxrow.memory"
    },
    {
      "id": "restart-gateway",
      "label": "Restart Gateway",
      "type": "agent-task",
      "agent": "main",
      "prompt": "Run the gateway restart procedure using the gateway-restart skill.",
      "requiresConfirmation": true
    }
  ],

  "publishInterval": 60,
  "standalone": true
}

Field Reference

Identity

Field Type Required Description
domain string Dot-namespaced path (e.g., production.work-centers.cnc-3)
name string Human-readable display name
description string One-line description of what this domain represents
icon string Emoji icon displayed on tile
version string Manifest version (increment on breaking changes)

Ownership

Field Type Required Description
owner.agent string Agent ID responsible for this domain's health signals
owner.workspace string Filesystem path to the agent's workspace
owner.human string Human identifier paired with this domain

Hierarchy

Field Type Required Description
parent string Parent domain path. Null = top-level domain
children string[] Child domain paths. Empty = leaf node. Can be populated dynamically by the agent

Data Sources

Declares where the agent reads data to compute health. The signal bus uses this to understand what filesystem paths to watch for change-triggered re-evaluation.

Type Description
session-files OpenClaw JSONL session files
memory-files Agent memory directory
cron-config OpenClaw cron job config
netsuite-api NetSuite SuiteQL (agent polls)
hubspot-api HubSpot API (agent polls)
file-watch Arbitrary file or directory
sensor Physical sensor (via Home Assistant)
manual Agent sets state directly from its own reasoning

Health Rules

Rules the agent evaluates to determine its status. Rules are evaluated in order; the worst result wins.

{
  "id": "rule-id",
  "description": "Human readable description",
  "check": "expression",
  "onFail": "amber | red",
  "code": "signal.code.to.publish"
}

Check expressions are simple and declarative. The agent's publisher module evaluates them against collected metrics. Complex logic stays in the agent's own code — the manifest captures the threshold.

Notifications

Who gets notified at each severity level. Multiple targets supported.

{
  "amber": [
    { "target": "human:jerry", "channel": "telegram" },
    { "target": "agent:main", "prompt": "Context for investigation..." }
  ],
  "red": [
    { "target": "human:jerry", "channel": "telegram" },
    { "target": "human:michael", "channel": "telegram" },
    { "target": "physical:ha:shop-andon-light", "state": "red" }
  ]
}

Target formats: - human:{id} — person, routed via their preferred channel - agent:{id} — spawns a task on that agent with the provided prompt - physical:ha:{entity-id} — Home Assistant entity - channel:{name} — broadcast to a channel (Slack, Telegram group)

Actions

Actions available from this domain's tile in the UI. Actions can be triggered manually by a human or automatically on signal publish (via auto: true in the signal object).

Action types: - drill-down — navigate to a child domain in the UI - agent-task — spawn an agent task with context - message — send a message to a human or channel - physical — trigger a Home Assistant entity - external — call a webhook or API


Domain Path Naming Convention

Paths are dot-namespaced, lowercase, hyphen-separated words.

[top-domain].[sub-domain].[constituent].[detail]

Examples:
  production
  production.work-centers
  production.work-centers.cnc-3
  ai-system
  ai-system.agents
  ai-system.agents.maxrow
  ai-system.crons
  ai-system.crons.system-orchestrator
  integrations.netsuite
  integrations.shopify
  sales.pipeline
  sales.pipeline.commercial
  fulfillment.open-orders

Top-Level Domains (Stikwood)

comergence/
├── production/              → Sawyer (production agent)
│   ├── work-centers/        → per-machine agents (future)
│   ├── scheduling/
│   └── quality/
├── fulfillment/             → Sawyer
│   ├── open-orders/
│   ├── shipping/
│   └── inventory/
├── sales/                   → Maven
│   ├── pipeline/
│   ├── accounts/
│   └── specs/
├── marketing/               → Maven
│   ├── campaigns/
│   ├── email/
│   └── social/
├── finance/                 → TBD agent
│   ├── accounts-receivable/
│   ├── cash-flow/
│   └── budget/
├── ai-system/               → Maxrow
│   ├── agents/              → per-agent tiles
│   ├── crons/               → per-cron tiles
│   ├── nodes/               → VPS, mccall-home
│   ├── channels/            → Telegram, Slack
│   └── integrations/        → API health per system
└── home/                    → Gus/Luma
    ├── climate/
    ├── lighting/
    ├── security/
    └── audio/

Discovery Mechanism

The signal bus watches a discovery directory for manifests:

~/.comergence/
  registry/
    ai-system.agents.maxrow.json    ← manifest files
    ai-system.agents.maven.json
    production.json
    fulfillment.json
    ...
  signals/
    [live signal files]
  history/
    [archived signals]

Agent startup sequence: 1. Agent reads its comergence.json from workspace 2. Agent copies it to ~/.comergence/registry/{domain}.json 3. Signal bus detects new file via chokidar 4. Dashboard receives new domain → renders tile 5. Agent begins publishing signals to ~/.comergence/signals/

On shutdown or agent deregistration: 1. Agent removes its registry file 2. Signal bus detects removal 3. Dashboard marks tile as offline


The Human-Agent Pair Manifest

For work center agents paired with a human operator, the manifest extends with pairing info:

{
  "domain": "production.work-centers.cnc-3",
  "name": "CNC-3",
  "icon": "⚙️",

  "owner": {
    "agent": "cnc3-agent",
    "human": "operator-mike"
  },

  "pairing": {
    "human": {
      "id": "operator-mike",
      "name": "Mike",
      "preferredChannel": "telegram",
      "telegramId": "123456789",
      "role": "CNC Operator",
      "shift": "06:00-14:00"
    },
    "interface": "mobile",
    "guidanceStyle": "brief",
    "escalationChain": ["operator-mike", "michael", "jerry"]
  }
}

The pairing.escalationChain defines who gets contacted if the paired human doesn't acknowledge an alert within a configurable window.


Versioning & Evolution

Manifests include a version field. When the agent publishes an updated manifest: - The registry replaces the old version - The dashboard diffs and re-renders changed tiles - Historical signals from the old version remain archived

Breaking changes (domain path changes, renamed children) increment version. The dashboard handles graceful migration — old tiles fade to unknown as new tiles appear.


The registry is the map. The signals are the territory. The agents keep them in sync.