# Signal Contract v1.0 — Specification

> Generated from the canonical protocol content (do not hand-edit; run
> `npx tsx scripts/generate_protocol_spec_md.ts`).
> Machine-readable schema: https://vibenet.ai/protocol/v1/schema.json
> Source: https://github.com/jamesfgibbons/vibenet-signal-contract (published v1.0.0, tagged 2026-04-20; current source v1.0.1)
> Human guide: https://vibenet.ai/protocol/

The Signal Contract is a small, flat, renderer-facing event object. It carries
what changed, which public semantic channel it belongs to, and how strongly it
should be felt — so one event can become audio, motion, trace rows, logs, or
device cues without changing shape.

## Fields

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `schema_version` | string | yes | Published version of the flat public event object. | `1.0` |
| `id` | string | yes | Stable event identifier for dedupe, replay, and audit references. | `sig_demo_005` |
| `occurred_at` | RFC 3339 timestamp | yes | When the awareness event occurred, not when the renderer received it. | `2026-04-19T18:32:18.442Z` |
| `producer` | string | yes | System or adapter that emitted the event. | `vibenet-demo` |
| `entity` | string | yes | Stable subject identifier for the thing whose state changed. | `agent.serpradio.route_intelligence` |
| `event` | string | yes | Meaningful awareness event name. Snake case is recommended. | `handoff.requested` |
| `channel` | enum | yes | Public semantic channel for how the state should be interpreted. | `handoff` |
| `valence` | number 0-1 | yes | Normalized affective polarity for the current state. | `0.42` |
| `energy` | number 0-1 | yes | Normalized activity level of the state change. | `0.66` |
| `tension` | number 0-1 | yes | Normalized instability or unresolved uncertainty. | `0.73` |
| `intensity` | number 0-1 | yes | Renderer-facing emphasis. Higher values should feel harder to ignore. | `0.72` |
| `hue` | number 0-360 | yes | Flat renderer-facing hue hint for browser, lighting, or AR renderers. | `44` |
| `pulse` | number 0-1 | yes | Flat renderer-facing pulse hint for motion, cadence, or temporal emphasis. | `0.78` |
| `confidence` | number 0-1 | no | Optional producer confidence in the emitted awareness event. | `0.94` |
| `ttl_ms` | integer | no | How long a renderer should keep expressing the event before it expires. | `15000` |
| `metadata` | object | no | Context payload for links, IDs, route names, renderer-safe details, and optional publishable/indexable convention fields. | `{"publishable":false,"indexable":true,"fallback_reason":"primary_source_stale"}` |

Numeric bounds: `valence`, `energy`, `tension`, `intensity`, and
`pulse` are 0–1; `hue` is 0–360. `schema_version` is the constant
`"1.0"`.

## Public semantic channels

### nominal

- Meaning: Expected operating state. Nothing requires attention.
- Typical sound: Quiet pulse bed.
- Emit guidance: Use when the system is steady and no intervention is needed.
- Intensity range: 0.00-0.35
- Break-through: No. This should stay backgrounded.
- Example: An agent is idle, healthy, and waiting for the next task.

### advisory

- Meaning: Work is happening. Attention is optional.
- Typical sound: Soft rise, gentle rhythmic activation.
- Emit guidance: Use for planning, tool calls, synthesis, and healthy in-flight state shifts.
- Intensity range: 0.20-0.65
- Break-through: Usually no. Let the operator ask if they care.
- Example: A retriever call starts and returns within the expected envelope.

### warning

- Meaning: Something deserves a second look.
- Typical sound: Dissonant sustained interval.
- Emit guidance: Use when confidence drops, retries stack up, or trust changes materially.
- Intensity range: 0.45-0.85
- Break-through: Often. Depends on cognitive gating and local policy.
- Example: A key source fails validation before synthesis completes.

### critical

- Meaning: Intervention required.
- Typical sound: Urgent break-through cue above the bed.
- Emit guidance: Use when a human or policy boundary must intervene immediately.
- Intensity range: 0.75-1.00
- Break-through: Yes. This is designed to cut through suppression.
- Example: A guarded tool call is blocked and the run cannot proceed autonomously.

### recovery

- Meaning: The system is resolving back toward nominal.
- Typical sound: Resolved chord or cadence.
- Emit guidance: Use when an earlier warning has been contained or when the run lands cleanly.
- Intensity range: 0.20-0.70
- Break-through: No. This should feel like release rather than interruption.
- Example: A fallback source restores enough confidence to keep moving.

### opportunity

- Meaning: An actionable window has appeared.
- Typical sound: Bright consonant lift.
- Emit guidance: Use when the system detects a state worth acting on soon but not urgently.
- Intensity range: 0.35-0.80
- Break-through: Sometimes. It depends on whether the window is short lived.
- Example: A route becomes attractive while operational tension remains low.

### handoff

- Meaning: Attention is passing between agents, humans, or devices.
- Typical sound: Spatial pan or motif migration.
- Emit guidance: Use when responsibility moves and the receiver needs situational context.
- Intensity range: 0.25-0.75
- Break-through: Only when the receiving party must respond.
- Example: A browser trace hands the next question to a voice surface or human reviewer.

## Example event

```json
{
  "schema_version": "1.0",
  "id": "sig_demo_005",
  "occurred_at": "2026-04-19T18:32:18.442Z",
  "producer": "vibenet-demo",
  "entity": "agent.serpradio.route_intelligence",
  "event": "handoff.requested",
  "channel": "handoff",
  "valence": 0.42,
  "energy": 0.66,
  "tension": 0.73,
  "intensity": 0.72,
  "hue": 44,
  "pulse": 0.78,
  "confidence": 0.94,
  "ttl_ms": 15000,
  "metadata": {
    "reason": "source_confidence_below_threshold",
    "route": "JFK-LHR"
  }
}
```

## Conformance

- Validate against the JSON Schema at https://vibenet.ai/protocol/v1/schema.json.
- Reject events with unknown channels or out-of-bounds numerics.
- Renderers must not invent fields; producers must not depend on renderer
  internals. The event stays portable before any renderer makes it beautiful.
