# Cadence Monitor — Operator Guide

## Overview

The §48.10 + §48.16 cadence monitor (chunk-8) tracks whether admitted Settlement Venues
and Settlement Platforms are publishing attestations within their declared cadence windows.
When a cadence lapses beyond the staleness threshold, the monitor auto-quarantines the entity.
Quarantine can be cleared via the CB/operator un-quarantine ceremony.

- Schema: `platform/db/schema/38-cadence-monitor.sql`
- Handler: `platform/src/platform/mcp-bridge/cadence-monitor.ts`
- ADR: `ops/decisions/ADR-2026-0158-v0-2-119-cadence-monitor-schema.md` (schema)
- ADR: `ops/decisions/ADR-2026-0159-v0-2-120-cadence-monitor-bridge-tools.md` (tools)

---

## Entity kinds

| entity_kind | Registry | Cadence field | Staleness multiplier |
|---|---|---|---|
| 0 | §48.10 Settlement Venue | `reserve_attestation_cadence_slots` | 2 |
| 1 | §48.16 Settlement Platform | `platform_attestation_cadence_slots` | 2 |

**Staleness threshold** = `cadence_slots × staleness_multiplier`. When `current_slot − last_observed_attestation_slot > threshold`, the monitor transitions the entity to `quarantine_triggered`.

---

## Quarantine status values

| Value | Name | Meaning |
|---|---|---|
| 0 | `healthy` | Last observed attestation within cadence × multiplier |
| 1 | `quarantine_triggered` | Cadence lapsed; auto-quarantine emitted by monitor service |
| 2 | `cleared` | Entity un-quarantined via CB/operator ceremony |

These are **monitor states**. The entity's own `venue_state` / `platform_state` is updated by the bridge tools in parallel.

---

## Lifecycle

```
Venue/Platform admitted (§48.10 / §48.16)
          │
          ▼
Monitor enrolls entity (v0.2.121 — initial_registration)
          │
          ▼
Periodic scan (v0.2.121):
  last_observed_attestation_slot updated on fresh attestation
  │
  ├── Within threshold → healthy (quarantine_status=0)
  │
  └── Threshold crossed → quarantine_triggered (quarantine_status=1)
          │   venue_state / platform_state → quarantined (1)
          │   SETTLEMENT_VENUE_QUARANTINED / SETTLEMENT_PLATFORM_QUARANTINED
          │
          └── un-quarantine ceremony → cleared (quarantine_status=2)
                  venue_state / platform_state → active (0)
```

---

## Tools

### `thread.query_entity_cadence_status`

Query the cadence monitor state for a single entity.

**Params:**

| Param | Type | Description |
|---|---|---|
| `entity_kind` | integer | 0 = venue (§48.10), 1 = platform (§48.16) |
| `entity_id` | integer | `venue_id` or `platform_id` |

**Success response:** Full monitor status row including `quarantine_status`, `last_observed_attestation_slot`, `cadence_slots`, `staleness_multiplier`, last transition fields.

**Error:** `entity_not_found` if entity not enrolled in monitor.

---

### `thread.list_quarantined_entities`

List all entities currently in `quarantine_triggered` state.

**Optional params:**

| Param | Type | Description |
|---|---|---|
| `entity_kind` | integer | Filter by type: 0=venue, 1=platform. Omit for both. |
| `since_slot` | integer | Only entities quarantined at or after this slot. |
| `limit` | integer | Max results (default 20, max 100). |
| `offset` | integer | Pagination offset (default 0). |

**Success response:** `{ entities: [...], total: N }`

---

### `thread.list_entity_cadence_transitions`

List the append-only transition audit log. Filter by entity or globally.

**Optional params:**

| Param | Type | Description |
|---|---|---|
| `entity_kind` | integer | Filter by entity type. |
| `entity_id` | integer | Filter to specific entity. |
| `reason_code` | string | Filter by reason: `initial_registration`, `cadence_lapsed`, `attestation_observed`, `ceremony_cleared`. |
| `limit` | integer | Max results (default 20, max 100). |
| `offset` | integer | Pagination offset (default 0). |

**Success response:** `{ transitions: [...], total: N }`. Results ordered `recorded_at DESC`.

---

### `thread.unquarantine_entity`

CB/operator un-quarantine ceremony. Transitions the entity from `quarantine_triggered` (1) to `cleared` (2) and resets the entity registry state to `active` (0).

**Required params:**

| Param | Type | Description |
|---|---|---|
| `entity_kind` | integer | 0 = venue, 1 = platform |
| `entity_id` | integer | `venue_id` or `platform_id` |

**Optional params:**

| Param | Type | Description |
|---|---|---|
| `ceremony_slot` | integer | Solana slot of the ceremony. Defaults to current time. |
| `justification_hash_hex` | string | 64-char hex (32 bytes). Dev stub for CB AUTHORITY resume signature. |
| `witness_sig_hex` | string | Optional witness co-signature (dev stub). |
| `detail` | string | Human-readable ceremony detail. |

**Success response:**

```json
{
  "entity_kind": 0,
  "entity_kind_label": "venue",
  "entity_id": "1",
  "from_status": 1,
  "to_status": 2,
  "ceremony_slot": "4450100000",
  "reason_code": "ceremony_cleared",
  "status": "cleared"
}
```

**Errors:**

| Code | Cause |
|---|---|
| `entity_not_found` | Entity not enrolled in cadence monitor |
| `entity_not_quarantined` | Entity not in `quarantine_triggered` state |

---

## Transition reason codes

| Code | Emitted by | Meaning |
|---|---|---|
| `initial_registration` | Monitor service (v0.2.121) | Entity first enrolled in monitor |
| `cadence_lapsed` | Monitor service (v0.2.121) | Staleness threshold crossed; auto-quarantine |
| `attestation_observed` | Monitor service (v0.2.121) | Fresh attestation received while healthy |
| `ceremony_cleared` | `unquarantine_entity` tool | CB/operator ceremony completed |

---

## Common operator flow

```bash
# 1. Check a venue's cadence health
curl -s http://127.0.0.1:9401/mcp/invoke -d '{
  "tool": "thread.query_entity_cadence_status",
  "params": { "entity_kind": 0, "entity_id": 1 }
}'

# 2. List all currently quarantined entities
curl -s http://127.0.0.1:9401/mcp/invoke -d '{
  "tool": "thread.list_quarantined_entities",
  "params": {}
}'

# 3. Un-quarantine a venue after fresh Reserve Attestation submitted
curl -s http://127.0.0.1:9401/mcp/invoke -d '{
  "tool": "thread.unquarantine_entity",
  "params": {
    "entity_kind": 0,
    "entity_id": 1,
    "ceremony_slot": 4450100000,
    "justification_hash_hex": "<32-byte-hex>",
    "detail": "fresh reserve attestation submitted 2026-05-09; CB VARA co-sign ref XYZ"
  }
}'

# 4. Inspect transition log for an entity
curl -s http://127.0.0.1:9401/mcp/invoke -d '{
  "tool": "thread.list_entity_cadence_transitions",
  "params": { "entity_kind": 0, "entity_id": 1 }
}'
```

---

## Operator workflow (v0.2.122 scripts)

Two operator scripts wrap the HL tools for production use:

### `platform/scripts/query-cadence-status.ts`

```bash
# Check a specific venue
tsx platform/scripts/query-cadence-status.ts \
  --entity-kind venue --entity-id 1

# List all quarantined entities
tsx platform/scripts/query-cadence-status.ts --list-quarantined

# JSON output for dashboards
tsx platform/scripts/query-cadence-status.ts \
  --list-quarantined --format json

# Filter quarantined platforms only
tsx platform/scripts/query-cadence-status.ts \
  --list-quarantined --entity-kind platform
```

### `platform/scripts/unquarantine-entity.ts`

```bash
# Dry-run: see ceremony payload without submitting
tsx platform/scripts/unquarantine-entity.ts \
  --entity-kind venue --entity-id 1 \
  --justification-hash <64-hex> \
  --dry-run

# Submit ceremony
tsx platform/scripts/unquarantine-entity.ts \
  --entity-kind venue --entity-id 1 \
  --justification-hash <64-hex> \
  --ceremony-slot 4450100000 \
  --detail "fresh reserve attestation submitted; CB VARA co-sign ref XYZ"
```

Audit log written to `platform/var/unquarantine-entity/<kind>-<id>-<timestamp>.json`.

---

## Deferred scope

| Item | Status |
|---|---|
| Cadence monitor service (auto-quarantine emitter) | v0.2.121 ✓ |
| Operator scripts | v0.2.122 ✓ |
| `MBRIDGE_VENUE_STATE_DIVERGENT` advisory emission | Post-chunk-8; health advisory broadcasting |
| Production CB AUTHORITY COSE_Sign1 resume signature verification | Post-v0.3.0 (dev stub accepted now) |
| §48.16 platform-specific attestation document type | Spec gap; monitor uses `reserve_attestations` as proxy |

---

## Chunk-8 milestones

| Version | Deliverable |
|---|---|
| v0.2.119 | Schema: `entity_cadence_status` + `entity_cadence_transitions` + cross-region pub (ADR-2026-0158) |
| v0.2.120 | HL bridge tools: query/list + un-quarantine ceremony (ADR-2026-0159) |
| v0.2.121 | Cadence monitor service: periodic scan + auto-quarantine emitter (ADR-2026-0160) |
| v0.2.122 | Operator scripts: un-quarantine + query quarantine list (ADR-2026-0161) |
| v0.2.123 | E2e smoke + chunk-8 close (ADR-2026-0162) |

---

## Protocol anchors

- §48.10 + §48.16 spec: `thread/15a-settlement-venue-cross-ledger.md`
- §48.10 + §48.16 registries: `thread/27-registries-and-pqc.md` (→ `27b-sub-registries.md`)
- Schema: ADR-2026-0158 (v0.2.119)
- Bridge tools: ADR-2026-0159 (v0.2.120)
- Monitor service: ADR-2026-0160 (v0.2.121)
