Skip to content

Comergence — Signal Schema

The universal language every domain speaks.


Design Principles

  • Simple enough that a shop floor agent and a finance agent both implement it without translation
  • Rich enough that the visual layer, notification router, and action engine get everything they need from one object
  • Self-describing — a signal explains itself without requiring external lookup
  • Domain-agnostic — the schema knows nothing about business logic; the agent knows everything

The Signal Object

{
  "id": "uuid-v4",

  "source": {
    "domain": "production",
    "path": ["production", "work-centers", "cnc-3"],
    "agent": "production-master",
    "human": "operator-mike"
  },

  "status": "amber",
  "previousStatus": "green",
  "statusSince": "2026-02-22T14:32:00Z",
  "publishedAt": "2026-02-22T14:32:05Z",

  "signal": {
    "code": "DRIFT_WARNING",
    "message": "X-axis feed rate drifting +2.3% from nominal",
    "detail": "Current: 102.3 ipm / Nominal: 100 ipm / Threshold: ±2%",
    "data": {}
  },

  "propagate": true,
  "ttl": 3600,

  "actions": [
    {
      "id": "notify-operator",
      "label": "Notify Operator",
      "type": "message",
      "target": "human:operator-mike",
      "auto": false
    },
    {
      "id": "spawn-investigation",
      "label": "Investigate",
      "type": "agent-task",
      "agent": "production-master",
      "prompt": "Work center cnc-3 has a feed rate drift warning. Assess and guide operator.",
      "auto": false
    },
    {
      "id": "andon-amber",
      "label": "Andon Signal",
      "type": "physical",
      "device": "ha:shop-floor-light",
      "state": "amber",
      "auto": true
    }
  ]
}

Field Reference

Top Level

Field Type Required Description
id string (uuid) Unique signal identifier
source object Where this signal originated
status enum Current health state
previousStatus enum State before this signal
statusSince ISO 8601 When current status began
publishedAt ISO 8601 When this signal was published
signal object What happened
propagate boolean Whether parent tiles inherit this state
ttl integer (seconds) How long signal stays active. Null = persistent until resolved
actions array Available responses

source

Field Type Required Description
domain string Top-level domain (matches registry)
path string[] Full drill-down path to this signal's node
agent string Agent ID that published this signal
human string Human operator paired with this node, if any

status values

Value Color Meaning
green 🟢 Normal operation, within all thresholds
amber 🟡 Attention needed, degrading but not critical
red 🔴 Critical failure, immediate action required
unknown Agent not publishing, data stale, monitoring gap
offline Agent/system confirmed offline

signal

Field Type Required Description
code string Machine-readable signal code (see Standard Codes)
message string Human-readable one-line summary
detail string Extended description with specifics
data object Domain-specific payload (any structure)

actions[*]

Field Type Required Description
id string Unique within this signal
label string Display label in the UI
type enum Action type (see Action Types)
auto boolean Whether to fire automatically on signal publish
target string For message type: human:id, agent:id, channel:name
agent string For agent-task type: agent ID to spawn
prompt string For agent-task type: context injected at task start
device string For physical type: ha:entity-id
state string For physical type: desired device state

Standard Signal Codes

Codes are dot-namespaced. Domain agents define their own codes under their namespace. Shared codes live under system.*.

system.*

Code Status Meaning
system.healthy green All checks passing
system.degraded amber Performance or availability degrading
system.critical red Critical failure
system.offline offline System unreachable
system.stale unknown Last signal older than expected interval

agent.*

Code Status Meaning
agent.active green Agent responding, sessions active
agent.idle green Agent responding, no active sessions
agent.error red Agent throwing errors or crashing
agent.cost_spike amber API cost above threshold
agent.cron_failed amber/red Scheduled job failed
agent.heartbeat_missed amber Heartbeat not received in expected window

production.*

Code Status Meaning
production.on_schedule green All work centers on time
production.order_aging amber Orders approaching SLA threshold
production.sla_breach red Orders past SLA
production.machine_down red Work center offline
production.drift_warning amber Process parameter drifting

fulfillment.*

Code Status Meaning
fulfillment.on_schedule green Shipments on time
fulfillment.delay_risk amber Carrier or inventory delay detected
fulfillment.sla_breach red Committed ship date missed

sales.*

Code Status Meaning
sales.pipeline_healthy green Normal velocity and conversion
sales.deal_stall amber High-value deals without activity
sales.conversion_drop amber Spec-to-bid conversion declining

integration.*

Code Status Meaning
integration.connected green API healthy, auth valid
integration.degraded amber Slow response times or rate limit warnings
integration.auth_expiring amber Token expires within 7 days
integration.auth_failed red Authentication failure
integration.sync_failed red Data sync not completing

Status Propagation

Parent tiles inherit the worst status of their children, with one exception: unknown does not override a known status.

child: red    → parent: red
child: amber  → parent: amber (if no children are red)
child: green  → parent: green (if all children are green)
child: unknown → parent: unchanged (ghost child — doesn't pull parent down)
child: offline → parent: amber (a constituent going dark is a warning, not a crisis)

An agent can set propagate: false to publish a signal that affects only its own tile without rolling up. Useful for informational signals that don't indicate domain health problems.


Resolution

A signal is resolved when: 1. The agent publishes a new signal with status: "green" on the same source.path 2. The ttl expires and no new signal has been published (node goes unknown) 3. The domain is deregistered

Resolved signals are archived, not deleted. The archive enables historical health views and pattern analysis over time.


Signal Bus Interface

Agents interact with the signal bus through two operations:

PUBLISH  path  signal_object   → publishes signal, notifies subscribers
SUBSCRIBE  path_pattern  callback  → receives signals matching pattern

Path patterns support wildcards: - production.* — all production signals - *.work-centers.* — all work center signals across all domains - * — all signals (dashboard uses this)

Initial implementation: file-based (signals written to ~/.comergence/signals/), watched by chokidar. Upgrade path to Redis pub/sub or NATS for multi-machine deployments.


Example Signals

Agent healthy (AI System domain)

{
  "id": "a1b2c3d4",
  "source": { "domain": "ai-system", "path": ["ai-system", "agents", "maxrow"], "agent": "main" },
  "status": "green",
  "statusSince": "2026-02-22T11:05:00Z",
  "publishedAt": "2026-02-22T15:00:00Z",
  "signal": { "code": "agent.active", "message": "Maxrow active, 1 session running", "data": { "sessions": 1, "cost7d": 4.21 } },
  "propagate": true,
  "ttl": 600,
  "actions": []
}

Integration auth expiring

{
  "id": "e5f6g7h8",
  "source": { "domain": "integrations", "path": ["integrations", "shopify"], "agent": "main" },
  "status": "amber",
  "statusSince": "2026-02-22T09:00:00Z",
  "publishedAt": "2026-02-22T09:00:00Z",
  "signal": { "code": "integration.auth_expiring", "message": "Shopify token expires in 6 days", "detail": "Token refresh cron last ran 14h ago" },
  "propagate": true,
  "ttl": 86400,
  "actions": [
    { "id": "refresh-now", "label": "Refresh Token", "type": "agent-task", "agent": "main", "prompt": "Shopify token is expiring. Run the token refresh script immediately.", "auto": false },
    { "id": "notify-jerry", "label": "Notify Jerry", "type": "message", "target": "human:jerry", "auto": true }
  ]
}

Shop floor machine down

{
  "id": "i9j0k1l2",
  "source": { "domain": "production", "path": ["production", "work-centers", "cnc-3"], "agent": "production-master", "human": "operator-mike" },
  "status": "red",
  "previousStatus": "green",
  "statusSince": "2026-02-22T13:47:00Z",
  "publishedAt": "2026-02-22T13:47:02Z",
  "signal": { "code": "production.machine_down", "message": "CNC-3 offline — spindle fault alarm", "detail": "Alarm code 1043. Machine halted. 3 jobs in queue affected." },
  "propagate": true,
  "ttl": null,
  "actions": [
    { "id": "guide-operator", "label": "Guide Operator", "type": "agent-task", "agent": "production-master", "prompt": "CNC-3 has a spindle fault (alarm 1043). Guide operator Mike through diagnosis and resolution.", "auto": true },
    { "id": "adjust-schedule", "label": "Adjust Schedule", "type": "agent-task", "agent": "production-master", "prompt": "CNC-3 is down. Reschedule its 3 queued jobs to available work centers.", "auto": true },
    { "id": "andon-red", "label": "Andon Red", "type": "physical", "device": "ha:shop-floor-light", "state": "red", "auto": true },
    { "id": "alert-michael", "label": "Alert Michael", "type": "message", "target": "human:michael", "auto": true }
  ]
}