# §15a mBridge Platform Connector — Operator Guide

## Overview

The mBridge Platform Connector (chunk-9) enables atomicity_mode=1 (mBridge native PvP) Cross-Ledger Escrows — where both settlement legs settle atomically across two CBDCs on an mBridge-class platform. Three surfaces:

1. **Settlement Platform Attestation** — periodic platform health publication by the platform operator (analog to Reserve Attestation §54.7, but platform-side).
2. **Multi-CB Settlement Attestation** — extends the chunk-4 Settlement Attestation pipeline to collect co-signatures from multiple CBs (one per venue in the PvP).
3. **MBRIDGE_PARTICIPANT (0x8000) service bit** — BANKER admission with CB attestation references required at atomicity_mode=1 escrow opening.

Protocol invariants enforced at bridge layer (v0.2.126):
- **I33** — operator BANKER must carry non-stale MBRIDGE_PARTICIPANT bit at escrow admission.
- **I34** — Settlement Attestation must be mode=1 with all participating CBs signed at escrow completion.
- **I35** — Cross-CBDC FX rate must resolve via triangulation (chunk-6 Rate Attestation) or direct Cross-CBDC Rate Attestation.

---

## MBRIDGE_PARTICIPANT Admission

### `thread.admit_mbridge_participant_bit`

Registers CB attestation references on a BANKER for the 0x8000 service bit. At least ONE non-stale reference required for I33 at escrow opening. Refs renew per `MBRIDGE_PARTICIPANT_ATTESTATION_RENEWAL_CADENCE_SLOTS` (~30d = 6,480,000 slots).

**Required params:**

| Param | Type | Description |
|---|---|---|
| `banker_secret_key_hex` | string | BANKER 32-byte Ed25519 seed (hex). Derives `banker_id`. |
| `mbridge_participant_attestation_refs` | array | Per-CB refs. Each: `{ref_hash_hex, valid_until_slot, cb_authority_id_hex}`. |
| `admitted_slot` | number | Slot at which refs are admitted. Defaults to current slot. |

Renewal: call again with new `ref_hash_hex` + later `valid_until_slot`. Old refs expire naturally.

### `thread.query_mbridge_participant_status`

| Param | Type | Description |
|---|---|---|
| `banker_agent_id_hex` | string | BANKER agent_id (64-char hex). |
| `current_slot` | number | Staleness evaluation slot (default: current). |

Returns `{mbridge_participant_bit, has_active_refs, latest_valid_until_slot, refs[]}`. `mbridge_participant_bit=1` iff `has_active_refs=true`.

---

## Settlement Platform Attestation

### Lifecycle

```
Operator: publish_settlement_platform_attestation  →  broadcast_status=0 (pending)
Pub svc (v0.2.127):  scans pending rows            →  broadcast_status=1 (broadcast_ok)
Any bridge:  query_settlement_platform_attestation / list_settlement_platform_attestations
At escrow admission (v0.2.126): latest attestation checked for freshness (expires_slot > current_slot)
```

### `thread.publish_settlement_platform_attestation`

Platform operator publishes a periodic health attestation.

**Required params:**

| Param | Type | Description |
|---|---|---|
| `signer_secret_key_hex` | string | Platform operator 32-byte Ed25519 seed. Agent_id MUST match `platform_operator_agent_id`. |
| `platform_id` | number | §48.16 platform_id. |
| `attestation_slot` | number | Slot this attestation covers. |
| `expires_slot` | number | Stale after this slot (must be > `attestation_slot`). |

**Optional params:**

| Param | Type | Default | Description |
|---|---|---|---|
| `venue_states` | array | `[]` | Per-venue state: `{venue_id, venue_state (0/1/2), venue_pvp_liquidity_attested_native_units}`. |
| `pvp_success_count_rolling` | number | 0 | Rolling count of PvP successes. |
| `pvp_failure_count_rolling` | number | 0 | Rolling count of PvP failures. |
| `primary_transparency_log_proof_hex` | string | random | §48.1 dual-log proof (hex). |
| `secondary_transparency_log_proof_hex` | string | random | Secondary log proof (hex). |
| `cose_sign1_signature_hex` | string | stub | COSE_Sign1 by `platform_settlement_attestation_pubkey`. Dev stub computed if omitted. |

### `thread.query_settlement_platform_attestation`

Accepts `platform_attestation_id_hex` (exact lookup) OR `platform_id` (returns latest).

### `thread.list_settlement_platform_attestations`

Filters: `platform_id`, `broadcast_status` (0/1/2), `attestation_slot_min`, `attestation_slot_max`, `limit` (max 100, default 20).

---

## Multi-CB Settlement Attestation

Extends chunk-4 `request_settlement_attestation` + `submit_attestation_signature`. No new tools — use existing tools with `attestation_mode=1`.

### Flow

```
1. thread.request_settlement_attestation
     attestation_mode=1, platform_id_ref=<platform_id>, threshold=<N participating CBs>

2. Each participating CB: thread.submit_attestation_signature
     (with each CB's secret_key_hex; auto-completes when threshold signatures collected)

3. thread.complete_cross_ledger_atomic_swap
     references the completed attestation (I34 enforcement checks attestation_mode=1 + all sigs)
```

### Multi-CB params for `request_settlement_attestation`

| Param | Type | Required when | Description |
|---|---|---|---|
| `attestation_mode` | number | — | 0=single_cb (default), 1=multi_cb_pvp. |
| `platform_id_ref` | number | mode=1 | §48.16 platform_id backing this attestation. |
| `threshold` | number | — | Total CB signatures required (default 1). For mode=1: set to 1 + number of additional CBs. |

---

## atomicity_mode=1 Escrow Flow

```
1. admit_mbridge_participant_bit (BANKER; once per admission cycle)
2. admit_settlement_platform (§48.16; one-time per platform)
3. publish_settlement_platform_attestation (periodic; before expiry)
4. publish_cross_cbdc_rate (chunk-6; for I35 FX oracle)
5. open_cross_ledger_atomic_swap
     atomicity_mode=1, platform_id, settlement_venue_id, counterparty_venue_id
     (I33: BANKER bit checked; I35: rate attestation freshness checked)
6. request_settlement_attestation (attestation_mode=1, platform_id_ref, threshold=N)
7. submit_attestation_signature × N CBs → pipeline_state=1 (complete)
8. complete_cross_ledger_atomic_swap (I34: attestation_mode=1 + all CB sigs verified)
```

---

## Error Catalog

| Error code | Cause |
|---|---|
| `MBRIDGE_PARTICIPANT_NOT_AUTHORIZED` | Banker has no `banker_mbridge_participant_attestations` rows. |
| `MBRIDGE_PARTICIPANT_ATTESTATION_STALE` | All refs have `valid_until_slot <= current_slot`. Renew with `admit_mbridge_participant_bit`. |
| `MBRIDGE_VENUE_PAIR_NOT_PARTICIPANT` | Both venues not in same §48.16 platform's venue list. |
| `MBRIDGE_MULTI_CB_ATTESTATION_INCOMPLETE` | Fewer CB sigs than `threshold` at completion. |
| `platform_attestation_expired` | Latest platform attestation `expires_slot <= current_slot`. Publish fresh attestation. |
| `platform_state_not_active` | Platform is quarantined (1) or retired (2). |
| `platform_not_found` | No §48.16 platform with given `platform_id`. |
| `platform_attestation_operator_mismatch` | Signer's agent_id ≠ `platform_operator_agent_id`. |

---

## Common Pitfalls

- **Signer mismatch**: `signer_secret_key_hex` for `publish_settlement_platform_attestation` must derive the same `agent_id` as `platform_operator_agent_id` on the §48.16 entry. Use the same key that was used to `admit_settlement_platform`.
- **Stale MBRIDGE_PARTICIPANT bit**: renew before `valid_until_slot` by calling `admit_mbridge_participant_bit` with a new `ref_hash_hex` + `valid_until_slot` ~30d ahead.
- **Platform attestation expiry**: publish fresh attestation before `expires_slot`. The publication service (v0.2.127) automates this for dev topologies.
- **Threshold off-by-one**: for 2-CB PvP (primary + 1 additional), set `threshold=2`. The primary CB signs at `position=0`; the additional CB signs at `position=1`.
- **I35 FX oracle**: escrow `fx_rate_attestation_ref` must point to a non-stale chunk-6 Cross-CBDC Rate Attestation (or two Price Oracle Attestations for triangulation). Stale rate → escrow admission rejected.

---

## Operator Workflow (v0.2.127)

Two operator scripts are provided for one-shot admission and publication tasks.

### Admit MBRIDGE_PARTICIPANT bit

```bash
tsx platform/scripts/admit-mbridge-participant.ts \
  --bridge http://127.0.0.1:9401 \
  --banker-key <32-byte-hex> \
  --cb-attestation-refs <ref_hash_hex>:<valid_until_slot>:<cb_authority_id_hex>[,...] \
  [--admitted-slot <int>] \
  [--dry-run]
```

Each ref must have `valid_until_slot > admitted_slot`. Multiple refs may be passed comma-separated. On CONFLICT the bridge updates `valid_until_slot` for existing `ref_hash_hex`.

Audit log: `platform/var/admit-mbridge-participant/<banker_id_prefix>-<ts>.json`

### Publish Settlement Platform Attestation

```bash
tsx platform/scripts/publish-platform-attestation.ts \
  --bridge http://127.0.0.1:9401 \
  --platform-id <int> \
  --signer-key <32-byte-hex> \
  --attestation-slot <int> \
  --expires-slot <int> \
  [--venue-states <venue_id>:<state>:<liquidity>,...] \
  [--pvp-success-count <int>] \
  [--pvp-failure-count <int>] \
  [--dry-run]
```

`--signer-key` must derive the same `agent_id` as `platform_operator_agent_id` on the §48.16 entry. `--attestation-slot` must be strictly greater than the previous attestation for this platform.

Audit log: `platform/var/publish-platform-attestation/<platform_id>-<ts>.json`

---

## Publication Cadence (v0.2.127)

### Dev broadcaster (topology Phase 12)

`platform/scripts/dev-platform-attestation-broadcaster.ts` is a standalone service that simulates a §48.16 Settlement Platform Operator for dev topologies. It:

1. Admits a stub platform at boot (`thread.admit_settlement_platform`) using existing active venues.
2. Publishes a fresh Platform Attestation immediately after admission.
3. Loops every 90–150s, publishing with `attestation_slot = current_slot` and `expires_slot = attestation_slot + cadence × 3`.

Activate in topology:

```bash
export THREAD_DEV_PLATFORM_ATTESTATION_BROADCASTER=true
bash platform/scripts/topology-up.sh
```

Trade log: `platform/var/topology/platform-attestation-broadcaster-<region>.jsonl`

In production (v0.3.x+), real platform operators run their own HSM-backed publication services. The dev broadcaster is not suitable for any non-dev environment.

---

*ADR-2026-0164 (v0.2.125 HL tools). Schema: ADR-2026-0163 (v0.2.124). I33/I34/I35 enforcement: ADR-2026-0165 (v0.2.126). Publication service + operator scripts: ADR-2026-0166 (v0.2.127). E2E smoke + CB-integration track close: ADR-2026-0167 (v0.2.128).*
