# §15a Settlement Attestation — Operator Guide

## Overview

Settlement Attestation is the co-signature collection pipeline that proves CBDC settlement occurred on the corresponding CBDC ledger. When a Cross-Ledger Escrow (§15a) settles, the operator collects cryptographic attestations from the Central Bank(s) involved and submits them to the THREAD bridge. The bridge transitions the attestation from `pending` to `complete` once the required threshold of CB signatures is collected.

Two attestation modes exist (spec §c01 / §c10):

| Mode | `attestation_mode` | Who signs | Used for |
|---|---|---|---|
| `single_cb` | `0` | Primary CB only (threshold=1) | HTLC escrows (atomicity_mode=0) |
| `multi_cb_pvp` | `1` | All participating CBs (threshold=N) | mBridge PvP escrows (atomicity_mode=1) |

---

## Lifecycle

```
Operator: request_settlement_attestation  →  pipeline_state=0 (pending)
CB(s):    submit_attestation_signature    →  pipeline_state=0 (pending, collecting)
                                          →  pipeline_state=1 (complete, if threshold met)
Expiry:   pipeline_state=2               →  if expires_slot reached before threshold
```

Both `complete` (1) and `expired` (2) are terminal — no further state changes.

---

## Tools

### `thread.request_settlement_attestation`

Operator initiates the co-signature collection request.

**Required params:**
- `secret_key_hex` — operator's 32-byte Ed25519 seed
- `attestation_id_hex` — 64-char hex (32 bytes); generate a random value
- `cross_escrow_id_hex` — 64-char hex; must match an existing §15a escrow
- `settlement_venue_id` — §48.10 venue ID
- `central_bank_authority_id_hex` — 64-char hex; primary CB authority
- `venue_settlement_tx_ref_hex` — opaque CBDC-ledger transaction reference
- `venue_settlement_block_or_slot` — finality marker on the CBDC ledger
- `principal_amount_native_settled` — MUST equal the escrow's `principal_amount_native`
- `settled_slot` — Solana slot at which settlement was observed
- `created_slot` — Solana slot at which this request is created
- `expires_slot` — deadline; attestation expires if threshold not met by this slot

**Optional params:**
- `hashlock_preimage_hex` — 64-char hex; for HTLC mode (omit for PvP)
- `attestation_mode` — `0` (single_cb, default) or `1` (multi_cb_pvp)
- `platform_id_ref` — §48.16 platform_id; required iff `attestation_mode=1`
- `threshold` — number of CB signatures required (default `1`)

**Returns:** `{ attestation_id_hex, operator_agent_id_hex, pipeline_state, threshold, expires_slot, status: 'pending' }`

### `thread.submit_attestation_signature`

CB authority submits a co-signature. Caller's `secret_key_hex` derives `cb_authority_id`.

**Required params:**
- `secret_key_hex` — CB authority's 32-byte Ed25519 seed
- `attestation_id_hex` — 64-char hex; the in-flight attestation
- `signature_hex` — COSE_Sign1 signature bytes (hex)
- `received_slot` — Solana slot when this signature was received

**Returns:** `{ attestation_id_hex, cb_authority_id_hex, signature_position, signatures_collected, threshold, pipeline_state, status }`

`status` is `'attestation_complete'` when `signatures_collected >= threshold`.

### `thread.query_settlement_attestation`

Fetch a single attestation record including all collected co-signatures.

**Required params:**
- `attestation_id_hex` — 64-char hex

**Returns:** Full attestation record with `signatures[]` array.

### `thread.list_settlement_attestations`

List attestations with optional filters.

**Optional params:**
- `pipeline_state` — `0` (pending), `1` (complete), `2` (expired)
- `central_bank_authority_id_hex` — filter by primary CB
- `cross_escrow_id_hex` — filter by escrow
- `limit` — max records (default 20, max 100)

**Returns:** `{ attestations: [...], count: N }`

---

## Error catalog

| Code | Meaning |
|---|---|
| `attestation_not_found` | No attestation with this attestation_id |
| `attestation_duplicate` | attestation_id already registered |
| `attestation_already_complete` | Attestation already reached threshold |
| `attestation_expired` | Attestation expired before threshold was met |
| `attestation_signer_not_authorized` | CB not permitted to sign this attestation (single_cb mode: only primary CB) |
| `attestation_signature_duplicate` | This CB already submitted a signature for this attestation |

---

## HTLC example flow

```
1. Operator opens escrow: thread.open_cross_ledger_htlc
2. Operator claims (CBDC leg settles on-ledger)
3. Operator calls thread.request_settlement_attestation
   - attestation_mode=0, hashlock_preimage_hex=<preimage>
4. Primary CB calls thread.submit_attestation_signature
   - pipeline_state → 1 (complete, threshold=1 met)
5. Operator/anyone queries thread.query_settlement_attestation to verify
```

## mBridge PvP example flow

```
1. Operator opens PvP escrow: thread.open_cross_ledger_atomic_swap
2. mBridge atomically completes both legs
3. Operator calls thread.request_settlement_attestation
   - attestation_mode=1, platform_id_ref=<platform_id>, threshold=N
4. Each of N participating CBs calls thread.submit_attestation_signature
5. After the Nth signature: pipeline_state → 1 (complete)
```

---

## Operator admission script

`platform/scripts/admit-settlement-attestation.ts` is the operator-facing CLI for registering settlement attestation requests. It wraps `thread.request_settlement_attestation` and optionally polls for completion.

**Minimal HTLC example:**

```bash
tsx platform/scripts/admit-settlement-attestation.ts \
  --bridge http://127.0.0.1:9401 \
  --operator-key <32-byte-hex-seed> \
  --escrow-id <cross_escrow_id_hex> \
  --venue-id 1 \
  --cb-authority <cb_authority_id_hex> \
  --tx-ref <cbdc_ledger_tx_hex> \
  --block-or-slot 12000001 \
  --amount 50000 \
  --settled-slot 9000000 \
  --wait
```

**Multi-CB PvP example:**

```bash
tsx platform/scripts/admit-settlement-attestation.ts \
  --bridge http://127.0.0.1:9401 \
  --operator-key <32-byte-hex-seed> \
  --escrow-id <cross_escrow_id_hex> \
  --venue-id 2 \
  --cb-authority <primary_cb_hex> \
  --tx-ref <cbdc_ledger_tx_hex> \
  --block-or-slot 12000001 \
  --amount 50000 \
  --settled-slot 9000000 \
  --mode 1 \
  --threshold 2 \
  --platform-id 1 \
  --wait
```

`--dry-run` prints all parameters without submitting. `--wait` polls every 5 s (configurable via `--poll-interval`) until `pipeline_state` reaches 1 (complete) or 2 (expired).

Audit log written to `platform/var/admit-settlement-attestation/<attestation_id_hex>.json` (secret_key_hex redacted).

---

## Protocol anchors

- `DOC_SETTLEMENT_ATTESTATION = 0x54485253` — CBOR document tag
- Spec: `thread/15a-settlement-venue-cross-ledger.md` §c01 (fields 0-13) + §c10 (fields 14-17)
- Schema: `platform/db/schema/34-settlement-attestation.sql`
- ADR: ADR-2026-0138 (schema), ADR-2026-0139 (tools), ADR-2026-0140 (collection service), ADR-2026-0141 (admission script)
