# Connected Services Framework — Full Documentation

Working draft of the open transport framework for the UK telecommunications industry.
Source: https://switchingforbusiness.com/framework

---
<!-- DOCUMENT: overview/readme | Overview — Connected Services Framework (CSF) -->

---
title: Connected Services Framework (CSF)
tags: [Overview]

---

# Connected Services Framework (CSF)

**An Open Transport Framework for the UK Telecommunications Industry**

Version 2.0 | Published by the Telecom Technical Architecture Group (TAG)

---

## What is the CSF?

The Connected Services Framework (CSF) is a free, open, and decentralised messaging framework that enables UK Communications Providers (CPs) to exchange messages securely and efficiently through Managed Access Providers (MAPs) — without reliance on a centralised hub or administrative body.

Built on established internet standards (TLS 1.3, OAuth 2.0, DKIM/PKI via RFC 6376) and the industry-standard JSON Asynchronous Messaging Specification (JAM), the CSF provides a peer-to-peer transport layer that any CP or MAP can adopt at zero licensing cost.

## Why CSF?

| Capability | Centralised Hub Model | CSF (Distributed Model) |
|---|---|---|
| **Cost** | Ongoing per-message or subscription fees | Free to operate — no licensing or transaction charges |
| **Independence** | All parties depend on a single operator | Each MAP operates autonomously |
| **Speed of change** | Change requests go through a single vendor | TAG consensus enables rapid iteration |
| **Resilience** | Single point of failure | Distributed — no single point of failure |
| **Scalability** | Hub capacity limits all participants | Each MAP scales independently |
| **CP freedom** | CPs may be locked to a provider | CPs control their MAP choice via DNS |
| **Security** | Trust delegated to hub operator | End-to-end PKI signing verifiable by any party |
| **Onboarding** | Central registration and approval | Peer-sponsored onboarding — operational in hours |
| **Market entry** | Barriers to becoming a provider | Any CP can become a MAP of 1 |

## Initial Use Case: Switching for Business (SforB)

The CSF's first application is delivering **Switching for Business** (SforB), formerly known as Gaining Provider Led Business Switching (GPLB). Unlike One Touch Switch (OTS) for residential customers, Ofcom has not mandated a single technical solution for business switching — enabling the industry to adopt this open, distributed approach.

The framework is not limited to SforB. It is designed to support any industry messaging process, including future applications such as number porting and bilateral communications.

## Documentation Structure

### Reference

| Document | Description |
|---|---|
| [Definitions & Terminology](standalone/definitions.md) | Consolidated reference for all acronyms, abbreviations, and CSF-specific terminology |
| [CP Rights Charter](standalone/cp-rights-charter.md) | Plain-language summary of CP rights under the CSF — standalone, no technical background required |
| [MAP Onboarding & Testing Process](standalone/onboarding-testing-process.md) | Practical handbook for developers, implementers, and testers — environments, status model, NowYoYo PKI test harness, and the TAG Baseline Test Suite |

This documentation is organised into two parts:

### Part 1 — Framework (Management & Architecture)

For decision-makers, solution architects, and programme managers.

| Document | Description |
|---|---|
| [Introduction](part1-framework/01-introduction.md) | Purpose, scope, and value proposition of the CSF |
| [Background](part1-framework/02-background.md) | OTS history, SforB context, and regulatory landscape |
| [Principles & Requirements](part1-framework/03-principles-and-requirements.md) | Gathered requirements with MoSCoW prioritisation |
| [Architecture Overview](part1-framework/04-architecture-overview.md) | Layered model, message flow, and entity definitions |
| [CP Registry, Master Registry & Directory](part1-framework/05-directory-and-registry.md) | Three-tier distributed registry model and synchronisation |
| [Security Overview](part1-framework/06-security-overview.md) | TLS 1.3, OAuth 2.0, and PKI/DKIM at a conceptual level |
| [Onboarding](part1-framework/07-onboarding.md) | MAP sponsorship and CP registration processes |
| [RCPID Management](part1-framework/08-rcpid-management.md) | UUIDv4 identifiers — allocation, transitions, and rationale |
| [Operational Excellence](part1-framework/09-operational-excellence.md) | Resilience, SLAs, monitoring, and deployment patterns |
| [Governance](part1-framework/10-governance.md) | Standards bodies, MoU, and change control |
| [Glossary](part1-framework/glossary.md) | Abbreviations and definitions |

### Part 2 — Implementation (Technical)

For developers, integration engineers, and technical architects.

| Document | Description |
|---|---|
| [Getting Started](part2-implementation/01-getting-started.md) | Prerequisites and onboarding checklist |
| [OAuth 2.0 Implementation](part2-implementation/02-oauth2-implementation.md) | Token requests, responses, and error handling |
| [PKI & DKIM Signing](part2-implementation/03-pki-dkim-signing.md) | DKIM process, CSF headers, worked examples, and error codes |
| [Message API](part2-implementation/04-message-api.md) | Letterbox API, HTTP codes, message delivery failures, and the `auditData` conventions for test flagging and match-session sequencing |
| [Directory API](part2-implementation/05-directory-api.md) | Registry JSON schema, MAP-level (`map.status`) and per-CP (`processSupport[].status`) status fields, and field reference |
| [TOTSCo Integration](part2-implementation/06-totsco-integration.md) | Hub interoperability and dual-endpoint configuration |
| [CP Transitions](part2-implementation/07-cp-transitions.md) | Six-step migration process, RCPID Status export schema, suggested in-flight order export routine, Step 6 sign-off checklist, and conflict resolution |
| [Commercial Scenarios](part2-implementation/08-commercial-scenarios.md) | MAP failure, CP mergers, and administration handling |
| [Operations](part2-implementation/09-operations.md) | Monitoring, malicious behaviour, regulatory and industry reporting (with the proposed distributed telemetry collection model), and risk register |
| [FAQ — GPLB Steering Group](standalone/sg-faq.md) | GPLB-SG questions and answers |
| [FAQ — TOTSCo Integration](standalone/totsco-faq.md) | TOTSCo integration questions and answers |
| [Appendix: OpenAPI Specification](part2-implementation/appendix-openapi.md) | Full OpenAPI 3.0.3 spec for the Letterbox API |

## Standards & External References

The CSF builds on and references the following industry standards:

- **JSON Asynchronous Messaging Specification (JAM)** — published on the [OTA2 website](https://www.offta.org.uk/)
- **RCPID Standards** — published on the [OTA2 website](https://www.offta.org.uk/)
- **[TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf)** — the industry-standard letterbox and directory API for SforB, used by TOTSCo and supported by CSF for hub interoperability
- **Switching for Business Process Documents** — published on the [FCS website](https://www.fcs.org.uk/gaining-provider-led-business-switching/)
- **GPLB-SG Switching for Business Message Specification v3.0** — bundled with this repo as `framework/GPLB SG Switching for Business Message Specification V3.0.pdf`; the authoritative low-level SforB message spec (canonical source published by the GPLB-SG via FCS)
- **TOTSCo Process & Technical Documents** — published on the [TOTSCo website](https://totsco.org.uk/process-technical-documents/)

## Key RFCs

| RFC | Usage in CSF |
|---|---|
| [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) | TLS 1.3 — mandatory transport encryption |
| [RFC 6376](https://datatracker.ietf.org/doc/html/rfc6376) | DKIM — message signing and verification |
| [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) | OAuth 2.0 — authorisation framework |
| [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) | UUIDv4 — RCPID format |
| [RFC 8463](https://datatracker.ietf.org/doc/html/rfc8463) | Ed25519 for DKIM — alternative signing algorithm |

## Reading the Working Draft

The **working draft** of the CSF is held by the **Telecom Technical Architecture Group (TAG)**. The TAG manages change control, version increments, and the editorial lifecycle of the document set.

**Published versions** are made available for download from the CSF website. Each published version is signed off by the TAG and superseded only by a subsequent published version through the TAG's change-control process.

## Contributing

The CSF is maintained by the Telecom Technical Architecture Group (TAG). The TAG steering group meets weekly to review changes and proposals. All CSF documentation is under TAG change control.

### Contributors

| Name                 | Organisation                    |
| -------------------- | ------------------------------- |
| Dave Stubbs          | Zentive Limited                 |
| David A Wilson       | iconectiv                       |
| Marcel Horst         | CWP                             |
| Mark Delo            | NowYoYo Limited                 |
| Shanmugavel Krishnan | iconectiv                       |
| Simon Phillips       | ICUK Computing Services Limited |
| Stephen Breen        | iconectiv                       |
| Steven Pearce        | NowYoYo Limited                 |
| Susan Mangini        | iconectiv                       |

## Version History

| Version | Date | Description |
|---|---|---|
| 2.0.1 | 2026-04-29 | Content additions: new MAP Onboarding & Testing Process handbook with the TAG Baseline Test Suite; expanded CP Transitions §7.3–§7.4 with detailed step descriptions, suggested in-flight order export routine, full RCPID Status export schema, and Step 6 sign-off checklist; new optional `map.status` enum (`ACTIVE`/`TEST`/`SUSPEND`) in the Directory API; tightened telemetry rules in §10.6 (collection limited to `ACTIVE` participants, `auditData.test=true` exclusion); new auditData conventions in the Letterbox doc cross-linking the test-flag and match-session-sequencing rules; bundled GPLB-SG SforB Message Specification v3.0 PDF as the authoritative low-level reference. |
| 2.0 | 2026-04-24 | Comprehensive rewrite in Markdown. Restructured into separate Part 1 (Framework) and Part 2 (Implementation) documents with deduplication, consistent terminology, and improved technical accuracy. |
| 1.0.5 | 2026-01-07 | Last Word document version (Part 1 — Framework) |
| 1.0.5 | 2025-11-14 | Last Word document version (Part 2 — Implementation) |

## Licence

The Connected Services Framework is an open transport framework, free for any Communications Provider or Managed Access Provider to use for any purpose. There are no licensing fees or transaction charges. Participation is governed by the Memorandum of Understanding (MoU) agreed among participating MAPs and CPs.

---

<!-- DOCUMENT: part1/01-introduction | Part 1 — Framework — 1. Introduction -->

---
title: 1. Introduction
tags: [Part 1]

---

# 1. Introduction

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 1.1 Purpose of This Document

This document defines the Connected Services Framework (CSF), an open transport framework for the UK telecommunications industry. It establishes the technical and operational prerequisites, architectural design, and implementation strategy that enable Managed Access Providers (MAPs) to exchange messages securely and efficiently on behalf of their Communications Providers (CPs).

The CSF is free for any organisation to adopt. There are no licensing fees, transaction charges, or commercial dependencies on any single provider.

## 1.2 What the CSF Does

The CSF is a **transport layer** — it defines how messages are wrapped, signed, and delivered between MAPs. It does not define the content of those messages. Industry processes such as Switching for Business (SforB) or One Touch Switch (OTS) define the message content; the CSF delivers it.

In practical terms, the CSF provides:

- **Secure peer-to-peer message delivery** between MAPs using TLS 1.3, OAuth 2.0, and DKIM-based PKI signing
- **A distributed registry model** where each MAP publishes a CP Registry of its CPs, all MAPs converge these into a private Master Registry, and each MAP derives a filtered Directory for its own CPs
- **DNS-based CP verification** that puts CPs in control of which MAP represents them
- **Standardised onboarding** through peer sponsorship, removing the need for centralised administration
- **In-flight order portability** so CPs can change MAPs without disrupting active switching orders

## 1.3 Who This Document Is For

**Part 1 (this document)** is written for:

- **Senior management and decision-makers** evaluating whether to adopt the CSF
- **Solution architects** designing CP or MAP implementations
- **Programme managers** planning SforB delivery

**Part 2 (Implementation)** is written for developers and integration engineers who need API specifications, code examples, and JSON schemas.

## 1.4 Scope

The CSF covers:

- The definition of a decentralised messaging architecture independent of any centralised administrative authority
- Requirements for interoperability, security protocols, and communication standards between MAPs
- Protocols for onboarding new MAPs and transitioning CPs between MAPs
- Guidelines for maintaining data integrity, ensuring secure communications, and managing exceptional scenarios such as MAP failures, CP migrations, mergers, and administration

The CSF does **not** cover:

- How a MAP integrates with its own CPs (this is each MAP's commercial decision)
- The content of industry process messages (defined by OTS, SforB, etc.)
- The internal architecture of any MAP's platform

## 1.5 The Case for a Distributed Model

The UK telecoms switching landscape currently operates through a centralised hub model for residential switching (OTS via TOTSCo). While this model served its purpose, it introduces constraints that are unnecessary for business switching:

**Cost**: A centralised hub requires ongoing funding — through per-message fees, subscriptions, or industry levies. The CSF eliminates these costs entirely. MAPs exchange messages directly with each other at no charge.

**Independence**: In a hub model, every CP and MAP depends on a single operator for message routing, change management, and availability. The CSF distributes these responsibilities across all participants.

**Speed of innovation**: Hub changes require approval from a single vendor's change control process. CSF changes are agreed by the TAG steering group and can be adopted incrementally by MAPs through versioning and feature releases.

**Resilience**: A centralised hub is a single point of failure. The CSF's peer-to-peer architecture means that an outage at one MAP affects only that MAP's CPs — not the entire industry.

**CP freedom**: The CSF gives CPs direct control over their MAP relationship through DNS. A CP can change MAP by updating two DNS records, and their RCPID stays with them for life.

**Market access**: Any CP can become a MAP of 1 (serving only itself) and exchange messages directly with the industry. This lowers barriers to entry and avoids monopolistic lock-in.

**Additional routes, not a replacement.** MAPs and CPs can already exchange SforB traffic today via the TOTSCo Hub. The CSF does not replace that route — it adds **two additional, complementary routes** for the industry:

- **Managed via a CSF MAP** — a CP subscribes to a CSF MAP and exchanges through that MAP's CSF outbound. The CSF supports multiple competing MAPs, giving CPs real commercial choice.
- **Self-served as a MAP-of-1** — a CP runs its own MAP infrastructure, exchanging messages directly with every other MAP on the CSF network.

Together with the existing TOTSCo Hub route, this gives the industry three concurrent routes. The deliberate intent is **rapid SforB expansion**: many smaller business CPs need to become compliant in a short window, and offering them more than one route — without losing the TOTSCo Hub option — is the lever that makes industry-wide adoption practical.

> :memo: **Note**: The CSF does not preclude the use of a centralised hub. TOTSCo can operate as a Hub MAP (HMAP) within the CSF, allowing CPs connected to the hub to exchange messages with CPs connected to other MAPs seamlessly. The HMAP interface each MAP exposes to TOTSCo is **dedicated to TOTSCo and locked down** — CSF spec increments do not propagate through it, so TOTSCo's integration is a one-time build, not an evergreen one. See [Standalone — TOTSCo HMAP Integration Guide](../standalone/totsco-hmap-integration-guide.md) for the full operating model.

> :memo: **CSF directory is TOTSCo-compatible by design.** The CSF CP Registry (Part 2 §5) was designed as a **strict superset** of the TOTSCo OTS/GPLB directory shape. Parties that already consume the TOTSCo directory can ingest the CSF Registry with their existing parser; CSF-specific additions are additive and never breaking. This was a deliberate design decision so the industry could operate easily with the CSF through the JSON contract alone.

## 1.6 Initial Application: Switching for Business (SforB)

The CSF's first industry application is **Switching for Business (SforB)**, formerly known as Gaining Provider Led Business Switching (GPLB).

Key differences from OTS:

- **No mandated hub**: Ofcom has not required a centralised technical solution for business switching
- **Gaining-provider-led**: The switching process is initiated by the gaining provider
- **Larger scale**: The industry expects a tenfold increase in RCPIDs compared to OTS
- **Longer onboarding**: Industry-wide ramp-on is expected to span a considerably longer timeframe

The CSF has been designed to support SforB as its initial use case, but is architected for any future industry messaging process — including number porting, bilateral communications, and processes not yet defined.

## 1.7 Document Structure

| Chapter | Content |
|---|---|
| [Background](02-background.md) | History of OTS, the emergence of SforB, and the regulatory context |
| [Principles & Requirements](03-principles-and-requirements.md) | Industry-gathered requirements with MoSCoW prioritisation |
| [Architecture Overview](04-architecture-overview.md) | Layered model, message flow, and entity definitions |
| [CP Registry, Master Registry & Directory](05-directory-and-registry.md) | The three-tier distributed registry model |
| [Security Overview](06-security-overview.md) | Multi-layered security architecture |
| [Onboarding](07-onboarding.md) | MAP sponsorship and CP registration |
| [RCPID Management](08-rcpid-management.md) | Identifier format, allocation, and lifecycle |
| [Operational Excellence](09-operational-excellence.md) | Resilience, SLAs, and deployment patterns |
| [Governance](10-governance.md) | Standards bodies and change control |
| [Glossary](glossary.md) | Terms and abbreviations |

---

<!-- DOCUMENT: part1/02-background | Part 1 — Framework — 2. Background -->

---
title: 2. Background
tags: [Part 1]

---

# 2. Background

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 2.1 The Evolution of UK Telecoms Switching

The United Kingdom's telecommunications sector has undergone significant evolution, driven by government policy objectives aimed at promoting a more competitive, consumer-focused market. Central to this transformation is the **Switching General Conditions**, a regulatory framework designed to streamline switching processes by minimising inefficiencies and eliminating procedural redundancies.

## 2.2 One Touch Switch (OTS): Establishing the Foundation

Through the Switching General Conditions, the industry formed a Detail Design Group (DDG) to establish the requirements for switching residential customers' broadband and voice services — what Ofcom termed "One Touch Switch."

The DDG established several foundational principles that the CSF builds upon:

1. **JSON message format**: A standardised format separating delivery instructions (the envelope) from the message content (the body)
2. **Shared directory**: A directory of all participating CPs that could be shared by all participants
3. **Common connectivity**: A standardised way for CPs to connect, send, and receive messages
4. **Multiple delivery platforms**: Support for multiple solutions — hub, portal, and direct integration — provided by what are now known as Managed Access Providers (MAPs)

These principles now form the basis of the **JSON Asynchronous Messaging Specification (JAM)**, published on the OTA2 website and used by both OTS and SforB.

### Limitations of the OTS Implementation

To guarantee timely delivery of OTS, certain original design principles were not fully implemented:

- Ofcom mandated that all OTS messages be routed through a single centralised hub (TOTSCo), limiting direct MAP-to-MAP exchange
- Industry processes for CP transitions between MAPs were not addressed
- RCPID management — where the CP, not the MAP, owns the identity — was not fully resolved
- The directory model, while distributed in concept, remained dependent on a central operator

These gaps created the need for the TAG and the CSF.

## 2.3 Switching for Business (SforB): Removing Restrictions

Mandated by Ofcom, the business switching process was established on principles similar to OTS, with one critical distinction: **Ofcom has not mandated that all messages be routed through a centralised hub**.

This removal of the routing restriction enables MAPs and individual CPs to exchange messages directly with one another, rather than through a central intermediary.

The Switching for Business process:

- Establishes the **gaining-provider-led model** as mandated by Ofcom
- Adopts the **Switching for Business (SforB) process** — stewarded by the GPLB Steering Group (GPLB-SG) — uniformly across the industry
- **Decouples** CPs from the constraints of any specific transport mechanism
- Represents the **first industry process** designed to streamline direct inter-provider messaging

## 2.4 The Telecom Technical Architecture Group (TAG)

The TAG is a consortium of telecom industry stakeholders — including MAPs, System Integrators, and CPs — convened to:

1. Identify gaps in the OTS messaging infrastructure
2. Establish core requirements for extending the OTS foundation to support SforB and future processes
3. Design and maintain the Connected Services Framework

The TAG collaborates closely with the GPLB Steering Group (GPLB-SG) and references the Switching for Business process documentation published on the FCS website.

Before designing any solution, core requirements were gathered from all MAPs, System Integrators, and related CPs. These requirements — covering cost reduction, security enhancement, and message exchange processing — form the foundation of the CSF as documented in [Principles & Requirements](03-principles-and-requirements.md).

## 2.5 From OTS to CSF: What Changed

| Aspect          | OTS                               | CSF                                       |
|-----------------|-----------------------------------|-------------------------------------------|
| Routing         | All messages via TOTSCo Hub       | Direct MAP-to-MAP (peer-to-peer)          |
| Hub dependency  | Mandatory                         | Optional (TOTSCo can operate as HMAP)     |
| Directory       | Centralised at TOTSCo             | Each MAP publishes its own registry       |
| RCPID format    | 4-character codes (e.g., RGXD)    | UUIDv4 for scalability and uniqueness     |
| CP identity     | Managed by MAP/Hub                | CP controls via DNS records               |
| Message signing | Hub validates                     | DKIM-based PKI — any recipient can verify |
| Onboarding      | Central registration              | Peer-sponsored, self-service              |
| Cost model      | Hub subscription/per-message fees | Free — no charges between MAPs            |
| CP portability  | Limited                           | Built-in: RCPID follows the CP for life   |
| Change control  | Hub vendor process                | TAG steering group (weekly)               |

---

<!-- DOCUMENT: part1/03-principles-and-requirements | Part 1 — Framework — 3. Principles and Requirements -->

---
title: 3. Principles and Requirements
tags: [Part 1]

---

# 3. Principles and Requirements

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 3.1 How Requirements Were Gathered

The requirements documented in this chapter were explicitly gathered from Managed Access Providers (MAPs), Systems Integrators (SIs), and their associated CPs. The purpose was to define how MAPs communicate with each other efficiently, reliably, and securely to facilitate messaging solutions on behalf of their CPs for any industry process.

The intention is that modifications stipulated within the CSF will not impact solutions already developed by CPs in support of OTS. However, MAPs may need to implement changes to fully support distributed messaging for processes such as SforB.

## 3.2 Requirements

Requirements are prioritised using the MoSCoW method:

- **Must** — Non-negotiable; the CSF cannot function without this
- **Should** — Important but not blocking; deviation requires justification
- **Could** — Desirable if achievable without significant cost or complexity
- **Won't** — Out of scope for the current version

### Connectivity and Routing

| Ref  | Requirement                                                                                                                                                                         | Priority |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| R.01 | MAPs MUST be free to acquire and manage their own customers without a technical or commercial dependency on, or imposed by, another MAP. No centralised administration is required. | Must     |
| R.02 | MAPs MUST make their customers available for message exchange with any other requesting MAP without applying a commercial or technical barrier.                                     | Must     |
| R.03 | Unless required by regulation or an agreed industry process, no single party SHALL be a dependency for routing messages to any other MAP and their CPs.                             | Must     |
| R.04 | All OTS messaging MUST continue to be routed via TOTSCo to meet Ofcom compliance requirements.                                                                                      | Must     |
| R.05 | Direct routing MUST NOT be mandated between MAPs. A MAP can choose who they route through unless required by regulation or an agreed industry process.                              | Must     |
| R.06 | MAPs MUST ensure they have peering capabilities to reach all CPs in the directory.                                                                                                  | Must     |
| R.07 | Any MAP MAY choose to provide routing services to another MAP (e.g. TOTSCo), but MUST NOT route to another routing MAP as circular routes MUST be avoided.                          | Must     |
| R.08 | MAPs MUST meet the requirements of the industry processes in delivering messages and meeting CP SLAs.                                                                               | Must     |
| R.09 | SLAs MUST be defined for all MAP-to-MAP transactions.                                                                                                                               | Must     |
| R.10 | MAPs MUST maintain a secure networking environment between all MAPs and their CPs.                                                                                                  | Must     |
| R.11 | MAPs MUST ensure they only accept messages from authenticated CPs and MAPs.                                                                                                         | Must     |
| R.12 | Every MAP MUST provide the same guaranteed delivery capability to its CPs, including retry mechanisms and failure reporting.                                                        | Must     |
| R.13 | A mechanism is REQUIRED to allow auto-discovery of CPs by onboarded MAPs.                                                                                                           | Must     |
| R.14 | The solution MUST support message sending and receiving in compliance with supported industry processes (e.g., OTS, SforB).                                                           | Must     |
| R.15 | The solution MUST be as simple as possible to implement.                                                                                                                            | Must     |

### Directory Management

| Ref  | Requirement                                                                                                            | Priority |
|------|------------------------------------------------------------------------------------------------------------------------|----------|
| R.17 | A centralised directory SHOULD NOT be a dependency or requirement.                                                     | Should   |
| R.18 | Every MAP MUST provide its customers with access to a complete directory list in support of their messaging processes. | Must     |
| R.19 | Every MAP is responsible for maintaining and publishing the CP Registry entries of its own CPs.                        | Must     |
| R.20 | All MAPs MUST be able to issue their own unique RCPIDs.                                                                | Must     |
| R.21 | A new MAP MUST have a sponsor and be onboarded before being added to the network.                                      | Must     |
| R.22 | Any shared directory model MUST be openly extensible.                                                                  | Must     |

### Messaging

| Ref   | Requirement                                                                                                                                                                                                                  | Priority |
|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| R.23  | Messages SHOULD be capable of being encrypted end-to-end.                                                                                                                                                                    | Could    |
| R.23a | All messages exchanged between MAPs MUST be digitally signed using DKIM (RFC 6376) so that the receiving MAP can verify the message has not been tampered with in transit and that it originated from the claimed source CP. | Must     |

### Operations

| Ref  | Requirement                                                                                                                    | Priority |
|------|--------------------------------------------------------------------------------------------------------------------------------|----------|
| R.24 | No MAP MAY charge for connectivity and routing of messages from or to another MAP, or levy charges to another MAP's customers. | Must     |
| R.25 | Every MAP MUST ensure they have connectivity to exchange and route messages.                                                   | Must     |

### Other

| Ref  | Requirement                                                                                | Priority |
|------|--------------------------------------------------------------------------------------------|----------|
| R.26 | Linking RCPIDs (e.g., association of OTS and SforB RCPID if a CP uses one for each process). | Could    |

### CP Right to Move

| Ref  | Requirement                                                                                                                                | Priority |
|------|--------------------------------------------------------------------------------------------------------------------------------------------|----------|
| R.27 | Every CP MUST have the right to change to another MAP.                                                                                     | Must     |
| R.28 | No MAP SHALL actively prevent a CP from moving to a new MAP.                                                                               | Must     |
| R.29 | No MAP SHALL deliberately prevent access to switching for a CP while still under contract when the CP is switching to another MAP.         | Must     |
| R.30 | A CP MUST be able to choose their service status within the MAP's directory, regardless of account status (e.g., ACTIVE, TEST, SUSPENDED). | Must     |

## 3.3 Summary of Principles

Taken together, these requirements establish that the CSF must:

1. **Ensure MAP independence** — No commercial or technical dependency on any other MAP
2. **Guarantee interoperability** — Secure routing of messages between all MAPs
3. **Remove barriers** — MAPs provide connectivity without imposing technical or commercial barriers
4. **Maintain security** — Authenticated message exchanges using OAuth 2.0, PKI, and DNS-based validation
5. **Enable auto-discovery** — Decentralised discovery of MAPs and CPs through shared directory structures
6. **Guarantee delivery** — Consistent message delivery with retry mechanisms and failure reporting
7. **Empower CPs** — Freedom and autonomy to switch MAPs without disruption or obstruction
8. **Enforce SLAs** — MAP-to-MAP service-level agreements for consistency and reliability
9. **Comply with regulation** — All MAP activities must comply with relevant industry regulations
10. **Reward good behaviour** — The framework encourages good actors and discourages bad actors without requiring centralised enforcement

These principles support operational excellence, regulatory compliance, and industry-wide interoperability, fostering an environment conducive to innovation and dynamic market competition.

---

<!-- DOCUMENT: part1/04-architecture-overview | Part 1 — Framework — 4. Architecture Overview -->

---
title: 4. Architecture Overview
tags: [Part 1]

---

# 4. Architecture Overview

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 4.1 Layered Architecture

The CSF operates as a layered messaging stack. Each layer has a distinct responsibility, and together they provide a complete, secure message delivery pipeline.

| Layer                  | Role                                                                        | Standards / Mechanisms                                                         |
|------------------------|-----------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| **Process Layer**      | Defines the business message content (e.g., SforB Switch Match, Switch Order) | Open industry process message formats (defined by GPLB-SG, OTS-DDG, etc.)      |
| **JAM Routing Layer**  | Defines addressing, message correlation, and routing                        | JSON Asynchronous Messaging Specification (RCPID addressing, envelope headers) |
| **CSF Security Layer** | Handles message signing, encapsulation, and verification                    | PKI/DKIM (RFC 6376), OAuth 2.0, DNS-based validation                           |
| **Transport Layer**    | Ensures secure delivery over the network                                    | HTTPS over TLS 1.3 (RFC 8446)                                                  |

The process layer and JAM routing layer are industry-wide standards that exist independently of the CSF. The CSF's contribution is the security layer and the operational framework that binds everything together.

## 4.2 Entity Definitions

### 4.2.1 Communications Provider (CP)

A CP is any party participating in an industry process — creating or consuming messages and sending or receiving them from other CPs. CPs include retailers, wholesalers, and agencies providing services on behalf of other CPs.

The CP involved will vary based on the industry process. A CP does not need to understand how the CSF works — it creates messages according to the industry process specification and hands them to its MAP for delivery.

### 4.2.2 Managed Access Provider (MAP)

A MAP facilitates message exchange on behalf of one or more CPs. MAPs provide integration services, portals, technical solutions, and the operational infrastructure to send and receive messages over the CSF.

Within the CSF, a MAP is the **only entity** authorised to exchange messages with other MAPs, because MAPs are responsible for:

- Publishing and maintaining their CP registry
- Applying PKI signing to outbound messages
- Verifying PKI signatures on inbound messages
- Establishing and maintaining OAuth 2.0 credentials with other MAPs
- Guaranteeing message delivery with retry mechanisms

A MAP may serve multiple roles concurrently for its clients (insourced, technical, fully managed), and the CSF imposes no restrictions on this. There are no charges or licensing requirements mandating specific MAP definitions.

### 4.2.3 MAP of 1

Any CP can become a "MAP of 1" — operating as its own MAP. This allows CPs to exchange messages directly with the industry for free, maintaining full control of all messages sent and received from their own infrastructure. The CP must abide by all MAP rules when implementing.

### 4.2.4 Hub Managed Access Provider (HMAP)

An HMAP is a specialised MAP designed to facilitate integration for proxy hubs such as TOTSCo. An HMAP:

- Accepts messages and forwards them among its subscribed members using a hub-and-spoke model
- Does **not** engage with the message payload — it routes based on addressing information
- When interfacing with the CSF, uses its Master Registry (built from collected CP Registries) to locate the destination CP and dispatches the message to the appropriate MAP
- Is **not required** to implement PKI/DKIM signing when exchanging messages on behalf of its CPs (to minimise integration cost)
- **Is strongly recommended** to implement the full CSF CP Registry format for SforB, as its CP clients benefit significantly from the additional information it provides

> :tick: **Best Practice**: MAPs on the CSF should provide a dedicated endpoint exclusively for HMAPs, separate from the endpoint used by other CSF MAPs. This allows rapid CSF iteration without disrupting established hub exchange networks.

## 4.3 Message Flow

The following diagram illustrates the end-to-end message flow through the CSF:

```mermaid
sequenceDiagram
    participant CP1 as CP 1 (Source)
    participant MAPA as MAP A
    participant MAPB as MAP B
    participant CP2 as CP 2 (Destination)

    Note over CP1,CP2: Industry Process (e.g., SforB Switch Match)

    CP1->>MAPA: 1. Send JAM message<br/>(industry process + envelope)
    Note over MAPA: 2. Validate message format<br/>3. Look up destination CP in Master Registry<br/>4. Identify MAP B as destination<br/>5. Sign message with CP1's private key (DKIM)

    MAPA->>MAPB: 6. Authenticate via OAuth 2.0<br/>7. Send signed message over TLS 1.3
    Note over MAPB: 8. Validate OAuth token<br/>9. Validate JSON envelope<br/>10. Verify DKIM signature via DNS<br/>11. Confirm message integrity

    MAPB-->>MAPA: 12. HTTP 202 Accepted
    MAPB->>CP2: 13. Deliver message to destination CP
```

### Step-by-Step Workflow

1. **CP creates message**: The CP creates a message according to the industry process specification (e.g., SforB) and wraps it in a JAM envelope with RCPID addressing, using directory information provided by its MAP.

2. **CP sends to MAP**: The CP sends the message to its MAP using whatever integration method the MAP provides (API, portal, BSS integration). MAP-to-CP integration is outside the scope of the CSF.

3. **MAP validates**: The MAP validates the message structure, format, and addressing. Unlike a hub model, MAPs **can** read the full CP payload and validate compliance before signing.

4. **MAP discovers route**: Using its Master Registry, the MAP identifies which MAP serves the destination CP.

5. **MAP signs message**: The MAP signs the message with the source CP's private key using DKIM (RFC 6376). The signature is placed in HTTP headers — the message body is not altered.

6. **MAP authenticates**: The sending MAP authenticates with the receiving MAP via OAuth 2.0.

7. **MAP delivers**: The signed message is sent over TLS 1.3 to the receiving MAP's letterbox endpoint.

8. **Receiving MAP verifies**: The receiving MAP validates the OAuth token, checks the JSON envelope, retrieves the source CP's public key from DNS, and verifies the DKIM signature to confirm the message is authentic and unaltered.

9. **Receiving MAP acknowledges**: On successful validation, the receiving MAP returns HTTP 202 (Accepted) — indicating the message has been accepted for processing but processing has not yet completed.

10. **Receiving MAP delivers**: The receiving MAP delivers the message to the destination CP.

> :memo: **Note**: If both CPs use the same MAP, the CSF is typically not needed as there is no inter-MAP exchange. However, MAPs operating multiple instances or solutions may elect to use the CSF for their own internal interconnections.

## 4.4 CSF Networks

Message exchanges are conducted solely between MAPs. The CSF may be employed across diverse industry processes, and the network adapts its size to the specific process in use.

Each MAP must:

1. **Undergo sponsored onboarding** with an existing MAP that supports the relevant industry process
2. **Establish secure connectivity** with all other MAPs (OAuth 2.0 credentials, endpoint registration)
3. **Publish its CP Registry** detailing its CPs and supported processes
4. **Retrieve all other MAPs' CP Registries** to build its Master Registry

Feature-based services are advertised in the CP Registry, allowing certain MAPs to utilise additional functionalities for bilateral and advanced communication. This design ensures MAPs transmit only messages that the receiving MAP can process.

## 4.5 API Versioning and Feature Releases

The CSF supports incremental evolution through two mechanisms:

### API Versioning

MAPs can support multiple API versions simultaneously, allowing new features to be adopted without disrupting existing integrations. When both parties support the latest version, they automatically use advanced features. Where compatibility varies, messages default to the highest compatible version.

### Feature Discovery

A MAP queries the directory to identify the supported feature set of another MAP. This enables:

- **Backward compatibility**: All MAPs maintain compatibility with earlier API versions
- **Flexible adoption**: MAPs can adopt new features at their own pace
- **Rapid iteration**: The TAG can release new capabilities without requiring industry-wide synchronisation

By implementing versioning and feature discovery, the CSF enables rapid feature adoption while reducing the constraints of traditional messaging protocols.

## 4.6 What the CSF Does Not Prescribe

The CSF is deliberately silent on:

- **MAP-to-CP integration**: How a MAP connects to its CPs is a commercial decision (API, portal, BSS plugin, etc.). Typically, MAPs will attempt to offload or shield CPs from as much of the heavy lifting for a process like SforB as possible, and this is often used to differentiate between MAPs, but this is a technical-commercial decision outside the scope of this framework.
- **Internal MAP architecture**: MAPs are free to use any technology stack
- **CP message creation**: CPs create messages according to industry process specifications, not CSF specifications
- **Commercial arrangements**: MAPs and CPs establish their own commercial relationships independently of the CSF

---

<!-- DOCUMENT: part1/05-directory-and-registry | Part 1 — Framework — 5. CP Registry, Master Registry, and Directory -->

---
title: '5. CP Registry, Master Registry, and Directory'
tags: [Part 1]

---

# 5. CP Registry, Master Registry, and Directory

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 5.1 Overview

The distributed registry model is a foundational pillar of the CSF. Unlike a centralised model where a single operator maintains the master list of all CPs, the CSF distributes this responsibility across all MAPs using a three-tier approach.

Each MAP:

1. **Publishes a CP Registry** — a JSON document listing its own CPs and their metadata, made available to other MAPs via an OAuth 2.0-protected API endpoint
2. **Collects all other MAPs' CP Registries** — via those same API endpoints
3. **Converges these into a Master Registry** — a private, consolidated view containing full routing, PKI, and contact details for all CPs across the entire CSF network
4. **Derives a Directory for its CPs** — a filtered, cut-down version of the Master Registry listing just the brand names and RCPIDs available to switch with

```mermaid
flowchart LR
    subgraph "MAP A"
        RA["CP Registry A\nCP1, CP2, CP3"]
    end
    subgraph "MAP B"
        RB["CP Registry B\nCP4, CP5"]
    end
    subgraph "MAP C"
        RC["CP Registry C\nCP6, CP7, CP8"]
    end

    RA -->|Collect| MB["MAP B\nMaster Registry\nAll CPs"]
    RC -->|Collect| MB
    RA -->|Collect| MC["MAP C\nMaster Registry\nAll CPs"]
    RB -->|Collect| MC
    RB -->|Collect| MA["MAP A\nMaster Registry\nAll CPs"]
    RC -->|Collect| MA

    MA -.->|Filter| DA["Directory\nfor MAP A CPs"]
    MB -.->|Filter| DBdir["Directory\nfor MAP B CPs"]
    MC -.->|Filter| DCdir["Directory\nfor MAP C CPs"]
```

### How the Three Tiers Work Together

1. A CP selects a destination brand from the **Directory** (e.g., a drop-down list in the MAP's portal)
2. The MAP uses the selected RCPID to look up the full routing and signing details in its private **Master Registry**
3. The Master Registry tells the MAP which MAP serves the destination CP, which endpoint to send to, and which PKI domain to use for verification
4. The destination CP's details originally came from that MAP's **CP Registry**, which was collected and converged into the Master Registry

## 5.2 CP Registry Structure

Each MAP's CP Registry contains two main sections:

### MAP Section

Comprehensive metadata about the MAP itself:

- **Identity**: MAP name, version timestamp
- **Contact information**: Phone, email, URL with availability hours and days
- **Connectivity**: CP Registry API endpoint URL, OAuth token URL, messaging service endpoints
- **Routing groups**: Which message types (e.g., `businessSwitch.*`, `residentialSwitch.*`) are accepted at which endpoint
- **Connections**: List of other MAPs this MAP has established connectivity with
- **Registration URI**: Where new CPs or MAPs can apply to register
- **Service status**: URL and API endpoint for checking operational status and planned changes

### CP List Section

For each CP registered with the MAP:

- **RCPID**: The CP's unique identifier (UUIDv4)
- **Brand name**: The human-readable name shown in search/drop-down lists
- **Process support**: Which industry processes the CP participates in (OTS, SforB) and their status (ACTIVE, SUSPENDED, TEST)
- **Resources**: Customer assist URLs, sales assist URLs, switch support contacts — backward compatible with OTS resource fields
- **Signing information**: The DNS domain used for PKI key lookup and which routing IDs should be signed with that domain
- **Contact details** (optional): A `contact` array using the same structure as the MAP contact object — phone, email, URL with availability hours, days, and purpose (sales, support, technical). This allows each CP to advertise its own preferred contact methods for operational escalations, independent of the MAP's contacts

> :bulb: For the full JSON schema and field reference, see [Part 2: Directory API](../part2-implementation/05-directory-api.md).

## 5.3 CP Registry Synchronisation

MAPs retrieve other MAPs' CP Registries via HTTP GET requests to each MAP's registry API endpoint, authenticated with OAuth 2.0 credentials established during onboarding.

### Frequency

- There is no mandatory synchronisation interval — MAPs can pull as frequently as needed
- A maximum frequency of approximately **60 seconds** is recommended to avoid unnecessary load
- MAPs MUST retrieve CP Registries regularly and in near-real time, particularly as new CPs are onboarded continuously throughout the day

### Building the Master Registry

Each MAP independently converges the collected CP Registries into its own private copy of the Master Registry. The Master Registry contains:

- **Full routing information**: Endpoint URLs, OAuth token URLs, and routing group definitions for every MAP
- **PKI signing domains**: The DNS domains used for DKIM signature verification for every CP
- **Contact details**: MAP and CP contact information for operational support and escalations
- **Service status**: Real-time availability indicators for each MAP

### Deriving the Directory

From the Master Registry, each MAP creates a Directory for its own CPs. The Directory contains only the information CPs need to address messages:

- **Brand names** and **RCPIDs** — for drop-down lists and search-as-you-type
- **Supported processes** — which CPs support OTS, SforB, etc.
- **Resource URLs** — customer assist and sales assist URLs (backward compatible with OTS)

The Directory excludes inter-MAP routing details, PKI signing domains, OAuth endpoints, and other sensitive operational information. How the MAP presents the Directory to its CPs (portal, API, BSS integration) is the MAP's commercial decision.

## 5.4 Advantages of the Distributed Model

| Benefit                        | Description                                                                                                                           |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Data accuracy**              | Each MAP is the authoritative source for its own CPs, reducing inaccuracies                                                           |
| **Real-time updates**          | New CPs can be onboarded and advertised in seconds, without central approval                                                          |
| **Scalability**                | Each MAP manages only its own CP Registry — the network scales naturally                                                              |
| **No single point of failure** | If one MAP is offline, all other MAPs continue to operate                                                                             |
| **Extensibility**              | The CP Registry schema can be extended without breaking existing implementations                                                      |
| **CP control**                 | CPs control their MAP association via DNS, not through a central register, which means CPs stay in control at all times, not the MAP. |
| **Transparency**               | Every MAP can see the full network state by converging all CP Registries into its Master Registry                                     |

## 5.5 Conflict Resolution

When a CP appears in more than one MAP's CP Registry simultaneously (typically during a CP transition between MAPs), the conflict is resolved using DNS:

1. The MAP performs a DNS lookup on the CP's `_mapkey` record
2. The DNS record indicates the CP's current MAP endpoint
3. The MAP routes messages to the MAP indicated by DNS, regardless of which CP Registry listed the CP
4. The MAP marks the conflicting entry as being in "conflict" in its Master Registry

This DNS-based resolution ensures that the CP — not the MAP — has ultimate control over routing.

> :bulb: For detailed conflict resolution procedures, see [Part 2: CP Transitions](../part2-implementation/07-cp-transitions.md).

## 5.6 TOTSCo Compatibility

The CSF CP Registry structure is backward compatible with the TOTSCo OTS directory. The same fields used in OTS (RCPID, brand name, customer assist URL, sales assist URL) are preserved in the CSF CP Registry using the same structure.

TOTSCo can collect CSF MAPs' CP Registries and either merge them into its own Master Registry or maintain them separately. The CP Registry is JSON-formatted, making convergence straightforward.

For details on consuming the TOTSCo Directory API, see [Part 2: TOTSCo Integration](../part2-implementation/06-totsco-integration.md). The [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) defines the standard directory and letterbox interfaces used by TOTSCo and supported by the CSF for hub interoperability.

---

<!-- DOCUMENT: part1/06-security-overview | Part 1 — Framework — 6. Security Overview -->

---
title: 6. Security Overview
tags: [Part 1]

---

# 6. Security Overview

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 6.1 Security Architecture

The CSF implements a multi-layered security architecture combining three established standards. Together, they deliver end-to-end encryption, authenticated access, and verifiable trust for every connection, credential, and message.

```mermaid
flowchart TB
    subgraph "CSF Security Stack"
        TLS["TLS 1.3 — RFC 8446\nTransport Encryption"]
        OAuth["OAuth 2.0 — RFC 6749\nAuthorisation & Access Control"]
        PKI["PKI / DKIM — RFC 6376\nMessage Signing & Verification"]
    end

    TLS --> |"Encrypts all data in transit"| OAuth
    OAuth --> |"Controls who can access endpoints"| PKI
    PKI --> |"Verifies message origin and integrity"| MSG["Trusted Message Delivery"]
```

| Layer                 | Standard  | Purpose                                                                              |
|-----------------------|-----------|--------------------------------------------------------------------------------------|
| **Transport**         | TLS 1.3   | Encrypts all data in motion, protecting against interception and tampering           |
| **Access Control**    | OAuth 2.0 | Ensures only authorised MAPs and CPs can interact with API endpoints                 |
| **Message Integrity** | PKI/DKIM  | Digital signatures verify message authenticity and that content has not been altered |

This combination delivers a **zero-trust, cryptographically assured trust boundary** across networks and services.

## 6.2 Transport Layer Security (TLS 1.3)

TLS is a cryptographic protocol providing secure communication over computer networks. It ensures that data transmitted between MAPs remains confidential, authentic, and integrity-protected.

### What TLS 1.3 Provides

- **Encryption**: Protects data from eavesdropping using symmetric encryption after a secure handshake
- **Authentication**: Verifies server identity using digital certificates from trusted Certificate Authorities
- **Integrity**: Ensures data has not been tampered with during transit through message authentication codes

### Why TLS 1.3 Specifically

TLS 1.3 (RFC 8446) is mandated by the CSF because it:

- Removes legacy insecure algorithms (RSA key exchange, SHA-1, static DH)
- Reduces handshake latency from two round-trips to one
- Mandates **forward secrecy** — session keys cannot be recovered even if a server's private key is compromised
- Supports only strong, modern encryption (AES-GCM, ChaCha20-Poly1305)
- Encrypts more of the handshake, hiding metadata from passive observers
- Has growing support for Post-Quantum cryptography (NTRU, ML-KEM, etc.)

> :tick: **CSF Requirement**: TLS 1.3 is mandatory for all CSF deployments. Earlier TLS versions MUST NOT be used.

## 6.3 OAuth 2.0

OAuth 2.0 is the authorisation framework used by the CSF to control access to API endpoints. It provides token-based security with granular permissions.

### How OAuth 2.0 is Used in the CSF

The CSF uses the **Client Credentials flow** — the machine-to-machine (M2M) flow — because CSF communication is between MAP servers, not end users.

Each MAP:

1. Registers with other MAPs during onboarding, receiving a `client_id` and `client_secret`
2. Requests a time-limited access token from the other MAP's OAuth token endpoint
3. Includes the bearer token in API requests to the other MAP's endpoints
4. The receiving MAP validates the token's signature, issuer, audience, and expiry on every request

### CSF OAuth 2.0 Requirements

- All token exchanges MUST use HTTPS/TLS 1.3
- Token scope and lifetime MUST be limited
- Client secrets MUST NOT be exposed in logs or client-side code
- Token signature, issuer, and audience MUST be validated on every request

> :memo: **OAuth 2.0**: mirrors the approach used by TOTSCo for OTS, making it the most compatible option across the industry. MAPs that already have TOTSCo OAuth credentials may be able to reuse them for CSF connectivity.

## 6.4 API Key Authentication

API key authentication is a simpler mechanism where a client includes a unique secret key in each request. In the CSF context:

- API keys are recommended for **MAP-to-CP** communication, where full OAuth 2.0 would be excessive
- API keys MUST NOT be used for **MAP-to-MAP** communication over the CSF — OAuth 2.0 is mandatory
- All API key exchanges MUST use TLS 1.3
- Keys MUST be stored securely, rotated regularly, and granted minimal access

## 6.5 PKI and DKIM Message Signing

Public Key Infrastructure (PKI) provides the cryptographic framework for message signing and verification. The CSF implements PKI through DKIM (DomainKeys Identified Mail, RFC 6376), a standard originally designed for email authentication but ideally suited to federated, distributed messaging.

### Why DKIM?

DKIM is ideal for the CSF because it:

- Provides **message integrity** — the message body cannot be tampered with undetected
- Provides **domain-level authentication** — the signature confirms which domain (and therefore which CP) authorised the message
- Uses **DNS for public key distribution** — no centralised certificate authority is needed
- Gives **CPs control** — a CP's DNS records determine which MAP is authorised to sign on their behalf
- Is a **proven standard** used at internet scale for email authentication

### How It Works (Conceptual)

1. When a MAP sends a message, it creates a cryptographic hash of the message body and selected headers
2. The hash is encrypted (signed) with the source CP's **private key** — held securely by the MAP
3. The signature is placed in the HTTP header `X-CSF-SIGNATURE` — the message body is not modified
4. The receiving MAP retrieves the source CP's **public key** from a DNS TXT record
5. The receiving MAP recalculates the hash and verifies it against the decrypted signature
6. If the hashes match, the message is authentic and unaltered; if not, the message is rejected

### DNS Records for Each CP

Each CP maintains two DNS TXT records that establish their identity and MAP association:

- **`[RCPID]._domainkey.[cp-domain]`** — Contains the CP's public key for signature verification
- **`[RCPID]._mapkey.[cp-domain]`** — Contains the URL of the CP's MAP message endpoint

These records are controlled by the CP, ensuring that:

- Only the MAP indicated in DNS can sign messages on the CP's behalf
- The CP can change MAP by updating these DNS records
- Any receiving MAP can independently verify the message origin without relying on a central authority

> **CSF Best Practice — DNS independence.** A CP SHOULD NOT delegate management of the DNS zone containing `_domainkey` / `_mapkey` records to its MAP. The whole point of the DNS-anchored model is that the CP retains unilateral control of *who is authorised to sign for it* and *which MAP routes its traffic*. If a CP delegates the DNS zone to its MAP, moving to a different MAP — or becoming a [MAP of 1](04-architecture-overview.md) — requires cooperation from the MAP the CP wishes to leave, which can be slow, contested, or commercially unattractive for the outgoing MAP. CPs SHOULD therefore host their own DNS or use an independent DNS provider with whom they have a direct commercial relationship that is not entangled with their MAP relationship. This keeps the CP's right to change MAP exercisable at any time, by the CP alone.

> **CSF Best Practice — local DNS server.** To ensure the DNS records used to verify CSF messages reflect the live public records as closely as possible, MAPs **SHOULD** operate a local DNS server that mirrors `_domainkey` and `_mapkey` records in near-real-time, observing the public TTLs published by each CP. Core standard: **[RFC 6303 — Locally Served DNS Zones](https://datatracker.ietf.org/doc/html/rfc6303)**. This is a common operational pattern (recursive resolver pinned to authoritative servers; or stub bypassing OS resolver cache) and imposes no new infrastructure cost. Detailed rationale and impacts-if-not-implemented are in [Part 2: PKI & DKIM Signing §3.3](../part2-implementation/03-pki-dkim-signing.md#33-dns-records).

> **For implementers**: Detailed DKIM implementation guidance, worked code examples (Java and C#), CSF HTTP headers, signing algorithms, and error codes are provided in [Part 2: PKI & DKIM Signing](../part2-implementation/03-pki-dkim-signing.md).

## 6.6 Security Summary

The CSF protects every interaction with:

- **TLS 1.3** — encrypting all data in transit between MAPs
- **OAuth 2.0** — controlling who can access which endpoints
- **PKI/DKIM** — verifying that every message is authentic, unaltered, and authorised by the source CP

No single layer is sufficient on its own. Together, they provide **confidentiality** (data cannot be read), **authentication** (identities are verified), **authorisation** (access is controlled), and **integrity** (content cannot be tampered with).

---

<!-- DOCUMENT: part1/07-onboarding | Part 1 — Framework — 7. Onboarding -->

---
title: 7. Onboarding
tags: [Part 1]

---

# 7. Onboarding

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 7.1 Overview

The CSF uses a peer-sponsored onboarding model. There is no centralised registration authority. Instead, existing MAPs take responsibility for validating and onboarding new participants, ensuring quality and compliance without the cost and complexity of a central governing body.

A minimum of **two MAPs** is sufficient for a basic bilateral exchange. This eliminates the need for a "big bang" approach — MAPs and CPs can be onboarded incrementally.

## 7.2 Onboarding a New MAP

### 7.2.1 Sponsorship Framework

New MAPs are onboarded through a structured, multi-phase process guided by a **Sponsor MAP** — an existing, onboarded MAP identified via FIFO rotation. The candidate initiates contact: it discovers the **current designated Sponsor** either from the TAG-published sponsor-registration page (URL to be published by the TAG) or by reading any existing MAP's CP Registry and locating the entry with the most recent `nextSponsorUpdated` timestamp (see the standalone *MAP Onboarding & Testing Process* §3.4 for the detailed mechanism).

Key principles:

- **Next Sponsor MAP**: Uses `nextSponsor` — a forward pointer that says "when I accepted my engagement, I designated X as next." The current sponsor is simply the MAP with the most recent `nextSponsorUpdated` timestamp. No consensus, no propagation of a shared value — just read the most recent write.
- **Capped costs (sponsor fees are free by default)**: Sponsor MAPs are **not expected to charge** for onboarding another MAP. There is an option to charge a fee when significant time and effort is required, capped at **£3,000 + VAT** for a `traditional` (multi-CP) engagement and at **£350 + VAT** for a `single-cp` (MAP-of-1) engagement. The option exists because the CSF expects the Sponsor MAP to apply a **quality gate** — all checks and baseline testing completed to TAG standards. The actual fee is a negotiation between the Sponsor MAP and the new MAP based on how much support is required. A MAP is only charged **once** for onboarding, regardless of how many industry protocols it eventually carries. A set of **shared test endpoints** will be created over time to further reduce sponsoring effort and cost. See §7.4.5 for the `single-cp` fast-track.
- **Gatekeeper role**: The Sponsor MAP acts as a gatekeeper to the CSF network, ensuring operational performance and compliance.
- **Evolving criteria**: The TAG continuously updates entry criteria to reflect the latest maturity levels and address known issues identified through industry testing and operational working groups.

### 7.2.2 On-Ramp Process

The onboarding process follows five phases:

> **1. Select Sponsor MAP** → **2. Initial Assessment** → **3. Integration & Testing** → **4. Operational Validation** → **5. Full Operations**

#### Phase 1 — Sponsor MAP Selection and Agreement

- The new MAP identifies and selects an existing MAP as its sponsor (or is assigned one via rotation)
- The Sponsor MAP verifies the request is legitimate
- Both parties agree on technical, operational, and compliance criteria

#### Phase 2 — Initial Assessment and Registration

- The Sponsor MAP conducts a capability assessment covering technical readiness, security, and compliance
- The new MAP registers essential details: endpoint URLs, PKI credentials, and directory synchronisation preferences

#### Phase 3 — Integration and Testing

- Secure communication channels are established using OAuth 2.0 and PKI
- Credentials at this stage provide **provisional/restricted access** — directory information should contain limited, obfuscated data to prevent disclosure of client information until testing is complete
- Testing verifies secure, authenticated message exchanges and directory synchronisation
- Once basic connectivity is proven, access levels are raised to **test** — the directory will now contain information to facilitate test communications (with CP consent or using test CPs)

#### Phase 4 — Operational Validation

- The Sponsor MAP verifies adherence to operational requirements: message delivery reliability, retry mechanisms, and SLA compliance
- Validation tests ensure interoperability with other MAPs and CPs
- Each other MAP performs additional sanity testing as they establish their own OAuth 2.0 connections with the new MAP
- A **72-hour soak** under projected production load is the default exit gate (see the standalone *MAP Onboarding & Testing Process* §6 Phase 4 and §9 Exit Criteria #2). The soak is **relaxed** for `single-cp` (MAP-of-1) engagements — see §7.4.9.

#### Phase 5 — Full Operations

- The Sponsor MAP formally approves the onboarding and notifies all other MAPs
- Connectivity is upgraded to **full access**
- The new MAP freely shares its complete CP Registry with other MAPs
- The new MAP commences independent, full operational integration

> The detailed testing process, entry criteria, and exit criteria are set out in the separate "New MAP Onboarding & Testing Process" document maintained by the TAG.

## 7.3 Onboarding a CP

CP onboarding is a commercial matter between the CP and its chosen MAP. The CSF does not prescribe how MAPs select or charge their CPs. However, the CSF requires certain steps to be completed before a CP can exchange messages:

### 7.3.1 MAP Responsibilities

1. **Allocate a unique RCPID** — A UUIDv4 identifier, verified against the directory to prevent collisions (see [RCPID Management](08-rcpid-management.md))
2. **Generate PKI key pair** — Create the public/private key pair for the CP
3. **Guide DNS setup** — Assist the CP in creating the two required DNS TXT records:
   - `[RCPID]._domainkey.[cp-domain]` — containing the public key
   - `[RCPID]._mapkey.[cp-domain]` — containing the MAP's message endpoint URL
4. **Collect customer data assets** — Ensure the MAP has sufficient data to perform timely Switch Match responses without relying on the CP being online
5. **Validate compliance** — Ensure the CP meets the requirements of the industry process they wish to participate in
6. **Publish in registry** — Add the CP to the MAP's registry with all mandatory fields

### 7.3.2 When a CP Can Exchange Messages

No messages can be exchanged until other MAPs verify that the CP is correctly associated with the MAP in its directory. This verification happens automatically when MAPs pull the updated registry and cross-reference it against the CP's DNS records.

A MAP can register a new CP and advertise it to other MAPs **within seconds**. However, the CP controls when it is ready to exchange by managing its DNS entries and service status (ACTIVE, TEST, SUSPENDED).

## 7.4 MAP-of-1 Onboarding (incl. TOTSCo → CSF Migration)

### 7.4.1 Definition and scope

A **MAP of 1** is a CP that operates the full MAP stack for its own brand: OAuth 2.0 token endpoint, Letterbox, CP Registry / Directory API, DKIM signing, and the CP's own `_domainkey` / `_mapkey` DNS records. The CP is a CSF peer to every other MAP and pays no transport fees to a third party. This section sets out the onboarding path **specifically for** a CP that wishes to take on the MAP role for itself — and in particular for the common case of a CP currently using **TOTSCo for SforB** (and / or for niche bilateral exchanges, or other non-OTS protocols) who wishes to **move that traffic to the CSF as their transport**.

> **OTS is out of scope of this migration.** OTS (One Touch Switch — residential switching) is **mandated by Ofcom to use TOTSCo as the single industry platform**. A CP that operates OTS in the UK MUST continue to use TOTSCo for that traffic. The §7.4 migration applies to **SforB** and other **non-OTS** protocols only — for example niche bilateral exchanges between CPs, or future industry protocols if and when the TAG adds them to the CSF baseline (see §7.4.10). A CP that currently uses TOTSCo for both OTS and SforB can move its **SforB** traffic to a CSF MAP-of-1 while **continuing OTS via TOTSCo unchanged**; the two are operationally independent at both the transport layer and the directory layer.

This section is in addition to §7.2 (sponsor-driven multi-CP MAP onboarding) and §7.3 (CP onboarding by an existing MAP). The technical onboarding mechanism is the **same five-phase on-ramp** as §7.2 — the differences are scope, fee guidance, soak relaxation, and the cutover story.

### 7.4.2 Strategic context — the CP remains in control

The CSF is the open-standard transport for SforB (and over time other industry protocols). It is the **bit pipe** (see [Definitions](../standalone/definitions.md)) for exchanging messages between CPs — a network provider that simply moves data without adding value or examining content. The CP — or MAP of 1 — remains in **direct control of its own customer relationship at all times**: end-consumer data, sales, support, billing, in-flight order state, and all CRM live with the CP, not with the transport. The transport (CSF or TOTSCo) carries the JAM-envelope messages; nothing more.

This is the central reader takeaway: a TOTSCo subscriber moving to the CSF as a MAP of 1 is **changing transport, not changing business**. The CP's brand, customers, **SORs (Switch Order References)** and ServiceIdentities are unaffected by the transport switch. The risk of the move is therefore low — provided the CP is in full operational control of its customer relationship before the cutover begins.

> **Brand uniqueness (industry constraint).** The SforB industry process supports a CP brand appearing **once** in the industry directory. This is not a CSF transport rule — it is a property of the industry-process layer (SforB / OTS) above the transport. The practical consequence is that a CP migrating from TOTSCo to a CSF MAP-of-1 **cannot dual-run** the same brand on both directories simultaneously; the move must be a **planned cutover** (see §7.4.7). The exception is during a brand change — e.g. as part of a merger or rebrand — where the new brand is a new directory entry and the old brand is consolidated under the §8.3 process.

### 7.4.3 Decision tree — "Should I become a MAP of 1?"

A CP considering self-serve operation on the CSF SHOULD work through the following:

| # | Factor | "Yes" if… |
|---|---|---|
| 1 | **Technical capability** | The CP can run TLS 1.3, OAuth 2.0 (client credentials), DKIM signing (RSA or Ed25519, using existing libraries — see §7.4.10), JSON registry serving, and CP-controlled DNS for the `_domainkey` and `_mapkey` records. |
| 2 | **Infrastructure overlap** | Most of the above (OAuth, DNS, TLS, JSON handling, message-queue and retry) is **already** running in the CP's existing TOTSCo integration — the increment for a MAP-of-1 is small. |
| 3 | **DKIM signing readiness** | The CP can integrate a DKIM signing library (RFC 6376 reference implementations exist for Java, .NET, Go, Python, Node, etc. — see §12 Tooling Reference in the standalone handbook). This is a one-off software change, not a recurring cost. |
| 4 | **Volume and business case** | The CP's annual TOTSCo subscription + unit charges exceed the CP's projected one-off MAP-of-1 build cost over a payback window the CP regards as acceptable. (See §7.4.10.) |
| 5 | **On-call cover** | The CP has, or can establish, the 24×7 incident-response posture required by §9 (Operational Excellence) and the SforB SLAs. |
| 6 | **Routing footprint** | The CP knows which other MAPs (or HMAPs like TOTSCo) it needs to exchange with, and is prepared to complete the bilateral tests for those it adds beyond the Sponsor MAP. |

If the CP cannot meet factor 1 today but expects to in the medium term, an interim **CP-onboarding-with-a-CSF-MAP** path (§7.3) is the safer choice; the CP can transition to MAP-of-1 later via §8.2 mechanisms. If the CP cannot meet factor 5 either, MAP-of-1 is not appropriate and a managed-MAP relationship should continue.

### 7.4.4 Pre-migration capability checklist

Before approaching a Sponsor MAP, the candidate CP SHOULD verify:

- [ ] **DNS zone control** — the CP controls the DNS zone(s) in which `[RCPID]._domainkey.[cp-domain]` and `[RCPID]._mapkey.[cp-domain]` will live (or has it under independent commercial control — see §6.5 best practice "keep DNS independent of the MAP").
- [ ] **TLS 1.3 endpoint capability** — the CP has, or can stand up, public HTTPS endpoints (OAuth token URL, Letterbox URL, Directory API URL, Service Status URL).
- [ ] **OAuth 2.0 IdP** — the CP can issue and validate client-credentials bearer tokens. Most CPs already operate one for their TOTSCo integration.
- [ ] **DKIM signing** — the CP can integrate a DKIM signing library and produce a CSF-format `X-CSF-SIGNATURE` header that passes against the public NowYoYo PKI Test Harness.
- [ ] **JSON registry** — the CP can publish a CP Registry that validates against the §5 Directory API schema.
- [ ] **Monitoring and on-call** — the CP has alerting, logging, and an on-call rota suitable for SforB SLAs.
- [ ] **CRM authority** — the CP's own CRM is the authoritative source of customer state (so the transport change does not depend on the outgoing hub).
- [ ] **In-flight order list** — the CP can enumerate the in-flight orders open on its TOTSCo subscription as of the planned cutover date (used to plan §7.4.7).

### 7.4.5 Sponsor MAP programme — fast track for single-CP

Sponsor MAPs are **encouraged** to use the `single-cp` engagement type (tracked as `type: "single-cp"` in `sponsorship.active[]`, see the standalone handbook §3.4) as a positive industry-development offering. The CSF treats existing-MAP sponsorship of TOTSCo-subscriber CPs as a **first-class adoption mechanism**: it grows the open network, gives the sponsor commercial visibility with a new peer, and gives the candidate a low-friction route in.

Differences for a `single-cp` engagement:

| Aspect | Traditional sponsorship | `single-cp` sponsorship |
|---|---|---|
| Fee | Free by default; capped at **£3,000 + VAT** when significant support is required | Free by default; capped at **£350 + VAT** when significant support is required (the absolute ceiling — the reduced scope, single CP, no multi-tenant DKIM, smaller registry, typically keeps the actual negotiated fee well below the cap) |
| Phase 4 soak | 72 hours at projected production load | **Soak waived** for the single-CP MAP-of-1 case — see §7.4.9 |
| Bilateral ≥50% coverage in Phase 4 | Required | **Waived** — only the bilateral tests the candidate intends to route to are required (see §7.4.9) |
| Speed | Weeks to months | Days to weeks once exit gate is met |

This is not a quality compromise: the candidate must still pass §8.1 – §8.9 of the standalone handbook against the Sponsor MAP and the NowYoYo PKI harness. What's relaxed is the **production-scale validation step**, on the basis that a MAP-of-1 is **a CP managing its own transport — the operational risk is internalised by the CP** (per §7.4.2). The CP that runs the MAP-of-1 is, by construction, the same CP who carries the consequence of a defect.

### 7.4.6 Finding your Sponsor MAP

Two discovery paths are available to a candidate (including before joining the network):

1. **TAG-published registration page** (URL to be published by the TAG) — this is the **primary** entry point. The TAG publishes the current designated Sponsor MAP and their registration contact details on the public TAG website. Updated whenever the rotation advances.
2. **Directory bootstrap** (fallback) — read any existing MAP's CP Registry over HTTPS and locate the `sponsorship` entry with the most recent `nextSponsorUpdated`. This is the in-band mechanism documented in the standalone handbook §3.4 and the only mechanism available before the TAG website is live.

Once the current Sponsor MAP is identified, the candidate contacts the Sponsor MAP's `map/contact[]` registration entry (or the TAG page's registration link). The Sponsor MAP's own onboarding portal handles the rest (Phase 1 — see §7.2.2 and the handbook §6).

### 7.4.7 The cutover journey — big-bang, CP-controlled

Because the SforB industry directory supports a CP brand only once (§7.4.2 brand uniqueness), the move from TOTSCo to a CSF MAP-of-1 **MUST be a planned cutover** — there is no dual-running window for a single brand. The cutover is **CP-controlled** at every step. Five stages:

1. **Build** (CP timetable; typically weeks). The CP builds and tests its MAP-of-1 stack against the Sponsor MAP's Test Tenant. `map.status=TEST`. The CP's TOTSCo subscription is unaffected. Phases 1 – 3 of §7.2.2 complete.
2. **Exit-gate pass** (CP timetable). Baseline tests §8.1 – §8.9 (handbook) pass against the Sponsor MAP and the NowYoYo PKI harness; Phase 4 relaxations per §7.4.9 satisfied; Sponsor MAP issues Phase 5 approval.
3. **In-flight position** (CP decision). The CP chooses the in-flight policy for its open TOTSCo orders. **Two valid paths** — neither imposed by the framework; the CP picks based on volume and risk:
   - **Drain-first (preferred when feasible)** — the CP stops accepting new switch matches on TOTSCo, lets all open in-flight orders complete or cancel cleanly, then performs the cut with zero in-flight balance. Lower operational complexity at cutover; longer total elapsed time.
   - **CP-managed migration** — the CP cuts when ready and reconciles in-flight orders from its own CRM. SORs and ServiceIdentities **do not need to change** — the CP holds the customer relationship throughout and the transport change is invisible to the underlying business state. If TOTSCo can be persuaded to honour an `rcpidStatusRequest`-equivalent export, happy-path import via the MAP-of-1 applies; otherwise the CRM-reconstruction model from §8.2.4 (CP Emergency Migration unhappy path) applies. The CP carries the operational risk — which is appropriate because the CP is the party in control.
4. **Cutover (big-bang)**. The CP coordinates with TOTSCo to terminate the **TOTSCo SforB** directory entry for the brand as the new CSF MAP-of-1 directory entry goes live. If the same brand also operates OTS via TOTSCo, the **OTS directory entry is unaffected** and continues unchanged — OTS is Ofcom-mandated to TOTSCo (see §7.4.1) and is out of scope of this migration. **TTL pre-staging** is used on the CP's `_mapkey` and `_domainkey` to keep the observed outage to single-digit minutes (the standard enterprise DNS-change routine: lower the TTL ≥24h before the cut-over, swap, then restore — see Part 2 §3 *PKI & DKIM Signing* for the canonical clause). The new CSF UUIDv4 RCPID is allocated per §7.4.8 — the legacy TOTSCo **SforB** `Rxxx` is retired (not migrated); any OTS `Rxxx` for the same brand on TOTSCo is independent and untouched.
5. **TOTSCo wind-down (SforB only)**. The CP closes its **TOTSCo SforB** participation per the TOTSCo contract terms (notice period, final invoice). If the CP continues to use TOTSCo for OTS, the **OTS subscription / participation continues unaffected** — only the SforB element is wound down. Audit retention rules per §9 apply.

> **The risk is low precisely because the CP is in control.** The CSF (and TOTSCo before it) is the transport, not the business. End-consumer relationships, SORs, ServiceIdentities, billing, support — all of these live in the CP's CRM and are unaffected by the cut.

### 7.4.8 RCPID allocation rule

A CSF MAP-of-1 is allocated a **new UUIDv4 RCPID** in the standard way (see §8 RCPID Management) — the legacy TOTSCo `Rxxx` 4-character RCPID is **not reused, not migrated, and not preserved as the CSF RCPID**. The two identifiers are independent.

For OTS-side historic reporting (post-cutover queries that reference the legacy `Rxxx`), the CP retains its TOTSCo records under TOTSCo's own retention regime; the CSF retention applies only to messages exchanged over the CSF.

### 7.4.9 Phase 4 relaxation for MAP-of-1

For `single-cp` (MAP-of-1) engagements, Phase 4 (Operational Validation) is modified as follows:

| §7.2.2 Phase 4 element | Traditional MAP | MAP-of-1 (`single-cp`) |
|---|---|---|
| 72-hour soak under projected production load | **Required** (handbook §6 Phase 4 / §9 #2) | **Waived** — a single-CP MAP has no meaningful production-scale traffic to soak, and the CP carries the operational risk directly |
| Bilateral connectivity with ≥50% of onboarded MAPs | **Required** (handbook §9 #4) | **Waived** for the ≥50% target. **Required** for any MAP / HMAP the candidate intends to exchange with at go-live, including TOTSCo as HMAP |
| Retry & delivery policy tests (§8.7) | Required | **Required — unchanged** |
| Conflict resolution & DNS tests (§8.8) | Required | **Required — unchanged** |
| Security & negative edge cases (§8.9) | Required | **Required — unchanged** |
| §8.10 V-01 (72-hour soak) | Required | **Waived** with V-02 – V-05 still required |

The Sponsor MAP records the waivers in the Phase 5 approval record. The TAG MAY require additional evidence if subsequent operational incidents suggest a single-CP MAP-of-1 has been under-tested in this respect.

### 7.4.10 Bilateral testing of additional protocols

The CSF transport is process-agnostic. A MAP-of-1 — like any other MAP — MAY use the CSF as the transport for **niche routing** or future industry protocols beyond SforB.

- **SforB** — if the MAP-of-1 supports SforB, the §8.6 SforB baseline tests are **mandatory** for Phase 3 sign-off (no relaxation for `single-cp`).
- **Niche routing / bilateral protocols** — for any protocol the candidate adds beyond what's currently in the baseline, the candidate and its bilateral counterparty MUST **buddy-test** the protocol against each other once the Sponsor MAP has signed off the CSF transport baseline. This applies equally to traditional and `single-cp` engagements.
- **Future industry protocols** — when a future protocol (for example, **OTS Porting**, or a future bilateral notification flow) is brought onto the CSF, the TAG will add a §8.x baseline test set for it (see the standalone handbook §8 "Scope and Extensibility"). Once published, a MAP that adopts that protocol — including a MAP-of-1 — MUST pass the corresponding baseline before Sponsor sign-off.

This means a MAP-of-1 supporting only SforB completes the §8 baseline once; a MAP-of-1 that subsequently adds a niche bilateral protocol completes that protocol's baseline (if published) and its bilateral tests at the point it adds the support.

### 7.4.11 Cost model — qualitative

The MAP-of-1 cost story (qualitative; specific numbers vary by candidate):

- **Most of the operating infrastructure is already running.** A CP currently subscribing to TOTSCo already operates OAuth 2.0 client integration, DNS records, TLS endpoints, retry queues, and JSON message handling. The MAP-of-1 stack reuses these.
- **DKIM signing is the principal new component.** DKIM is RFC 6376 — there are mature reference implementations in every major language (Apache James jDKIM for Java, MailKit for .NET, etc. — see standalone handbook §12 Tooling Reference). The cost is a **one-off software-integration exercise**, not a recurring infrastructure spend.
- **Directory API serving is small.** A single-CP registry is a few-kilobyte JSON document. Any web framework can serve it.
- **Sponsor fee is free by default; one-off and capped** at **£3,000 + VAT** for traditional engagements, or **£350 + VAT** for `single-cp` engagements, only when significant Sponsor MAP support is required (see §7.4.5). Charged once per MAP regardless of how many protocols it eventually carries.
- **The savings are the recurring TOTSCo charges.** The MAP-of-1's running cost is principally a small increment over what the CP was already paying for its TOTSCo integration; the operating saving is the **removal of TOTSCo subscription and per-unit fees**. A CP whose annual TOTSCo spend exceeds the one-off MAP-of-1 build plus the annual marginal cost of the additional CSF-specific components has a positive business case.

CPs SHOULD produce their own business case using their own commercial inputs. The framework provides no transport fees of its own.

### 7.4.12 What a MAP-of-1 *does not* lose

A CP moving from TOTSCo to a CSF MAP-of-1 retains:

- Its end-consumer relationship and CRM
- Its SORs and ServiceIdentities (the transport change does not propagate down)
- Its existing OAuth 2.0 / DNS / TLS infrastructure (most of it is reused)
- Its industry contact-details discoverability — the CSF Directory carries CP-to-CP, CP-to-MAP, MAP-to-MAP, and MAP-to-CP contact entries (phone, email, ticketing URL, purpose tags, availability hours). **The TOTSCo OTS CP-to-CP tool is not mandated for SforB**; the CSF registry contact entries replace the need for a specialised industry tool.
- Its right to come back — the CP can move from MAP-of-1 to a managed-MAP relationship later via the §7 normal transition process or, if necessary, §8.2 CP Emergency Migration.

## 7.5 Testing in Production

The CSF supports testing in production during onboarding:

- All test traffic MUST be explicitly marked as test in the audit record held in the JAM envelope
- The onboarding MAP MUST override the test flag until the CP has passed exit criteria — even if the CP sets it
- A published set of test data assets is available for entry criteria testing, performed locally with the MAP using a Virtual Test Host
- A hidden set of unit tests forms the exit criteria before the CP is granted production status
- PKI verification tools are available to assist with setup and testing

> **Note**: Not all CPs will have SIT/UAT environments. The CSF is designed to support continuous onboarding throughout core business hours, with strict protocols and test-flagging to prevent test traffic from affecting production operations.

## 7.6 Memorandum of Understanding (MoU)

MAPs and CPs that collaborate on the CSF are bound by a Memorandum of Understanding that outlines the terms of participation. The MoU is designed to be simple to join, reflecting the CSF's nature as an open standard that is licence-free for any CP or MAP to use for any purpose.

---

<!-- DOCUMENT: part1/08-rcpid-management | Part 1 — Framework — 8. RCPID Management -->

---
title: 8. RCPID Management
tags: [Part 1]

---

# 8. RCPID Management

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 8.1 What is an RCPID?

A Retail Communications Provider Identifier (RCPID) is a unique identifier assigned to a CP brand for the purpose of message exchange. Each RCPID maps 1:1 to a human-readable brand name that appears in search and drop-down lists used by CPs when initiating a Switch Match.

## 8.2 Why UUIDv4?

The CSF adopts **UUIDv4** (RFC 4122) as the RCPID format, replacing the 4-character alphanumeric codes used by OTS.

### Problems with the OTS Format

The OTS format (`Rxxx` — e.g., RGXD, RYHC) has several limitations:

- **Collision risk**: With only 4 characters, the probability of duplication increases as more CPs join for business switching (expected tenfold increase over OTS)
- **Human confusion**: Similar codes are easily mistaken (e.g., RYHC and RYCH are different brands but commonly confused — and they can exist in the same MAP)
- **MAP coupling**: If prefixes are tied to MAPs, changing MAP requires changing RCPID, which is costly and disruptive
- **Scalability**: The format does not scale for business switching where CPs may have multiple brands requiring separate identifiers

### Benefits of UUIDv4

UUIDv4 addresses all of these issues:

- **Virtually zero collision risk**: With 122 bits of randomness, the odds of collision between any two UUIDs are 1 in 2.71 x 10^18. One would need to generate 1 billion UUIDs per second for 85 years to have a 50% chance of a single collision.
- **Self-allocation**: MAPs can generate RCPIDs independently without central coordination
- **No human bias**: Machine-generated identifiers eliminate human-readable confusion
- **Portability**: The RCPID stays with the CP for life, regardless of which MAP they use
- **Data continuity**: All historical data (time-series, audit records, reporting) remains consistent as CPs move between MAPs

**Example RCPID**: `d8322d80-92c8-4906-a408-f1d2daf7e03d`

### Compatibility with OTS

The UUIDv4 format does not preclude any CP or MAP (including TOTSCo) from continuing to use the OTS `Rxxx` format internally. MAPs can maintain a mapping between their internal codes and the UUIDv4 RCPID used for SforB message exchange.

The SforB Message Specification defines the source and destination identity fields as strings with a maximum length of 256 characters. UUIDv4 (36 characters including hyphens) fits well within this constraint.

## 8.3 Allocation Process

1. The MAP generates a UUIDv4 for the new CP brand
2. The MAP provisionally allocates it to the CP
3. Before going live, the MAP pulls all other MAP directories and checks for collisions
4. If no collision is detected, the MAP publishes the RCPID in its registry
5. If a collision is detected (extremely unlikely), the MAP generates a new UUID and repeats

> **Responsibility**: It is the MAP's responsibility to ensure no duplication or collisions occur. The MAP MUST check the generated ID against the directory before allocating it to a CP and advertising it as live.

## 8.4 RCPID Lifecycle

### Allocation

An RCPID is allocated to a CP brand and remains associated with that brand **for life**. This helps with:

- CPs moving between MAPs
- Future brand consolidation or growth
- Mergers and acquisitions
- Consistent time-series data and historical reporting across all MAPs

### MAP Transitions

When a CP moves between MAPs:

1. The RCPID **does not change** — it remains constant and unique across the network
2. The new MAP adds the existing RCPID to its CP Registry
3. The old MAP removes the RCPID from its CP Registry
4. Other MAPs detect the change through CP Registry synchronisation and DNS verification

This ensures seamless continuity for in-flight orders and network-wide consistency.

### Retirement

When a CP brand is dissolved or merged, the RCPID is retired and retained in an archived state for historical reporting purposes. It MUST NOT be reused for a different brand.  While there is no centralised record each MAP will be responsible for hold a legagcy record and avoiding the risk of re-using for a nominal period of time. Once all inflight orders are resolved and SORs expired then there is a low risk asociated with reuse. It is also very unlikely, given UUID v4 size and the method suggested for picking new ones, that anyone will pick a previously used RCPID. 

## 8.5 Handling Exports During Transitions

When a CP moves to a new MAP, the in-flight order data must be transferred:

1. **Export with ID mapping**: On a valid "RCPID Status" request, the old MAP provides a standardised JSON export of all in-flight orders for the specified RCPID
2. **Validation**: The request is validated by checking that the RCPID's DNS entry now points to the MAP making the request
3. **CP Registry updates**: The old MAP removes the CP from its CP Registry before responding, ensuring no duplicate entries exist
4. **Verification**: The new MAP verifies the accuracy of the RCPIDs and ensures no collisions

> For the complete transition process including in-flight order handling, see [Part 2: CP Transitions](../part2-implementation/07-cp-transitions.md).

## 8.6 Summary

| Aspect | OTS (Legacy) | CSF |
|---|---|---|
| Format | 4-character alpha (Rxxx) | UUIDv4 (36 characters) |
| Allocation | Centralised or MAP-specific | MAP self-allocates |
| Collision risk | Moderate (grows with scale) | Negligible (1 in 2.71 x 10^18) |
| Portability | Tied to MAP (prefix-based) | Follows the CP for life |
| Human readability | Confusing (RYHC vs RYCH) | Not human-readable (by design) |
| Scalability | Limited for business switching | Unlimited |

---

<!-- DOCUMENT: part1/09-operational-excellence | Part 1 — Framework — 9. Operational Excellence -->

---
title: 9. Operational Excellence
tags: [Part 1]

---

# 9. Operational Excellence

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 9.1 Core Principles

The CSF is built on three operational cornerstones:

- **Security**: Strong encryption, robust authentication, and digital signing
- **Efficiency**: Accurate and timely telecom service transitions
- **Reliability**: Resilient architecture ensuring continuous availability

## 9.2 Availability Target

MAPs MUST target **99.95% availability** (three nines & a five) for switching services. This equates to 21 minutes and 55 seconds of downtime per month, or about 4 hours and 23 minutes of downtime per year and aligns with TOTSCo Availability Target.


## 9.3 High Availability and Redundancy

MAPs SHOULD:

- Deploy **multiple geographically distributed** instances (subject to GDPR) to eliminate single points of failure
- Implement **automatic failover** mechanisms capable of instantly transitioning operations to backup systems without noticeable service disruption
- Maintain **fully redundant network paths** and infrastructure components

## 9.4 Continuous Operations During Maintenance

MAPs MUST implement rolling updates and upgrades to ensure that maintenance activities — including software updates and security patching — do not impact service continuity.

Recommended deployment strategies:

- **Blue-Green Deployment**: Maintain two identical production environments. Deploy updates to the inactive environment, validate, then seamlessly switch traffic. This enables rapid rollback if issues are discovered.
- **Canary Deployment**: Gradually roll out updates to a small subset of traffic, monitor performance, and incrementally increase exposure based on positive outcomes.

MAPs SHOULD clearly communicate planned maintenance activities — even when designed to have no service impact — to maintain transparency and stakeholder confidence.

## 9.5 Monitoring and Alerting

MAPs MUST provide:

- **Real-time, proactive monitoring** with automated alerting capable of detecting and addressing issues before they affect availability
- **Mandatory status indication** in the MAP Registry when an incident occurs, including clearly recorded planned changes highlighting any periods of potential risk

MAPs SHOULD provide:

- A transparent, real-time **status dashboard** accessible by connected providers, showing platform health and operational metrics

## 9.6 Disaster Recovery

MAPs MUST:

- Regularly **test and validate** disaster recovery procedures, including full failover scenarios and restoration processes
- Establish **Recovery Time Objectives (RTO)** and **Recovery Point Objectives (RPO)** that align with the commitment to continuous availability

## 9.7 Security and Compliance

MAPs MUST:

- Maintain rigorous security standards and apply timely patches without disrupting ongoing service
- Adopt **secure-by-design** principles to ensure resilience includes robust protections against cyber threats
- Conduct **regular security audits** and vulnerability assessments to identify and mitigate risks proactively

## 9.8 Guaranteed Message Delivery

### Pre-Send Verification

Before sending a message, the originating MAP SHOULD verify the resilience status of the receiving MAP using information from the MAP Directory. This includes checking:

- Whether the receiving MAP is currently online
- Whether they are in a known period of planned change or experiencing an incident

### Retry Policy

If the originating MAP does not receive a synchronous `HTTP 202` acknowledgement (e.g. it receives a `4xx`, `5xx`, or times out), it MUST:

1. Apply the **1 second connection timeout** and **3 second response timeout** specified in [Part 2 §4.7.2](../part2-implementation/04-message-api.md#472-required-behaviours-csf-map-to-map).
2. Automatically retry message delivery using **exponential backoff with jitter** — never a linear or fixed-cadence schedule. The architectural rationale for this is set out in [Part 2 §4.7.5](../part2-implementation/04-message-api.md#475-why-exponential-backoff-and-not-linear--fixed-cadence-retry).
3. Implement a **circuit-breaker pattern** after N consecutive failures (recommended `N = 5`, tunable per MAP) to stop overwhelming a struggling destination.
4. Honour `Retry-After` on `HTTP 429` / `503` responses.
5. Maintain comprehensive **audit trails** of all message exchanges, delivery attempts, and outcomes.
6. Define a **bounded maximum retry period** — the framework recommends hours, not days. Beyond the window, the sender raises `9008` and the failure escalates to the operational-engagement path in [Part 2 §4.7.3](../part2-implementation/04-message-api.md#473-operational-engagement-escalation): `map/outage[]` publication by the failing MAP, alert on the sender, inter-MAP engagement via `map/contact[]`.

The retry policy applies to **CSF MAP-to-MAP traffic**. Traffic crossing the **HMAP boundary** to TOTSCo follows the GPLB hub schedules on TOTSCo's side — see [Part 2 §4.7.4](../part2-implementation/04-message-api.md#474-the-hmap-boundary) and the [TOTSCo HMAP Integration Guide](../standalone/totsco-hmap-integration-guide.md).

### Asynchronous Error Handling

The CSF employs asynchronous error codes (8xxx series) to signal and assist MAPs during message processing. These codes are designed for self-healing and promoting good practices, complementing the industry-standard 9xxx codes used by OTS/TOTSCo.

> For details on error codes and message delivery failure formats, see [Part 2: Message API](../part2-implementation/04-message-api.md).

## 9.9 Service Level Agreements

Specific SLAs for MAP-to-MAP activity are to be formalised. The following indicative levels have been agreed:

| Category | Target |
|---|---|
| Platform availability | 24x7 high availability (queue and retry during unavailability) |
| Directory freshness | Near-real-time updates (never delete the last compiled directory) |
| Working hours | Core business hours for support |
| Planned maintenance | Outside business hours (with objective of minimal planned outages) |
| MAP-to-MAP response time | 1 working day |
| Priority 1 (MAP unavailable) | Fix within 4 working hours |
| Priority 2 (CP unavailable) | Fix within 1 working day |
| Priority 3 (Service degradation) | Fix within 2 working days |
| Priority 4 (Change requests) | Actioned within 1 working week |

## 9.10 Capacity Planning

MAPs should scale their infrastructure to align with their CP base. The following minimum rate calculation has been agreed by the TAG and applies for CSF v2.0:

**Messages per second** = Total Switchable Asset Base / 1,000

With an **absolute minimum of 2 messages/second**.

### What counts as a Switchable Asset

The **Switchable Asset Base** is the total count of customer services across all of a MAP's CPs that can be switched as part of the **Switching for Business (SforB)** protocol. Two service types are in scope:

- **IAS — Internet Access Service.** Broadband or internet connectivity provided to end customers — e.g. fibre-to-the-premise (FTTP), fibre-to-the-cabinet (FTTC), cable broadband, fixed-wireless access. Defined in the [Switching General Conditions](https://www.ofcom.org.uk/) and reflected in the CSF [Definitions and Terminology](../standalone/definitions.md).
- **NBICS — Number-Based Interpersonal Communications Service.** Voice telephony provided to end customers via an assigned number — e.g. traditional landline, VoIP, hosted business voice. Also covered by the Switching General Conditions.

A "switchable asset" is therefore one IAS line *or* one NBICS line. A single business customer can therefore contribute multiple assets to the count (one IAS + one NBICS = two switchable assets for that customer). The Switchable Asset Base aggregates this across every CP a MAP serves.

This figure is the input to the capacity formula above and to several SLA / governance calculations elsewhere in the CSF.

**Examples**:
- MAP with 5,000 switchable assets: 5,000 / 1,000 = 5 msg/s
- MAP with 20,000 switchable assets: 20,000 / 1,000 = 20 msg/s

MAPs can enhance acceptance rates using hardware acceleration and internal queuing, as SLAs for business switching are significantly longer than the 60-second Switch Match response times required by OTS.

---

<!-- DOCUMENT: part1/10-governance | Part 1 — Framework — 10. Governance -->

---
title: 10. Governance
tags: [Part 1]

---

# 10. Governance

> Connected Services Framework (CSF) — Part 1: Framework — Version 2.0

## 10.1 Standards Landscape

The CSF operates within a multi-layered governance structure. Each layer has its own standards body, documentation, and change control process. The CSF leverages these existing standards rather than duplicating them.

```mermaid
flowchart TB
    subgraph "Industry Standards — External"
        OTA2["OTA2<br/>RCPID Standards<br/>JAM Specification"]
        TOTSCo["TOTSCo<br/>OTS Process & Msg Specs<br/>Transport Delivery Policy<br/>9xxx"]
        GPLB["GPLB-SG<br/>SforB Process Documents<br/>Matching & Valid Specs"]
    end

    subgraph "CSF Standards — TAG"
        CSF["TAG<br/>CSF Framework &<br/>Implementation<br/>Transport Policy 8xxx<br/>Onboarding & Testing"]
    end

    OTA2 -->|"Message format<br/>& addressing"| CSF
    TOTSCo -->|"OTS compatibility<br/>& error codes"| CSF
    GPLB -->|"Business process<br/>& message content"| CSF
```

## 10.2 Standards Bodies

### 10.2.1 OTA2 — Office of the Telecommunications Adjudicator

**Accountable for**:
- RCPID Standards
- JSON Asynchronous Messaging Specification (JAM Spec)

The industry has established RCPIDs and the JAM envelope as standards that MUST be implemented by all current and future transport providers, including TOTSCo and the CSF. These standards enable consistent addressing and routing of messages. The use of specific envelope fields may vary across industry processes (OTS, SforB) but the fields themselves are standardised.

All documentation is published on the [OTA2 website](https://www.offta.org.uk/).

### 10.2.2 TOTSCo — Telecoms One Touch Switching Company

**Accountable for**:
- All OTS-related Message Process and Message Specification documentation
- OTS Best Practice Guidance
- Transport Delivery Policy and Response Codes (9xxx)
- [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf)

The Industry Process Group (IPG) and Operations Group (OG) generate original documentation and proposed changes. All documentation is under change control and published on the [TOTSCo website](https://totsco.org.uk/process-technical-documents/).

### 10.2.3 GPLB-SG — GPLB Steering Group

The **GPLB Steering Group (GPLB-SG)** is an independent body of industry stakeholders working alongside the OTA2. It guides and facilitates the steering meetings and the publication of the Switching for Business (SforB) process documentation via FCS. The group retains the historical "GPLB" label even though the underlying **process** has been renamed from Gaining Provider Led Business switching to **Switching for Business (SforB)** to better describe the protocol.

**Accountable for** (via FCS publication):
- Switching for Business (SforB) Process documentation
- Switching Open Orders specification
- Matching Summary and Validation Process
- **SforB Response Codes** and Asset List Guidance
- Customer Matching Guidance
- Best Practice Guide for Avoidance of Erroneous Transfers
- SLAs

All documentation is under change control from 30 September 2025 and published on the [FCS website](https://www.fcs.org.uk/gaining-provider-led-business-switching/).

### 10.2.4 TAG — Telecom Technical Architecture Group

**Accountable for**:
- Connected Services Framework (CSF) — this documentation
- CSF Transport Delivery Policy and Response Codes (industry 9xxx + CSF 8xxx enhancements)
- Testing and Onboarding of MAP documentation
- Hub Implementation Overview Plan

The TAG maintains autonomy to manage and iterate specific areas of the CSF. All changes to CSF documentation are undertaken by the TAG group, which meets via its steering group call **weekly**.

## 10.3 Change Control

### CSF Documentation

All CSF documentation builds on existing OTS message exchange standards, including directory elements and TOTSCo 9xxx codes, to maintain consistency and avoid misunderstandings. Where additional response codes are required for security and signalling between MAPs and CPs, these are introduced using the **8xxx series**.

Changes to the CSF follow this process:

1. **Proposal**: Any TAG member can propose a change
2. **Review**: The TAG steering group reviews the proposal at its weekly meeting
3. **Consensus**: Changes require consensus among TAG members
4. **Publication**: Approved changes are published and versioned
5. **Adoption**: MAPs adopt changes incrementally through API versioning and feature releases

### Industry Process Documentation

Changes to industry process documents (SforB process, JAM Spec, RCPID standards) follow the change control processes of their respective standards bodies (GPLB-SG, OTA2, TOTSCo). The CSF does not control these processes but references them.

## 10.4 Memorandum of Understanding

The MAPs and CPs that participate in the CSF are bound by a Memorandum of Understanding (MoU). The MoU:

- Makes it simple to join and contribute to the CSF
- Reflects the CSF's nature as an open standard
- Is licence-free for any CP or MAP to use for any purpose
- Outlines the collaborative responsibilities of participants

## 10.5 Decentralised Governance

The CSF deliberately decentralises governance responsibilities:

- **No centralised administrator**: Controls are distributed to CPs and MAPs
- **Self-regulation**: The framework promotes good behaviour and discourages bad behaviour through its design (e.g., DNS-based CP control, PKI verification, directory transparency)
- **Commercial independence**: MAPs and CPs are free to establish their own commercial relationships; the CSF has no impact on these arrangements
- **Cost reduction**: Decentralising basic functions reduces costs for all parties and makes message exchange more transparent

## 10.6 Governance Controls

The governance controls below were ratified by the TAG steering group on **2026-04-29** and form the operational baseline for the CSF's decentralised model. Each control leverages the framework's existing peer-to-peer architecture and the TAG's weekly steering group, without introducing heavy central administration.

### 10.6.1 TAG Decision-Making and Voting

The TAG steering group operates by consensus wherever possible. Where consensus cannot be reached, the following formal procedure applies:

- **Quorum**: A formal vote MUST be attended (in person or by recorded proxy) by at least **60% of currently onboarded MAPs**. A vote held below quorum is invalid and MUST be rescheduled.
- **Voting weight**: **One MAP, one vote**, regardless of MAP size, footprint, or seniority. A MAP that operates as a MAP-of-1 carries the same single vote as a MAP serving many CPs.
- **Voting threshold**: A simple majority of votes cast is sufficient for operational decisions. Specification changes (additions to or breaking changes in the CSF documents) require a supermajority of votes cast.
- **Decision records**: All TAG decisions MUST be recorded with the date, attendees, proposal summary, vote tally, outcome, and dissenting views. These records are accessible to all MoU signatories.
- **Observer status**: Organisations that are not yet MAPs but have a legitimate interest (e.g., prospective MAPs, industry bodies, OTA2, TOTSCo) MAY attend TAG meetings as observers. Observers contribute to discussion but do not count toward quorum and have no voting rights.

### 10.6.2 MAP Compliance and Periodic Review

Onboarding validates a MAP at a point in time, but ongoing compliance must also be assured:

- **Annual self-certification**: Each MAP SHOULD submit an annual self-certification to the TAG confirming continued compliance with the CSF requirements, including PKI key hygiene, SLA adherence, and CP Registry accuracy.
- **Peer review**: The TAG SHOULD establish a lightweight peer review process where MAPs periodically verify each other's CP Registry accuracy, DNS record consistency, and endpoint availability. This can be automated through existing registry collection and DNS verification mechanisms.
- **Evolving exit criteria**: As the TAG updates onboarding entry and exit criteria to reflect new use cases and lessons learned, existing MAPs SHOULD be required to demonstrate compliance with material changes within an agreed adoption window.

### 10.6.3 Version Adoption Policy

API versioning enables incremental change, but without adoption timelines the network could fragment:

- **Minimum support window**: When a new CSF version is released, MAPs MUST continue to support the previous version for **six months** from the release date, to allow all participants to upgrade.
- **Deprecation notice**: The TAG MUST provide at least 3 months' notice before deprecating a CSF version.
- **Adoption tracking**: The TAG SHOULD track which CSF version each MAP supports (visible in the CP Registry) and follow up with MAPs that have not adopted within the agreed window.

### 10.6.4 Dispute Resolution

Disputes between MAPs (e.g., over CP ownership, message delivery failures, or onboarding decisions) need a resolution path that does not require legal action as a first resort:

- **Tier 1 — Direct resolution**: The MAPs involved attempt to resolve the dispute directly using the contact details published in their CP Registries.
- **Tier 2 — TAG mediation**: If direct resolution fails within 5 working days, either party can escalate to the TAG steering group, which will mediate at its next meeting. The TAG may appoint a subset of uninvolved MAPs to review the facts.
- **Tier 3 — Independent adjudication**: If TAG mediation fails, the dispute MUST be referred to an **external, independent body** appointed by the TAG to act as the standing Tier-3 adjudicator for the CSF. The adjudicator's decision is binding on the parties to the dispute. The TAG's **preferred candidate** for this role is the **Office of the Telecommunications Adjudicator (OTA2)** — see [§10.2.1](#1021-ota2--office-of-the-telecommunications-adjudicator) — given its established independence and history of binding industry dispute resolution; the appointment is **subject to formal acceptance** by the candidate body. The TAG will engage the appointed adjudicator directly and provide the case file, supporting evidence, and the result of Tier 1 and Tier 2 attempts. Until an external Tier-3 adjudicator has formally accepted the role, the TAG SHALL document the route used for any Tier-3 case (typically bilaterally-agreed commercial arbitration between the parties) so the audit trail is unaffected.
- **Interim measures**: During any dispute, both MAPs MUST continue to exchange messages normally. A dispute MUST NOT be used as a reason to block or degrade service to CPs.

### 10.6.5 Incident Response Coordination

While each MAP manages its own security, coordinated response to network-wide incidents is essential:

- **Security contact**: Each MAP MUST publish a dedicated security contact in its CP Registry (separate from general support) for reporting vulnerabilities and incidents.
- **Coordinated disclosure**: If a MAP discovers a vulnerability that affects the CSF specification or other MAPs, it MUST notify the TAG within 24 hours. The TAG will coordinate disclosure and remediation across all MAPs.
- **Breach notification**: If a MAP suffers a data breach that could affect CP data or message integrity, it MUST notify all connected MAPs, the TAG, and affected CPs within **72 hours of becoming aware**, in alignment with the wider industry standard set by UK GDPR / Data Protection Act 2018 Article 33 personal-data breach notification. Notifications MUST include the nature of the breach, categories and approximate volume of data affected, the likely consequences, and the mitigations taken or proposed.
- **Post-incident review**: Significant incidents SHOULD trigger a post-incident review at the TAG steering group to identify systemic improvements.

### 10.6.6 MAP Suspension and Removal

The CSF must have a clear, proportionate process for dealing with MAPs that persistently fail to meet their obligations or act maliciously:

- **Warning**: The TAG issues a formal written warning identifying the non-compliance and a remediation deadline (typically 10 working days).
- **Probation**: If the MAP fails to remediate, the TAG may place the MAP on probation. During probation, the MAP's status is flagged in other MAPs' Master Registries, and the MAP loses its voting rights in TAG decisions.
- **Suspension**: For serious or persistent non-compliance, the TAG may vote to suspend a MAP. Suspended MAPs' CPs are treated as if the MAP were in distress — the CP emergency migration process (see [Commercial Scenarios](../part2-implementation/08-commercial-scenarios.md)) applies, and CPs are encouraged to move to another MAP.
- **Removal**: A suspended MAP that does not remediate within 30 days may be permanently removed from the CSF by TAG supermajority vote. The MAP's CP Registries are no longer collected by other MAPs.
- **CP protection**: At every stage, the priority is CP continuity. No enforcement action against a MAP should leave CPs unable to exchange messages for longer than necessary. The CSF's built-in ability to migrate CPs — including their in-flight orders — between MAPs via the RCPID Status export process (see [CP Transitions](../part2-implementation/07-cp-transitions.md)) is an integral safeguard here. Where a MAP is suspended or removed, the TAG SHOULD proactively coordinate with affected CPs and receiving MAPs to ensure that the CP Emergency Migration Process (export inflight orders) is initiated promptly, in-flight order exports are completed before the MAP is taken offline, and CPs are re-established on new MAPs with minimal disruption to end consumers.

### 10.6.7 Anti-Competitive Safeguards

The CSF's open, free-to-use nature must be actively protected:

- **No exclusionary behaviour**: No MAP or group of MAPs may act to exclude a legitimate new entrant from the CSF. Sponsor MAPs MUST NOT unreasonably refuse or delay onboarding.
- **No preferential routing**: MAPs MUST NOT give preferential treatment to their own CPs' messages over messages routed on behalf of other MAPs' CPs.
- **No information misuse**: Information obtained from other MAPs' CP Registries (e.g., CP lists, contact details, switching volumes) MUST NOT be used for competitive advantage, marketing, or customer solicitation.
- **Telemetry collection**: Every MAP MUST collect telemetry data for all messages sent and received **between `ACTIVE`-status MAPs and on behalf of `ACTIVE`-status CPs only**, including: message type (routingID), date/time, source CP (RCPID), destination CP (RCPID), source MAP, destination MAP, and delivery outcome (success, failure code). Messages where either endpoint MAP carries `map.status = TEST` or `SUSPEND`, where either CP carries `processSupport[].status = TEST` or `SUSPEND`, **or where the JAM envelope's `auditData` carries the explicit test marker (`{ "name": "test", "value": "true" }`)** MUST be excluded from telemetry counted toward industry statistics. This ensures that onboarding traffic, bilateral test runs, and post-incident soak testing never pollute reporting or KPIs. Telemetry data MUST be stored securely and handled in accordance with GDPR and the data retention policies agreed by the TAG. Test-flagged messages MAY still be logged separately for audit and onboarding evidence, but MUST be tagged as such and held outside the production telemetry corpus. See [Onboarding & Testing Process §5](../standalone/onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope) for the audit-flag rules and [§4](../standalone/onboarding-testing-process.md#4-status-model-and-json-status-values) for status semantics.
- **Transparency**: The TAG SHOULD publish an annual summary of CSF network activity — including aggregated message volumes by message type, number of active MAPs and CPs, onboarding activity, and delivery success rates — to demonstrate openness and healthy competition. Each MAP MUST contribute its aggregated telemetry to this summary, **drawn solely from production traffic between `ACTIVE` participants** as defined above. Individual CP-level data, message content, or commercially sensitive patterns MUST NOT be disclosed — only aggregated, anonymised statistics are published. Detaile on this will follow in subsequent revisions for options on how telemetry can be collected and shared without revealing sensitive data or breaching GDPR.

### 10.6.8 CP Representation

While the CSF primarily governs MAP-to-MAP interactions, CPs are the ultimate beneficiaries and should have a voice:

- **CP feedback channel**: The TAG SHOULD establish a mechanism for CPs to raise concerns or propose improvements, either directly or through their MAPs.
- **CP rights charter**: The [CP Rights Charter](../standalone/cp-rights-charter.md) is published as a standalone document, written in plain language, so CPs can understand their entitlements without reading the full CSF specification. It is derived from the formal requirements in [Principles & Requirements — CP Right to Move](03-principles-and-requirements.md).

### 10.6.9 Documentation and Transparency

- **Public documentation**: The CSF specification (this documentation) SHOULD be publicly accessible to any interested party, not restricted to MoU signatories. Transparency builds trust and encourages adoption.
- **Change log**: All changes to the CSF specification MUST be recorded in a versioned change log with dates, descriptions, and the TAG meeting reference where each change was agreed.
- **Archived versions**: Previous versions of the CSF specification MUST be retained and accessible so that MAPs running older versions can reference the specification they implemented against.

## 10.7 Supporting Documents

The following documents support the CSF and are maintained separately:

| Document | Version | Maintainer |
|---|---|---|
| MAP Onboarding and Testing | Draft | TAG |
| PKI Overview | Draft | TAG |
| Use-Cases and Examples | Draft | TAG |
| TOTSCo Integration — Implementation Plan | v1.1 | TAG |
| TOTSCo Integration — Overview Slides | v1.0 | TAG |
| JSON Asynchronous Messaging Specification | v1.0 | OTA2 |
| Principles of Use for RCPID | v1.0 | OTA2 |
| [TOTSCo Hub API Specification](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) | v2.0 | TOTSCo |

---

<!-- DOCUMENT: part1/glossary | Part 1 — Framework — Glossary -->

---
title: Glossary
tags: [Part 1]

---

# Glossary

> Connected Services Framework (CSF) — Version 2.0

This glossary defines the abbreviations and terms used throughout the CSF documentation.

## Abbreviations

| Abbreviation | Full Term | Definition |
|---|---|---|
| CP | Communications Provider | An organisation participating in an industry process (e.g., OTS, SforB) that creates or consumes messages and sends or receives them via a MAP. CPs include retailers, wholesalers, and agencies providing services on behalf of other CPs. |
| CSF | Connected Services Framework | A set of open message communication standards that define how MAPs exchange messages securely and efficiently on a peer-to-peer basis, without reliance on a centralised hub. |
| DDG | Detail Design Group | The original industry group that documented the requirements for the technologies and processes of switching residential customers' broadband and voice services (One Touch Switch). |
| DKIM | DomainKeys Identified Mail | A message authentication standard (RFC 6376) that uses PKI to verify the sender's domain identity and ensure that the message has not been altered in transit. The CSF adapts DKIM for HTTP message signing between MAPs. |
| DNS | Domain Name System | The internet system that resolves domain names to IP addresses. In the CSF, DNS TXT records are used to publish CP public keys and MAP associations. |
| GPLB | Gaining Provider Led Business Switching | The original name for the industry **process** for switching business telecommunications services, now branded as Switching for Business (SforB). Ofcom has not mandated a single technical solution for this process. |
| GPLB-SG | GPLB Steering Group | An independent body of industry stakeholders together with the OTA2, that guides and facilitates the steering meetings and publication of the SforB process documentation via FCS. The group retains the historical "GPLB" label even though the process has been renamed to Switching for Business (SforB). |
| HMAP | Hub Managed Access Provider | A specialised MAP type that operates as a hub-and-spoke delivery mechanism (e.g., TOTSCo). An HMAP accepts messages and forwards them among its subscribed members without engaging with the message payload. |
| JAM | JSON Asynchronous Message | The industry-wide messaging standard published on the OTA2 website. JAM defines the envelope format (addressing, routing, correlation) used by all CPs and MAPs regardless of the underlying transport. |
| MAP | Managed Access Provider | An organisation that facilitates message exchange on behalf of CPs by offering integration services, portals, and technical solutions. A CP can become a MAP of 1 (itself) by abiding by MAP rules. |
| MoU | Memorandum of Understanding | The agreement governing collaboration between MAPs and CPs participating in the CSF. |
| OTA2 | Office of the Telecommunications Adjudicator | The industry body accountable for publishing and controlling RCPID Standards and the JSON Asynchronous Messaging Specification. |
| OTS | One Touch Switch | The Ofcom-mandated process for switching residential IAS and NBICS services between consumer CPs. All OTS messages must be routed via the TOTSCo Hub. |
| PKI | Public Key Infrastructure | A framework for managing cryptographic key pairs and digital certificates. In the CSF, PKI is implemented via DKIM (RFC 6376) to sign and verify messages between MAPs. |
| RCPID | Retail Communications Provider Identifier | A unique identifier assigned to a CP brand for the purpose of message exchange. In the CSF, RCPIDs use the UUIDv4 format (RFC 4122) and remain with the CP for life, even when changing MAPs. |
| RFC | Request for Comments | A publication series from organisations such as the IETF that defines internet standards, protocols, and technical specifications. |
| SforB | Switching for Business | The current branding for the GPLB process — the industry process for switching business telecommunications services. |
| TAG | Telecom Technical Architecture Group | A consortium of telecoms industry stakeholders responsible for the development, publication, and change control of the CSF. The TAG meets weekly via its steering group. |
| TLS | Transport Layer Security | A cryptographic protocol providing secure communication over networks. The CSF mandates TLS 1.3 (RFC 8446) for all connections. |
| TOTSCo | Telecoms One Touch Switching Company | The organisation operating the centralised hub for OTS message routing. TOTSCo also publishes OTS process and technical documentation. For SforB, TOTSCo may operate as an HMAP within the CSF. |

## Key Definitions

### CP Registry

A JSON data structure published by each MAP containing detailed information about that MAP, its connected CPs, and their supported processes (including RCPIDs, brand names, PKI signing domains, resource URLs, and contact details). Both the MAP and each individual CP can include a `contact` array using the same structure — the MAP contact is for MAP-to-MAP technical issues, while each CP's contact is for CP-to-CP operational escalations (sales, support, technical). Each MAP publishes its own CP Registry and makes it available to other MAPs via an OAuth 2.0-protected API endpoint. The CP Registry is the outward-facing data that MAPs share with each other.

### Master Registry

The private, consolidated view built by each MAP when it collects and converges all other MAPs' CP Registries. The Master Registry contains the full routing, PKI signing, and contact details for every CP across the entire CSF network. It is held privately by the MAP and used internally for message routing, DKIM signature verification, and CP-to-MAP resolution. Each MAP maintains its own copy of the Master Registry.

### Directory

A filtered, cut-down version of the Master Registry that a MAP shares with its own CPs. The Directory lists the brand names and RCPIDs available to switch with — the information CPs need to populate drop-down lists, search-as-you-type fields, and message addressing. It excludes inter-MAP routing details, PKI signing domains, and other sensitive operational information. When a CP selects a destination from the Directory, the MAP uses the RCPID to look up the full routing and signing details in its private Master Registry.

### Sponsor MAP

An onboarded MAP that is assigned (via round-robin rotation) to guide a new MAP through the onboarding process. The Sponsor MAP validates the new MAP's technical readiness, conducts testing, and acts as a gatekeeper to the CSF network.

### New MAP

An organisation that wishes to join the CSF and begin exchanging messages with other MAPs. A New MAP must complete the sponsored onboarding process before it can publish its registry or exchange production messages.

### Bit pipe

Refers to a network provider that simply moves data without adding value or examining content. The CSF is, by design, a bit pipe for SforB and any other industry processes that use it — it carries the JAM envelope and does not interpret the message body. The full normative definition is in [Definitions](../standalone/definitions.md) §2.3.

### SOR (Switch Order Reference)

A reference number associated with a Switch Order. SORs have a validity period (typically 31 days) and cannot be transferred between MAPs; they must be re-issued. The full definition is in [Definitions](../standalone/definitions.md) §2.6.

### Letterbox

The REST API endpoint used by MAPs to send and receive messages. The letterbox accepts JAM-formatted JSON messages over HTTPS (TLS 1.3) with OAuth 2.0 authentication and returns an HTTP 202 to acknowledge receipt.

### Routing Group

A named collection of routing ID patterns (expressed as regular expressions) that determines which message types are accepted by a specific MAP service endpoint. For example, `businessSwitch.*` for SforB messages or `residentialSwitch.*` for OTS messages.

### Feature Release

A mechanism within the CSF that allows MAPs to adopt new capabilities incrementally without requiring all MAPs to upgrade simultaneously. MAPs advertise their supported feature sets in the registry, enabling automatic negotiation of the highest compatible version between interacting parties.

---

<!-- DOCUMENT: part2/01-getting-started | Part 2 — Implementation — 1. Getting Started -->

---
title: 1. Getting Started
tags: [Part 2]

---

# 1. Getting Started

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 1.1 Purpose

This section provides a practical checklist for MAPs implementing the CSF. Whether you are a new MAP joining the network or an existing MAP adding CSF support, this guide covers the prerequisites and steps to get operational.

## 1.2 Prerequisites

Before beginning implementation, ensure you have:

- [ ] Read [Part 1: Framework](../part1-framework/01-introduction.md) to understand the architecture and principles
- [ ] Reviewed the [JSON Asynchronous Messaging Specification (JAM)](https://www.offta.org.uk/best-practice-guide#:~:text=Switching%20for-,Business,-GPLB%20SG%20Switching) published on the OTA2 website
- [ ] Reviewed the **RCPID Standards** (in the process of being published by OTA2; no direct link available at the time of this publication — check the [OTA2 website](https://www.offta.org.uk/) for the latest)
- [ ] Reviewed the [Switching for Business Process Documents](https://www.fcs.org.uk/gaining-provider-led-business-switching/) published on the FCS website
- [ ] Reviewed the [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) for hub interoperability requirements
- [ ] Identified a Sponsor MAP (or been assigned one via the rotation)
- [ ] Agreed terms and costs with the Sponsor MAP for the onboarding process

## 1.3 Implementation Checklist

### Infrastructure Setup

- [ ] Provision TLS 1.3-capable endpoints for:
  - Letterbox API (message sending/receiving)
  - Directory API (registry publishing)
  - OAuth 2.0 token endpoint
- [ ] Configure OAuth 2.0 authorisation server (Client Credentials flow)
- [ ] Set up PKI key management (generation, storage, rotation)
- [ ] Implement DNS management for CP `_domainkey` and `_mapkey` TXT records

### API Implementation

- [ ] Implement the **Letterbox API** — accepting JAM-formatted JSON messages via HTTP POST, returning HTTP 202 on success (see [Message API](04-message-api.md))
- [ ] Implement the **Directory API** — serving your registry as a JSON document via HTTP GET (see [Directory API](05-directory-api.md))
- [ ] Implement **OAuth 2.0 token endpoint** — issuing access tokens to authenticated MAPs (see [OAuth 2.0 Implementation](02-oauth2-implementation.md))

### Security Implementation

- [ ] Implement **DKIM message signing** for outbound messages (see [PKI & DKIM Signing](03-pki-dkim-signing.md))
- [ ] Implement **DKIM signature verification** for inbound messages
- [ ] Implement **DNS-based CP verification** — validating the `_domainkey` and `_mapkey` records
- [ ] Generate PKI key pairs for each CP (minimum RSA-2048 or Ed25519)

### Directory and Registry

- [ ] Build and publish your **MAP registry** in the specified JSON format
- [ ] Implement **registry collection** — pulling other MAPs' registries via their directory API
- [ ] Implement **directory convergence** — merging collected registries into a unified directory
- [ ] Implement **conflict resolution** — handling CPs that appear in multiple registries

### Message Processing

- [ ] Implement **message validation** — envelope structure, RCPID verification, signing validation
- [ ] Implement **retry logic** with exponential backoff for failed deliveries
- [ ] Implement **asynchronous error handling** using 9xxx (industry) and 8xxx (CSF) error codes
- [ ] Implement **message delivery failure notifications** to the originating CP/MAP

### Operations

- [ ] Set up **monitoring and alerting** for endpoint availability
- [ ] Implement **status reporting** in the registry (incident flags, planned changes)
- [ ] Establish **audit logging** for all message exchanges
- [ ] Implement **rate limiting** and denial-of-service protections

### Onboarding

- [ ] Complete **Sponsor MAP assessment** — technical, security, and compliance review
- [ ] Establish **OAuth 2.0 credentials** with the Sponsor MAP
- [ ] Pass **connectivity testing** with provisional/restricted access
- [ ] Pass **process-level testing** with test CPs
- [ ] Pass **operational validation** — delivery reliability, retry, and SLA compliance
- [ ] Pass **exit criteria** — including hidden unit tests and PKI verification
- [ ] Establish **OAuth 2.0 credentials** with all other MAPs
- [ ] Obtain **full access** approval from Sponsor MAP

### TOTSCo Integration (if applicable to the protocol e.g. SforB)

- [ ] Register CSF endpoints with TOTSCo using existing procedures
- [ ] Configure a **dedicated endpoint for TOTSCo** (separate from CSF MAP endpoint)
- [ ] Ensure TOTSCo can access your **Directory API** using existing OAuth 2.0 credentials
- [ ] Test message exchange with TOTSCo using their existing letterbox interface

> See [TOTSCo Integration](06-totsco-integration.md) for detailed integration guidance.

## 1.4 Recommended Endpoint Structure

While the CSF does not mandate specific URL patterns, the following structure is recommended:

| Endpoint | URL Pattern | Purpose |
|---|---|---|
| OAuth Token | `https://{fqdn}/oauth2/token` | Issue access tokens |
| Directory API | `https://{fqdn}/directory` | Serve MAP registry |
| Letterbox (CSF) | `https://{fqdn}/letterbox/csf/{version}/post` | Receive messages from CSF MAPs |
| Letterbox (Hub) | `https://{fqdn}/letterbox/hub/{version}/post` | Receive messages from HMAPs (e.g., TOTSCo) |
| Service Status | `https://{fqdn}/status` | Operational status page/API |

> **Best Practice**: Maintain separate letterbox endpoints for CSF MAPs and HMAPs (e.g., TOTSCo). This allows the TAG to iterate the CSF rapidly without affecting established hub exchange networks.

## 1.5 Development Resources

| Resource                      | Location                                                                                                  |
| ----------------------------- | --------------------------------------------------------------------------------------------------------- |
| PKI verification testing tool | [CSF Documentation Wiki](https://github.com/nowyoyo/csf-documentation/wiki/Verification-Testing-endpoint) |
| CSF test endpoints            | Available from TAG members for integration testing                                                        |
| Virtual Test Host             | Provided by MAPs for local onboarding testing                                                             |
| Sample code (Java, C#)        | See [PKI & DKIM Signing — Worked Examples](03-pki-dkim-signing.md#38-worked-examples)                        |
| OpenAPI specification         | See `letterbox-openapi.yaml` in the CSF documentation repository                                          |
| TOTSCo Basic Connectivity testing         |    https://totsco.org.uk/business-user-guide/                                     |

---

<!-- DOCUMENT: part2/02-oauth2-implementation | Part 2 — Implementation — 2. OAuth 2.0 Implementation -->

---
title: 2. OAuth 2.0 Implementation
tags: [Part 2]

---

# 2. OAuth 2.0 Implementation

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 2.1 Overview

The CSF uses **OAuth 2.0 Client Credentials flow** for machine-to-machine authentication between MAPs. This is the same approach used by TOTSCo for OTS, ensuring maximum compatibility across the industry.

Each MAP operates as both:
- An **OAuth 2.0 Authorisation Server** — issuing tokens to other MAPs that want to access its endpoints
- An **OAuth 2.0 Client** — requesting tokens from other MAPs to access their endpoints

During onboarding, MAPs exchange `client_id` and `client_secret` credentials with each other.

## 2.2 Access Token Request

To obtain an access token, the requesting MAP sends an HTTP POST to the target MAP's token endpoint.

**Request URL**: `https://{fqdn}/oauth2/token`

The FQDN is obtained from the `oauthTokenURL` field in the target MAP's registry (see [Directory API](05-directory-api.md)).

### Request Headers

| Header | Value | Notes |
|---|---|---|
| `Authorization` | `Basic <Base64(client_id:client_secret)>` | Base64-encoded credentials provided during onboarding |
| `Content-Type` | `application/x-www-form-urlencoded` | Standard OAuth 2.0 form encoding |

### Request Body Parameters

| Field | Type | Required | Description |
|---|---|---|---|
| `grant_type` | String| yes| always `client_credentials` |
| `client_id` | String | Yes | Client identifier provided by the target MAP during onboarding |
| `client_secret` | String | Yes | Client secret provided by the target MAP during onboarding |

Note : A MAP should support `client_id` + `client_secret` in both headers and body as per OAuth 2.0 Standard

## 2.3 Access Token Response

A successful request returns an HTTP 200 with the following JSON body:

```json
{
  "access_token": "{OAuth2 Access Token}",
  "token_type": "bearer",
  "scope": "default",
  "expires_in": 3600
}
```

| Field | Type | Mandatory | Default | Description |
|---|---|---|---|---|
| `access_token` | String | Y | — | The bearer token to include in subsequent API requests |
| `token_type` | String | Y | `bearer` | The type of token issued |
| `scope` | String | N | `default` | The scope of access granted |
| `expires_in` | Integer | Y | `3600` | Token validity in seconds (typically 1 hour) |

## 2.4 Using the Access Token

Include the access token in the `Authorization` header of all API requests:

```
Authorization: Bearer {access_token}
```

The token MUST be validated by the receiving MAP on every request, checking:
- Token signature validity
- Token has not expired
- Issuer matches the expected authorisation server
- Audience/scope is appropriate for the requested resource

## 2.5 Token Lifecycle

- Tokens are **short-lived** (typically 1 hour)
- MAPs SHOULD cache tokens and reuse them until close to expiry
- Client secrets MUST be stored securely (e.g., in environment variables or secret vaults, never in source code)
- Client secrets SHOULD be rotated periodically

## 2.6 Error Responses

The following errors may be returned during token generation:

| HTTP Code | Error | Root Cause |
|---|---|---|
| 400 | Bad Request | Invalid request parameters or missing required fields |
| 401 | Unauthorised | Incorrect client credentials (`client_id` or `client_secret`) |
| 404 | Not Found | Incorrect token generation URL |
| 405 | Method Not Allowed | Incorrect HTTP method (must be POST) |
| 415 | Unsupported Media Type | Missing or incorrect `Content-Type` header |

## 2.7 Security Requirements

| Requirement | Mandatory |
|---|---|
| All token exchanges over TLS 1.3 | Yes |
| Validate token signature, issuer, and audience on every request | Yes |
| Limit token scope and lifetime | Yes |
| Never expose client secrets in frontend code or logs | Yes |
| Store client secrets in secure vaults or environment variables | Yes |
| Rotate client secrets periodically | Recommended |
| Use Proof Key for Code Exchange (PKCE) for public clients | If applicable |

---

<!-- DOCUMENT: part2/03-pki-dkim-signing | Part 2 — Implementation — 3. PKI and DKIM Message Signing -->

---
title: 3. PKI and DKIM Message Signing
tags: [Part 2]

---

# 3. PKI and DKIM Message Signing

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 3.1 Overview

Without a centralised authentication body, the recipient of a message must verify that:

1. The originator is who they claim to be
2. The MAP is authorised to act on behalf of the CP
3. The message has not been altered in transit

The CSF achieves this using **DKIM** [DomainKeys Identified Mail, RFC 6376](https://datatracker.ietf.org/doc/html/rfc6376) — a well-established PKI-based signing standard originally designed for email, adapted here for HTTP message signing between MAPs.

DKIM is ideally suited to a federated network where trust has been established through onboarding, but ongoing verification of the CP/MAP relationship and payload integrity is required.

## 3.2 Public/Private Key Pairs

The CSF uses asymmetric cryptography. Each CP has a **key pair**:

- **Private key**: Held securely by the MAP. Used to sign outbound messages on behalf of the CP.
- **Public key**: Published in the CP's DNS TXT records. Used by receiving MAPs to verify signatures.

If the signature encrypted with a private key can be correctly decrypted with the corresponding public key, the recipient knows the signed payload originated from the holder of that private key.

## 3.3 DNS Records

Every CP registered with a MAP maintains **two DNS TXT records**:

### Domain Key Record

```
[RCPID]._domainkey.[cp-domain]
```

Contains the public key in RFC 6376 format. Example:

```
7d87c2a7-4f64-433c-8ae1-9460f19a0a13._domainkey.supercompany.com
```

**TXT value**: `k=rsa; p=MIIBojANBgkqhkiG9w0BAQE...` (Base64-encoded public key)

### MAP Key Record

```
[RCPID]._mapkey.[cp-domain]
```

Contains the URL of the MAP's message endpoint. Example:

```
7d87c2a7-4f64-433c-8ae1-9460f19a0a13._mapkey.supercompany.com
```

**TXT value**: `https://switching.supermap.com/api/`

### Why Two Records?

- The `_domainkey` record enables signature verification by any receiving MAP
- The `_mapkey` record provides routing verification — the MAP name from the directory could be spoofed, but the DNS record cannot
- Having the RCPID in the domain allows a CP to have **multiple RCPIDs hosted at different MAPs** if required

### CP Responsibilities

The CP only needs to create/update these two DNS records. All remaining processing is performed by the MAPs. During onboarding, the MAP (or CP) generates the key pair, places the public key in the `_domainkey` record, and gives the private key to the MAP.

### MAP Responsibilities

MAPs MUST NOT cache a CP's public key in-process beyond the published DNS TTL — a stale public key honoured after rotation creates exactly the post-revocation forgery risk DKIM/PKI is designed to prevent.

To ensure that the DNS records used to verify CSF messages reflect the live public records as closely as possible, **MAPs SHOULD operate a local DNS server** that mirrors the public DNS entries for `_domainkey` and `_mapkey` records in near-real-time, observing the public TTLs published by each CP. The core standard for locally served DNS zones is **[RFC 6303 — Locally Served DNS Zones](https://datatracker.ietf.org/doc/html/rfc6303)**.

This is a common operational pattern — for example, an authoritative-only recursive resolver pinned to upstream authoritative servers, or a stub resolver bypassing the OS resolver cache. It is widely deployed software and does **not** impose new infrastructure cost on MAPs.

**Why a local DNS server matters in CSF:**

- **Reduced latency.** DNS lookups become near-local rather than going through general internet resolver chains, lowering per-message verification time.
- **Live-or-near-live freshness.** The MAP sees public DNS changes as soon as published TTLs allow, rather than being subject to upstream resolver caches that may serve stale records past the published TTL.
- **No missed CP key rotations or MAP changes.** When a CP rotates its `_domainkey` or updates its `_mapkey` (e.g. during a [MAP change](07-cp-transitions.md)), the MAP picks up the new value at TTL expiry without depending on the behaviour of public recursive resolvers.

**Impact if not implemented.** A MAP that relies on the default OS resolver cache (or any other shared recursive resolver) may:

- **Continue to honour stale `_domainkey` records** — accepting signatures verified against a CP's previous public key after the CP has rotated. This is the primary attack surface for post-revocation key forgery and is **the single largest reason** the local-DNS-server recommendation matters.
- **Route via a stale `_mapkey`** — sending messages or registering counterparties at the CP's previous MAP after the CP has moved. The destination MAP's `9301` reject path eventually corrects this, but only at the cost of delivery latency and false-failure noise on inter-MAP telemetry.
- **Misdiagnose its own DNS-related `8102 TEMP_FAIL` rejections** — opaque upstream-resolver behaviour can make transient DNS lookups look like systemic issues, hampering operational triage and slowing incident response.

MAPs that choose not to operate a local DNS server SHOULD nevertheless document the operational implications they have accepted (the cache TTL of their chosen recursive resolver, their monitoring of stale-data incidents) and SHOULD treat the resulting freshness gap as a known operational risk in their MAP MoU with CPs.

## 3.4 DKIM Signature Process

The signing process follows RFC 6376:

```
body-hash  = hash-alg(canon-body)
data-hash  = hash-alg(h-headers, D-SIG, body-hash)
signature  = sig-alg(d-domain, selector, data-hash)
```

Where:

| Term         | Description                                                          |
|--------------|----------------------------------------------------------------------|
| `body-hash`  | Hash of the message body using the specified algorithm               |
| `hash-alg`   | The hashing algorithm (from the `a` parameter)                       |
| `canon-body` | Canonicalised body using the algorithm in the `c` parameter          |
| `data-hash`  | Hash of headers + DKIM-Signature header + body hash                  |
| `h-headers`  | Headers listed in the `h` parameter, to be included in the signature |
| `D-SIG`      | The DKIM-Signature header without the `b` value                      |
| `signature`  | The final signature value                                            |
| `sig-alg`    | The signing algorithm (from the `a` parameter)                       |
| `d-domain`   | The domain from the `d` parameter                                    |
| `selector`   | The selector from the `s` parameter (always the CP's RCPID)          |

> **Note**: The `l` parameter from RFC 6376 has been removed. While helpful for large emails, it is not relevant for CSF messages that are typically a few hundred KB at most.

## 3.5 CSF HTTP Headers

The CSF uses two HTTP headers for message signing:

| Header                      | Purpose                         | Format                                    |
|-----------------------------|---------------------------------|-------------------------------------------|
| `X-CSF-SIGNATURE-DATESTAMP` | Timestamp of signature creation | `yyyyMMddHHmmssS` (S = tenth of a second) |
| `X-CSF-SIGNATURE`           | The DKIM signature              | See structure below                       |

### X-CSF-SIGNATURE Structure

Example:

```
a=rsa-sha256; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1;
d=gplb-test.nowyoyo.net; bh=/CWGLVBT2gdyO5cudfAEUSF43KHLmlJjU/Nr2YNqkos=;
h=X-CSF-SIGNATURE-DATESTAMP;
b=4J4OGZfxiIetZP8WMMt56+MBqX0W/KdV9pAxzeS4PBC5rjmRtQc9PNMfkd0+...
```

### Mandatory Tags

| Tag  | Description                                                                        |
|------|------------------------------------------------------------------------------------|
| `a`  | Algorithms used for hashing and encryption (e.g., `rsa-sha256`)                    |
| `s`  | Selector — always the CP's RCPID                                                   |
| `c`  | Canonicalisation algorithms — always `simple/simple` for CSF HTTP messages         |
| `d`  | Domain for DNS public key lookup                                                   |
| `h`  | Header fields included in the signature (must include `X-CSF-SIGNATURE-DATESTAMP`) |
| `bh` | Base64 hash of the message body                                                    |
| `b`  | Base64 signature data                                                              |


### Mandatory Tags with Fixed Values

| Tag | Value     | Description                        |
|-----|-----------|------------------------------------|
| `v` | `1`       | DKIM version                       |

### Optional Tags with Fixed Values

| Tag | Value     | Description                        |
|-----|-----------|------------------------------------|
| `q` | `dns/txt` | Method of acquiring the public key |


### DKIM-Signature Canonicalisation

During signature creation and verification, the DKIM-Signature MUST be formatted as:

```
DKIM-Signature: <signature value>
```

> **Important**: Note the exact casing, the colon immediately after the header name, and the single space (ASCII 0x20) after the colon. Any variance will cause valid signatures to fail verification.

## 3.6 Supported Algorithms

### Encryption and Signing

| Algorithm | Hash     | `a` Tag Value    |
|-----------|----------|------------------|
| RSA       | SHA2-256 | `rsa-sha256`     |
| RSA       | SHA2-512 | `rsa-sha512`     |
| Ed25519   | SHA2-256 | `ed25519-sha256` |
| Ed25519   | SHA2-512 | `ed25519-sha512` |

> **Note**: SHA-1 has been removed as it is no longer secure. SHA-3 is not used.

### Key Length Requirements

- **RSA**: Minimum **2048-bit** keys. Verifiers SHOULD reject anything smaller. Avoid RSA-4096 for DKIM unless mandated, due to higher CPU cost and potential DNS/UDP size issues.
- **Ed25519**: Fixed **256-bit** keys only (no size choice). Ed25519 keys are significantly shorter than RSA keys.

### DNS Key Examples

**RSA 2048-bit public key TXT record**:
```
k=rsa; p=MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6/RekuGAsET2Ir8E4K5BU74MBXe
bo7QwrOnSGirtNgRLDcwP2R84Eeum9BLxZtiumUrmO6ja7DrteSZhzOyC09KM3b22zV43bm7nv/FF40+
KpTDQ/FZ32W838UIZGgHOyICk37hlPvnGrVPg7rT6HAKsaj5W0zbvO5vKDUOz2r3bvrWo79YSxtVfGQ1
pHhhZYV2dL1C0uiADbz5L1Cu0qCBjqGJQbYq4ALdaKTnAm2NG/N9W2i3IWJUQIyiTr11qtBrrR8sj2Yh
Yeph6GTsOXggpAWZnEHZz+LKzD4roVqUxkByLWRLB2I5Ju/xPPtTjCDakfvGlsiWl5BMAhn79p0mW6hz
cA4DT7Iz+nSV8K3XMU4rxs0AcaafcBsKREmfbGz4K3ycWHZ/Yrxb+PqYHy7NSK76mHsAjuU8nuKYtZGI
YHwT4friS2R3HtXJ+olLmdZ+XnkpdvEGDb+ZVv/G9vYp020LZQBBd0hp1Ez8a/3F7jRt8xUJ0ljstWjb
q+m3bAgMBAAE=
```

**Ed25519 public key TXT record**:
```
k=ed25519; p=MCowBQYDK2VwAyEAqiCrokPReIFI1h4Jdp7RCRRVQ4Fltdyn429O4H2jYog=
```

### Canonicalisation

The CSF uses `simple/simple` canonicalisation for both headers and body. This is the most straightforward implementation — no post-processing of headers or body content is required.

## 3.7 Public Key Storage

The public key is stored as a DNS TXT record following DKIM standards.

**Domain format**: `[s]._domainkey.[d]`

Where `s` and `d` are the values from the `X-CSF-SIGNATURE` header. The `s` value is always the CP's RCPID.

Example: `809b6e65-a6e7-40f6-8b52-04dd65b6fce1._domainkey.gplb-test.nowyoyo.net`

The CP's RCPID MUST also match an entry in the directory, which defines the valid domain (`d`) for that CP's public key. Any request where `d` does not match the directory entry MUST be rejected.

## 3.8 Worked Examples
What follows are simplistic Low-Level worked examples of the DKIM process for signing and verifying. However, it is possible that developers are able to make use of Higher-Level libraries that already implement the DKIM RFC and remove a lot of the low level implementation.
See [Higher Level Libraries](#384-higher-level-libraries)

### 3.8.1 Java — Creating a Signature

```java
public String createSignature() throws Exception {
  byte[] httpBody = """
      {
        "test_field": "Test Data"
      }""".getBytes();

  String privateKeyPEM = "MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDr9F6S4YCwRPYivwTgrkFTvgwFd5ujtDCs6dIaKu02BEsNzA/ZHzgR66b0EvFm2K6ZSuY7qNrsOu15JmHM7ILT0ozdvbbNXjdubue/8UXjT4qlMND8VnfZbzfxQhkaAc7IgKTfuGU++catU+DutPocAqxqPlbTNu87m8oNQ7Pavdu+tajv1hLG1V8ZDWkeGFlhXZ0vULS6IANvPkvUK7SoIGOoYlBtirgAt1opOcCbY0b831baLchYlRAjKJOvXWq0GutHyyPZiFh6mHoZOw5eCCkBZmcQdnP4srMPiuhWpTGQHItZEsHYjkm7/E8+1OMINqR+8aWyJaXkEwCGfv2nSZbqHNwDgNPsjP6dJXwrdcxTivGzQBxpp9wGwpESZ9sbPgrfJxYdn9ivFv4+pgfLs1IrvqYewCO5Tye4pi1kYhgfBPh+uJLZHce1cn6iUuZ1n5eeSl28QYNv5lW/8b29inTbQtlAEF3SGnUTPxr/cXuNG3zFQnSWOy1aNur6bdsCAwEAAQKCAYANK3PJUfZpDfqbSXIACUVJdcomsfgAAFfpK2HYFH0lZXk7z/tXU2yvP2C4il79G+soB1nVr1exXnaimPMxNtliOt99yljr42UjFJroGlxSwL3e+TefyowE9Fq5EOub5Mk490kzazRMDJ7N4EQBPtOyE0D7ofb5qOGlCU2lRXV5Fd1Uzy1RgsrWN9K+Xd4KWVbbObznmWMXRLIFhd4dNHneGnSzPxavsxrsNr1hVmXNXVuLVB+h0XMS5PHkbHre5vOWwk0x/BpqHtA15sU6tdtWAem1zR8cKDn8D4uVSIU91K6sAqSR34YpJAb79GiEtTFdXCA1IPMyBRHmwF2jiK0UZpbBhuYnLkwcbSMul7xaMlEHMTxZxgMFK765IKtK/cQjENMCcFO9JSRkTMRsnD8pjNU846keyMFUZ1ap2FddUpfNuAV2f9844QNJyF07oly4gmx/+ruzjWjWN+ByUJvB7zEZh/zHcUCgd9+Ixay1F/AD6Dub3mIh/toi2VqOFnkCgcEA7TM/oQu8udZc3M9IWdipJV2iehhPqXAIUqipQnICK780qYRW6UdVSXk1twEAg+VymITOht1ICCzyqKP9KhNLRKfAnZLJkV1zEEJin19gp6YNoPWfaJEwUrpb6WjgvADdPuq+teZ+Hk5G8MoOKkqDt6rlrpdtib1mHTogyKKfjClX+cmwU2AkkcYWm/T/7tO3+aPWWFN+B70PUEf/K5OEfKIPiSGGPg04DWki99M+d+Gnt9OzrbDxC985MkZT43wZAoHBAP6n2PELun2BD2rEqUDV5HBDAewKSYWsyOsfTbvLMa1ALu54h/FQsrPKkgnkpPBGKRaDtgSixcigVvHKb6jm96Zn43pg7uxCq9QpKfg9pUj3orfNvw7GmgEg/J8vW8T6ux3jlhOsY12XegmabOvYHr0/M6zvX1KWtLXig2SZN53eAFCYMbkBrcwnDjgIcai48wasapa0p8mD3xoBOG14+lL2Y/DFHgoF+2l3njISZGBntBc/tgyOa104TqMy8+D4EwKBwQDHpk02RmTRnsaG7MmfJigo1Uk+r1vN6Ah5WpEs5j1BiSzQSh3FOE9nCmjV4jgGzIfKLG6RQYuxpfORUoZydc7yuKf9eWHDwv5ofxf3wRXfxnrOMi+8mggsecOHEMmoNKoEnR1sidc5tvUrE0cc/Z8kZunwLHD8cLiUfSq+9XKJTPtJuiN56gCd2jeJiYwp/3Zo3yg5K/12kgFjt1Xl3cK0DMw6xkbxz7qQPyA5rEp2KS88ISqpVbduILNJx7wwS3ECgcEAzQkZ3CLEWc6zOhTz7bcKAfWBs6oovk97SgxfSyf0bHk0EF/NnNeLusUMRpjo0Gi9JlqQEDV6p+mpd2617rlghoQ5HMy1MlcQAHfQSgZgcVqpkfI/tcbkMqp7nDPGYNg8Fnmq2VZAfxe6c8b5kf7l6RvdII1vI5EiGRwzDKlspVgcysdvqXUXmTuM8EKkOOQJEMN74rG8Mr1RwZ9f7oysiGXH3BDp+coNPkLIhapXVWPKFbn/eyakfV8bub0JrYYvAoHAc0forosmO0gtkBXOo4XJlEd4zZ7IoqEHoVarIodtIlSBDtEXibvKvuEoSlSosvskaUcc2nk3ZJPx2VkRkPt0lad9IY0bQde7mcpiYR4itCaj4Siz0JyKryPBL2lC/PlgkSpLCK92C8MEFrZOhXYnvrng2pP4EWI2s6xIrxi62s2OMyAkXoLcOI4pZKztDRwVs1M+vHuaNQtaRPcA8cf0MUQ5KbcXUixwhbfggN7hASQGYz1+AYaowtDBZATPS6QQ";
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyPEM)));

  MessageDigest digest = MessageDigest.getInstance("SHA256");
  // Get the body hash, using simple canonicalization (2nd part of 'c') as per https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.3
  String bh = Base64.getEncoder().encodeToString(digest.digest(httpBody));
  // bh = IVIj2cQQOAapFmSJl6X0y6dQgKWhYHqQetWe9mWINNQ=

  // Assumes we are using a CP with ID 809b6e65-a6e7-40f6-8b52-04dd65b6fce1 that is hosted on the MAP Nowyoyo.
  String sigTemplate = "a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=" + bh + ";";
  // sigTemplate = a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=IVIj2cQQOAapFmSJl6X0y6dQgKWhYHqQetWe9mWINNQ=;

  // Normally we would parse the 'a' tag to get the correct algorithm, but this is a simple example.
  Signature signature = Signature.getInstance("SHA256withRSA");
  // Initialise with the Private Key
  signature.initSign(privateKey);
  // As we are using simple canonicalization (1st part of 'c'), we add the header value only
  signature.update("202412121340391".getBytes());
  // Each Header must be appended with \r\n as per https://datatracker.ietf.org/doc/html/rfc6376#section-3.7
  signature.update("\r\n".getBytes());
  // Append the signature using simple canonicalization (1st part of 'c') as per https://datatracker.ietf.org/doc/html/rfc6376#section-5.6
  signature.update(("DKIM-Signature: " + sigTemplate+ " b=").getBytes());

  // append the signature to the sigTemplate
  String finalSignature = sigTemplate + " b=" + Base64.getEncoder().encodeToString(signature.sign());
  // finalSignature = a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=IVIj2cQQOAapFmSJl6X0y6dQgKWhYHqQetWe9mWINNQ=; b=rSnlux6S7feBZBEA3wl0X+XA6RfNq8MFnS2nMo0dgEMNmQguNhRIpzuPBTU/BgPmZA57IXF4eMN886rFC5Lo0yy5cuSZpHaVbI5gvf/1hX/SAMJfa2PAipn1/9+yeUj8ajnUYMsO6v1i6bx6LA5Gq+mJEBm4XRwA3Ps3wdgJ1bzTQ7s1L8+/iXci1OqieMdWHvdBi7uncBhpFUQdHVEYZ7zpzDjG59B2i1Z2BGFBEfcTF9FJPfJbJoabUuzT1iZlcW1s18tnZyav/4X3ZTM5YIVGYo355gtiT4YNEmz+mwFN/cOvRkE+X7ukFvNrXOfjNTtfBf2aGWOxMuSFX9UkHi74Vyi5/Snim9Qp1OrKCYRhb+6NaqXev4rbs244t7NTAy0D3WcWxWZN5tf6R8rQ1jm1LklaX2xtr7GaM07mPGRFvGGukT7VSzo1nxD9JDKTiP/C8cA5+kunIFXNrst6xXI+0GYC3QiPZymsbsYEcp06AyOH/QZjUoGO77lAbZKJ

  // The result is then added to the HTTP Request as Header X-CSF-SIGNATURE
  return finalSignature;
}
```

### 3.8.2 Java — Verifying a Signature
In this code section, it is assumed that the Public Key has already been acquired from the DNS entry in the signature and has been verified that it matches the details from the directory
```java
  public boolean verifySignature(PublicKey publicKey, HttpHeaders httpHeaders, byte[] httpBody) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  // Get Signature and Timestamp from header
  String signatureHeader = httpHeaders.getFirst("X-CSF-SIGNATURE");
  // pull out the headers stated in the 'h' tag, they are appended to the signature in the order they appear in 'h'
  // in this simplistic example we already know that there was only 1 field mentioned.
  String timestampHeader = httpHeaders.getFirst("X-CSF-SIGNATURE-DATESTAMP");
  // timestampHeader = 202412121340391

  // get the Base 64 decoded value of the 'b' tag
  byte[] signatureBytes = getSignatureBytes(signatureHeader);
  // get the signature line without the 'b' tag
  String signatureTemplate = unsignedSignature(signatureHeader);
  // signatureTemplate = a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=IVIj2cQQOAapFmSJl6X0y6dQgKWhYHqQetWe9mWINNQ=;

  MessageDigest digest = MessageDigest.getInstance("SHA256");
  // Get the body hash, using simple canonicalization (2nd part of 'c') as per https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.3
  String bh = Base64.getEncoder().encodeToString(digest.digest(httpBody));
  // bh = IVIj2cQQOAapFmSJl6X0y6dQgKWhYHqQetWe9mWINNQ=

  // Check the bh is the same as the bh value in the signature. throw exception if not
  verifyBodyHash(signatureHeader, bh);

  // Normally we would parse the 'a' tag to get the correct algorithm, but this is a simple example.
  Signature signature = Signature.getInstance("SHA256withRSA");
  // Initialise with the public Key for Verification
  signature.initVerify(publicKey);
  // As we are using simple canonicalization (1st part of 'c'), we add the header value only
  signature.update(timestampHeader.getBytes());
  // Each Header must be appended with \r\n as per https://datatracker.ietf.org/doc/html/rfc6376#section-3.7
  signature.update("\r\n".getBytes());


  // Append the signature using simple canonicalization (1st part of 'c') as per https://datatracker.ietf.org/doc/html/rfc6376#section-5.6
  signature.update(("DKIM-Signature: " + signatureTemplate + " b=").getBytes());

  // simple true/ false result
  return signature.verify(signatureBytes);
}
```

### 3.8.3 C# — Complete Sign and Verify Example

```csharp
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using System.Security.Cryptography;

// === SIGNING ===

string csfTimestamp = DateTime.Now.ToString("yyyyMMddHHmmssf");
string cpId = "809b6e65-a6e7-40f6-8b52-04dd65b6fce1";
string hValue = "X-CSF-SIGNATURE-DATESTAMP";

// Parse private key
byte[] privateKeyBytes = Convert.FromBase64String(privateKeyPEM);
AsymmetricKeyParameter privateKey = PrivateKeyFactory.CreateKey(privateKeyBytes);

// Hash the message body
SHA256 sha256 = SHA256.Create();
byte[] messageBytes = System.Text.Encoding.ASCII.GetBytes(GetMessage());
byte[] messageBodyHashBytes = sha256.ComputeHash(messageBytes);
string bh = Convert.ToBase64String(messageBodyHashBytes);

// Build signature template
string signature = $"a=rsa-sha256; q=dns/txt; c=simple/simple; "
    + $"s={cpId}; d=gplb.onetouchgateway.net; v=1; "
    + $"h={hValue}; bh={bh};";

// Organise data to sign
string dataToSign = csfTimestamp + "\r\n" + "DKIM-Signature: " + signature + " b=";

// Sign with RSA private key
ISigner signer = SignerUtilities.GetSigner("SHA256withRSA");
signer.Init(true, privateKey);
signer.BlockUpdate(
    System.Text.Encoding.ASCII.GetBytes(dataToSign), 0, dataToSign.Length
);
byte[] signatureBytes = signer.GenerateSignature();

string csfSignature = signature + " b=" + Convert.ToBase64String(signatureBytes);

// === VERIFICATION ===

// Parse public key
byte[] publicKeyBytes = Convert.FromBase64String(publicKeyString);
AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(publicKeyBytes);

// Get unsigned portion
string unsignedSignature = csfSignature.Substring(0, csfSignature.IndexOf(" b="));

// Verify body hash
byte[] verifyBytes = System.Text.Encoding.ASCII.GetBytes(GetMessage());
string bhVerify = Convert.ToBase64String(sha256.ComputeHash(verifyBytes));
string bhInSig = /* extract bh from signature */;
if (bhInSig != bhVerify) throw new Exception("Hash mismatch!");

// Verify signature
string dataToVerify = csfTimestamp + "\r\n"
    + "DKIM-Signature: " + unsignedSignature + " b=";
ISigner verifier = SignerUtilities.GetSigner("SHA256withRSA");
verifier.Init(false, publicKey);
verifier.BlockUpdate(
    System.Text.Encoding.ASCII.GetBytes(dataToVerify), 0, dataToVerify.Length
);
byte[] sigBytes = Convert.FromBase64String(
    csfSignature.Substring(csfSignature.IndexOf(" b=") + 3)
);
bool isVerified = verifier.VerifySignature(sigBytes);
```

### 3.8.4 Higher-Level Libraries

Developers can use existing DKIM libraries with minor modifications, removing the need for low-level implementation:

- **Java**: [Apache James jDKIM](https://github.com/apache/james-jdkim)
- **.NET**: [MailKit](https://github.com/jstedfast/MailKit)

## 3.9 Error Codes

If a message fails signature verification, the receiving MAP MUST return one of the following error codes in a synchronous response body with **HTTP 403** status:

| Error Code | Meaning                                                                                         | Retry?             |
|------------|-------------------------------------------------------------------------------------------------|--------------------|
| `8101`     | **PERM_FAIL** — The message failed verification. Retrying will not resolve the issue.           | No                 |
| `8102`     | **TEMP_FAIL** — The message failed verification due to a temporary problem (e.g., DNS failure). | Yes (with backoff) |

> An `8102` response suggests a retry may resolve the issue, but does not guarantee it. The CP/MAP MUST have controls in place to handle delivery exceptions. Further details are in the CSF message delivery policy.

### Response Format

```json
{
  "errorText": "<description of the failure>",
  "errorCode": 8101
}
```

### Example Responses

**PERM_FAIL — Invalid domain for CP**:
```json
{
  "errorText": "Domain gplb-test.nowyoyo.net is not valid key source for CP 809b6e65-a6e7-40f6-8b52-04dd65b6fce1",
  "errorCode": 8101
}
```

**PERM_FAIL — Body hash mismatch**:
```json
{
  "errorText": "Body Hash 3hzlA9zA8SAVapmd5ZZnMdwaZpk/WOyQXixrqVu/WMc= is different to signature /CWGLVBT2gdyO5cudfAEUSF43KHLmlJjU/Nr2YNqkos=",
  "errorCode": 8101
}
```

**PERM_FAIL — Missing mandatory tags**:
```json
{
  "errorText": "Signature has missing mandatory tag(s): [b, bh]",
  "errorCode": 8101
}
```

**TEMP_FAIL — DNS resolution failure**:
```json
{
  "errorText": "Unable to resolve 809b6e65-a6e7-40f6-8b52-04dd65b6fce1._domainkey.gplb-test.nowyoyo.net. TXT entry does not exist.",
  "errorCode": 8102
}
```

**TEMP_FAIL — Cannot extract public key**:
```json
{
  "errorText": "Unable to resolve 809b6e65-a6e7-40f6-8b52-04dd65b6fce1._domainkey.gplb-test.nowyoyo.net. Cannot get public key",
  "errorCode": 8102
}
```

## 3.10 Replay Attack Protection

The `X-CSF-SIGNATURE-DATESTAMP` header provides protection against replay attacks. The timestamp is embedded in the encrypted signature and cannot be tampered with independently.

Receiving MAPs SHOULD validate the timestamp based on the message type — rejecting messages with timestamps that are unreasonably old.

## 3.11 Passthrough Headers

If a MAP is passing a message on to a third party (e.g., TOTSCo operating as a SforB HMAP forwarding to its CPs), the `X-CSF-SIGNATURE` header SHOULD be left intact. This provides additional trust that the message has not been tampered with since it left the originating CP.

## 3.12 Route Tracking

`X_CSF_ROUTE` is an optional but recommended HTTP header that records the route a message has taken through the network.

**Format**: `{Epoch milliseconds} {MAP Name}` (alphanumerics only: `[A-Za-z0-9]`)

When a message passes through a MAP, a **new** `X_CSF_ROUTE` header SHOULD be added (not appended to existing headers).

**Examples**:
```
X_CSF_ROUTE: 1741947045684 TheYellowMap
X_CSF_ROUTE: 1741947056789 AnotherMap
```

In most cases there will be a single entry. When a message passes through a forwarding MAP (e.g., TOTSCo), multiple headers will be present, allowing the final destination to diagnose the route taken while still validating (using PKI) that the message came from the originator.

## 3.13 Outbound Conflict Resolution

The DNS records used for message signing also resolve routing conflicts. If a CP appears in more than one MAP directory simultaneously (e.g., during a MAP transition):

1. The sending MAP looks up `[RCPID]._mapkey.[cp-domain]` in DNS
2. The DNS record indicates the correct MAP endpoint
3. The message is routed to the MAP indicated by DNS

It is the CP's responsibility to update their DNS entries and remove outdated records that could result in invalid routing.

> **Note**: CPs having more than one MAP during transition MUST have a new RCPID with the new MAP.

## 3.14 Testing Tool

A verification and testing tool is available for developers implementing PKI signing:

Documentation: [CSF Verification Testing Endpoint](https://github.com/nowyoyo/csf-documentation/wiki/Verification-Testing-endpoint)

---

<!-- DOCUMENT: part2/04-message-api | Part 2 — Implementation — 4. Message API (Letterbox) -->

---
title: 4. Message API (Letterbox)
tags: [Part 2]

---

# 4. Message API (Letterbox)

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 4.1 Overview

The CSF defines a REST API — the **Letterbox API** — for sending and receiving messages between MAPs. This API is compatible with the TOTSCo Hub letterbox interface as defined in the [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf).

The Letterbox API is **synchronous** in its HTTP interaction: when a message is sent, the API replies within the same session. However, the messaging model is **asynchronous** — the HTTP 202 response acknowledges receipt, not processing completion.

## 4.2 API Specification

| Field              | Value                                                                                     |
|--------------------|-------------------------------------------------------------------------------------------|
| API Name           | CSF-LetterboxAPI                                                                          |
| HTTP Method        | POST                                                                                      |
| URI Pattern        | `https://{fqdn}/letterbox/{version}/post`                                                 |
| Transport Security | HTTPS, TLS 1.3                                                                            |
| Authentication     | OAuth 2.0 Bearer Token                                                                    |
| Request Format     | `application/json`                                                                        |
| Request Headers    | `Authorization`, `Accept`, `Content-Type`, `X-CSF-SIGNATURE`, `X-CSF-SIGNATURE-DATESTAMP` |

### URI Elements

| Element   | Description                                                 | Format              |
|-----------|-------------------------------------------------------------|---------------------|
| `fqdn`    | Fully Qualified Domain Name of the MAP's letterbox endpoint | RFC 1035 compliant  |
| `version` | API version number                                          | `n.n` (e.g., `1.0`) |

## 4.3 Message Structure

Every message consists of two parts:

1. **Envelope** — Delivery instructions (source, destination, routing, audit data). Defined by the JAM Specification.
2. **Message Body** — The industry process content (e.g., SforB Switch Match). Defined by the relevant process specification.

The CSF is responsible only for the **envelope**. The message body is opaque to the transport layer unless the MAP provides a hosted solution (portal, matching service) on behalf of its CPs.

### Envelope Example

The following JSON example uses the structure from the JAM Specification. Each `auditData` entry is a `{ "name": "<String>", "value": "<String>" }` pair — both fields are strings and use double-quoted keys consistently. All JSON examples in this document have been audited for that consistency.

```json
{
  "envelope": {
    "source": {
      "type": "RCPID",
      "identity": "d8322d80-92c8-4906-a408-f1d2daf7e03d",
      "correlationID": "XYZ987"
    },
    "destination": {
      "type": "RCPID",
      "identity": "7d87c2a7-4f64-433c-8ae1-9460f19a0a13",
      "correlationID": "ABC123"
    },
    "routingID": "businessSwitchMatchRequest",
    "auditData": [
      {
        "name": "auditFieldName",
        "value": "auditFieldValue"
      }
    ]
  },
  "_messageBody": {
    "_comment": "Process-specific message content goes here"
  }
}
```

### Envelope Elements

| Element                                   | Description                                                                                           | Type   | Required                         |
|-------------------------------------------|-------------------------------------------------------------------------------------------------------|--------|----------------------------------|
| `envelope`                                | Container for delivery information                                                                    | Object | Yes                              |
| `source`                                  | Originator of the message and return address                                                          | Object | Yes                              |
| `destination`                             | Intended recipient of the message                                                                     | Object | Yes                              |
| `source/type`, `destination/type`         | The directory list type (e.g., `RCPID`)                                                               | String | Yes                              |
| `source/identity`, `destination/identity` | The RCPID of the sender/recipient                                                                     | String | Yes                              |
| `source/correlationID`                    | Unique identifier for request correlation. MUST always be provided in source.                         | String | Yes                              |
| `destination/correlationID`               | Present only in response messages — contains the original sender's correlationID                      | String | Yes in Response/Failure messages |
| `routingID`                               | Determines message type and routing. Must be a value supported by the recipient MAP's routing groups. | String | Yes                              |
| `auditData`                               | Name-value pairs for reporting and auditing                                                           | Array  | Optional                         |
| `auditData[]/name`                        | The audit field name                                                                                  | String | Yes (within array)               |
| `auditData[]/value`                       | The audit field value                                                                                 | String | Yes (within array)               |

> **Note**: The actual message body eelement name MUST match the `routingID` (e.g., `businessSwitchMatchRequest`). The `_messageBody` key shown above is illustrative.

### Audit Data Conventions

Two CSF-wide uses for `auditData` shape how the field SHOULD be populated by senders and read by receivers:

- **Test traffic flagging.** Messages originated by, or routed on behalf of, a `TEST`-status CP or `TEST`-status MAP MUST include `{ "name": "test", "value": "true" }`. The receiving MAP MUST preserve this flag end-to-end and MUST exclude such messages from production telemetry. The full rules — including the MAP-overrides-CP behaviour and the per-message exclusion criteria — are defined in [Onboarding & Testing Process §5 — Test Traffic Flagging in the JAM Envelope](../standalone/onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope) and [§5.1 — Telemetry Exclusion](../standalone/onboarding-testing-process.md#51-telemetry-exclusion).
- **Match-session sequencing for telemetry.** A SforB Switch Match journey often spans several `businessSwitchMatchRequest` attempts as the GRCP corrects its data. Session and attempt metadata SHOULD be carried in `auditData` so multi-attempt journeys can be aggregated as a single customer journey when MAPs compute industry KPIs, rather than each attempt inflating the failure rate. The recommended `match*` / `serviceMatch*` / `lrcp*` / `map*` field-name prefixes and the three-layer GRCP/LRCP/MAP scheme are summarised in [Onboarding & Testing Process §5](../standalone/onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope), with the full proposal in [REVIEW.md §6.5 — Match Session Sequencing](../standalone/REVIEW.md#65-match-session-sequencing--auditdata-based-telemetry-proposal).

## 4.4 Successful Response

On successful validation and acceptance, the API returns:

**HTTP 202 Accepted**

> "The request has been accepted for processing, but the processing has not been completed. The request might or might not be eventually acted upon and may be disallowed when processing occurs."

No JSON body is returned on a successful 202 response.

### Validation Performed Before 202

The receiving MAP validates the following:

1. OAuth 2.0 token validity
2. JSON message structure
3. Envelope attribute validity
4. Source type and RCPID validity
5. Source RCPID account status
6. Destination type and RCPID validity
7. Destination RCPID account status
8. **Source MAP authorisation via `_mapkey` DNS verification** — see §4.4.1 below.
9. Routing ID validity
10. DKIM signature verification (via `X-CSF-SIGNATURE`)

The MAP could perform these in any order, but the MAP MUST NOT respond until all checks have passed.

### 4.4.1 Per-Message Source-MAP Verification (Step 8 detailed)

For every inbound message, in addition to the DKIM signature verification defined in [§3.4](03-pki-dkim-signing.md#34-dkim-signature-process), the receiving MAP MUST verify that the originating MAP is the one currently authorised by the source CP in DNS:

1. The receiving MAP MUST resolve `[sourceRCPID]._mapkey.[source-cp-domain]` in DNS, where `sourceRCPID` is taken from `envelope.source.identity` and `source-cp-domain` is the signing domain from the DKIM `d=` tag in the `X-CSF-SIGNATURE` header.
2. The receiving MAP MUST extract the originating MAP's letterbox URL — for direct CSF-MAP-to-CSF-MAP traffic this is the MAP that established the TLS connection and presented the OAuth bearer token; for HMAP-forwarded traffic, it is the first non-HMAP entry in the `X_CSF_ROUTE` header chain (see §4.4.2 below).
3. If the resolved `_mapkey` URL does not match the originating MAP's letterbox URL (compared on host + path, **case-insensitive on host, case-sensitive on path**, trailing-slash-insensitive), the receiving MAP MUST reject the message with HTTP 403 and CSF error code **`9301`** ("DNS `_mapkey` does not resolve to the originating MAP"). The asynchronous delivery-failure record MUST include the resolved `_mapkey` value (for diagnostics).
4. DNS resolutions performed for `_domainkey` ([§3.4](03-pki-dkim-signing.md#34-dkim-signature-process)) and `_mapkey` (this section) MUST honour the published TTL and SHOULD be served from the MAP's local DNS server per [§3.3 — MAP Responsibilities](03-pki-dkim-signing.md#33-dns-records-for-each-cp) (RFC 6303).

> **Note on `9301` scope.** Error code `9301` was previously documented as the reject for `rcpidStatusRequest` authorisation failures only ([§7.2.3](07-cp-transitions.md)). As of CSF v2.x it covers **all** source-MAP authorisation failures, including this per-message verification. Existing §7.2.3 usage is unchanged and is a specialisation of this general rule.

> **Note on TOTSCo response policy.** The `9301` code is a CSF-specific failure. When operating as a Hub MAP (HMAP), TOTSCo does not implement DKIM signing (§3.6) and does not perform this check; CSF MAPs MUST NOT include `9301` in responses sent back to TOTSCo Hub traffic ([§4.6](#46-asynchronous-error-handling--message-delivery-failures)). This is consistent with how CSF 8xxx codes are excluded from TOTSCo responses.

### 4.4.2 HMAP-Forwarded Traffic

When a message arrives from an HMAP (e.g. TOTSCo), the originating MAP for the purposes of §4.4.1 is the **first non-HMAP entry in the `X_CSF_ROUTE` header chain**, not the HMAP itself. HMAPs do not implement DKIM signing (§3.6) and do not appear in any CP's `_mapkey` record — the `_mapkey` check therefore does not apply to the HMAP. It applies only to the underlying CSF MAP that originated the message into the HMAP.

For HMAP-only traffic where no CSF MAP appears in the route (i.e. a message originated entirely within a hub-and-spoke network), §4.4.1 is not enforced; the integrity guarantee for such traffic rests on the HMAP's own commercial controls and existing TOTSCo authentication. The boundary between HMAP-only and CSF-originated traffic is determined by the presence or absence of CSF MAP entries in `X_CSF_ROUTE`.

> **Trust assumption for `X_CSF_ROUTE`.** The chain is treated as trustworthy on the basis of (a) the OAuth-authenticated channel each hop uses and (b) the bilateral trust model between MAPs that have completed onboarding. Signing of `X_CSF_ROUTE` entries by each MAP that appends to the chain is a future enhancement and not required for this clause.

## 4.5 Synchronous Error Responses

### HTTP Error Codes

| HTTP Code | Error                 | Description                                                                   |
|-----------|-----------------------|-------------------------------------------------------------------------------|
| 400       | Bad Request           | Invalid JSON, missing required fields, or validation error                    |
| 401       | Unauthorised          | Authentication failure (invalid OAuth token or API key)                       |
| 403       | Forbidden             | Valid credentials but insufficient authorisation, or PKI verification failure |
| 404       | Not Found             | Requested resource not found                                                  |
| 405       | Method Not Allowed    | HTTP method not supported (e.g., GET instead of POST)                         |
| 429       | Too Many Requests     | Rate limit exceeded                                                           |
| 500       | Internal Server Error | Unexpected processing error                                                   |
| 501       | Not Implemented       | HTTP method not supported by the server                                       |
| 502       | Bad Gateway           | Invalid response from upstream                                                |
| 503       | Service Unavailable   | Temporary maintenance                                                         |
| 504       | Gateway Timeout       | Upstream response timeout                                                     |

### Validation Error Codes (9xxx Series)

These codes are returned in the JSON error response body alongside the appropriate HTTP status code:

| Step | Validation                                     | HTTP Code | Error Code |
|------|------------------------------------------------|-----------|------------|
| 1    | OAuth 2.0 token validation                     | 401       | N/A        |
| 2    | JSON message structure                         | 400       | N/A        |
| 3    | Envelope attribute validation                  | 400       | N/A        |
| 4    | Source type validity                           | 400       | 9002       |
| 5    | Source RCPID validity                          | 400       | 9003       |
| 6    | Source RCPID account status                    | 403       | 9003       |
| 7    | Destination type validity                      | 400       | 9000       |
| 8    | Destination RCPID validity                     | 400       | 9001       |
| 9    | Destination RCPID account status               | 403       | 9001       |
| 10   | Source MAP authorisation via `_mapkey` DNS check (§4.4.1) | 403       | 9301       |
| 11   | Routing ID mapping to source RCP               | 400       | 9010       |
| 12   | Routing ID validity                            | 400       | 9012       |

### PKI Error Codes (8xxx Series)

| Error Code | Meaning                                                                      | Retry? |
|------------|------------------------------------------------------------------------------|--------|
| 8101       | PERM_FAIL — Signature verification failed permanently                        | No     |
| 8102       | TEMP_FAIL — Signature verification failed due to temporary issue (e.g., DNS) | Yes    |

### Synchronous Error Codes (9xxx Series)

| Error Code | Meaning                                                                      |
|------------|------------------------------------------------------------------------------|
| 9000       | Unknown or invalid destination Type. | 
| 9001       | Unknown or invalid destination ID. | 
| 9002       | Unknown or invalid source Type. | 
| 9003       | Unknown or invalid source ID. | 
| 9301       | DNS `_mapkey` does not resolve to the originating MAP — source-MAP authorisation failed (§4.4.1). Also used for `rcpidStatusRequest` authorisation failures ([§7.2.3](07-cp-transitions.md)). Not sent to TOTSCo Hub traffic. | 

### Error Response Format

For validation errors:

```json
{
  "errorCode": "9002",
  "errorText": "Unknown or invalid source Type."
}
```

For HTTP-level errors:

```json
{
  "code": "400",
  "message": "Bad Request",
  "description": "Schema validation failed in the Request: [Path '/directory'] Object has missing required properties ([\"listID\"])"
}
```

The original documentation uses two different error response formats — one with `errorCode`/`errorText` for validation errors (9xxx,8xxx) and another with `code`/`message`/`description` for HTTP errors. Implementers should support both formats.


## 4.6 Asynchronous Error Handling — Message Delivery Failures

When a MAP is unable to deliver a message to its intended recipient, it creates a failure notification message back to the originator using the following format:

```json
{
  "envelope": {
    "source": {
      "type": "RCPID",
      "identity": "MAP-X-IDENTITY"
    },
    "destination": {
      "type": "RCPID",
      "identity": "ORIGINAL-SOURCE-RCPID",
      "correlationID": "ORIGINAL-CORRELATION-ID"
    },
    "routingID": "messageDeliveryFailure",
    "auditData": [
      { "name": "originalDestinationType", "value": "RCPID" },
      { "name": "originalDestination", "value": "DESTINATION-RCPID" },
      { "name": "originalRoutingID", "value": "businessSwitchMatchRequest" },
      { "name": "faultCode", "value": "9008" }
    ]
  },
  "messageDeliveryFailure": {
    "code": "9008",
    "text": "Unable to deliver the message to the destination, timed out.",
    "severity": "failure"
  }
}
```

### Delivery Failure Fields

| Field                    | Description                                                        | Type    |
|--------------------------|--------------------------------------------------------------------|---------|
| `messageDeliveryFailure` | Container for delivery failure details                             | Object  |
| `code`                   | Numeric fault code for remedial action                             | Integer |
| `text`                   | Human-readable description of the fault                            | String  |
| `severity`               | Nature of the notification: `information`, `warning`, or `failure` | String  |

> **Note**: The source does not contain a `correlationID` because delivery failure notifications cannot be replied to. The originator's correlation ID is returned in the destination field.

### Delivery Failure Codes (9xxx Series)

| Code | Description                                                                      | Severity |
|------|----------------------------------------------------------------------------------|----------|
| 9005 | Unable to deliver — no valid route                                               | Failure  |
| 9006 | Unable to deliver — rejected, invalid message format (HTTP 400 from destination) | Failure  |
| 9007 | Recipient rejected message (HTTP 404 from destination)                           | Failure  |
| 9008 | Unable to deliver — timed out (HTTP 5xx or timeout after retries)                | Failure  |
| 9013 | Unable to deliver — invalid API key                                              | Failure  |
| 9014 | Unable to deliver — API key expired                                              | Failure  |
| 9015 | Unable to deliver — digital certificate invalid                                  | Failure  |
| 9016 | Unable to deliver — digital certificate expired                                  | Failure  |

The CSF-specific 8xxx series is complete with `8101` (PERM_FAIL) and `8102` (TEMP_FAIL) — no further CSF 8xxx delivery failure codes are required (agreed by the TAG). When responding to TOTSCo, CSF-specific 8xxx codes MUST NOT be included in the response, since TOTSCo does not recognise them and only the industry-standard 9xxx series applies on that interface.

| Error Code | Meaning                                                                      | Retry? |
|------------|------------------------------------------------------------------------------|--------|
| 8101       | PERM_FAIL — Signature verification failed permanently                        | No     |
| 8102       | TEMP_FAIL — Signature verification failed due to temporary issue (e.g., DNS) | Yes    |

## 4.7 Message Delivery Policy

This section ratifies the CSF's message delivery policy for MAP-to-MAP exchanges. It also marks the boundary at which TOTSCo's hub-side principles (the OTA2 "GPLB Switching for Business Message Delivery Principles") bind on the TOTSCo side — see §4.7.4.

The policy was formalised by the TAG following the comparative analysis against the OTA2 principles document (see the CSF-vs-GPLB-MDP Analysis Report). The architectural framing in §4.7.1 below explains why CSF retains its own P2P delivery policy rather than adopting the GPLB hub schedules wholesale.

### 4.7.1 Architectural framing — synchronous P2P vs hub boundary

The CSF is a **peer-to-peer synchronous** transport. Two MAPs exchange JAM messages directly over TLS 1.3 / OAuth 2.0 / DKIM-signed HTTP. The sending MAP knows the result of its delivery attempt **in the same HTTP exchange**:

- `HTTP 202` confirms the receiving MAP has accepted the message for downstream processing.
- `HTTP 4xx` plus a synchronous `9xxx` industry error code confirms the receiving MAP has rejected it for a documented reason.
- A network / connection / response timeout signals that the receiving MAP is unreachable.

This is materially different from a centralised hub model — where the hub sits between sender and destination and absorbs the delivery asynchrony, queueing, retrying on a per-protocol schedule, ageing stale queue items, and emitting asynchronous failure notifications back to the sender on a separate channel. **CSF MAPs do none of that at the framework layer.** The synchronous response IS the delivery indication for the transport step.

The asymmetry has one important boundary: the **HMAP interface** between a CSF MAP and TOTSCo. TOTSCo is a hub by its own design, so traffic crossing that boundary follows the GPLB Message Delivery Principles on TOTSCo's side. See §4.7.4 below.

### 4.7.2 Required behaviours (CSF MAP-to-MAP)

When a sending MAP attempts to deliver a JAM message to a receiving MAP's letterbox, the following are required:

- **Connection timeout: 1 second.** TCP / TLS handshake to the destination MUST succeed within 1 second or the attempt is treated as a failed delivery and feeds into the retry loop.
- **Response timeout: 3 seconds.** Once connected, the sender waits 3 seconds for `HTTP 202`. If no response is received within 3 seconds, the attempt is treated as a failed delivery and feeds into the retry loop.
- **Retry with exponential backoff and jitter.** See §4.7.5 for the architectural rationale. MAPs MUST NOT use linear or fixed-cadence retry schedules at the CSF P2P boundary.
- **Respect HTTP semantics.** MAPs MUST honour `503 Service Unavailable` and `429 Too Many Requests` with the destination's `Retry-After` header. A `Retry-After` value overrides the sender's normal backoff schedule for that attempt.
- **Circuit-breaker pattern.** MAPs MUST implement a circuit-breaker: after **N consecutive failures** to the same destination (recommended `N = 5`, tunable per MAP), the sender SHOULD stop active retry, fail subsequent messages fast for a recovery period, and raise an operational alert.
- **Bounded maximum retry period.** MAPs MUST NOT "wait forever". The framework recommends a maximum retry window in the order of **hours, not days** — typically 1–4 hours for production traffic. Persistent failure beyond the window triggers the escalation in §4.7.3.
- **All delivery attempts MUST be logged.** Log entries include the destination URL, timestamp, attempt number, outcome, and any synchronous error code returned. Audit retention follows §9 audit-log requirements.

### 4.7.3 Operational-engagement escalation

When a destination MAP fails persistently beyond the sender's retry window, the CSF's primary recovery mechanism is **operational engagement between MAP operations teams** — not silent retry. The procedure:

1. The failing MAP publishes a `map/outage[]` entry in its CP Registry (per §5.4 Field Reference). Every other MAP picks it up on the next directory poll and applies the appropriate downgrade to retry behaviour (see Part 2 §9.3 Outage Notification).
2. The sender raises an internal alert when its retry window is exhausted. The alert records the destination RCPID, the duration of consecutive failure, and the last synchronous error code observed.
3. Operations teams from both sides engage via the published `map/contact[]` channels (phone, email, ticketing URL — see §5.6 CP Contact Object). Contact entries include availability hours, days, and purpose tags so the sender knows which channel is appropriate at the time of the incident.
4. The framework's standard incident response process applies — see [Part 1 §10.6.5 Incident Response Coordination](../part1-framework/10-governance.md#1065-incident-response-coordination).

This sequence is the deliberate replacement for "wait 12 days" hub-side queue ageing. **CSF MAPs do not silently retry for days; they escalate.** A persistent destination failure is a P1 / P2 incident, not a routine retry condition.

### 4.7.4 The HMAP boundary

When a CSF MAP exchanges traffic with TOTSCo via the dedicated HMAP interface, the boundary inherits hub behaviour by definition. TOTSCo is a centralised hub, and the **GPLB Switching for Business Message Delivery Principles V0.2** (OTA2) bind TOTSCo's hub-side delivery to the destination RCP. Specifically:

- The 1 s connection / 3 s response timeouts in §4.7.2 are aligned with the GPLB principles — no asymmetry on those two values.
- TOTSCo applies its own hub-side retry schedules per the GPLB principles — **linear** 5 / 10 / 15 / 20 / 25 s for Match Requests within a **30 s** window; 10 / 20 / 30 / 60 s then a 60 s fixed-cadence tail for other SforB messages within a **12-day** window.
- TOTSCo emits asynchronous failure notifications back to the sender's pre-configured failure endpoint when hub-side delivery fails. The CSF MAP receives those notifications as a standard hub client.
- TOTSCo operates the single-flight-per-endpoint queue and queue ageing on its hub side.

**The HMAP interface is locked down per [§6.3.1](06-totsco-integration.md#631-dedicated-locked-down-hmap-interfaces--both-directions).** CSF version increments — including any future change to §4.7 itself — do **NOT** propagate through the dedicated TOTSCo endpoints. The asymmetric behaviour at the HMAP boundary is stable and bilateral by design, so the GPLB hub schedules do not bleed back into the wider CSF P2P transport.

For the full operating model — including the per-MAP dedicated endpoint pattern, the worked NowYoYo / Red Company bidirectional example, and the locked-down interface architectural commitment — see the standalone [TOTSCo HMAP Integration Guide](../standalone/totsco-hmap-integration-guide.md).

### 4.7.5 Why exponential backoff (and not linear / fixed-cadence retry)

The CSF retains exponential backoff with jitter as its P2P default. The linear and fixed-cadence retry schedules in the OTA2 GPLB Message Delivery Principles (5 / 10 / 15 / 20 / 25 s for Match Requests; 10 / 20 / 30 / 60 s then a 60 s cadence for other messages) are architecturally appropriate for a single centralised hub but **inappropriate** for a distributed P2P network for two distinct reasons:

1. **Linear schedules synchronise retry storms.** When a destination is recovering, many CSF MAPs hitting it at exactly the same intervals creates the "thundering herd" effect that exponential-with-jitter is specifically designed to prevent. Under linear retry pressure, the destination has a synchronised load spike every 5 s (Match) or every 60 s (other) until it falls back over. Under exponential-with-jitter pressure, the load is spread across the recovery window and the destination is far more likely to recover cleanly.

2. **Exponential-with-jitter is the industry-standard distributed-systems pattern.** Every modern cloud SDK (AWS, Google, Microsoft, Cloudflare, etc.) uses this pattern as its default retry policy. The pattern is documented in the SRE literature and is the recommended approach for any service operating across multiple independent clients. The CSF aligns with that practice; the alignment is deliberate, not incidental.

The framework's principle is therefore: **exponential backoff with jitter, bounded by a maximum retry window, with operational escalation taking over beyond that window.** Specific exponential parameters (base, cap, jitter range) are MAP implementation choices; the SHAPE of the curve — geometric growth with randomisation — is required.

#### What exponential backoff with jitter means in practice

- **Exponential backoff**: when a request fails, wait a short period, then exponentially grow the delay between subsequent retries (e.g. 1 s, 2 s, 4 s, 8 s, 16 s, capped at some maximum). This gives the struggling destination time to recover instead of repeatedly hammering it.
- **Jitter**: a random component (typically ±25 %) added to each delay, so independent clients spread their retries across the recovery window rather than aligning on identical intervals.

This is the only retry shape that scales gracefully as the CSF network grows. Linear retries do not.

### 4.7.6 Summary of bindings

| Rule | CSF MAP-to-MAP (P2P) | HMAP boundary (CSF MAP ↔ TOTSCo) |
|---|---|---|
| 1 s connection timeout | MUST | MUST (aligned with GPLB) |
| 3 s response timeout | MUST | MUST (aligned with GPLB) |
| Exponential backoff with jitter | MUST | TOTSCo applies GPLB linear / fixed-cadence schedule on its hub side; CSF MAP applies exponential on its own retries to TOTSCo |
| Respect `Retry-After` on 429 / 503 | MUST | MUST |
| Circuit-breaker | MUST | MUST (CSF MAP side); n/a on hub side |
| Maximum retry period | MUST be bounded (hours) | TOTSCo applies the GPLB 30 s Match / 12-day other-message holds |
| Failure notification to sender | Synchronous — `9xxx` / `8xxx` in the original response | Asynchronous from TOTSCo when hub-side delivery fails; CSF MAP consumes as a standard hub client |
| Operational escalation via `map/contact[]` / `map/outage[]` | Primary recovery mechanism beyond the retry window | Applies on the CSF MAP side; TOTSCo follows its own incident process |
| Logging of every delivery attempt | MUST | MUST |

For test cases that exercise these behaviours, see [Onboarding & Testing Process §8.7 Retry & Delivery Policy](../standalone/onboarding-testing-process.md#87-retry--delivery-policy).

---

<!-- DOCUMENT: part2/05-directory-api | Part 2 — Implementation — 5. CP Registry API -->

---
title: 5. CP Registry API
tags: [Part 2]

---

# 5. CP Registry API

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 5.1 Overview

Each MAP publishes a **CP Registry** — a JSON document containing everything another MAP needs to know about the publishing MAP and its connected CPs. Other MAPs collect these CP Registries via a REST API endpoint and converge them into a private **Master Registry**. From the Master Registry, each MAP derives a filtered **Directory** for its own CPs.

> **Design intent — superset of TOTSCo's directory.** The CSF CP Registry is **deliberately a strict superset of the TOTSCo OTS/GPLB directory structure** so that TOTSCo (and any party that already consumes the TOTSCo directory) can ingest the CSF Registry with its existing parser. CSF-specific additions — `signing[]`, expanded `resource[]`, `contact[]`, `outage[]`, and the routing-group metadata in §5.4.1 — are additive. Parsers that don't recognise these fields ignore them; the underlying TOTSCo-compatible shape is unchanged. This was an explicit design decision intended to make industry-wide consumption trivial through the JSON contract.

### 5.1.1 Side-by-side — TOTSCo vs CSF registry shape

**TOTSCo format (OTS / GPLB today):**

```json
"list": [
    {
        "listType": "RCPID",
        "identity": [
            {
                "id": "RTLL",
                "name": "NowYoYo",
                "processSupport": [
                    {
                        "process": "OTS",
                        "status": "ACTIVE"
                    }
                ],
                "resource": [
                    {
                        "name": "salesAssistURL",
                        "type": "URL",
                        "value": "https://nowyoyo.com/ots/sales-assistance/"
                    },
                    {
                        "name": "customerAssistURL",
                        "type": "URL",
                        "value": "https://nowyoyo.com/ots/customer-assistance/"
                    }
                ]
            }
        ]
    }
]
```

**CSF format (superset — extra fields are additive, never breaking):**

```json
"list": [
    {
        "identity": [
            {
                "id": "c42569a5-d0ed-46f7-b9df-4ea0ba6a29c8",
                "name": "Red Company ISP",
                "processSupport": [
                    {
                        "process": "GPLB",
                        "status": "ACTIVE"
                    }
                ],
                "resource": [
                    {
                        "name": "customerAssistURL",
                        "type": "URL",
                        "value": "https://gplb.red-company.com/customerAssistURL.html"
                    }
                ],
                "signing": [
                    {
                        "domain": "gplb-test.nowyoyo.net",
                        "routingID": [
                            "businessSwitch.*"
                        ]
                    }
                ]
            }
        ]
    }
]
```

> The `id` is wider in the CSF (UUIDv4 instead of 4-character) but both are valid `string` values under the JAM Specification (up to 256 characters). The `signing[]` block is CSF-only; TOTSCo can ignore it. CSF MAPs publish the same `processSupport[].process` values (`OTS`, `GPLB`) that TOTSCo already uses, so process-based filtering is identical on both sides.

### 5.1.2 Dual-process filtering — same URL pattern across both networks

TOTSCo's pre-production Directory v2 already combines OTS and GPLB entries in one list, distinguishing them by `processSupport[].process`. MAPs that want a single-process view filter on an `identity` query parameter:

```
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=all
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=ots
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=gplb
```

We assume the same filter pattern in production. The CSF's Master Registry follows the same convention — `processSupport[].process` carries `OTS`, `GPLB`, and future process tags — so any TOTSCo-side filtering logic carries over unchanged when consuming a CSF CP Registry.

## 5.2 API Specification

| Field              | Value                                                  |
|--------------------|--------------------------------------------------------|
| HTTP Method        | GET                                                    |
| Authentication     | OAuth 2.0 Bearer Token (same credentials as messaging) |
| Response Format    | `application/json`                                     |
| Transport Security | HTTPS, TLS 1.3                                         |

## 5.3 Registry JSON Structure

The registry has two main sections: `map` (MAP metadata) and `list` (CP directory entries).

### Complete Example

```json
{
  "map": {
    "name": "myMap",
    "version": "2024-01-01T13:45:24Z00000",
    "registrationURI": "https://apply.mymapdomain.com/register",
    "serviceStatusURI": "https://status.mymapdomain.com/myStatus",
    "serviceStatusServiceURI": "https://status.mymapdomain.com/myStatusAPI",
    "contact": [
      {
        "type": "phone",
        "value": "01111 111111",
        "purpose": ["support", "sales"],
        "availabilityFrom": "09:00",
        "availabilityTo": "17:00",
        "availabilityDays": ["monday", "tuesday", "wednesday", "thursday", "friday"],
        "comment": "Use for all support calls. Support hours 9am to 5pm."
      },
      {
        "type": "email",
        "value": "support@myMapDomain.com"
      },
      {
        "type": "url",
        "value": "https://support.mymapdomain.com/support"
      }
    ],
    "connectivity": {
      "directory": {
        "url": "https://api.mymapdomain.com/directory",
        "oauthTokenURL": "https://api.mymapdomain.com/token"
      },
      "services": [
        {
          "description": "Endpoint for OTS messages",
          "service": "messaging",
          "url": "https://api.mymapdomain.com/letterboxOTS",
          "oauthTokenURL": "https://api.mymapdomain.com/token",
          "routingGroups": ["OTSMessages"]
        },
        {
          "description": "Endpoint for SforB (GPLB) messages",
          "service": "messaging",
          "url": "https://api.mymapdomain.com/letterboxGPLB",
          "oauthTokenURL": "https://api.mymapdomain.com/token",
          "routingGroups": ["GPLBMessages"]
        }
      ]
    },
    "routingGroups": [
      {
        "name": "OTSMessages",
        "routingID": ["residentialSwitch.*"]
      },
      {
        "name": "GPLBMessages",
        "routingID": ["businessSwitch.*"]
      }
    ],
    "connections": [
      {
        "name": "MAP1",
        "registrationURI": "https://apply.map1.com/register"
      },
      {
        "name": "MAP2",
        "registrationURI": "https://apply.map2.com/register"
      }
    ],
    "sponsorship": {
      "order": 3,
      "nextSponsor": 4,
      "nextSponsorUpdated": "2026-06-09T10:00:00Z",
      "capacity": 2,
      "registrationURI": "https://apply.mymapdomain.com/become-a-map",
      "active": [
        {
          "id": "a3f91c2d-7e4b-4f8a-b1c2-9d3e5f6a7b8c",
          "type": "traditional",
          "opened": "2026-06-09T10:00:00Z",
          "candidateRef": "ONB-2026-0042"
        }
      ]
    }
  },
  "list": [
    {
      "listType": "RCPID",
      "identity": [
        {
          "id": "d8322d80-92c8-4906-a408-f1d2daf7e03d",
          "name": "Xenon Telecom",
          "processSupport": [
            { "process": "OTS_Porting", "status": "Active" },
            { "process": "GPLB", "status": "Active" }
          ],
          "resource": [
            { "name": "customerAssistURL", "type": "URL", "value": "https://xenon.com/SforB" },
            { "name": "salesAssistURL", "type": "URL", "value": "https://xenon.com/sales" }
          ],
          "signing": [
            {
              "domain": "ots.xenon.com",
              "routingID": ["residentialSwitch.*"]
            },
            {
              "domain": "gplb.xenon.com",
              "routingID": ["businessSwitch.*", "notification"]
            }
          ],
          "contact": [
            {
              "type": "phone",
              "value": "020 7946 0123",
              "purpose": ["sales"],
              "availabilityFrom": "09:00",
              "availabilityTo": "17:00",
              "availabilityDays": ["monday", "tuesday", "wednesday", "thursday", "friday"],
              "comment": "Sales team available weekdays 9am-5pm"
            },
            {
              "type": "email",
              "value": "switching-support@xenon.com",
              "purpose": ["support", "technical"],
              "comment": "24/7 email support — response within core business hours"
            },
            {
              "type": "url",
              "value": "https://xenon.com/switching-support",
              "purpose": ["support"],
              "comment": "Online ticketing system for switch query resolution"
            }
          ]
        }
      ]
    }
  ]
}
```


TOTSCo maps the CSF Source UUIDv4 values to their own pseudo-created 4-digit character equivalents, which can be done transparently with its own managed clients.  The CSF network does not need to know what these 4-digit characters are. When TOTSCo sends a message to the CSF, they will translate their own Source 4-digit RCPID to the required CSF UUIDv4 RCPID before routing the message using the Master CSF directory that they have compiled.

### MAP in TEST Mode — Onboarding Example

When a new MAP is undergoing onboarding, its registry SHOULD include `map.status` set to `TEST`. Receiving MAPs MUST treat every CP under that MAP as test, regardless of the per-CP `processSupport[].status`, and exclude those CPs from the CP-facing Directory until the MAP transitions to `ACTIVE`. See [Onboarding & Testing Process §4.2](../standalone/onboarding-testing-process.md#42-per-map-status-cp-registry--mapstatus-optional).

```json
{
  "map": {
    "name": "newMap",
    "status": "TEST",
    "version": "2026-04-29T10:30:00Z00000",
    "registrationURI": "https://apply.newmapdomain.com/register",
    "...": "remainder of map object as per the main example"
  },
  "list": [ "..." ]
}
```

> :memo: **Note**: `map.status` is optional. If absent, the MAP is treated as `ACTIVE`. The valid values are `ACTIVE`, `TEST`, and `SUSPEND`.


## 5.4 MAP Section — Field Reference

| JSON Path | Description | Type | Required |
|---|---|---|---|
| `map` | Container for MAP metadata | Object | Yes |
| `map/name` | MAP name | String | Yes |
| `map/status` | MAP-level operational status: `ACTIVE`, `TEST`, `SUSPEND`. If absent, treated as `ACTIVE`. When set to `TEST`, all CPs under this MAP are treated as test regardless of their own per-CP `processSupport[].status`. See [Onboarding & Testing Process §4.2](../standalone/onboarding-testing-process.md#42-per-map-status-cp-registry--mapstatus-optional). | String (enum) | Optional |
| `map/version` | Last updated timestamp. Used to determine if local cached values need changing| DateTime (`yyyy-MM-ddTHH:mm:ssZSSSSS`) | Yes |
| `map/registrationURI` | URI for CP/MAP registration | String | Optional |
| `map/serviceStatusURI` | URI for operational status page | String | Optional |
| `map/serviceStatusServiceURI` | API URI for programmatic status checks | String | Optional |
| `map/contact[]` | Contact methods for the MAP | Object Array | Yes |
| `map/contact[]/type` | Contact type: `phone`, `email`, `url` | String (enum) | Yes |
| `map/contact[]/value` | Contact value (number, address, or URL) | String | Yes |
| `map/contact[]/purpose[]` | What the contact is for: `support`, `sales`, `technical` | String Array | Optional |
| `map/contact[]/availabilityFrom` | Availability start time | Time (`HH:mm`) | Optional |
| `map/contact[]/availabilityTo` | Availability end time | Time (`HH:mm`) | Optional |
| `map/contact[]/availabilityDays[]` | Days available | String Array (day names) | Optional |
| `map/contact[]/comment` | Usage notes | String | Optional |
| `map/outage[]` | Array of current outage or planned maintenance entries. An empty array or absent field signals GREEN — no reported issues. MAPs implementing outage notification SHOULD always include this field, even as an empty array. See [§9.4 Outage Notification](09-operations.md#94-outage-notification). | Object Array | Yes (empty if no issues) |
| `map/outage[]/priority` | ITIL incident priority: `P1` (MAP unavailable — fix within 4 working hours), `P2` (CP unavailable — fix within 1 working day), `P3` (service degradation — fix within 2 working days). Primary severity indicator; replaces traffic light model. See [§9.4.2](09-operations.md#942-incident-priority). | String (enum) | Yes |
| `map/outage[]/type` | Outage type: `PLANNED` or `INCIDENT` | String (enum) | Yes |
| `map/outage[]/start` | Start time of the outage or maintenance window (ISO 8601 UTC) | DateTime | Yes |
| `map/outage[]/end` | Expected or actual end time (ISO 8601 UTC). Omit for active incidents where resolution time is unknown. | DateTime | Optional |
| `map/outage[]/affectedServices` | Routing group names (matching `map/routingGroups[]/name`) affected by this entry. If absent or empty, all services are considered affected. | String Array | Optional |
| `map/outage[]/description` | Human-readable status narrative: what is affected, current status, ETA (if known), and any workaround. Updated as the incident evolves. | String | Yes |
| `map/outage[]/contact` | Escalation contact specific to this outage. Uses the same structure as a `map/contact[]` entry. | Object | Optional |
| `map/outage[]/contact/type` | Contact type: `phone`, `email`, or `url` | String (enum) | Yes (if contact present) |
| `map/outage[]/contact/value` | Contact value (number, address, or URL) | String | Yes (if contact present) |
| `map/outage[]/contact/comment` | Usage instructions — e.g. reference numbers, bridge PINs, or when to use this contact | String | Optional |
| `map/connectivity` | Connection details | Object | Yes |
| `map/connectivity/directory/url` | Directory API endpoint | String | Yes |
| `map/connectivity/directory/oauthTokenURL` | OAuth token endpoint for directory access | String | Yes |
| `map/connectivity/services[]` | Service endpoints | Object Array | Yes |
| `map/connectivity/services[]/description` | Human-readable description | String | Yes |
| `map/connectivity/services[]/service` | Service type (e.g., `messaging`) | String | Yes |
| `map/connectivity/services[]/url` | Service endpoint URL | String | Yes |
| `map/connectivity/services[]/oauthTokenURL` | OAuth token endpoint for this service | String | Yes |
| `map/connectivity/services[]/routingGroups[]` | Routing groups served by this endpoint | String Array | Yes |
| `map/connectivity/services[]/relay` | Whether this endpoint supports message relay | Boolean | Yes |
| `map/routingGroups[]` | Routing group definitions | Object Array | Yes |
| `map/routingGroups[]/name` | Routing group name (matches service routing groups) | String | Yes |
| `map/routingGroups[]/routingID[]` | Accepted routing ID patterns (regex) | String Array | Yes |
| `map/connections[]` | Other MAPs this MAP has connectivity with | Object Array | Yes |
| `map/connections[]/name` | Name of the connected MAP | String | Yes |
| `map/connections[]/registrationURI` | Registration URI of the connected MAP | String | Yes |
| `map/sponsorship` | Sponsor rotation metadata for the decentralised onboarding of new MAPs. See §5.4.2 for the rotation rules and the [Onboarding & Testing Process §3.4](../standalone/onboarding-testing-process.md#34-sponsor-map-via-the-cp-registry) for the full mechanism. | Object | Yes |
| `map/sponsorship/order` | This MAP's permanent FIFO position in the rotation. Assigned at onboarding; **never changes** — preserved for historical audit consistency even when the MAP withdraws or its `map/status` becomes non-`ACTIVE`. The rotation skips entries whose `map/status` is not `ACTIVE`. | Integer | Yes |
| `map/sponsorship/nextSponsor` | The `order` number of the MAP designated as the **next** Sponsor after this MAP. Updated when this MAP accepts a new sponsorship engagement. | Integer | Yes |
| `map/sponsorship/nextSponsorUpdated` | Timestamp when `nextSponsor` was last updated (ISO 8601 UTC). The MAP with the most recent `nextSponsorUpdated` is the current active Sponsor. | DateTime | Yes |
| `map/sponsorship/capacity` | Maximum concurrent sponsorships this MAP will accept. **Minimum: `1`; no upper bound** — set to reflect the MAP's own operational throughput. A MAP that primarily takes `single-cp` (MAP-of-1) engagements MAY support a higher `capacity` because those complete faster than traditional multi-CP onboardings. | Integer | Yes |
| `map/sponsorship/registrationURI` | URI advertising the Sponsor MAP's onboarding application page for prospective MAPs (self-service portal, contracted form, or structured registration endpoint). Omitted if the MAP uses non-electronic registration (email, telephone, ticketing); prospective MAPs then use the MAP's `map/contact[]` entries as the contact channel. | URI | Optional |
| `map/sponsorship/active[]` | Array of currently open sponsorship engagements. Empty array when idle. | Object Array | Yes |
| `map/sponsorship/active[]/id` | UUIDv4 identifier for this engagement, generated by the Sponsor MAP on acceptance. | String (UUID) | Yes |
| `map/sponsorship/active[]/type` | Type of candidate: `traditional` (multi-CP MAP) or `single-cp` (MAP onboarding with a single CP, e.g. a MAP-of-1 migrating from TOTSCo SforB per [Part 1 §7.4](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration)). Both types count as **`1`** against the MAP's `capacity`. | String (enum) | Yes |
| `map/sponsorship/active[]/opened` | Timestamp when the Sponsor MAP accepted the engagement (ISO 8601 UTC). | DateTime | Yes |
| `map/sponsorship/active[]/candidateRef` | Non-identifying reference assigned by the Sponsor MAP for its own coordination — for example a ticket number from the Sponsor's internal onboarding system when handling several concurrent engagements. Free-form string; not standardised across MAPs; consumers outside the issuing MAP MUST NOT rely on its semantics. | String | Optional |


### 5.4.1 Routing Groups
In the MAP section the `routingGroups` in conjunction with `connectivity/services[]` are used to determine where to send a message.
In this snippet of the MAP object, there are 3 routing groups:

```json
[
  {
    "name": "OTSMessages",
    "routingID": [
      "resi.*"
    ]
  },
  {
    "name": "GPLBMessages",
    "routingID": [
      "businessSwitch.*"
    ]
  },
  {
    "name": "FutureMessages",
    "routingID": [
      "futureThing.*"
    ]
  }
]
```
The `routingID` is a standard regex pattern that is matched against the `routingID` in the envelope of the message to be sent. The sender uses this to determine the `name` of
the correct routing group. So a message with a routing ID of `futureThingActivateRequest` will match with the `FutureMessages` routing group.

This routing group `name` is then matched against the array `connectivity/services[]`, specifically the `routingGroups[]` array.

Below is a snippet of the `connectivity/services[]` MAP object:

```json
[
  {
    "description": "Endpoint for OTS messages",
    "service": "messaging",
    "url": "https://api.mymapdomain.com/letterboxOTS",
    "oauthTokenURL": "https://api.mymapdomain.com/token",
    "routingGroups": [
      "OTSMessages"
    ]
  },
  {
    "description": "Endpoint for Other messages",
    "service": "messaging",
    "url": "https://api.mymapdomain.com/letterbox",
    "oauthTokenURL": "https://api.mymapdomain.com/token",
    "routingGroups": [
      "GPLBMessages", "FutureMessages"
    ]
  }
]
```
By using the `name` calculated in the previous step, `FutureMessages` is matched against and resolves to the `Endpoint for Other messages`. 
This contains a Auth and Message URL allowing the message to sent to the MAP in question.

This is a simple example of how routing groups can be used to determine where to send a message. Some MAPs may use the same endpoints for all messages, 
while others may a different endpoint for each message type. It provides maximum flexibility.

### 5.4.2 Sponsorship Object — Rotation Rules

The `sponsorship` object enables MAPs to coordinate a fair, decentralised rotation for onboarding new MAPs onto the CSF. The detailed mechanism (acceptance-advance, chain-walk overflow, edge-case handling, worked examples) is set out in the [Onboarding & Testing Process §3.4](../standalone/onboarding-testing-process.md#34-sponsor-map-via-the-cp-registry). This section sets out the rules that bind every MAP's implementation of the `sponsorship` object.

| Rule | Statement |
|---|---|
| **Capacity bounds** | The minimum permitted `capacity` is **1** — every onboarded MAP MUST be willing to take at least one engagement at a time. There is **no upper bound** on `capacity`; a MAP sets the value to reflect its own operational throughput. A MAP that primarily takes `single-cp` (MAP-of-1) engagements MAY support a higher `capacity` because those engagements complete faster than traditional multi-CP onboardings. |
| **Engagement weighting** | A `traditional` engagement and a `single-cp` engagement each count as **`1`** against the MAP's `capacity`. No reduced weighting is applied to `single-cp`. The equal-weighting rule protects small MAPs operating at `capacity: 1`: such a MAP is not expected to take additional engagements simply because some are MAP-of-1s. |
| **`order` persistence** | A MAP's `order` is permanent. When a MAP withdraws or its `map/status` becomes non-`ACTIVE`, its `order` is **retained for historical audit consistency** and is not reassigned. The rotation skips entries whose `map/status` is not `ACTIVE`. |
| **Designated-position hold time** | There is **no maximum hold time** on the designated-sponsor position. A designated MAP that receives no candidate remains designated until a candidate arrives. The rotation is event-driven — advance occurs on acceptance — so an idle period has no operational cost and no fairness implication. |
| **`candidateRef`** | `active[]/candidateRef` is **OPTIONAL**. When present, it carries a non-identifying reference assigned by the Sponsor MAP for its own coordination — for example a ticket number from the Sponsor's internal onboarding system. The field is free-form and is not standardised across MAPs; consumers outside the issuing MAP MUST NOT rely on its semantics. |
| **`sponsorship.registrationURI`** | `sponsorship.registrationURI` is **OPTIONAL**. When present, it advertises the Sponsor MAP's own onboarding application page (self-service portal, contracted form, or structured registration endpoint), enabling prospective MAPs and the TAG-published sponsor-registration page to deep-link into that MAP's onboarding flow. A MAP that uses non-electronic registration (email, telephone, ticketing) omits the field; prospective MAPs then use the MAP's `map/contact[]` entries as the contact channel. |

## 5.5 Directory Section — Field Reference

| JSON Path                                        | Description                                                     | Type                     | Required |
|--------------------------------------------------|-----------------------------------------------------------------|--------------------------|----------|
| `list[]`                                         | Array of directory lists                                        | Object Array             | Yes      |
| `list[]/listType`                                | List type (currently only `RCPID`)                              | String                   | Yes      |
| `list[]/identity[]`                              | Array of CP identity objects                                    | Object Array             | Yes      |
| `list[]/identity[]/id`                           | Unique RCPID (UUIDv4)                                           | String                   | Yes      |
| `list[]/identity[]/name`                         | Full brand name                                                 | String                   | Yes      |
| `list[]/identity[]/processSupport[]`             | Supported industry processes                                    | Object Array             | Yes      |
| `list[]/identity[]/processSupport[]/process`     | Process name: `OTS`, `GPLB`                                     | String                   | Yes      |
| `list[]/identity[]/processSupport[]/status`      | Status: `ACTIVE`, `SUSPEND`, `TEST`                             | String                   | Yes      |
| `list[]/identity[]/resource[]`                   | CP resources (URLs, contacts)                                   | Object Array             | Yes      |
| `list[]/identity[]/resource[]/name`              | Resource name (e.g., `customerAssistURL`)                       | String                   | Yes      |
| `list[]/identity[]/resource[]/type`              | Resource type: `url`, `email`, `phone`                          | String                   | Yes      |
| `list[]/identity[]/resource[]/value`             | Resource value                                                  | String                   | Yes      |
| `list[]/identity[]/signing[]`                    | PKI signing configuration                                       | Object Array             | Yes      |
| `list[]/identity[]/signing[]/domain`             | Root domain for public key lookup                               | String                   | Yes      |
| `list[]/identity[]/signing[]/routingID[]`        | Routing IDs signed with this domain (regex)                     | String Array             | Yes      |
| `list[]/identity[]/contact[]`                    | Contact methods for this CP (same structure as `map/contact[]`) | Object Array             | Optional |
| `list[]/identity[]/contact[]/type`               | Contact type: `phone`, `email`, `url`                           | String (enum)            | Yes      |
| `list[]/identity[]/contact[]/value`              | Contact value (number, address, or URL)                         | String                   | Yes      |
| `list[]/identity[]/contact[]/purpose[]`          | What the contact is for: `support`, `sales`, `technical`        | String Array             | Optional |
| `list[]/identity[]/contact[]/availabilityFrom`   | Availability start time                                         | Time (`HH:mm`)           | Optional |
| `list[]/identity[]/contact[]/availabilityTo`     | Availability end time                                           | Time (`HH:mm`)           | Optional |
| `list[]/identity[]/contact[]/availabilityDays[]` | Days available                                                  | String Array (day names) | Optional |
| `list[]/identity[]/contact[]/comment`            | Usage notes                                                     | String                   | Optional |

## 5.6 CP Contact Object

Each CP identity MAY include a `contact` array using the **same structure as the MAP contact object**. This provides CP-level contact details for operational purposes — typically CP-to-CP sales and support enquiries during the switching process.

### Purpose

The CP contact object allows each CP to advertise its preferred contact methods, trading hours, and escalation points directly in the CP Registry. This eliminates the need for offline spreadsheets or specialised tools — a MAP's application can look up the other CP's preferred contact method in real time and present it to the agent handling the switch.

### Usage Rules

- If `availabilityTo` and `availabilityFrom` are absent, the contact SHOULD be interpreted as **24-hour availability**
- If `availabilityDays` is absent, the contact SHOULD be assumed available **7 days a week**
- This encourages CPs to be always reachable and promotes optimal behaviour
- The `purpose` field allows granular control — a CP can advertise different contact methods for `sales`, `support`, and `technical` enquiries
- Contact details are held in the CP Registry and are only accessible via OAuth 2.0-authenticated API calls — they are **not publicly accessible** and must not be shared with end consumers

### Relationship to MAP Contact Object

| Level                                  | Contact Object           | Typical Use                                                             |
|----------------------------------------|--------------------------|-------------------------------------------------------------------------|
| **MAP** (`map/contact[]`)              | MAP operational contacts | MAP-to-MAP technical issues, delivery failures, infrastructure problems |
| **CP** (`list[]/identity[]/contact[]`) | CP operational contacts  | CP-to-CP sales queries, Switch Match escalations, switch support        |

Both use the identical JSON structure (`type`, `value`, `purpose`, `availabilityFrom`, `availabilityTo`, `availabilityDays`, `comment`), making implementation straightforward — the same parsing code handles both.

### Example Use Case

A CP agent has exhausted all local options trying to resolve a Switch Match failure. Using the MAP's application, the agent looks up the losing CP's contact object from the Master Registry. The application checks the current time and day, filters to the `sales` purpose, and presents the available contact methods:

- During working hours: phone and email are both available
- Outside working hours: only the email/ticketing URL is shown
- The agent raises a query through the preferred channel with relevant correlation IDs

This process requires no swivel-chair, no MAP involvement, and no specialised tools beyond the agent's normal interface.

## 5.7 TOTSCo Directory API

For MAPs that need to consume the TOTSCo directory (to route messages to CPs connected directly to the TOTSCo Hub), the [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) defines the directory endpoint:

| Field              | Value               |
|--------------------|---------------------|
| API Name           | TOTSCo-DirectoryAPI |
| Context            | `/directory`        |
| Version            | `v1`                |
| HTTP Method        | GET                 |
| Transport Security | HTTPS, TLS 1.3      |
| Resource           | `/entry`            |

**Query format**: `https://{fqdn}/directory/{version}/entry?listType={listType}&identity={identity}`

| Parameter  | Description                                    | Required |
|------------|------------------------------------------------|----------|
| `listType` | Entity list type (e.g., `RCPID`)               | Yes      |
| `identity` | Specific RCPID, `all`, or omit for all entries | Optional |

This directory can be used to update your local cache when you receive a message from an unknown source ID or encounter an unrecognised signing key.

---

<!-- DOCUMENT: part2/06-totsco-integration | Part 2 — Implementation — 6. TOTSCo Integration -->

---
title: 6. TOTSCo Integration
tags: [Part 2]

---

# 6. TOTSCo Integration

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 6.1 Overview

TOTSCo operates centralised hubs for both **One Touch Switch (OTS)** residential switching and **Switching for Business (SforB)**. Both hubs use the same **JAM message envelope** specification and the same **OAuth 2.0 over TLS 1.3** transport that the CSF uses, which gives the two networks strong compatibility at the message layer. For SforB, TOTSCo can participate in the CSF as a **Hub Managed Access Provider (HMAP)** — routing messages between its connected CPs and the wider CSF network.

This chapter describes how the CSF and TOTSCo interoperate. The detailed implementation plan has been shared separately with TOTSCo and is available on request from the TAG.

> **CP migration path (SforB and non-OTS only).** A CP currently using TOTSCo for **SforB** (and / or for niche bilateral exchanges or other non-OTS protocols) who wishes to **become a MAP of 1 on the CSF** for that traffic is covered by [Part 1 §7.4 *MAP-of-1 Onboarding (incl. TOTSCo → CSF Migration)*](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration). The CSF treats this as a first-class adoption path; the strong JAM-envelope compatibility makes the move a transport switch rather than a business change. **OTS is out of scope** — OTS is Ofcom-mandated to use TOTSCo as the single industry platform, so a CP that operates OTS MUST continue to use TOTSCo for OTS traffic. The migration applies to SforB and other non-OTS protocols only.

## 6.2 Integration Principles

- **Zero to low impact** on existing TOTSCo infrastructure
- The CSF uses the **same JAM message specification** and **OAuth 2.0 authentication** as TOTSCo
- No modifications to the TOTSCo letterbox API are required
- TOTSCo's existing OTS connections with MAPs can be reused

## 6.3 Registering CSF Endpoints

**Impact: Zero to Low**

It is highly probable that existing MAPs already have connectivity with TOTSCo from OTS or SforB. Any new MAP or MAP-of-1 joining the CSF must also register with TOTSCo following their existing procedures:

- Provide IP addresses for allowlisting
- Exchange OAuth 2.0 or API key credentials
- Confirm message exchange conforms to the JAM Specification

The only additional requirement is a **Directory API endpoint URL** for TOTSCo to retrieve the MAP's CSF registry.

### 6.3.1 Dedicated, locked-down HMAP interfaces — both directions

The CSF and TOTSCo deliberately adopt a **per-partner, dedicated-endpoint** operating model in both directions. This mirrors how TOTSCo already runs OTS and SforB today — every CP and MAP that connects to the TOTSCo Hub does so through an endpoint TOTSCo provisions specifically for that partner.

| Direction | What the MAP does | What TOTSCo does |
|---|---|---|
| **MAP-side (inbound to the MAP from TOTSCo)** | Each CSF MAP exposes a **dedicated HMAP interface exclusively for TOTSCo**. This interface is not used by any other MAP or HMAP. It is **locked down** at the agreed contract — CSF spec increments, feature releases, envelope changes, and routing-group additions do **not** propagate through this interface. TOTSCo's exchanges with the MAP continue to work exactly as they did on day one. | TOTSCo treats the MAP's HMAP interface as a stable bilateral contract. |
| **TOTSCo-side (inbound to TOTSCo from the MAP)** | The CSF MAP delivers SforB messages to a dedicated TOTSCo letterbox URL provisioned specifically for that MAP. | TOTSCo provisions **one dedicated CSF letterbox URL per CSF MAP**, the same per-partner pattern TOTSCo already uses for every OTS / SforB partner today. Each URL is backed by the same hub infrastructure; only the URL path differs. |

> **Why locked down.** The architectural commitment to TOTSCo is that the HMAP interface is **steady-state**. The CSF can — and will — continue to evolve at its own cadence; that evolution happens behind each MAP's standard CSF interface, not through the dedicated HMAP interface TOTSCo consumes. This keeps TOTSCo's integration a one-time build, not an evergreen one, and isolates TOTSCo's regulated OTS operations from any CSF iteration.

> **Best Practice (legacy heading retained for backward compatibility of cross-references).** All MAPs should configure a dedicated, locked-down HMAP interface for TOTSCo. This is mandatory in the operating model described above and is the only pattern this section supports.

## 6.4 Directory Collection

**Impact: Medium**

TOTSCo must collect the CP Registry from each MAP on the CSF network. This involves:

1. **Accessing each MAP's CP Registry endpoint** using existing OAuth 2.0 credentials
2. **Converging the collected CP Registries** into a Master Registry — either merged with the existing TOTSCo directory or maintained separately
3. **Updating periodically** — every 5 minutes, hourly, or daily, at TOTSCo's discretion

The CSF CP Registry is intentionally a **strict superset** of the TOTSCo directory structure for OTS and SforB, making convergence straightforward. TOTSCo can choose to retain all data, or use the CSF-specific fields (`signing[]`, expanded `resource[]`, `contact[]`, `outage[]`) for the value they add, or ignore them entirely — none of those choices break TOTSCo's existing parser.

**Dual-process directory in TOTSCo today.** TOTSCo's pre-production Directory v2 already serves both OTS and GPLB (SforB) entries from a single list, distinguishing them by `processSupport[].process`. MAPs that want a single-process view filter on an `identity` query parameter:

```
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=all
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=ots
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=gplb
```

The production model is expected to follow the same shape. The CSF's Master Registry follows the same convention (`processSupport[].process` carries `OTS`, `GPLB`, and future process tags), so TOTSCo can apply its existing filter logic unchanged.

The number of CSF MAPs is anticipated not to exceed ten initially.

## 6.5 RCPID Format Handling

**Impact: Low**

The SforB Message Specification defines source and destination identity fields as strings (up to 256 characters). The CSF uses UUIDv4 (36 characters) — well within this constraint.

In practice:

- **CSF MAP sending to TOTSCo**: Uses the destination RCPID from the TOTSCo directory (typically 4-character OTS format)
- **TOTSCo sending to CSF MAP**: Uses the destination RCPID from its Master Registry (UUIDv4 format, collected from CSF CP Registries)

TOTSCo automatically acquires all CP UUIDs when collecting MAP registries. Both CSF and TOTSCo already accept UUIDv4 for correlation IDs.

## 6.6 API Compatibility

**Impact: Zero**

TOTSCo uses the industry JAM Specification for message exchange — the same standard used by the CSF. The CSF validates the JSON envelope identically and uses OAuth 2.0 over TLS 1.3.

| Aspect | TOTSCo | CSF | Compatible? |
|---|---|---|---|
| Message format | JAM Specification | JAM Specification | Yes |
| Envelope validation | Same rules | Same rules | Yes |
| Authentication | OAuth 2.0 | OAuth 2.0 | Yes |
| Transport | TLS 1.3 | TLS 1.3 | Yes |
| Success response | HTTP 202 | HTTP 202 | Yes |
| Error codes (sync) | 9xxx | 9xxx + 8xxx (PKI only) | Yes |

The 8xxx PKI error codes are CSF-specific and are not sent to TOTSCo. No API modifications are required on the TOTSCo side.

## 6.7 Message Flow: CSF to TOTSCo

In CSF, **CP 1 and MAP A are treated as a single unit at the transport layer** — the MAP handles all CSF message exchange, and the CP only gives the MAP internal instructions and receives internal nudges back when action is required. This is true whether the CP is operating as a **MAP-of-1** (CP and MAP are literally the same entity) or is a CP being served by a separate MAP. The mermaid diagram below uses a grouping box to make this visible.

```mermaid
sequenceDiagram
    box CSF — CP 1 + MAP A treated as one unit (e.g. MAP-of-1)
        participant CP1 as CP 1 (CSF)
        participant MAPA as MAP A (CSF)
    end
    participant TOTSCo as TOTSCo (HMAP)
    participant CP2 as CP 2 (TOTSCo)

    Note over CP1,MAPA: All CSF message exchange is handled by MAP A.<br/>CP 1 gives MAP A internal instructions and receives<br/>internal nudges back when action is required.
    CP1->>MAPA: Internal instruction (e.g. "perform Switch Match")
    Note over MAPA: Look up destination in directory<br/>Destination CP is on TOTSCo
    MAPA->>TOTSCo: OAuth 2.0 auth + JAM message<br/>(standard TOTSCo letterbox)
    TOTSCo-->>MAPA: HTTP 202
    TOTSCo->>CP2: Forward message to destination CP
```

## 6.8 Message Flow: TOTSCo to CSF

The same CSF grouping applies on the inbound side — MAP A receives the message from TOTSCo on behalf of CP 1, and CP 1 is notified internally if the message requires action.

```mermaid
sequenceDiagram
    participant CP2 as CP 2 (TOTSCo)
    participant TOTSCo as TOTSCo (HMAP)
    box CSF — CP 1 + MAP A treated as one unit (e.g. MAP-of-1)
        participant MAPA as MAP A (CSF)
        participant CP1 as CP 1 (CSF)
    end

    CP2->>TOTSCo: SforB message (JAM envelope)
    Note over TOTSCo: Look up destination in Master Registry<br/>Destination CP is on MAP A
    TOTSCo->>MAPA: OAuth 2.0 auth + JAM message<br/>(destination RCPID is UUIDv4)
    MAPA-->>TOTSCo: HTTP 202
    MAPA->>CP1: Internal nudge to CP (if action required)
    Note over MAPA,CP1: MAP A handles all CSF message exchange.<br/>CP 1 only receives internal nudges for actions it needs to perform.
```

## 6.9 PKI Considerations

TOTSCo, as an HMAP, is **not required** to implement DKIM/PKI signing when exchanging messages on behalf of its CPs. This is by design — to minimise integration cost for hub operators.

However:

- TOTSCo **is strongly recommended** to implement the full CSF CP Registry format for SforB, as its CP clients benefit significantly from the additional contact and support information
- TOTSCo **is not precluded** from implementing PKI if desired — the CSF framework supports it
- When a CSF MAP receives a message from TOTSCo's dedicated endpoint, it knows the message comes from a trusted hub and applies hub-specific validation rules rather than PKI verification

## 6.10 Passthrough Headers

When TOTSCo forwards a message from a CSF MAP to its own CPs, the `X-CSF-SIGNATURE` header SHOULD be left intact. This provides end-to-end trust verification — the destination CP (or its MAP) can verify the original signing even after hub forwarding.

## 6.11 Support and Diagnostics

By accessing CSF registries, TOTSCo gains direct access to MAP contact details (phone, email, URL with availability hours), enabling prompt issue resolution.

The CSF registry provides more detailed contact information than currently available through OTS, including:
- MAP and CP support hours
- Multiple contact methods with purpose tags (sales, support, technical)
- Service status URLs for real-time operational monitoring

## 6.12 Further Information

| Document | Description |
|---|---|
| [**TOTSCo HMAP Integration Guide**](../standalone/totsco-hmap-integration-guide.md) | The **TOTSCo-side build-and-commission handbook**: executive summary for middle management, six concrete deliverables (Directory API client, Master Registry convergence, RCPID translation, routing rules, dedicated CSF letterbox URL, optional PKI), five-phase plan (Discovery → Build → Test → Operational Commissioning → Production), copy-and-run test patterns, cost-and-effort estimate, risk register, and collective industry-benefit framing. Companion to this chapter; **read this guide alongside §6**. |
| TOTSCo Integration — Implementation Plan v1.1 | Detailed integration steps (shared with TOTSCo) |
| TOTSCo Integration — Overview Slides v1.0 | High-level integration overview |
| [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) | Industry-standard letterbox and directory API specification for SforB |

These documents are available on request from the TAG.

---

<!-- DOCUMENT: part2/07-cp-transitions | Part 2 — Implementation — 7. CP Transitions -->

---
title: 7. CP Transitions
tags: [Part 2]

---

# 7. CP Transitions

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 7.1 Overview

CPs are free to transition between MAPs, subject to standard commercial terms. The CSF is designed to make this transition seamless, with built-in mechanisms for identity portability, in-flight order transfer, and conflict resolution.

A CP can operate through only **one MAP at any given time** for a given RCPID. This relationship is established through DNS records controlled by the CP.

## 7.2 Reasons for Moving

A CP may move to a new MAP for various reasons:

- **Service dissatisfaction**: The existing MAP fails to meet agreed standards
- **Provider termination**: The current MAP enters administration or issues a termination notice
- **Strategic realignment**: The CP's business strategy requires a different MAP
- **Cost optimisation**: The CP wishes to become a MAP of 1 or consolidate providers
- **M&A** - A CP is purchased by another CP and their brand rolls into that of the acquirer

## 7.3 Transition Process

### Step 1 — Establish with New MAP

The CP establishes a commercial relationship with the new MAP and completes the CP onboarding process:
- New PKI key pair is generated by the new MAP
- The new MAP does NOT yet add the CP to its directory

### Step 2 — DNS Update

The CP updates its DNS TXT records. CPs should lower their TTL on the existing records in the days/hours prior:
- `[RCPID]._domainkey.[cp-domain]` — new public key from the new MAP
- `[RCPID]._mapkey.[cp-domain]` — URL of the new MAP's message endpoint

> **Note**: This temporarily stops message flow via the original MAP. Messages sent by other MAPs will fail PKI verification against the old MAP and be queued locally for retry.

### Step 3 — Directory Update

The new MAP performs the directory-side activation steps that make the CP visible and routable through it:

1. **Add the CP entry** to the new MAP's CP Registry under `list[].identity[]`, with the agreed `processSupport[]` array covering each SforB process the CP is signing up for (`businessSwitchMatch`, `businessSwitchOrder`, `businessSwitchOrderUpdate`, `businessSwitchOrderTrigger`, `businessSwitchOrderCancellation`, etc).
2. **Set per-CP status.** During cut-over the entry SHOULD be published with `processSupport[].status = TEST` if the new MAP is still onboarding the CP; or `ACTIVE` if the new MAP itself is already an `ACTIVE` participant and the only change is the move. The status is later transitioned to `ACTIVE` in Step 6, after in-flight reconciliation has cleared.
3. **Bump the registry `version` timestamp** so other MAPs polling the directory observe the change on their next refresh.
4. **Re-sign and re-publish** the new MAP's CP Registry per [Directory API §5](05-directory-api.md). Do NOT attempt to suppress the entry that still exists in the original MAP's registry — until Step 5 completes there is a deliberate, brief overlap which the [conflict-resolution rules in §7.5](#75-conflict-resolution) are designed to absorb.
5. **Wait for cache propagation.** Receiving MAPs cache registry data; allow at least one configured polling cycle (typically a few minutes) before relying on the entry being visible network-wide. The new MAP's registry endpoint MUST honour `If-Modified-Since` so peers can confirm freshness without polling the full payload.
6. **DNS already settled.** DNS was updated in Step 2; the directory entry is the authoritative *advertisement* of the routing change but the underlying authority comes from `_mapkey`, which receivers will re-resolve before sending sensitive traffic.

> :memo: **Note**: Until Step 5 has run and the original MAP's registry no longer lists the CP, the CP appears under two MAPs simultaneously. This is the expected transient state and is what triggers the conflict-detection rules in [§7.5](#75-conflict-resolution).

### Step 4 — RCPID Status Export Request

The new MAP sends a signed **`rcpidStatusRequest`** to the original MAP via the Letterbox API. This request is the formal handover trigger and authorises the original MAP to release in-flight order data and decommission its registry entry for the CP.

**Authorisation model.** Before responding, the original MAP MUST independently verify all three of:

1. The DKIM signature on the inbound request is valid per [PKI §3](03-pki-dkim-signing.md) and the signing CP's `_domainkey` resolves to the new MAP.
2. The moving CP's `_mapkey` DNS record now resolves to the *requesting* MAP. This is the cryptographic proof that the CP authorised the move — DNS is controlled by the CP, so a `_mapkey` pointing at the requesting MAP can only have been set with the CP's consent.
3. The requesting MAP's registry advertises the CP under it (at any status — `TEST` or `ACTIVE`).

**Request payload.**

```json
{
  "envelope": {
    "source":      { "type": "RCPID", "identity": "<new-MAP RCPID>",  "correlationID": "<uuid>" },
    "destination": { "type": "RCPID", "identity": "<old-MAP RCPID>" },
    "routingID":   "rcpidStatusRequest",
    "auditData":   [ { "name": "test", "value": "false" } ]
  },
  "rcpidStatusRequest": {
    "movingRCPID":   "<the moving CP's RCPID>",
    "purpose":       "MAP_TRANSFER",
    "newMAP":        "<new-MAP RCPID>",
    "newMAPDomain":  "letterbox.newmap.example",
    "requestedAt":   "2026-04-29T10:00:00Z",
    "specVersion":   "GPLB-SG SforB Msg Spec v3.0"
  }
}
```

**Response time and failure modes.**

| Condition | Response | HTTP / Code |
|---|---|---|
| All authorisation checks pass | Synchronous `rcpidStatusConfirmation` carrying the export (see [§7.4](#74-rcpid-status-export-schema)) | 202 |
| DNS `_mapkey` does not resolve to the requester | Reject — handover not authorised | 403 / `9301` |
| DKIM verification fails | Reject — signature invalid | 403 / `8101` |
| No in-flight SORs found for the moving CP | `rcpidStatusConfirmation` with empty `orders[]` array; registry entry still removed | 202 |
| Original MAP cannot comply within SLA | `rcpidStatusFailure` with retry guidance | 503 / `9302` |

**SLA expectations.** The original MAP SHOULD respond within 30 seconds during core business working hours for an export of fewer than 100 in-flight SORs and within 2 minutes for a complete export. A delayed response forces the new MAP to retry; the original MAP MUST handle idempotency by correlating retries against the original `correlationID`.

**Side effects on the original MAP.** As soon as the original MAP commits to processing the export, it MUST:

- **Quiesce the moving CP's mailbox** — block any new outbound SforB messages from the CP and queue inbound messages addressed to it until the response has been sealed, so that the export captures a consistent snapshot.
- **Remove the CP entry** from its CP Registry and re-sign and re-publish the registry version (so that other MAPs can stop attempting to route to it).
- **Persist the export** alongside the inbound `rcpidStatusRequest` correlation ID for at least 30 days for audit, regardless of the response outcome.

### Step 5 — In-Flight Order Reconciliation

Step 5 is where the in-flight Switch Orders move from the original MAP's state engine into the new MAP's state engine, and where every counterparty MAP gets the cross-check it needs to keep treating the customer journey as continuous.

#### 7.3.5.1 Suggested Export Routine (run by the original MAP)

The export routine runs server-side on the original MAP between accepting the `rcpidStatusRequest` and emitting the response. Each step is idempotent so the routine can be safely re-entered after a partial failure:

1. **Hold the moving CP's mailbox.** Block new outbound SforB messages from the moving CP (the GRCP path) and queue any inbound SforB messages addressed to it (the LRCP path). This freeze prevents new in-flight state from being created during the export window.
2. **Enumerate SORs.** Walk the SforB order store for every `switchOrderReference` where the moving CP is either the GRCP (originator of the match/order) or the LRCP (counterparty). Each SOR is processed independently.
3. **Capture the last completed interaction only.** For each SOR, identify the most recent completed request/response pair (e.g. `businessSwitchOrderRequest` → `businessSwitchOrderConfirmation`) per service. Partially completed exchanges are dropped, per the existing rule in [§7.4.5](#745-rules).
4. **Resolve counterparty routing.** For every SOR, record the counterparty CP's RCPID and that CP's *current* MAP — read live from the CP Registry, not from the cached SOR record — so the new MAP knows where to direct follow-up `rcpidStatusRequest` cross-checks in the reconciliation phase.
5. **Snapshot per-service state.** For every service inside the SOR (`IAS`, `NBICS`, `NBICSRange`, etc.) capture the current `status` from the SforB state machine (`matched`, `ordered`, `triggered`, `cancelled`, `failed`), the active `plannedSwitchDate`, and any `fault` block recorded against the service. This mirrors the structure documented in the [GPLB-SG SforB Message Specification v3.0 §3.3 — Business Switch Order Request](https://www.fcs.org.uk/wp-content/uploads/2025/11/GPLB-SG-Switching-for-Business-Message-Specification-V3.0.pdf) (canonical source published by GPLB-SG via the FCS).
6. **Capture original-match identity context.** Carry forward the customer-identifying fields (`grcpBrandName`, `name`, `account`, `identity[]`, `address`) from the `businessSwitchMatchRequest`/`Confirmation` that opened the SOR. This allows the new MAP to validate continuity if the counterparty asks for a re-match.
7. **Compute integrity hashes.** Canonicalise each SOR record and compute a SHA-256 `recordHash`, then an `aggregateHash` over the whole `orders[]` array. Sign `aggregateHash` with the original MAP's `_domainkey` private key (the MAP-level key from [PKI §3](03-pki-dkim-signing.md), NOT the CP-level key being moved).
8. **Wrap and return.** Emit the response payload described in [§7.4](#74-rcpid-status-export-schema) as the body of the `rcpidStatusConfirmation` message.
9. **Finalise registry removal.** Once the response has been transmitted, finalise removal of the CP from the registry as already initiated in Step 4 and re-publish.

#### 7.3.5.2 Reconciliation Performed by the New MAP

After receiving the export the new MAP:

1. **Verifies the aggregate signature** against the original MAP's `_domainkey` — this establishes chain-of-custody for the data being imported.
2. **Imports each SOR** into its own switching state engine, **preserving the `switchOrderReference` UUID** so the customer journey is not restarted. New correlation IDs are minted at the envelope layer for any subsequent outbound traffic, per the [§7.4.5](#745-rules) rule.
3. **Issues an `rcpidStatusRequest` to each counterparty MAP** named in the export — one per counterparty — to:
   - Notify them that the moving CP is now reachable via the new MAP.
   - Cross-check the SOR state from the counterparty's perspective. Any mismatch (e.g. counterparty believes a service is `triggered` when the export says `ordered`) is flagged and resolved bilaterally before further messages flow.
4. **Resumes message flow** by re-publishing the CP entry with `processSupport[].status = ACTIVE` in the new MAP's CP Registry once all reconciliation responses are received and clean.
5. **Notifies the moving CP** with a transition report (count of SORs imported, any reconciliation flags raised, and estimated time to full resumption).

#### 7.3.5.3 What Must Be in the Export — Minimum Detail per SOR

The full schema is documented in [§7.4](#74-rcpid-status-export-schema). At minimum, every in-flight SOR record MUST carry:

| Field group | Purpose |
|---|---|
| `switchOrderReference`, `role`, `currentState` | Identity of the order and which side the moving CP is on |
| `counterparty.{rcpid, mapRcpid}` | Tells the new MAP where to send the cross-check request |
| `originalMatch.{grcpBrandName, name, account, identity[], address}` | Identity context preserved from the opening match |
| `services[].{serviceType, serviceIdentifier, status, plannedSwitchDate, fault}` | Authoritative per-service state at the moment of export |
| `lastInteraction.{routingID, timestamp, sourceCorrelationID, destCorrelationID, payloadHash}` | The most recent completed exchange — the resumption baseline |
| `expectedNext.{messageType, deadline, slaWindow}` | What message is due next and the SLA clock the new MAP must continue to honour |
| `auditTrail[]` | Hashes (not bodies) of every prior completed exchange so anomalies can be investigated bilaterally without exposing message body content |

### Step 6 — Resume Operations

With the export imported and counterparty cross-checks clean, the new MAP can promote the moving CP to fully operational state. Treat the lists below as a sign-off checklist; nothing in Step 6 can be skipped without recording a deviation.

#### New MAP

- [ ] Cross-check responses received from every counterparty MAP referenced in the export, and any mismatches resolved bilaterally before resuming traffic.
- [ ] Per-CP `processSupport[].status` flipped from `TEST` to `ACTIVE` in the registry; registry version bumped, re-signed and re-published.
- [ ] Synthetic round-trip executed against the moving CP via the [TAG Baseline Test Suite — §8.5 Letterbox API](../standalone/onboarding-testing-process.md#85-letterbox-api-message-sendreceive) to confirm end-to-end delivery.
- [ ] Audit log entry written: time of completion, count of SORs imported, `aggregateHash` of received export, original MAP RCPID, signing key fingerprint.
- [ ] Telemetry resumed: outbound messages no longer carry `auditData.test=true` (unless the new MAP is itself still in `TEST` per [Onboarding & Testing Process §5](../standalone/onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope)).
- [ ] CP-facing portal or dashboard reflects every imported SOR with continuity preserved (same `switchOrderReference`, same per-service `status`).

#### Original MAP

- [ ] CP entry removed from registry; registry version bumped, re-signed and re-published.
- [ ] `_domainkey` retained for the agreed retention window so receivers verifying historic signatures within that window MUST still be able to resolve them.
- [ ] Inbound queue for the moving CP drained: each remaining queued message either forwarded under cover of an `rcpidStatusRequest` to the new MAP, or rejected with code `9999` (in migration) if forwarding is not feasible.
- [ ] Export package archived alongside the inbound `rcpidStatusRequest` correlation ID for at least 30 days.
- [ ] Operational support for the moving CP closed off cleanly, with the agreed handover support window communicated to the CP and the new MAP.

#### Counterparty MAPs

- [ ] Registry caches refreshed; the new MAP entry observed for the moving CP.
- [ ] `_mapkey` DNS resolved at least once after the directory change to confirm the authoritative MAP.
- [ ] Locally queued messages drained — those that were retrying against the original MAP MUST be re-signed and re-routed to the new MAP's letterbox.
- [ ] Bilateral SOR cross-check with the new MAP reported clean (or anomalies escalated through the conflict-resolution path in [§7.5](#75-conflict-resolution)).

#### The CP

- [ ] DNS records propagated globally — verify from at least three geographic resolvers before declaring the migration complete.
- [ ] All in-flight customer journeys visible in the new MAP's portal/dashboards.
- [ ] Old MAP support contact still reachable for the agreed handover support window.
- [ ] Stakeholder communications sent: customers, downstream CPs, and any affected industry forum.

## 7.4 RCPID Status Export Schema

The schema below is a CSF design proposal layered onto the GPLB-SG SforB Message Specification v3.0 to support lossless MAP migration. It is published here so that the TAG can ratify the field set and the canonicalisation rules used for `aggregateHash`/`recordHash` before the first MAP migration runs in production.

### 7.4.1 Top-Level Envelope

The export rides inside the standard CSF envelope. The body element is `rcpidStatusConfirmation` and contains two top-level objects: `exportMetadata` and `orders[]`.

```json
{
  "envelope": { "...": "as per Letterbox §4.3" },
  "rcpidStatusConfirmation": {
    "exportMetadata": { "...": "see §7.4.2" },
    "orders":         [ { "...": "see §7.4.3" } ]
  }
}
```

### 7.4.2 Export Metadata

| Field | Description | Type | Required |
|---|---|---|---|
| `exportVersion` | Schema version of this export. Current: `1.0`. | String | Yes |
| `generatedAt` | UTC timestamp at which the export was sealed. | String (ISO 8601) | Yes |
| `generatedBy` | RCPID of the original (sending) MAP. | String | Yes |
| `movingRCPID` | RCPID of the CP being transferred. | String | Yes |
| `newMAP` | RCPID of the new MAP — echoes the requester. | String | Yes |
| `dnsVerifiedAt` | UTC timestamp at which the original MAP confirmed `_mapkey` resolution to the new MAP. | String | Yes |
| `directoryRemovedAt` | UTC timestamp at which the moving CP was removed from the original MAP's registry. | String | Yes |
| `specReference` | Version of the SforB Message Spec the orders were created against (e.g. `GPLB-SG SforB Msg Spec v3.0`). | String | Yes |
| `orderCount` | Number of records in `orders[]`. | Integer | Yes |
| `aggregateHash` | SHA-256 hash over the canonicalised `orders[]` array. | String (hex) | Yes |
| `signature` | Base64 signature over `aggregateHash` using the original MAP's `_domainkey` private key (algorithm `rsa-sha256` or `ed25519-sha256` per [PKI §3](03-pki-dkim-signing.md)). | String | Yes |

### 7.4.3 Per-Order Record

Each entry in `orders[]` is a full snapshot of a single in-flight Switch Order. The schema is designed to map 1:1 onto the SforB state machine in the GPLB-SG SforB Message Specification v3.0 §3 so the new MAP can resume handling without re-deriving state.

| Field | Description | Type | Required |
|---|---|---|---|
| `switchOrderReference` | UUID of the SOR. Preserved verbatim — the new MAP MUST NOT mint a new SOR. | String | Yes |
| `role` | `gaining` if the moving CP is the GRCP for this SOR; `losing` if it is the LRCP. | String (enum) | Yes |
| `currentState` | High-level state: `matched`, `ordered`, `partially-triggered`, `partially-cancelled`, `complete-pending-trigger`, `trigger-failed`. | String (enum) | Yes |
| `counterparty.rcpid` | RCPID of the CP on the opposite side of the order. | String | Yes |
| `counterparty.mapRcpid` | RCPID of the counterparty's *current* MAP, looked up live at export time. | String | Yes |
| `originalMatch.grcpBrandName` | Brand name presented to the customer at match time. | String | If known |
| `originalMatch.name` | Customer or business name from the match. | String | Yes |
| `originalMatch.account` | LRCP-side account number, if supplied at match. | String | Optional |
| `originalMatch.identity[]` | Identity tuples (`contact`, `IAS`, `NBICS`, `SecureID`, `SIC`) used to anchor the match. | Array | Optional |
| `originalMatch.address` | UPRN / address lines / post town / post code from the match. | Object | Yes |
| `services[].serviceType` | `IAS`, `NBICS`, `NBICSRange` (or future industry-agreed type). | String | Yes |
| `services[].serviceIdentifier` | The GRCP's per-service reference. Required for every service, mirroring §3.3 of the SforB Msg Spec. | String | Yes |
| `services[].status` | Current service state: `matched`, `ordered`, `triggered`, `cancelled`, `failed`. | String | Yes |
| `services[].plannedSwitchDate` | Per-service planned switch date if it overrides the SOR header. | String (CCYY-MM-DD) | Optional |
| `services[].fault` | `{ faultCode, faultText }` if the service is in `failed` state. | Object | Optional |
| `lastInteraction.routingID` | Most recent completed exchange (e.g. `businessSwitchOrderConfirmation`). | String | Yes |
| `lastInteraction.timestamp` | When that exchange completed. | String (ISO 8601) | Yes |
| `lastInteraction.sourceCorrelationID` | The original sender-side correlation ID. | String | Yes |
| `lastInteraction.destCorrelationID` | The destination-side correlation ID, if available. | String | Optional |
| `lastInteraction.payloadHash` | SHA-256 of the canonicalised message body — included so the new MAP can verify with the counterparty without exposing the body itself. | String (hex) | Yes |
| `expectedNext.messageType` | The message type expected next on this SOR (e.g. `businessSwitchOrderTriggerRequest`). | String | Optional |
| `expectedNext.deadline` | Hard SLA deadline by which the next message must be sent. | String (ISO 8601) | Optional |
| `expectedNext.slaWindow` | The SLA budget remaining as ISO 8601 duration. | String | Optional |
| `auditTrail[]` | Array of `{ routingID, timestamp, payloadHash }` for every prior completed exchange on this SOR. Hashes only — message bodies are NOT exported. | Array | Yes |
| `recordHash` | SHA-256 over the canonicalised record above (excluding `recordHash` itself). Allows individual orders to be re-verified after import. | String (hex) | Yes |

### 7.4.4 Worked Example

A minimal export covering one SOR where the moving CP is the GRCP and the order is in the `ordered` state, awaiting trigger:

```json
{
  "rcpidStatusConfirmation": {
    "exportMetadata": {
      "exportVersion": "1.0",
      "generatedAt": "2026-04-29T10:00:00Z",
      "generatedBy": "<old-MAP RCPID>",
      "movingRCPID": "809b6e65-a6e7-40f6-8b52-04dd65b6fce1",
      "newMAP": "<new-MAP RCPID>",
      "dnsVerifiedAt": "2026-04-29T09:58:42Z",
      "directoryRemovedAt": "2026-04-29T09:59:01Z",
      "specReference": "GPLB-SG SforB Msg Spec v3.0",
      "orderCount": 1,
      "aggregateHash": "5a3b...c812",
      "signature": "MEUCIQDh..."
    },
    "orders": [
      {
        "switchOrderReference": "123e4567-e89b-12d3-a456-426614174000",
        "role": "gaining",
        "currentState": "ordered",
        "counterparty": {
          "rcpid": "d8322d80-92c8-4906-a408-f1d2daf7e03d",
          "mapRcpid": "<counterparty MAP RCPID>"
        },
        "originalMatch": {
          "grcpBrandName": "Bridgend Telecoms (Telesales)",
          "name": "The Coffee Shop",
          "account": "0003316563216",
          "identity": [
            { "name": "contact", "value": "John Smith" },
            { "name": "NBICS",   "value": "01234987654" },
            { "name": "SIC",     "value": "AB1234" }
          ],
          "address": {
            "uprn": "12345",
            "addressLines": ["Unit 1", "Highlands Industrial Estate", "22 Cheshunt Mews"],
            "postTown": "Glasgow",
            "postCode": "SW2R 5AF"
          }
        },
        "services": [
          { "serviceType": "IAS",        "serviceIdentifier": "ABC123",                "status": "ordered" },
          { "serviceType": "NBICS",      "serviceIdentifier": "0101111222",            "status": "ordered" },
          { "serviceType": "NBICSRange", "serviceIdentifier": "0101112000-0101112999", "status": "ordered", "plannedSwitchDate": "2025-05-27" }
        ],
        "lastInteraction": {
          "routingID": "businessSwitchOrderConfirmation",
          "timestamp": "2026-04-12T14:21:08Z",
          "sourceCorrelationID": "ABC123",
          "destCorrelationID": "XYZ987",
          "payloadHash": "8f1a...0e44"
        },
        "expectedNext": {
          "messageType": "businessSwitchOrderTriggerRequest",
          "deadline": "2025-04-03T23:59:59Z",
          "slaWindow": "P14D"
        },
        "auditTrail": [
          { "routingID": "businessSwitchMatchRequest",      "timestamp": "2026-04-08T09:00:00Z", "payloadHash": "..." },
          { "routingID": "businessSwitchMatchConfirmation", "timestamp": "2026-04-08T09:00:18Z", "payloadHash": "..." },
          { "routingID": "businessSwitchOrderRequest",      "timestamp": "2026-04-12T14:20:55Z", "payloadHash": "..." },
          { "routingID": "businessSwitchOrderConfirmation", "timestamp": "2026-04-12T14:21:08Z", "payloadHash": "..." }
        ],
        "recordHash": "9c2d...4e10"
      }
    ]
  }
}
```

### 7.4.5 Rules

- **Switch Orders only.** The export includes Switch Orders only. Switch Matches that have not progressed to an order MUST be repeated by the CP via its new MAP.
- **Completed interactions only.** Partially completed interactions MUST NOT be exported — only the last completed interaction for each exchange.
- **Correlation IDs.** The new MAP mints fresh envelope correlation IDs for any subsequent messages — the originals are recorded in `lastInteraction` and `auditTrail[]` for traceability only.
- **Directory update precedence.** The original MAP MUST remove the moving CP from its directory before transmitting the export response. Receivers can rely on the registry version bumping in tandem with the export.
- **Body hashes, not bodies.** Only message-body hashes are exported. The body itself is opaque to the CSF and remains the property of the originating CP — the hashes are sufficient to support bilateral counterparty cross-checks without re-exposing customer data.
- **Signed end-to-end.** The export's `aggregateHash` MUST be signed with the original MAP's `_domainkey` private key (the MAP-level key), giving the new MAP and any audit body cryptographic proof of provenance for the imported data.

## 7.5 Conflict Resolution

When a CP appears in more than one MAP's directory simultaneously:

1. The detecting MAP checks the CP's `_mapkey` DNS record
2. DNS indicates the current MAP endpoint
3. The MAP marks the conflicting entry as being in "conflict"
4. The new MAP advertises the old MAP as being in conflict, signalling other MAPs to check

Over time, all MAPs will recognise the conflict and update their directories accordingly.

### Latency During Transition

A CP should plan its move to minimise the gap — typically done overnight. During the transition:

- Messages sent by other MAPs will reflect routing from their current directories
- PKI verification will eventually prevent delivery to the old MAP
- Messages will be queued locally by sending MAPs for retry
- Once the new MAP has completed DNS changes and RCPID Status exports, messages resume flowing to the correct MAP

This self-healing methodology is native to the distributed CP Registry model — PKI provides the final verification check before sending.

## 7.6 RACI for In-Flight Order Handling

| Activity | Original MAP | New MAP | CP |
|---|---|---|---|
| Generate new PKI keys | — | Responsible | — |
| Update DNS records | — | Assists | Responsible |
| Stop processing messages (after DNS change) | Automatic | — | — |
| Respond to RCPID Status request | Responsible | — | — |
| Remove CP from directory | Responsible | — | — |
| Add CP to directory | — | Responsible | — |
| Send RCPID Status requests to other MAPs | — | Responsible | — |
| Import in-flight order data | — | Responsible | — |
| Notify affected CPs | — | Responsible | Informed |

---

<!-- DOCUMENT: part2/08-commercial-scenarios | Part 2 — Implementation — 8. Commercial Scenarios -->

---
title: 8. Commercial Scenarios
tags: [Part 2]

---

# 8. Commercial Scenarios

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## 8.1 Overview

The CSF addresses several commercial scenarios that were not fully covered by OTS. These scenarios are critical for ensuring business continuity, CP autonomy, and consumer/business protection.

## 8.2 CP Emergency Migration

**CP Emergency Migration** is the reactive process by which a CP transfers to a new MAP under one of the §8.2.2 trigger conditions (most often a failing, suspended, removed, or unresponsive MAP). It contrasts with a *normal* CP transition (§7), which is planned and CP-driven on a commercial timeline. The CSF mandates that every MAP supports emergency on-boarding of an existing CP as a core capability.

### 8.2.1 Definition and Scope

Emergency migration applies when the CP needs to move with little or no notice — usually because the current MAP can no longer be relied on to sign, route, or audit the CP's messages. It is *not* a substitute for a normal transition (§7); it is the framework's safety net.

Under OTS, a CP cannot move its in-flight orders between MAPs without significant manual effort, and the same risk exists if a MAP enters administration. The CSF addresses this by:

- Decoupling the CP from the MAP through DNS-controlled identity (§6)
- Enabling CPs to move freely between MAPs (or across multiple MAPs under different brands)
- Mandating that every MAP supports in-flight order export as a core capability (§4)
- Providing the `rcpidStatusRequest` flow so a new MAP can reconstruct or import in-flight state from the old MAP (§4) or, when the old MAP is offline, from other MAPs holding the orders

### 8.2.2 Triggers

Any one of the following invokes CP Emergency Migration:

| # | Trigger | Source / authority |
|---|---|---|
| **T1** | MAP failure / outage (technical, not by TAG decision) | Operational |
| **T2** | MAP enters administration or insolvency | Statutory / commercial |
| **T3** | MAP **suspended** by TAG (after governance review) | §10 governance — `SUSPENDED` directory status |
| **T4** | MAP **removed** by TAG (after 30-day remediation window) | §10 governance — removal from Master Registry |
| **T5** | MAP unresponsive (operationally unreachable but not formally suspended) | CP / TAG-observable behaviour — repeated `rcpidStatusRequest` non-response, `9301` reject noise above threshold, sustained failure to advertise in directory |
| **T6** | CP-initiated emergency (CP invokes emergency rather than normal transition — e.g. MAP material breach of MoU / SLA) | CP–MAP commercial contract |

Triggers T1, T2, T5 cover the "MAP can't do its job" cases. T3 and T4 are TAG-driven and are also referenced in the **draft Anti-Competitive Enforcement clause** — to be published as an **Appendix to the CSF framework** once it has been legally reviewed and signed off by the TAG members (tracked as P-3 in the open-conflicts log). Until the Appendix is published, T3/T4 follow the existing §10.7 graduated enforcement ladder. T6 covers the rare case where the CP itself elects to invoke the emergency process.

### 8.2.3 Happy Path — Distressed MAP Still Online

When a MAP is in distress but still operational:

1. The CP establishes a new MAP relationship and updates DNS
2. The new MAP advertises the CP and sends `rcpidStatusRequest` to the original MAP
3. The original MAP responds with in-flight order exports
4. Other MAPs detect the directory change and update routing

If the CP appears in both directories temporarily, **conflict management** resolves it automatically using DNS verification (the CP's `_mapkey` is the tiebreaker — see §6.5).

The new MAP SHOULD advertise the distressed MAP as being in "conflict," signalling other MAPs to verify their CP associations with that MAP.

Migration can be completed in **a few hours** if the new MAP expedites CP onboarding.

### 8.2.4 Unhappy Path — Distressed MAP Offline

If the failing MAP cannot perform exports:

1. The CP contacts a new MAP and completes onboarding
2. The CP uses its own CRM records to identify in-flight orders
3. The new MAP issues `rcpidStatusRequest` to **other MAPs** involved in those in-flight orders
4. All new requests use new correlation IDs
5. Switch Matches without Switch Orders can be re-issued (they are not part of the export)

During the offline period:
- The CP will not appear in any directory or drop-down lists
- Messages cannot be exchanged for the affected CPs
- Any order updates must be managed with prospects and supply chains manually

> All MAPs can onboard new CPs within hours, so the offline period is not expected to exceed **2 working days**.

### 8.2.5 Per-Scenario Timing Targets

Three different commitments apply, depending on which path is in play:

| Scenario | Target window | Path |
|---|---|---|
| **Planned MAP change** (not an emergency) — normal CP transition with TTL pre-staging | **Single-digit minutes** of actual outage | §7 + the DNS TTL pre-staging routine (§3.3) |
| **Happy-path emergency** — distressed MAP still online; `rcpidStatusRequest` exports succeed | **A few hours** | §8.2.3 |
| **Unhappy-path emergency** — distressed MAP offline; CRM-based reconstruction | **≤ 2 working days** | §8.2.4 |

These are framework targets; an individual MAP's MoU may commit to tighter numbers commercially.

### 8.2.6 Normal Transition vs Emergency Migration — Contrast

| Attribute | Normal CP Transition (§7) | CP Emergency Migration (§8.2) |
|---|---|---|
| **Trigger** | CP-driven commercial decision | One of the §8.2.2 triggers (T1 – T6) |
| **Notice** | Planned, weeks to months | None — reactive |
| **TTL pre-staging** | Yes — 24 h+ before cut-over | Not possible (no advance notice) |
| **New-MAP onboarding pace** | Standard | Expedited — CP treated as an experienced user |
| **Original MAP's cooperation** | Required for in-flight export | Best effort; CRM fallback if offline (§8.2.4) |
| **In-flight order recovery** | Exported by old MAP via `rcpidStatusRequest` | Imported via `rcpidStatusRequest` (happy path) **or** reconstructed from CP CRM + sibling MAPs (unhappy path) |
| **Fees / costs** | Per CP – new-MAP commercial agreement | See §8.2.8 — depends on trigger |
| **Target window** | Single-digit minutes (online) | A few hours (happy) / ≤ 2 working days (unhappy) |
| **TAG involvement** | None | None unless triggered by §10 (T3 or T4) |
| **Audit log requirement** | Normal (§9) | Normal **plus** explicit emergency-event log entry (§8.2.9) |

### 8.2.7 Emergency RACI

This RACI applies to the emergency process specifically. The in-flight-order RACI for *normal* transitions is in §7.6.

| Activity | CP | New MAP | Old MAP | Other MAPs | TAG |
|---|---|---|---|---|---|
| Identify trigger and decide to migrate | A/R | I | I | I | I (T3/T4 only) |
| Select new MAP | A/R | I | I | — | — |
| Expedited onboarding | C | A/R | I | — | — |
| Generate new PKI keys; update CP DNS (`_domainkey`, `_mapkey`) | A/R | C | — | — | — |
| Advertise CP in new registry | I | A/R | — | I (via directory sync) | I |
| Issue `rcpidStatusRequest` to old MAP (happy path) | I | A/R | C (if online) | — | — |
| Reconstruct in-flight orders from CP CRM (unhappy path) | A/R | C | — | — | — |
| Issue `rcpidStatusRequest` to sibling MAPs holding the orders | I | A/R | — | C (must respond) | — |
| Re-issue Switch Matches lacking Switch Orders | I | C | — | A/R | — |
| Mark old MAP as **"in conflict"** in directory | — | A/R | — | I | I |
| Emergency-event audit log (§8.2.9) | C | A/R | C (if available) | C | I |

R = Responsible · A = Accountable · C = Consulted · I = Informed

### 8.2.8 Fee Guidance

Fees for an emergency migration depend on which trigger applies:

| Trigger | Fee treatment |
|---|---|
| **T1 / T2** — MAP failure or administration | New-MAP expedited-onboarding at the new MAP's **standard published rates**; the CP is not at fault. A new MAP MAY waive expedite fees as goodwill / market practice. |
| **T3 / T4** — TAG-suspended or TAG-removed MAP | Same as T1/T2 by default. The **draft Anti-Competitive Enforcement clause** — to be published as an **Appendix to the CSF framework** once legally reviewed and signed off by TAG members (tracked as P-3 in the open-conflicts log) — would require waiver of expedite fees on the receiving side; until the Appendix is published, the T1/T2 treatment applies. |
| **T5** — MAP unresponsive | Same as T1/T2. The CP MAY seek recovery from the unresponsive MAP under their MoU. |
| **T6** — CP-initiated emergency | New-MAP **standard onboarding fees apply** as for a normal transition; the CP is electing the emergency path. |

In all cases, the new MAP MUST publish its expedite-onboarding charge alongside its standard onboarding charge (transparency requirement, §10).

### 8.2.9 Audit and Retention

Both happy- and unhappy-path emergencies generate an **emergency-event log entry** that the new MAP MUST persist. The entry SHALL contain at minimum:

- Trigger (T1 – T6 from §8.2.2) and free-text reason
- Timestamps: decision-to-migrate, DNS update, new-registry advertise, first `rcpidStatusRequest` issued, all completed
- Old MAP RCPID and new MAP RCPID
- List of `rcpidStatusRequest` correlation IDs issued and which responded
- Outcome: "happy" (all responses received) or "unhappy" (CRM reconstruction used)
- Any in-flight orders re-issued with new correlation IDs

Retention:

- **Happy path** — exported in-flight order package retained alongside the new MAP's normal CSF audit logs per the data retention policy in §9 (5 years).
- **Unhappy path** — the CP's CRM-reconstruction record forms the authoritative in-flight set for the affected interval and SHOULD be retained for the same period; the new MAP records the reconstruction inputs received from the CP.
- **All `rcpidStatusRequest` and response messages** issued or received during the emergency MUST be persistently logged per §9 audit-log requirements.

### 8.2.10 CP Emergency Migration Checklist

- [ ] CP contacts new MAP and agrees terms
- [ ] New MAP treats the CP as an experienced user (expedited onboarding)
- [ ] New PKI keys generated and DNS records updated (`_domainkey`, `_mapkey`)
- [ ] New MAP advertises CP in its registry
- [ ] `rcpidStatusRequest` issued to original MAP (if available) and affected sibling MAPs
- [ ] In-flight order data imported (happy) or reconstructed from CP CRM (unhappy) and reconciled
- [ ] Emergency-event audit log entry written (§8.2.9)
- [ ] Old MAP marked "in conflict" in the new MAP's directory (where applicable)
- [ ] Full operations resume

## 8.3 CP Merger, Acquisition, and Consolidation

CPs involved in mergers may need to consolidate brands over time. The CSF supports this through a staged process:

### Stage 1 — Stop Selling

Mark consolidating brands as not accepting new Switch Matches (but still process in-flight orders and handle losses).

### Stage 2 — Asset Migration

Move customer assets from stop-sell brands to the surviving RCPID. During this period:
- The stop-sell brands remain in the directory
- The current MAP continues to handle any losses for those brands
- Care must be taken if this extends over a long period

### Stage 3 — Close In-Flight Orders

Complete all remaining in-flight orders on consolidating brands. For any remaining orders:
- Complete gains
- Cancel losses where appropriate
- Migrate remaining customer assets to the surviving RCPID

### Stage 4 — Remove Brands

Remove stop-sell brands from the MAP's directory. This signals to other MAPs that those CPs no longer exist. The RCPIDs are:
- Retained in time-series data for audit records
- Archived under normal data retention policies
- Never reused for different brands

## 8.4 CP Going into Administration

When a CP enters administration with outstanding in-flight orders:

### MAP Responsibilities

1. **Hold all in-flight orders**: Switching to a CP in administration would have greater impact on end consumers than maintaining the status quo
2. **Continue processing outbound switches**: All in-flight orders transferring **away** from the CP in administration MUST continue to be processed, even if the MAP is not being paid
3. **Suspend new business**: The MAP sets the CP status to `SUSPENDED` in the directory
   - No new Switch Matches or Switch Orders will be processed
   - Existing customers are locked with their current provider under business continuity terms
4. **Await resolution**: Continue until the CP is recovered by another party or managed by an appointed insolvency team

### Industry Considerations

The response of a MAP when a CP enters administration MUST be formally defined by each individual MAP and is outside of the scope of the CSF. Refer to [OTA2 guidance](https://www.offta.org.uk/siteassets/ota/solr-industry-process.pdf?v=384772) 

## 8.5 Summary of Built-in Protections

| Scenario | OTS Capability | CSF Capability |
|---|---|---|
| CP changes MAP | Significant manual effort | Seamless — DNS update + RCPID Status export |
| In-flight order portability | Not supported | Built-in via standardised JSON export |
| MAP failure (online) | Limited options | Automated conflict resolution + export |
| MAP failure (offline) | Major disruption | CP emergency migration within 2 working days |
| Brand consolidation | Ad-hoc | Staged process with directory controls |
| CP administration | Undefined | Defined responsibilities with status controls |

---

<!-- DOCUMENT: part2/09-operations | Part 2 — Implementation — 9. Operations -->

---
title: 9. Operations
tags: [Part 2]

---

# 9. Operations

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0


## 9.1 Monitoring

Detailed monitoring specifications are to be defined by the TAG. The following principles apply:

MAPs MUST implement:
- Audit payload monitoring for all message exchanges
- Endpoint availability monitoring with automated alerting
- Anomaly detection for unusual traffic patterns

MAPs SHOULD implement:
- Transparent status dashboards accessible by connected providers
- Service status API endpoints for programmatic monitoring
- Incident and planned change indicators in the MAP registry

## 9.2 Malicious Behaviour Detection

In all of these scenerios is it not in the commerical interest of MAP to behave in a malicous way and all MAPs will be vetted through the onboarding process. The following scenarios MUST be monitored to detect and prevent malicious or erroneous behaviour that could happen if a MAPs was compromised. This situation is not unique to any type of architecture, hub or peer-to-peer, but within the CSF there are inherent protection mechanisms to help handle these realworld scenarios as follows:

### 9.2.1 Directory Hijacking

A MAP continues to advertise a CP in its directory after the CP has moved to another MAP. **Detection**: The CP will appear in two registries simultaneously, but only one DNS `_mapkey` entry will be valid. **Resolution**: DNS-based conflict resolution identifies the legitimate MAP.

### 9.2.2 Fraudulent CP Advertisement

A MAP advertises a CP that does not belong to it, with an incorrect root domain, attempting to send fraudulent messages. **Detection**: If all DNS entries are referentially correct, automated detection is difficult. **Resolution**: Escalation and severe penalties for the misbehaving MAP. This is monitored through the onboarding and testing process.

### 9.2.3 Traffic Blackholing

A MAP silently drops messages destined for one or more of its CPs. **Detection**: Sending MAPs will observe failed deliveries and timeouts. **Resolution**: Escalation via MAP contact details in the registry.

### 9.2.4 Denial of Service

Due to the trusted nature of MAP-to-MAP connections, a compromised or buggy MAP could launch a denial-of-service attack against another MAP. **Detection**: Unusual traffic volume or patterns. **Resolution**: Implement standard rate limiting and the following protections:

- Reduce response frequency to make the target less appealing
- Classify the source CP as suspicious and broadcast through the directory
- Implement circuit-breaker patterns to stop processing from the offending source
    - Software design practice used to prevent cascading failures in distributed systems, such as microservices. It acts like a safety switch that temporarily blocks calls to an unresponsive or failing service, allowing it time to recover while protecting the main system from wasting resources.The pattern dynamically manages traffic using three primary states:
    - Closed: The system operates normally, and requests flow freely to the dependent service.
    - Open: The failure rate crosses a predefined threshold. The "breaker trips," immediately blocking all requests to prevent further strain or system-wide crashes.
    - Half-Open: After a set timeout, a few test requests are allowed to pass. If they succeed, the system returns to the Closed state; if they fail, it reverts to the Open state.

### 9.2.5 False Contact Information

A MAP advertises incorrect support contact information, redirecting support queries to malicious websites or phone numbers. **Detection**: Manual verification during onboarding and periodic audits. **Resolution**: Escalation and removal from the network.

> More details on detection and protection are included in the TAG's Onboarding and Testing documentation.

## 9.3 Standard Reporting and KPIs

### 9.3.1 Overview

In a distributed exchange model, there is no centralised hub for reporting. This offers advantages:

- **No expensive centralised reporting tool** to fund and maintain
- **No security risks** from a single entity tracking all industry-wide exchange patterns
- **No competition concerns** from one party having visibility of all switching traffic

MAPs have significant opportunities to provide detailed reporting statistics to their CPs and the wider community while meeting any regulatory requirements.

### 9.3.2 Regulatory Reporting

At the time of writing, there are no official Ofcom statistics that must be collected for business switching. This is recorded in the risk register (RK1). A baseline set of mandatory data point collections needs to be established, with consistent calculations published in this document. A method for sharing statistics with Ofcom may be required if they mandate submissions.

### 9.3.3 Industry Reporting

A standard set of industry metrics is to be defined by the TAG and will be included in subsequent versions of the CSF as part of its feature release mechanism allowing CP/MAPs to support this when they are ready.

- Switch Match success/failure rates by sending and receiving CP
- Switch Order completion rates and timelines
- In-session Switch Match failure counts (using an incremented counter in the audit envelope)
- Grouping of failures by volume per CP to identify patterns

> **OTS Gap**: The significant 1107 error ratio currently seen with OTS needs to be addressed. By enabling in-session Switch Match failure counts, the industry can distinguish between, for example, 17 attempts to achieve a successful match (which is 1 success, not 16 failures) and genuine systemic issues.


## 9.4 Outage Notification

The CSF outage notification mechanism is registry-native: operational status is published in the MAP Registry alongside connectivity and contact information. Because MAPs pull each other's registries at up to 5-minute intervals, any status change propagates across the network within one polling cycle — without any separate notification channel, outage calendar, or centralised hub.

The CSF considers traditional outage calendars (as used in OTS) to be outdated. A MAP suffering an incident should not need to telephone a central service desk or update a shared spreadsheet. By publishing status directly in the registry, the network self-heals: other MAPs detect the outage automatically, queue messages accordingly (see [§1.3 Message Delivery Policy](04-message-api.md)), and resume delivery as soon as the outage entry is cleared.

### 9.4.1 Design Principles

- **Registry-native**: Outage state lives in `map/outage[]` in the MAP Registry — the same pull used for CP discovery also delivers operational status.
- **Near-real-time**: At a 5-minute maximum polling interval, all connected MAPs receive updated status within 5 minutes of publication.
- **Pull-based resilience**: If a MAP fails to respond, the receiving MAP checks its cached registry for a declared outage entry. This directly informs the retry and circuit-breaker logic in §1.3.
- **Graceful degradation**: A MAP that detects a `P1` or `P2` incident on a destination SHOULD queue messages and retry rather than immediately failing the CP interaction.
- **Self-clearing**: The publishing MAP adds and removes entries. An entry with a past `end` time SHOULD be removed once service is restored. An absent or empty `outage` array means fully operational — no entry is needed to signal this state.
- **Consistent with monitoring**: The `outage[]` state SHOULD be the source of truth for the MAP's `serviceStatusURI` status page and `serviceStatusServiceURI` API — both SHOULD reflect what the registry publishes.

### 9.4.2 Incident Priority

Each outage entry carries an ITIL-aligned `priority` value, directly linked to the SLA fix targets in [§9.9 of the Operational Excellence specification](../part1-framework/09-operational-excellence.md). An absent or empty `outage` array means the MAP is fully operational — no entry is needed to signal this state.

| Priority | §9.9 Category | CSF Meaning | Receiving MAP Action | SLA Fix Target |
|---|---|---|---|---|
| `P1` | MAP unavailable | Complete MAP outage — all services unavailable for all CPs | Queue ALL messages for ALL services; apply maximum exponential backoff per §1.3; raise an immediate P1 alert; escalate via the outage entry `contact` | Fix within 4 working hours |
| `P2` | CP unavailable | One or more services or CPs unavailable, or significant degradation affecting CP operations | Queue messages for affected services; apply expedited retry intervals; raise an internal alert; consult the outage entry `contact` if failures persist | Fix within 1 working day |
| `P3` | Service degradation | Partial or intermittent degradation — service operates but at reduced capacity or reliability | Continue delivery; apply shorter retry intervals; monitor closely; alert operations if failure rate increases | Fix within 2 working days |

> An absent or empty `outage` array means the MAP is fully operational. No entry is needed to signal this state.

### 9.4.3 Outage Types

| Type | When to Use |
|---|---|
| `PLANNED` | Scheduled maintenance or infrastructure change where service impact is expected. MAPs SHOULD publish planned outages at least **24 hours in advance** where possible. |
| `INCIDENT` | Unplanned failure or degradation. MAPs MUST publish an incident entry as soon as the incident is confirmed (target: **within 15 minutes** of detection). |

### 9.4.4 JSON Structure

The `outage` array is a new field in the `map` section of the CP Registry, positioned after the `contact` array and before `connectivity`. It reuses the same `contact` sub-object for per-outage escalation details. See the full field reference in [§5.4 of the CP Registry API specification](05-directory-api.md).

#### Fully operational — empty array

```json
{
  "map": {
    "name": "myMap",
    "version": "2026-06-05T08:00:00Z00000",
    "outage": []
  }
}
```

#### Planned maintenance window

```json
{
  "map": {
    "name": "myMap",
    "version": "2026-06-06T18:00:00Z00000",
    "outage": [
      {
        "type": "PLANNED",
        "start": "2026-06-07T02:00:00Z",
        "end": "2026-06-07T04:00:00Z",
        "affectedServices": ["GPLBMessages", "OTSMessages"],
        "description": "Scheduled database maintenance. Brief interruptions of up to 30 seconds may occur. Messages will be queued and delivered on completion.",
        "contact": {
          "type": "email",
          "value": "noc@mymapdomain.com",
          "comment": "24/7 NOC — quote this outage entry when contacting"
        }
      }
    ]
  }
}
```

#### Active incident (P2 — single service)

```json
{
  "map": {
    "name": "myMap",
    "version": "2026-06-05T11:42:00Z00000",
    "outage": [
      {
        "priority": "P2",
        "type": "INCIDENT",
        "start": "2026-06-05T11:38:00Z",
        "affectedServices": ["GPLBMessages"],
        "description": "Letterbox API for GPLBMessages is not responding. Engineering team engaged. ETA for resolution: 30 minutes.",
        "contact": {
          "type": "phone",
          "value": "01111 999999",
          "comment": "Major incident bridge — for MAP technical contacts only"
        }
      }
    ]
  }
}
```

#### Active incident (P1 — complete MAP outage)

```json
{
  "map": {
    "name": "myMap",
    "version": "2026-06-05T11:42:00Z00000",
    "outage": [
      {
        "priority": "P1",
        "type": "INCIDENT",
        "start": "2026-06-05T11:38:00Z",
        "description": "MAP infrastructure failure. All services unavailable. Engineering team engaged. ETA: 1 hour.",
        "contact": {
          "type": "phone",
          "value": "01111 999999",
          "comment": "Major incident bridge — for MAP technical contacts only"
        }
      }
    ]
  }
}
```

#### Multiple concurrent entries

A MAP may publish multiple entries — for example, a forthcoming planned outage alongside an active incident on a different service:

```json
{
  "map": {
    "name": "myMap",
    "version": "2026-06-05T11:42:00Z00000",
    "outage": [
      {
        "priority": "P2",
        "type": "INCIDENT",
        "start": "2026-06-05T11:38:00Z",
        "affectedServices": ["GPLBMessages"],
        "description": "GPLBMessages SwitchMatchResponses unavailable. Engineering engaged. ETA: 30 minutes.",
        "contact": { "type": "phone", "value": "01111 999999", "comment": "Major incident bridge" }
      },
      {
        "type": "PLANNED",
        "start": "2026-06-07T02:00:00Z",
        "end": "2026-06-07T04:00:00Z",
        "affectedServices": ["GPLBMessages"],
        "description": "Scheduled GPLB letterbox maintenance window.",
        "contact": { "type": "email", "value": "noc@mymapdomain.com" }
      }
    ]
  }
}
```

When multiple entries are present, the **highest priority** (lowest number) for a given service determines the action taken by receiving MAPs for that service.

### 9.4.5 Field Reference

| JSON Path | Description | Type | Required |
|---|---|---|---|
| `map/outage[]` | Array of current incident or planned maintenance entries. An empty array or absent field means fully operational. MAPs implementing outage notification SHOULD always include this field, even as an empty array, to signal participation. | Object Array | Yes (empty if operational) |
| `map/outage[]/priority` | ITIL incident priority aligned to §9.9 SLA targets: `P1` (MAP unavailable — fix within 4 working hours), `P2` (CP unavailable — fix within 1 working day), `P3` (service degradation — fix within 2 working days). This is the primary severity indicator. See §9.4.2. | String (enum) | Yes for `INCIDENT`, No for `PLANNED`|
| `map/outage[]/type` | Outage type: `PLANNED` or `INCIDENT`. See §9.4.3. | String (enum) | Yes |
| `map/outage[]/start` | Start time of the outage or maintenance window (ISO 8601 UTC). | DateTime | Yes |
| `map/outage[]/end` | Expected or actual end time (ISO 8601 UTC). For active incidents where resolution time is unknown, omit until the ETA is established. MAPs MUST add or update this field as the ETA becomes known. | DateTime | Optional |
| `map/outage[]/affectedServices` | Routing group names (matching `map/routingGroups[]/name`) covered by this entry. If absent or empty, **all services** on this MAP are considered affected. | String Array | Optional |
| `map/outage[]/description` | Human-readable status narrative. SHOULD include: what is affected, current status, ETA for resolution (if known), and any available workaround. Updated as the incident evolves. | String | Yes |
| `map/outage[]/contact` | Escalation contact specific to this outage (e.g. NOC phone number, incident bridge). Uses the same structure as a `map/contact[]` entry. | Object | Optional |
| `map/outage[]/contact/type` | Contact type: `phone`, `email`, or `url`. | String (enum) | Yes (if contact present) |
| `map/outage[]/contact/value` | Contact value (number, address, or URL). | String | Yes (if contact present) |
| `map/outage[]/contact/comment` | Usage instructions — e.g. reference numbers, bridge PINs, or when to use this contact. | String | Optional |

### 9.4.6 Receiving MAP Behaviour

When a MAP fetches another MAP's CP Registry, it MUST process the `outage` array as follows:

**Step 1 — Determine effective priority per service**

For each service in `map/connectivity/services[]`:

1. Collect all `outage[]` entries that reference that service in `affectedServices`, or have no `affectedServices` restriction (no restriction means all services are affected).
2. If any such entry carries `priority: "P1"`, the effective priority for that service is **P1**.
3. Otherwise, if any such entry carries `priority: "P2"`, the effective priority is **P2**.
4. Otherwise, if any such entry carries `priority: "P3"`, the effective priority is **P3**.
5. If no matching entries exist, the service is **fully operational** — proceed with normal delivery.

**Step 2 — Apply delivery policy**

| Effective Priority | Action |
|---|---|
| Fully operational (no entries) | Deliver messages normally |
| `P3` | Continue delivery; apply shorter retry intervals; monitor closely; alert operations if failure rate increases |
| `P2` | Queue messages for affected services; apply expedited retry intervals; raise an internal alert; consult the outage entry `contact` if failures persist |
| `P1` | Queue ALL messages for ALL services; apply maximum exponential backoff per §1.3; raise an immediate P1 alert; escalate via the outage entry `contact` |

**Step 3 — Handle unexpected failures without a declared outage**

If a MAP fails to respond and has **no** outage entry in its registry, the receiving MAP SHOULD:

1. Attempt delivery using the normal retry and backoff policy (§1.3)
2. Re-pull the source MAP's registry at the next poll cycle
3. If an outage entry subsequently appears (the MAP published one after the failure began), treat it as declared and act accordingly
4. If no entry appears after repeated failures, escalate via the MAP's `map/contact[]` entries — the absence of a declared outage when the MAP is unreachable is itself an escalation trigger

### 9.4.7 MAP Obligations

**Planned Outages**

- MAPs MUST publish a `PLANNED` entry at least **24 hours before** any maintenance with expected service impact
- The entry MUST include a realistic `end` time and a `priority` classification — typically `P3` for routine maintenance; `P2` where CP operations are expected to be significantly affected
- If the maintenance completes early, the MAP MUST remove the entry promptly
- If impact extends beyond the declared `end`, the MAP MUST update the entry immediately

**Incidents**

- MAPs MUST publish an `INCIDENT` entry within **15 minutes** of incident confirmation
- The entry MUST include a `priority` classification. The declared `priority` commits the publishing MAP to the corresponding SLA fix target in §9.9
- The initial entry MAY carry a brief `description` if full impact is still being assessed — it MUST be updated as the situation develops
- If the incident escalates — for example, from a single service affected (`P2`) to complete MAP unavailability (`P1`) — the MAP MUST update `priority` and `description` immediately
- MAPs MUST update `priority` and `description` as the incident evolves (e.g., downgrading from `P1` to `P2` on partial recovery)
- MAPs MUST remove the entry within **30 minutes** of confirmed full recovery
- Leaving stale entries causes unnecessary queuing by other MAPs — timely clearance is a network-wide obligation

### 9.4.8 Relationship to map.status and Monitoring

The `outage` array is distinct from the `map/status` lifecycle field:

| Mechanism | Purpose | Values |
|---|---|---|
| `map/status` | Administrative / lifecycle state — used for onboarding and suspension | `ACTIVE`, `TEST`, `SUSPEND` |
| `map/outage[]` | Operational state — real-time ITIL incident priority | `P1`, `P2`, `P3` entries (absent = fully operational) |

A MAP that is `ACTIVE` in `map/status` may simultaneously carry P1/P2/P3 entries in `map/outage[]` during an incident. A MAP with `map/status: "SUSPEND"` would not normally publish outage entries — the suspension itself signals unavailability.

The `outage[]` array SHOULD be the single source of truth for the MAP's operational status pages: the `serviceStatusURI` human-readable page and the `serviceStatusServiceURI` API endpoint SHOULD derive their published status from the same underlying state, ensuring consistency between what the registry advertises and what external observers see.

### 9.4.9 Feature Advertising

MAPs that implement the outage notification mechanism SHOULD advertise the `outage-notification` feature in their `map/csf/features[]` array (see design proposal §6.1 of the Review Tracker):

```json
"csf": {
  "versions": ["2.0"],
  "currentVersion": "2.0",
  "features": ["outage-notification", "status-api"]
}
```

A MAP that does not advertise `outage-notification` should be treated by receiving MAPs as if its `outage[]` is always empty (GREEN) — but its status signal cannot be relied upon.

## 9.5 Risk Register

The following risk register records risks identified across the MAP membership:

| Date | ID | Description | Status | Impact | Likelihood | Owner |
|---|---|---|---|---|---|---|
| 2025-03-20 | RK1 | **Regulatory and industry reporting requirements** — No official Ofcom statistics mandated for business switching. Need baseline mandatory data points with consistent open calculations. In-session Switch Match failure counting needs to be resolved. | Discovery | Low | High | TBD |
| 2025-04-09 | RK2 | **CP and MAP due diligence checks** — When onboarding, the sponsor is expected to complete typical credit checks, company registration, VAT registration, trading history, fraud, and ICO Data Protection registration checks. This is an industry-wide gap, not specific to CSF. | TBD | Medium | Low | TBD |
| 2025-04-09 | RK3 | **Data retention policy** — Like due diligence, this is a broader industry discussion. Must address across both OTS and SforB to determine suitable retention policies and archiving/destruction methods acceptable to Data Controllers (CPs). | TBD | TBD | TBD | TBD |


## 9.6 The Right to Block

The right to block is a **protective mechanism, not a competitive tool**. A MAP may temporarily suspend routing to or from another MAP or CP when network integrity, security, or compliance obligations require it. No central authority approves a block — the mechanism is self-administering — but each MAP's obligations under the Membership Agreement (MoU) govern when a block is legitimate, and impose strict notification and escalation duties.

### 9.6.1 Principles

- **Protection-first**: Blocking exists to protect the network, CPs, and end-customers — not to disadvantage competitors
- **Proportionality**: The response must match the threat. Automatic technical blocks are the lightest touch; governance escalation is the most severe
- **Transparency**: The blocking MAP MUST notify the affected party promptly and document the grounds
- **Time-limited**: All blocks MUST be reviewed at defined intervals. An indefinite block requires governance oversight
- **Self-healing**: Reinstatement SHOULD be immediate once the triggering condition is resolved

### 9.6.2 Grounds for Blocking

Three categories define legitimate grounds:

**Category A — Technical / Security**

An immediate block is permitted without prior notification:

| Trigger | Example |
|---|---|
| DoS or traffic flooding | Inbound MAP-to-MAP message rate exceeds the agreed cap by more than 10× |
| Malformed or malicious payloads | Repeated messages failing DKIM signature validation or containing injection attempts |
| Credential or key compromise | A MAP's signing key is reported or confirmed compromised |
| Active fraud | A MAP advertises CPs it does not own (§9.2.2) |

**Category B — Operational / SLA**

A notification attempt SHOULD be made before imposing the block:

| Trigger | Example |
|---|---|
| Persistent unresponsiveness | A MAP unreachable for more than 4 continuous hours with no `outage[]` entry published (§9.4) |
| Repeated SLA breaches | Three or more Priority 1 SLA breaches (§9.9) within a rolling 30-day window |
| Stale registry data | CP Registry not updated for more than 48 hours with no declared reason |
| Unresolved security vulnerability | A critical vulnerability unpatched beyond the agreed remediation window |

**Category C — Governance / MoU**

Formal written notification to GPLB-SG MUST precede or accompany the block:

| Trigger | Example |
|---|---|
| Material MoU breach | Persistent refusal to comply with TAG-ratified obligations |
| Network integrity risk | Evidence that a MAP poses a systemic risk to the CSF network |
| Regulatory enforcement | A MAP is subject to enforcement action that affects its CSF participation |

### 9.6.3 Blocking Procedure

Blocks operate at three tiers:

| Tier | Grounds | Decided By | Max Unilateral Duration | Notification Deadline |
|---|---|---|---|---|
| **T1 Automatic** | Category A | Technical systems (circuit breaker / rate limiter) | Indefinite while threat persists; auto-clears | Notify affected MAP within 4 working hours if block persists |
| **T2 Operational** | Category B | Blocking MAP's authorised personnel | 5 working days | Notify affected MAP within 2 working hours of imposing the block |
| **T3 Governance** | Category C | Blocking MAP initiates; GPLB-SG oversees | Until resolved by governance | Notify affected MAP and GPLB-SG secretary within 1 working day |

**Tier 1 — Automatic Technical Block**

Technical protections (rate limiters, circuit breakers, signature validation) activate automatically. When a block persists beyond 4 working hours, the blocking MAP's operations team MUST notify the affected MAP via its `map/contact[]` entries. The block lifts automatically when the threat condition clears, or is manually lifted after review.

**Tier 2 — Operational Block**

1. Before blocking, the blocking MAP SHOULD attempt to contact the affected MAP via `map/contact[]` to allow resolution
2. If no response within 2 working hours — or if immediate risk exists — the block MAY be imposed without prior contact
3. The blocking MAP MUST notify the affected MAP of: the block, the specific Category B grounds, and the conditions for reinstatement
4. The block MUST be reviewed every 5 working days. If unresolved, the blocking MAP MUST escalate to T3

**Tier 3 — Governance Block**

1. The blocking MAP notifies the GPLB-SG secretary and the affected MAP simultaneously, citing Category C grounds with evidence
2. GPLB-SG facilitates a resolution process within a timeframe agreed by the steering group
3. The blocking MAP may maintain the block during governance proceedings
4. Resolution may include: conditional reinstatement, a formal remediation plan, or suspension of the affected MAP's participation (`map/status: "SUSPEND"`)

### 9.6.4 Escalation Path

```
T1 (automatic)   →  4 working hours  →  Notify affected MAP
T2 (operational) →  5 working days   →  Escalate to GPLB-SG (T3)
T3 (governance)  →  GPLB-SG process  →  Reinstatement or suspension
```

A blocking MAP MUST NOT remain at T2 indefinitely. Escalation to T3 after 5 working days is a duty, not an option.

### 9.6.5 Reinstatement

Reinstatement is as lightweight as the block — no central approval is required for T1 or T2.

**Tier 1**: Auto-reinstated when the threat clears, or manually lifted by the blocking MAP. No formal process required.

**Tier 2**:
1. The affected MAP notifies the blocking MAP that the triggering condition has been resolved, with evidence
2. The blocking MAP MUST confirm or dispute within 1 working day
3. Confirmed: the block is removed immediately
4. Disputed: escalates to T3

**Tier 3**: Reinstatement requires GPLB-SG agreement. The affected MAP submits a reinstatement request with a remediation summary. GPLB-SG may impose conditions (e.g. monitoring period, reporting obligations) before granting full reinstatement.

### 9.6.6 Misuse of the Right to Block

A block imposed without legitimate grounds, or maintained beyond the point of resolution, is itself a MoU breach. An affected MAP that believes it has been blocked improperly may escalate directly to T3 — bypassing the blocking MAP — by notifying the GPLB-SG secretary with evidence. A MAP found to have blocked without grounds, or to have used blocking as a competitive measure, is subject to the same governance remedies as the blocked MAP.

### 9.6.7 MoU and Governance Integration

The right to block takes effect through the MAP Membership Agreement. The MoU MUST include:

- A reference to this section as the governing procedure for all blocks
- An obligation on all MAPs to maintain `map/contact[]` entries reachable within the notification windows above
- An obligation to publish and maintain `map/outage[]` (§9.4) as a precondition for challenging any Category B block raised on grounds of unresponsiveness
- An acknowledgement that T3 blocks may result in formal suspension of MAP participation

The **User Rights documentation** SHOULD reference this section to make clear to CPs that their MAP has both the right and the obligation to block other MAPs in defined circumstances — and that this mechanism exists to protect CP service continuity, not to restrict competition.

---

<!-- DOCUMENT: part2/appendix-openapi | Part 2 — Implementation — Appendix: OpenAPI Specification -->

---
title: 'Appendix: OpenAPI Specification'
tags: [Part 2]

---

# Appendix: OpenAPI Specification

> Connected Services Framework (CSF) — Part 2: Implementation — Version 2.0

## Overview

This appendix contains the OpenAPI 3.0.3 specification for the CSF Letterbox API. It defines the message sending/receiving interface between MAPs, including:

- The JAM envelope structure (source, destination, routingID, auditData)
- CSF-specific HTTP headers for DKIM signing (`X-CSF-SIGNATURE`, `X-CSF-SIGNATURE-DATESTAMP`) and route tracking (`X_CSF_ROUTE`)
- OAuth 2.0 Bearer authentication
- All synchronous error responses (HTTP 4xx/5xx with 9xxx and 8xxx error codes)
- The asynchronous message delivery failure structure

This specification is compatible with the [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf). MAPs implementing this spec can exchange messages with both CSF MAPs and the TOTSCo Hub.

This OpenAPI specification should be reviewed alongside the Message API documentation to ensure all error codes, field descriptions, and examples are aligned. The `messageBody` is modelled as a generic object — in production, the property name should match the `routingID` (e.g., `businessSwitchMatchRequest`).

---

## Specification

```yaml
openapi: 3.0.3
info:
  title: CSF Letterbox API
  version: "2.0.0"
  description: |
    The Connected Services Framework (CSF) Letterbox API enables Managed Access
    Providers (MAPs) to exchange messages on behalf of their Communications
    Providers (CPs) over a secure, peer-to-peer transport layer.

    This API is compatible with the TOTSCo Hub letterbox interface (v2.0) and
    uses the industry-standard JSON Asynchronous Messaging (JAM) envelope for
    addressing, routing, and correlation.

    ## Key Characteristics

    - **Transport**: HTTPS over TLS 1.3 (mandatory)
    - **Authentication**: OAuth 2.0 Bearer Token (Client Credentials flow)
    - **Message Signing**: DKIM-based PKI via `X-CSF-SIGNATURE` header (RFC 6376)
    - **Acceptance Model**: HTTP 202 — accepted for processing, not yet completed
    - **Error Model**: Synchronous 4xx/5xx with 9xxx (industry) and 8xxx (CSF) codes

    ## Message Structure

    Every message consists of:
    1. An **envelope** containing delivery instructions (source, destination,
       routingID, auditData) — defined by the JAM Specification
    2. A **message body** containing the industry process payload (e.g., SforB
       Switch Match) — defined by the relevant process specification

    The actual message body property name MUST match the `routingID`
    (e.g., `businessSwitchMatchRequest`). This specification models it as a
    generic `messageBody` object for portability.

  contact:
    name: Telecom Technical Architecture Group (TAG)
  license:
    name: Open — Free for any CP or MAP to use
    url: https://github.com/nowyoyo/csf-documentation

servers:
  - url: https://{fqdn}/letterbox
    description: MAP Letterbox Endpoint
    variables:
      fqdn:
        default: api.example-map.com
        description: The MAP's Fully Qualified Domain Name (RFC 1035)

paths:
  /{version}/post:
    post:
      operationId: postMessage
      summary: Post a JAM message to the letterbox
      description: |
        Accepts a JAM-formatted JSON message and returns **202 Accepted** if
        the message passes validation and is accepted for processing.

        ### Validation Sequence

        The receiving MAP validates the message in the following order:

        1. OAuth 2.0 token validity
        2. JSON message structure
        3. Envelope attribute validation
        4. Source type and RCPID validity
        5. Source RCPID account status
        6. Destination type and RCPID validity
        7. Destination RCPID account status
        8. Source MAP authorisation via `_mapkey` DNS check (HTTP 403 + 9301 on mismatch) — see Message API §4.4.1
        9. Routing ID validity
        10. DKIM signature verification (via `X-CSF-SIGNATURE`)

        Validation stops at the first failure and the corresponding error is returned.

        ### DKIM Signing (CSF MAPs only)

        Messages between CSF MAPs MUST include `X-CSF-SIGNATURE` and
        `X-CSF-SIGNATURE-DATESTAMP` headers. Messages from HMAPs (e.g., TOTSCo)
        are not required to include these headers.

      tags:
        - Messaging
      security:
        - bearerAuth: []

      parameters:
        - name: version
          in: path
          required: true
          description: |
            Letterbox API version number. This version will only change if there
            is a substantial update in how messages are processed. Previous
            versions remain in service for backward compatibility.
          schema:
            type: string
            pattern: "^[0-9]+\\.[0-9]+$"
            example: "2.0"

        - name: X-CSF-SIGNATURE
          in: header
          required: false
          description: |
            DKIM signature for the message. Required for CSF MAP-to-MAP exchanges.
            Not required for HMAP (e.g., TOTSCo) exchanges.

            Format follows RFC 6376 with CSF-specific tags:
            `a=rsa-sha256; c=simple/simple; s={RCPID}; d={domain}; bh={bodyHash}; h=X-CSF-SIGNATURE-DATESTAMP; b={signature}`

            See PKI & DKIM Signing documentation for full details.
          schema:
            type: string
          example: "a=rsa-sha256; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; bh=/CWGLVBT2gdyO5cudfAEUSF43KHLmlJjU/Nr2YNqkos=; h=X-CSF-SIGNATURE-DATESTAMP; b=4J4OGZfxi..."

        - name: X-CSF-SIGNATURE-DATESTAMP
          in: header
          required: false
          description: |
            Timestamp of when the DKIM signature was created. Required whenever
            `X-CSF-SIGNATURE` is present. Embedded in the signature to protect
            against replay attacks.
          schema:
            type: string
            pattern: "^[0-9]{15}$"
            description: Format yyyyMMddHHmmssS (S = tenth of a second)
          example: "202508121340391"

        - name: X_CSF_ROUTE
          in: header
          required: false
          description: |
            Optional but recommended. Records the route the message has taken.
            Each MAP adds a new header entry (do not append to existing headers).
            Format: `{EpochMilliseconds} {MAPName}` (alphanumerics only).
          schema:
            type: string
          example: "1741947045684 TheYellowMap"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LetterboxMessage'
            examples:
              sfbSwitchMatch:
                summary: SforB Switch Match Request
                description: A business Switch Match request using UUIDv4 RCPIDs
                value:
                  envelope:
                    source:
                      type: RCPID
                      identity: "d8322d80-92c8-4906-a408-f1d2daf7e03d"
                      correlationID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                    destination:
                      type: RCPID
                      identity: "7d87c2a7-4f64-433c-8ae1-9460f19a0a13"
                    routingID: businessSwitchMatchRequest
                    auditData:
                      - name: "channel"
                        value: "api"
                      - name: "testFlag"
                        value: "false"
                  businessSwitchMatchRequest:
                    customerPostcode: "AB12 3CD"
                    customerSurname: "SMITH"
                    businessName: "Smith Trading Ltd"

              deliveryFailure:
                summary: Message Delivery Failure Notification
                description: Asynchronous notification when a message cannot be delivered
                value:
                  envelope:
                    source:
                      type: RCPID
                      identity: "MAP-X-IDENTITY"
                    destination:
                      type: RCPID
                      identity: "d8322d80-92c8-4906-a408-f1d2daf7e03d"
                      correlationID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                    routingID: messageDeliveryFailure
                    auditData:
                      - name: "originalDestinationType"
                        value: "RCPID"
                      - name: "originalDestination"
                        value: "7d87c2a7-4f64-433c-8ae1-9460f19a0a13"
                      - name: "originalRoutingID"
                        value: "businessSwitchMatchRequest"
                      - name: "faultCode"
                        value: "9008"
                  messageDeliveryFailure:
                    code: "9008"
                    text: "Unable to deliver the message to the destination, timed out."
                    severity: "failure"

      responses:
        '202':
          description: |
            **Accepted** — The message has been accepted for processing, but
            processing has not been completed. The request might or might not
            be eventually acted upon and may be disallowed when processing occurs.

            No JSON body is returned on success.

        '400':
          description: |
            **Bad Request** — The message failed validation. This covers:
            - Invalid JSON structure
            - Missing required envelope fields
            - Invalid source/destination type or RCPID
            - Invalid routing ID
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/HttpError'
              examples:
                invalidDestinationType:
                  summary: Unknown destination type (9000)
                  value:
                    errorCode: "9000"
                    errorText: "Unknown or missing destination Type."
                invalidDestinationId:
                  summary: Unknown destination RCPID (9001)
                  value:
                    errorCode: "9001"
                    errorText: "Unknown or Invalid destination."
                invalidSourceType:
                  summary: Unknown source type (9002)
                  value:
                    errorCode: "9002"
                    errorText: "Unknown or invalid source Type."
                invalidSourceId:
                  summary: Unknown source RCPID (9003)
                  value:
                    errorCode: "9003"
                    errorText: "Unknown or invalid source Id."
                invalidRoutingMapping:
                  summary: No routing ID mapped to source (9010)
                  value:
                    errorCode: "9010"
                    errorText: "No routingID is mapped with Source RCP."
                invalidRoutingId:
                  summary: Unknown routing ID (9012)
                  value:
                    errorCode: "9012"
                    errorText: "Unknown or invalid routing ID."
                schemaValidation:
                  summary: Schema validation failure
                  value:
                    code: "400"
                    message: "Bad Request"
                    description: "Schema validation failed in the Request: [Path '/directory'] Object has missing required properties ([\"listID\"])"

        '401':
          description: |
            **Unauthorised** — Authentication failed. This covers:
            - Invalid or expired OAuth 2.0 bearer token
            - Source type and ID not permitted from originating location (9004)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/HttpError'
              examples:
                sourceNotPermitted:
                  summary: Source not permitted from this location (9004)
                  value:
                    errorCode: "9004"
                    errorText: "Source type and ID not permitted from originating location."
                invalidCredentials:
                  summary: Invalid OAuth 2.0 credentials
                  value:
                    code: "900901"
                    message: "Invalid Credentials"
                    description: "Access failure for API: /letterbox/v2.0, version: v2.0 status: (900901) - Invalid Credentials. Make sure you have provided the correct security credentials."

        '403':
          description: |
            **Forbidden** — Authorisation succeeded but the request is not
            permitted. This covers:
            - Source RCPID account status is not valid (9003)
            - Destination RCPID account status is not valid (9001)
            - DKIM signature verification failed (8101 PERM_FAIL, 8102 TEMP_FAIL)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/PkiError'
              examples:
                sourceAccountInvalid:
                  summary: Source RCPID account status invalid (9003)
                  value:
                    errorCode: "9003"
                    errorText: "Source RCPD ID account status is not valid."
                destinationAccountInvalid:
                  summary: Destination RCPID account status invalid (9001)
                  value:
                    errorCode: "9001"
                    errorText: "Destination RCPD ID account status is not valid."
                pkiPermFail:
                  summary: DKIM signature permanently failed (8101)
                  value:
                    errorCode: 8101
                    errorText: "Domain gplb-test.nowyoyo.net is not valid key source for CP 809b6e65-a6e7-40f6-8b52-04dd65b6fce1"
                pkiTempFail:
                  summary: DKIM signature temporarily failed (8102)
                  value:
                    errorCode: 8102
                    errorText: "Unable to resolve 809b6e65-a6e7-40f6-8b52-04dd65b6fce1._domainkey.gplb-test.nowyoyo.net. TXT entry does not exist."
                pkiBodyHashMismatch:
                  summary: Body hash mismatch (8101)
                  value:
                    errorCode: 8101
                    errorText: "Body Hash 3hzlA9zA8SAVapmd5ZZnMdwaZpk/WOyQXixrqVu/WMc= is different to signature /CWGLVBT2gdyO5cudfAEUSF43KHLmlJjU/Nr2YNqkos="
                pkiMissingTags:
                  summary: Missing mandatory signature tags (8101)
                  value:
                    errorCode: 8101
                    errorText: "Signature has missing mandatory tag(s): [b, bh]"

        '404':
          description: |
            **Not Found** — The requested resource was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
              examples:
                notFound:
                  value:
                    code: "404"
                    message: "Runtime Error"
                    description: "No matching resource found for given API Request"

        '405':
          description: |
            **Method Not Allowed** — The HTTP method is not supported
            (e.g., GET instead of POST).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
              examples:
                methodNotAllowed:
                  value:
                    code: "405"
                    message: "Runtime Error"
                    description: "Method not allowed for given API resource"

        '429':
          description: |
            **Too Many Requests** — Rate limit exceeded. The `nextAccessTime`
            field indicates when the client can retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThrottledError'
              examples:
                throttled:
                  value:
                    code: "900804"
                    message: "Message throttled out"
                    description: "MAP exceeded the quota. You can access API after 2026-Apr-26 04:43:00+0000 UTC"
                    nextAccessTime: "2026-Apr-26 04:43:00+0000 UTC"

        '500':
          description: |
            **Internal Server Error** — An unexpected error occurred during processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
              examples:
                internalError:
                  value:
                    code: "101503"
                    message: "Runtime Error"
                    description: "Error connecting to the back end"

        '501':
          description: |
            **Not Implemented** — The HTTP method is not supported by the server.

        '502':
          description: |
            **Bad Gateway** — Invalid response from an upstream server.

        '503':
          description: |
            **Service Unavailable** — The server is temporarily unable to handle
            the request (e.g., maintenance). Clients SHOULD respect the
            `Retry-After` header if present.

        '504':
          description: |
            **Gateway Timeout** — The server did not receive a timely response
            from an upstream server.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        OAuth 2.0 Bearer Token obtained via the Client Credentials flow.
        Request a token from the target MAP's OAuth token endpoint using
        the `client_id` and `client_secret` exchanged during onboarding.

  schemas:

    # ──────────────────────────────────────────────
    # Request Body
    # ──────────────────────────────────────────────

    LetterboxMessage:
      type: object
      required:
        - envelope
      properties:
        envelope:
          $ref: '#/components/schemas/Envelope'
      additionalProperties:
        type: object
        description: |
          The message body. The property name MUST match the `routingID`
          in the envelope (e.g., `businessSwitchMatchRequest`,
          `messageDeliveryFailure`). Modelled here as `additionalProperties`
          because the key is dynamic.
      description: |
        A JAM-formatted message consisting of an envelope and a
        process-specific message body.

    Envelope:
      type: object
      required:
        - source
        - destination
        - routingID
      properties:
        source:
          $ref: '#/components/schemas/EndpointRef'
          description: |
            The originator of the message and return address for any
            response. The `correlationID` MUST always be provided in source.
        destination:
          $ref: '#/components/schemas/EndpointRef'
          description: |
            The intended recipient. The `correlationID` is only present in
            response messages — it contains the original sender's correlationID.
        routingID:
          type: string
          description: |
            Determines the message type and routing. Must be a value supported
            by the recipient MAP's routing groups. Valid values include
            `businessSwitchMatchRequest`, `businessSwitchOrderRequest`,
            `residentialSwitchMatchRequest`, `messageDeliveryFailure`,
            and `notification`.
          example: businessSwitchMatchRequest
        auditData:
          type: array
          description: |
            Name-value pairs for regulatory reporting, diagnostics, and
            industry auditing. Each industry process defines its own audit
            requirements. The `testFlag` audit field MUST be set to `"true"`
            for all test traffic.
          items:
            $ref: '#/components/schemas/AuditDatum'

    EndpointRef:
      type: object
      required:
        - type
        - identity
      properties:
        type:
          type: string
          description: |
            The directory list type. Currently only `RCPID` is supported.
          enum:
            - RCPID
          example: RCPID
        identity:
          type: string
          description: |
            The RCPID of the sender (source) or recipient (destination).
            For CSF, this is a UUIDv4 (36 characters). For TOTSCo
            compatibility, 4-character OTS codes are also accepted.
          example: "d8322d80-92c8-4906-a408-f1d2daf7e03d"
        correlationID:
          type: string
          description: |
            In source: MUST always be provided. Should be sufficiently unique
            to allow correlation of responses over a reasonable period. UUIDs
            are recommended.

            In destination: only present in response messages, containing the
            original sender's correlationID.
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

    AuditDatum:
      type: object
      required:
        - name
        - value
      properties:
        name:
          type: string
          description: The audit field name
          example: "channel"
        value:
          type: string
          description: The audit field value
          example: "api"

    # ──────────────────────────────────────────────
    # Asynchronous Delivery Failure Body
    # ──────────────────────────────────────────────

    MessageDeliveryFailure:
      type: object
      required:
        - code
        - text
        - severity
      properties:
        code:
          type: string
          description: |
            Numeric fault code for remedial action. Uses 9xxx series codes.
          example: "9008"
        text:
          type: string
          description: Human-readable description of the fault
          example: "Unable to deliver the message to the destination, timed out."
        severity:
          type: string
          description: |
            Nature of the notification.
          enum:
            - information
            - warning
            - failure
          example: failure
      description: |
        Sent asynchronously by a MAP when it cannot deliver a message to the
        intended recipient. The envelope source is the MAP that failed to
        deliver, and the envelope destination contains the original sender's
        correlationID.

        ### Delivery Failure Codes (9xxx)

        | Code | Description | Severity |
        |------|-------------|----------|
        | 9005 | No valid route to destination | failure |
        | 9006 | Rejected — invalid message format (HTTP 400) | failure |
        | 9007 | Recipient rejected message (HTTP 404) | failure |
        | 9008 | Timed out after retries (HTTP 5xx or timeout) | failure |
        | 9013 | Invalid API key | failure |
        | 9014 | API key expired | failure |
        | 9015 | Digital certificate invalid | failure |
        | 9016 | Digital certificate expired | failure |

    # ──────────────────────────────────────────────
    # Error Response Bodies
    # ──────────────────────────────────────────────

    ValidationError:
      type: object
      required:
        - errorCode
        - errorText
      properties:
        errorCode:
          type: integer
          description: |
            Numeric error code from the 9xxx (industry) or 8xxx (CSF) series.
          example: "9002"
        errorText:
          type: string
          description: |
            Human-readable description of the error with suggested
            remedial action.
          example: "Unknown or invalid source Type."
      description: |
        Returned for validation errors detected during envelope processing.
        Uses 9xxx codes for industry-standard validations and 8xxx codes
        for CSF PKI errors.

        ### Validation Error Codes (9xxx)

        | Code | HTTP | Description |
        |------|------|-------------|
        | 9000 | 400 | Unknown or missing destination type |
        | 9001 | 400 | Unknown or invalid destination RCPID |
        | 9001 | 403 | Destination RCPID account status invalid |
        | 9002 | 400 | Unknown or invalid source type |
        | 9003 | 400 | Unknown or invalid source RCPID |
        | 9003 | 403 | Source RCPID account status invalid |
        | 9004 | 401 | Source not permitted from originating location |
        | 9010 | 400 | No routing ID mapped to source RCP |
        | 9012 | 400 | Unknown or invalid routing ID |

        ### PKI Error Codes (8xxx)

        | Code | HTTP | Description | Retry? |
        |------|------|-------------|--------|
        | 8101 | 403 | PERM_FAIL — signature verification permanently failed | No |
        | 8102 | 403 | TEMP_FAIL — signature verification temporarily failed | Yes |

    PkiError:
      type: object
      required:
        - errorCode
        - errorText
      properties:
        errorCode:
          type: integer
          enum:
            - 8101
            - 8102
          description: |
            8101 = PERM_FAIL (do not retry)
            8102 = TEMP_FAIL (retry with backoff)
        errorText:
          type: string
          description: Detailed description of the PKI failure
      description: |
        Returned with HTTP 403 when DKIM signature verification fails.
        Only used for CSF MAP-to-MAP exchanges (not sent to TOTSCo).

    HttpError:
      type: object
      properties:
        code:
          type: string
          description: HTTP status code or internal process code
          example: "400"
        message:
          type: string
          description: Short error classification
          example: "Bad Request"
        description:
          type: string
          description: Detailed error description with remedial guidance
          example: "Schema validation failed in the Request"
      description: |
        Generic HTTP error response. Used for schema validation failures,
        authentication errors, and server-side errors.

    ThrottledError:
      type: object
      properties:
        code:
          type: string
          description: Internal process code (not an HTTP error code)
          example: "900804"
        message:
          type: string
          example: "Message throttled out"
        description:
          type: string
          example: "MAP exceeded the quota."
        nextAccessTime:
          type: string
          description: |
            When the client can retry. Format varies by implementation.
          example: "2026-Apr-26 04:43:00+0000 UTC"
      description: |
        Returned with HTTP 429 when the receiving MAP's rate limit is exceeded.
```

---

## Usage Notes

### Content-Type

All requests MUST use `Content-Type: application/json` with charset UTF-8.

### TLS Requirement

All connections MUST use TLS 1.3. Earlier TLS versions MUST be rejected.

### DKIM Headers

For CSF MAP-to-MAP exchanges, the `X-CSF-SIGNATURE` and `X-CSF-SIGNATURE-DATESTAMP` headers are **mandatory**. For messages from HMAPs (e.g., TOTSCo), these headers are **optional**.

When a MAP forwards a message (e.g., TOTSCo passing a CSF-signed message to its CPs), the `X-CSF-SIGNATURE` header SHOULD be left intact for end-to-end verification.

### Route Tracking

The `X_CSF_ROUTE` header is optional but recommended. Each MAP that handles the message adds a **new** header (not appended to existing headers). The final recipient can read all `X_CSF_ROUTE` headers to reconstruct the message route.

### Dynamic Message Body Key

The JAM specification allows the message body property name to match the `routingID`. For example, a message with `routingID: "businessSwitchMatchRequest"` would have its body under:

```json
{
  "envelope": { ... },
  "businessSwitchMatchRequest": { ... }
}
```

The OpenAPI specification models this using `additionalProperties` on the root `LetterboxMessage` object, since the key name is dynamic.

### Error Response Formats

The CSF uses two distinct error response formats, each governed by an industry standard that the framework cannot modify. This is a statement of fact, not a review item:

1. **`ValidationError`** (`errorCode` / `errorText`) — for 9xxx and 8xxx validation and PKI errors. This format is defined by the industry-standard JSON Asynchronous Messaging (JAM) Specification and is used consistently across CSF and TOTSCo implementations. Changing it would break compatibility with the wider switching ecosystem.
2. **`HttpError`** (`code` / `message` / `description`) — for HTTP-level and schema errors. This format follows established IETF RFC standards for HTTP error responses and cannot be modified without breaking standards compliance.

Implementers MUST support receiving both formats. The dual-format design reflects the layered nature of the CSF (industry application protocol over HTTP transport) — it is not transitional and is not under review.

---

<!-- DOCUMENT: standalone/cp-rights-charter | Standalone Documents — CP Rights Charter -->

---
title: CP Rights Charter
tags: [Overview]

---

# CP Rights Charter

**Connected Services Framework (CSF) — Your Rights as a Communications Provider**

Version 2.0 | Published by the Telecom Technical Architecture Group (TAG)

---

## What This Document Is

This charter sets out your rights as a Communications Provider (CP) participating in the Connected Services Framework (CSF). It is written in plain language so you can understand what the framework guarantees you — without needing to read the full CSF technical specification.

The CSF is the open, free-to-use transport framework that enables your messages (such as Switching for Business requests) to be exchanged securely between you and other CPs through Managed Access Providers (MAPs).

**If you use a MAP to send and receive switching messages, these rights apply to you.**

---

## Your Rights

### 1. The right to choose your MAP

You are free to choose which MAP you use. No MAP may impose technical or commercial barriers that prevent you from selecting the provider that best meets your needs. You are also free to become your own MAP (a "MAP of 1") and exchange messages directly with the industry.

### 2. The right to change your MAP

You can move to a different MAP at any time, subject only to your normal commercial contract terms with your current MAP. No MAP may actively prevent you from moving to a new provider or deliberately obstruct the transition.

### 3. No disruption during a MAP change

When you move to a new MAP, your RCPID (your unique identity in the switching network) stays with you — it does not change. Your in-flight switching orders are transferred to your new MAP through a standardised export process, so your end customers are not affected by the move.

### 4. You control your identity

Your association with your MAP is recorded in your own DNS records — records that you control, not your MAP. By updating two DNS entries, you determine which MAP is authorised to send messages on your behalf. No MAP can override this — the CSF verifies your DNS records before processing any message.

> **CSF Best Practice — keep DNS management in-house.** A CP SHOULD NOT delegate management of these DNS records (or the wider DNS zone they live in) to its MAP. If a CP hands DNS control to its MAP, the CP could lose practical control over **who supplies its switching services** — moving to a different MAP, or becoming a [MAP of 1](part1-framework/04-architecture-overview.md), then requires cooperation from the very MAP the CP wishes to leave. Keep DNS with the CP (or with an independent DNS provider the CP has its own commercial relationship with) so that the right to change MAP remains exercisable unilaterally.

### 5. Your RCPID is yours for life

Your RCPID is allocated to your brand permanently. It follows you if you change MAP, and it remains consistent across all historical records, reporting, and in-flight orders. No MAP can reassign, revoke, or alter your RCPID.

### 6. No charges for message exchange

No MAP may charge you — or any other CP — for the routing and connectivity of messages between MAPs. The CSF is free to operate. Your commercial relationship with your MAP for their services (portal, integration, support) is separate and between you and your MAP, but the act of exchanging messages across the CSF network carries no transaction fees or levies.

### 7. You control your visibility

You can choose your service status in the MAP's registry at any time, regardless of your account status with the MAP:

- **ACTIVE** — you are live and available for switching
- **TEST** — you are onboarding or testing and will not appear in other CPs' switching lists
- **SUSPENDED** — you are temporarily unavailable for new switching activity

### 8. Your messages are delivered securely

Every message sent on your behalf is digitally signed using your own cryptographic key pair (DKIM/PKI). The receiving MAP verifies this signature before processing the message. This means:

- No one can alter your message in transit without detection
- No one can send a fraudulent message pretending to be you
- Only the MAP you have authorised (via your DNS records) can sign messages on your behalf

### 9. Your contact details are protected

Your operational contact information (phone, email, support URLs) is stored in the CP Registry and is only accessible to other MAPs and CPs via secure, authenticated connections. It is never publicly available and must not be shared with end consumers.

### 10. You have a voice

You have the right to raise concerns, provide feedback, or propose improvements to the CSF — either directly to the TAG or through your MAP. The TAG steering group meets weekly and is committed to representing the interests of all participants.

---

## What Your MAP Must Do For You

Your MAP has obligations under the CSF framework. These include:

| Obligation | What it means for you |
|---|---|
| **Guaranteed delivery** | Your MAP must deliver your messages reliably, with retry mechanisms and failure reporting if delivery fails |
| **Accurate registry** | Your MAP must keep your information in the CP Registry accurate and up-to-date in near-real time |
| **Security** | Your MAP must sign your messages with your private key, verify inbound messages, and maintain TLS 1.3 encryption on all connections |
| **Connectivity** | Your MAP must maintain connections with all other MAPs so your messages can reach any CP in the network |
| **In-flight order export** | If you leave your MAP, they must provide a standardised export of all your in-flight switching orders so your new MAP can continue processing them without disruption |
| **No lock-in** | Your MAP must not prevent you from moving to another MAP or obstruct the transition process |
| **SLA compliance** | Your MAP must meet the service-level agreements defined by the TAG for MAP-to-MAP activity |

---

## What Your MAP Must Not Do

| Prohibited action | Why it matters |
|---|---|
| **Block your move** to another MAP | You are free to change provider at any time |
| **Charge other MAPs** for routing your messages | Message exchange across the CSF is free |
| **Withhold your in-flight orders** when you leave | Your switching orders must be exported to your new MAP |
| **Misuse your data** from the CP Registry for marketing or customer solicitation | Registry data is for operational purposes only |
| **Refuse to process losses** if you are suspended or in administration | In-flight orders transferring customers away from you must still be processed |
| **Alter your messages** after you have submitted them | Your messages are digitally signed and any tampering is detected |

---

## If Something Goes Wrong

### Your MAP is not meeting its obligations

1. **Raise it with your MAP directly** — use the support contacts published in the CP Registry
2. **Escalate to the TAG** — if your MAP does not resolve the issue, you can raise it with the TAG steering group (via your MAP or directly)
3. **Move to another MAP** — you always have the right to change MAP; your RCPID and in-flight orders move with you

### Your MAP goes into administration or fails

The CSF has built-in protections:

- You can migrate to a new MAP, typically within hours
- Your RCPID stays the same — no reregistration needed
- Your in-flight orders are exported (if the old MAP is still online) or can be reconstructed from your records and the other MAPs involved
- Other MAPs will detect the change automatically and route messages to your new MAP

### You believe a MAP is acting anti-competitively

The TAG has governance controls including dispute resolution, anti-competitive safeguards, and the ability to warn, suspend, or remove MAPs that breach their obligations. Report concerns to the TAG steering group.

---

## Key Terms (Plain Language)

| Term | What it means |
|---|---|
| **CP** | Communications Provider — that's you. Any organisation that sends or receives switching messages. |
| **MAP** | Managed Access Provider — the organisation that handles the technical side of sending and receiving messages on your behalf. |
| **RCPID** | Your unique identity in the switching network. It's a code (UUIDv4) that other CPs use to address messages to you. It stays with you for life. |
| **CP Registry** | The list your MAP publishes containing your details (brand name, RCPID, contact information, supported processes). Other MAPs collect this to know you exist and how to reach you. |
| **DNS records** | Internet records that you control. Two DNS entries link your RCPID to your MAP — this is how you control who represents you in the network. |
| **DKIM/PKI signing** | A security mechanism that digitally signs every message sent on your behalf, so the recipient can verify it genuinely came from you and hasn't been tampered with. |
| **In-flight order** | A switching order that has been submitted but not yet completed. If you change MAP, these are transferred to your new MAP so your customers aren't affected. |
| **TAG** | The Telecom Technical Architecture Group — the industry group that maintains the CSF. They meet weekly and are responsible for the rules that protect your rights. |

---

## Further Information

This charter summarises your rights under the Connected Services Framework. The full technical specification is available in the CSF documentation:

- [CSF Overview and Documentation Index](README.md)
- [Principles & Requirements](part1-framework/03-principles-and-requirements.md) — the formal requirements this charter is derived from
- [CP Transitions](part2-implementation/07-cp-transitions.md) — how the MAP change process works technically
- [Commercial Scenarios](part2-implementation/08-commercial-scenarios.md) — what happens if a MAP fails or a CP enters administration
- [Definitions & Terminology](definitions.md) — full glossary of all CSF terms

---

*This charter is maintained by the TAG and will be updated as the CSF evolves. If you have questions or feedback, contact the TAG through your MAP or directly via the TAG steering group.*

---

<!-- DOCUMENT: standalone/csf-message-delivery-policy | Standalone Documents — CSF Message Delivery Policy -->

---
title: CSF Message Delivery Policy
tags: [Standalone, Message Delivery, Retry, Operational]

---

# CSF Message Delivery Policy

> Connected Services Framework (CSF) — Standalone Companion Document — Version 1.0
>
> Maintained by the Telecom Technical Architecture Group (TAG). This document consolidates the CSF's message-delivery rules into a single self-contained reference. The canonical normative source is [Part 2 §4.7 Message Delivery Policy](../part2-implementation/04-message-api.md#47-message-delivery-policy); this standalone is the readable summary that does not require the reader to navigate the full Master Document.

---

## Document Control

| | |
|---|---|
| **Audience** | MAP implementers; CPs preparing to become a MAP-of-1; SI partners building or integrating CSF endpoints; the GPLB Steering Group; TOTSCo (for the HMAP-boundary context). |
| **Status** | Published — ratified by the TAG and consolidated from the framework on 2026-06-24. |
| **Companion to** | The full normative text in [Part 2 §4.7](../part2-implementation/04-message-api.md#47-message-delivery-policy); the test suite in [Onboarding & Testing §8.7](./onboarding-testing-process.md#87-retry--delivery-policy); the architectural analysis in `wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles.md`. |
| **Purpose** | Set out, in one place, how a CSF MAP delivers JAM messages to another CSF MAP, what happens when delivery fails, how persistent failures escalate, and how the rules differ at the HMAP boundary with TOTSCo. |

---

## 1. Purpose and scope

This document is the **CSF Message Delivery Policy** — the contract every MAP follows when sending a JAM-envelope message to a peer MAP's letterbox.

It covers:

- The lifecycle of a single delivery attempt (connect → send → response).
- The timeouts that govern that attempt.
- What happens when a delivery attempt fails (retry / circuit-breaker / escalation).
- The operational-engagement path when failure persists beyond the retry window.
- The asymmetric behaviour at the **HMAP boundary** where a CSF MAP exchanges with TOTSCo.
- The architectural defence for why CSF retains **exponential backoff with jitter** rather than the linear / fixed-cadence schedules used by centralised hubs.

It does **not** cover:

- The JAM envelope structure — see the OTA2 JAM specification.
- DKIM signing of outbound messages — see [Part 2 §3 PKI & DKIM Signing](../part2-implementation/03-pki-dkim-signing.md).
- OAuth 2.0 authentication — see [Part 2 §2 OAuth 2.0 Implementation](../part2-implementation/02-oauth2-implementation.md).
- TLS transport security — mandated as TLS 1.3 throughout the framework (see [Part 1 §6 Security Overview](../part1-framework/06-security-overview.md)).
- Directory and registry exchange between MAPs — see [Part 2 §5 Directory API](../part2-implementation/05-directory-api.md).
- The error-code taxonomy itself (`9xxx` industry / `8xxx` CSF PKI) — see [Part 2 §4.6](../part2-implementation/04-message-api.md#46-asynchronous-error-handling--message-delivery-failures).

---

## 2. Architectural framing

The CSF is a **peer-to-peer synchronous** transport. Two MAPs exchange JAM messages directly over TLS 1.3 / OAuth 2.0 / DKIM-signed HTTP. The sending MAP knows the result of every delivery attempt **in the same HTTP exchange**:

| Outcome | What it means |
|---|---|
| `HTTP 202 Accepted` | The receiving MAP has accepted the message for downstream processing. Delivery is confirmed at the transport layer. |
| `HTTP 4xx` + `9xxx` industry error code | The receiving MAP has rejected the message for a documented envelope / process reason. Sender does **not** retry. |
| `HTTP 4xx` + `8xxx` CSF error code | The receiving MAP has rejected the message for a signature / verification reason. Retry rules vary by sub-code (see [Part 2 §3](../part2-implementation/03-pki-dkim-signing.md)). |
| Network / connection / response timeout | The receiving MAP is unreachable. Sender enters the retry loop. |

This is materially different from a **centralised hub** model — where a hub sits between sender and destination, absorbs the asynchrony, queues messages per-endpoint, retries on a per-protocol schedule, ages stale queue items, and emits asynchronous failure notifications back to the sender on a separate channel. **CSF MAPs do none of that at the framework layer.** The synchronous response IS the delivery indication.

The asymmetry has one important boundary: the **HMAP interface** between a CSF MAP and TOTSCo. TOTSCo is a hub by its own design, so traffic crossing that boundary follows the OTA2 GPLB Message Delivery Principles on TOTSCo's side. See §7 below.

### Two-tier scope at a glance

| Boundary | Delivery model | Rules in this document |
|---|---|---|
| **CSF MAP ↔ CSF MAP** | Synchronous P2P | §§3–6 (the bulk of this document) |
| **CSF MAP ↔ TOTSCo (HMAP)** | Asymmetric — TOTSCo applies hub schedules; the CSF MAP applies CSF rules on its own side | §7 |

---

## 3. The delivery lifecycle

A single CSF MAP-to-MAP delivery attempt proceeds as follows. The sender's responsibility is to attempt delivery; the receiver's responsibility is to acknowledge synchronously.

### 3.1 Connection

The sender opens a TCP / TLS 1.3 connection to the destination MAP's letterbox URL (published in the destination's CP Registry — see [Part 2 §5.4](../part2-implementation/05-directory-api.md#54-map-section--field-reference)).

- **Connection timeout: 1 second.** If the handshake does not complete within 1 second, the sender treats the attempt as a failed delivery and feeds it into the retry loop (§4).

### 3.2 Request

Once connected, the sender POSTs the signed JAM envelope to the letterbox URL with:

- An OAuth 2.0 bearer token in the `Authorization` header.
- The DKIM signature in the `X-CSF-SIGNATURE` header (per [Part 2 §3](../part2-implementation/03-pki-dkim-signing.md)).
- The optional `X-CSF-ROUTE` chain (for HMAP-bridged traffic — see [Part 2 §4.4](../part2-implementation/04-message-api.md)).

### 3.3 Response

The sender waits for the receiving MAP's response.

- **Response timeout: 3 seconds.** If no response is received within 3 seconds, the attempt is treated as a failed delivery and feeds into the retry loop.

The response is one of:

- `HTTP 202 Accepted` — delivery confirmed. No body needed. The sender removes the message from its outbound queue.
- `HTTP 4xx` + structured JSON `{ "code": "9xxx", "description": "..." }` — synchronous industry-level rejection. The sender does NOT retry; it surfaces the failure to the originating CP via its internal mechanism.
- `HTTP 4xx` + structured JSON `{ "code": "8xxx", "description": "..." }` — synchronous CSF signature-level rejection. The sender does NOT retry permanent codes (`8101`); it retries with backoff on transient codes (`8102`).
- `HTTP 429 Too Many Requests` with `Retry-After` — the destination is rate-limited. The sender backs off respecting the header.
- `HTTP 503 Service Unavailable` with `Retry-After` — the destination is temporarily unhealthy. The sender backs off respecting the header.
- Any `HTTP 5xx` without `Retry-After` — the sender retries with exponential backoff (§4).

---

## 4. Retry policy (CSF MAP-to-MAP)

When a delivery attempt fails for a retryable reason, the sender retries. The rules in this section are the framework's **MUST** statements for every CSF MAP at the P2P boundary.

### 4.1 Exponential backoff with jitter

Retries grow **exponentially** in delay (each interval geometrically larger than the previous, typically doubling) and carry **jitter** (a random component of ±25 % added to each delay so independent senders do not align on identical retry timestamps).

```
attempt    delay (typical)
 1         1 s  ±25 %
 2         2 s  ±25 %
 3         4 s  ±25 %
 4         8 s  ±25 %
 5        16 s  ±25 %
 6        32 s  ±25 %  ← capped here in most implementations
 7        32 s  ±25 %
 …
```

The specific base, multiplier, and cap are MAP implementation choices. The **shape** of the curve — geometric growth with randomisation — is required.

MAPs **MUST NOT** use linear or fixed-cadence retry schedules at the CSF P2P boundary. The architectural rationale is in §6.

### 4.2 Respect HTTP semantics

MAPs **MUST** honour:

- `HTTP 429 Too Many Requests` with `Retry-After` — back off for at least the period specified by the header.
- `HTTP 503 Service Unavailable` with `Retry-After` — same.

A `Retry-After` value overrides the sender's normal backoff schedule for that attempt.

### 4.3 Circuit-breaker

After **N consecutive failures** to the same destination (recommended `N = 5`, tunable per MAP), the sender:

1. Stops active retry to that destination.
2. Fails subsequent messages destined for it FAST (within ~100 ms) without attempting delivery.
3. Raises an operational alert.
4. Holds the outbound queue for that destination — does not drop pending messages.

After a recovery period the circuit transitions to **half-open**: the sender issues a single probe attempt. If the probe succeeds the circuit closes and normal flow resumes; if it fails the circuit returns cleanly to **open** for the next recovery period.

### 4.4 Bounded retry window

MAPs **MUST NOT** "wait forever". The framework recommends a maximum retry window in the **order of hours, not days** — typically 1 to 4 hours for production traffic. Beyond the window the sender:

1. Stops retrying.
2. Raises a `9008` Delivery Failure for the originating message.
3. Increments the persistent-failure counter for that destination.
4. Triggers the operational-engagement path (§5).

### 4.5 Logging

Every delivery attempt **MUST** be logged for audit. The log entry includes, at minimum:

- Destination URL.
- Timestamp of the attempt.
- Attempt sequence number.
- Outcome (`202`, `4xx` + code, network error).
- Any `Retry-After` value observed.
- The originating message's correlation IDs.

Audit retention follows [Part 2 §9 Audit Log requirements](../part2-implementation/09-operations.md).

---

## 5. Operational-engagement escalation

When delivery persistently fails beyond the sender's retry window, the framework's **primary recovery mechanism is human operational engagement between MAP teams** — not silent retry. The procedure:

1. **The failing MAP publishes a `map/outage[]` entry** in its CP Registry per [Part 2 §5.4](../part2-implementation/05-directory-api.md#54-map-section--field-reference). The entry carries an ITIL-style priority (P1, P2, P3), start/end timestamps, affected services, a short description, and escalation contacts.
2. **Every other MAP picks the entry up on the next directory poll** (typical poll interval: 5 minutes; max recommended: hourly) and downgrades its retry behaviour to the destination — see [Part 2 §9.3 Outage Notification](../part2-implementation/09-operations.md#93-outage-notification).
3. **The sender raises an internal alert** when its retry window is exhausted, naming the destination RCPID, duration of consecutive failure, and the last synchronous error code observed.
4. **Operations teams from both sides engage** via the published `map/contact[]` channels (phone, email, ticketing URL — see [Part 2 §5.6 CP Contact Object](../part2-implementation/05-directory-api.md#56-cp-contact-object)). Contact entries include availability hours, days, and purpose tags so the sender knows which channel is appropriate at the time of the incident.
5. **The framework's standard incident response process applies** — see [Part 1 §10.6.5 Incident Response Coordination](../part1-framework/10-governance.md#1065-incident-response-coordination).

This sequence is the deliberate replacement for "wait 12 days" hub-side queue ageing. **CSF MAPs do not silently retry for days; they escalate.** A persistent destination failure beyond a few hours is treated as a P1 / P2 incident, not a routine retry condition.

---

## 6. Why exponential backoff and not linear / fixed-cadence retry

The CSF retains exponential backoff with jitter as its P2P default. Linear retry schedules (e.g. retries every 5 seconds for 30 seconds, then fail) and fixed-cadence tails (e.g. every 60 seconds for 12 days) are architecturally appropriate for a single centralised hub but **inappropriate** for a distributed P2P network for two distinct reasons:

### 6.1 Linear schedules synchronise retry storms

When a destination is recovering from an outage, the **identical retry intervals across many independent senders** create a "thundering herd" — a synchronised load spike every 5 s (or every 60 s) until the destination falls back over. This is precisely the failure mode exponential-with-jitter is designed to prevent.

Under exponential-with-jitter pressure, the load is **spread across the recovery window**: each sender backs off on its own random schedule, the destination sees a manageable trickle of probes rather than a coordinated burst, and recovery is far more likely to complete cleanly.

### 6.2 Exponential-with-jitter is the industry-standard distributed-systems pattern

Every modern cloud SDK (AWS, Google, Microsoft, Cloudflare, …) uses this pattern as its default retry policy. The pattern is documented in the SRE literature (Google SRE book, "Implementing Service Level Objectives", Amazon Builders' Library) and is the recommended approach for any service operating across multiple independent clients.

The CSF aligns with that practice. The alignment is deliberate, not incidental.

### 6.3 What the framework permits and what it does not

| Pattern | Allowed at the CSF P2P boundary? |
|---|---|
| Exponential backoff with jitter, bounded by a maximum retry window | **MUST** |
| Linear retry schedule (e.g. every 5 s, every 30 s) | **MUST NOT** |
| Fixed-cadence retry tail (e.g. every 60 s indefinitely) | **MUST NOT** |
| Honouring `Retry-After` from a destination | **MUST** |
| Per-implementation tuning of base / cap / jitter range | Permitted |
| Circuit-breaker after N consecutive failures | **MUST** |
| Operational escalation beyond the retry window | **MUST** |

---

## 7. The HMAP boundary

When a CSF MAP exchanges traffic with TOTSCo via the dedicated HMAP interface, the boundary inherits **hub behaviour** by definition. TOTSCo is a centralised hub, and the OTA2 *Switching for Business Message Delivery Principles V0.2* bind TOTSCo's hub-side delivery to the destination RCP.

### 7.1 What applies on TOTSCo's side

TOTSCo applies its own hub-side delivery schedule per the GPLB principles. Summarised:

| GPLB principle                        | Match Requests                                             | All other SforB messages                                   |
| ------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| Connection timeout                    | 1 s                                                        | 1 s                                                        |
| Response timeout                      | 3 s                                                        | 3 s                                                        |
| Retries at (from hub's 202 to sender) | 5, 10, 15, 20, 25 s                                        | 10, 20, 30, 60 s, then every 60 s                          |
| Total hold window                     | **30 s**                                                   | **12 days**                                                |
| Failure notification                  | Async, to sender's pre-configured failure endpoint         | Async, to sender's pre-configured failure endpoint         |
| Queueing                              | Single-flight per endpoint; queue items age at same window | Single-flight per endpoint; queue items age at same window |

These are TOTSCo's rules for the hub it operates. No change is required of TOTSCo when integrating CSF — the GPLB principles already govern TOTSCo's existing operation.

### 7.2 What the CSF MAP does on its side

The CSF MAP behaves as a **standard TOTSCo hub client**:

- Posts JAM envelopes to TOTSCo's letterbox with the same OAuth + TLS + JAM-envelope conventions used by every TOTSCo MAP today.
- Receives `HTTP 202` synchronously on hub-side acceptance.
- Receives **asynchronous failure notifications** from TOTSCo at a sender-configured failure endpoint when TOTSCo's hub-side delivery to the destination RCP fails (per GPLB principles).
- Applies CSF's own retry policy (§§4–5) on its own retries to TOTSCo's letterbox if a delivery to TOTSCo itself fails for connection / response timeout reasons.

### 7.3 The locked-down interface

The HMAP interface is **locked down by design** — see [Part 2 §6.3.1 Dedicated, locked-down HMAP interfaces — both directions](../part2-implementation/06-totsco-integration.md#631-dedicated-locked-down-hmap-interfaces--both-directions) and the [TOTSCo HMAP Integration Guide §1](./totsco-hmap-integration-guide.md).

This means:

- CSF version increments do **NOT** propagate through the dedicated TOTSCo endpoints.
- The GPLB hub schedules at the boundary stay stable for TOTSCo.
- The CSF P2P rules in §§3–6 stay stable for the wider framework.
- The asymmetry is bilateral, predictable, and durable.

In other words: the GPLB hub schedules **do not bleed** into the CSF P2P transport. They bind only TOTSCo's side of the HMAP boundary.

---

## 8. Summary of bindings

This table is the practical reference. Each row states which rule applies on each side of the boundary.

| Rule | CSF MAP ↔ CSF MAP (P2P) | HMAP boundary (CSF MAP ↔ TOTSCo) |
|---|---|---|
| 1 s connection timeout | **MUST** | **MUST** (aligned with GPLB on TOTSCo's side) |
| 3 s response timeout | **MUST** | **MUST** (aligned with GPLB on TOTSCo's side) |
| Exponential backoff with jitter | **MUST** on retry | CSF MAP applies on its retries to TOTSCo. TOTSCo applies the GPLB linear / fixed-cadence schedule on its hub side. |
| Respect `Retry-After` on `429` / `503` | **MUST** | **MUST** |
| Circuit-breaker after N consecutive failures | **MUST** (CSF MAP side; recommended N = 5) | **MUST** (CSF MAP side) — n/a on TOTSCo's hub side |
| Maximum retry period bounded | **MUST** — typically hours | TOTSCo applies the GPLB 30 s Match / 12-day other-message holds |
| Failure notification to sender | Synchronous — `9xxx` / `8xxx` codes in the original HTTP response | Asynchronous from TOTSCo when hub-side delivery fails; CSF MAP consumes as standard hub client |
| Operational escalation via `map/contact[]` / `map/outage[]` | Primary recovery mechanism beyond the retry window | Applies on the CSF MAP side; TOTSCo follows its own incident process |
| Single-flight per endpoint + queue ageing | Not required; MAP implementation choice | TOTSCo applies hub-side single-flight + queue ageing |
| Logging of every delivery attempt | **MUST** | **MUST** |

---

## 9. Testing

The TAG Baseline Test Suite formally exercises this policy. The test set is at [Onboarding & Testing Process §8.7](./onboarding-testing-process.md#87-retry--delivery-policy) — tests **R-01..R-18**, summarised here for context:

| ID | Type | What it validates |
|---|---|---|
| R-01..R-03 | P | `Retry-After` honouring on `503` / `429`; transient network failure retry with exponential backoff and jitter |
| R-04..R-06 | N | No retry on `400` (`9006`) / `404` (`9007`); max retry window exhausted raises `9008` |
| R-07..R-09 | E | Circuit-breaker open / close behaviour; persistent `8102` (DNS) failure |
| **R-10** | P | **1 s connection timeout** (TCP / TLS SYN drop) |
| **R-11** | P | **3 s response timeout** (connection established, no `202`) |
| **R-12** | P | **Exponential backoff shape** — geometric growth, each step ≥ 1.5× the previous |
| **R-13** | P | **Jitter present** — ±15 % variance across independent senders |
| **R-14** | P | **Circuit-breaker activation** after N consecutive failures |
| **R-15** | P | **Circuit-breaker recovery** (half-open → closed) on probe success |
| **R-16** | E | **Half-open probe failure** returns cleanly to open |
| **R-17** | P | **Bounded retry window** — raises `9008` and triggers operational escalation |
| **R-18** | E | **Operational engagement** — sender downgrades retry on `map/outage[]` |

A MAP cannot complete onboarding (Phase 3 → Phase 4) without these tests passing.

---

## 10. Cross-references

- **Canonical normative source:** [Part 2 §4.7 Message Delivery Policy](../part2-implementation/04-message-api.md#47-message-delivery-policy) — the ratified clause this standalone summarises.
- **Retry-related operational rules:** [Part 1 §9 Operational Excellence](../part1-framework/09-operational-excellence.md), specifically the *Retry Policy* paragraph.
- **Test suite:** [Onboarding & Testing Process §8.7](./onboarding-testing-process.md#87-retry--delivery-policy) — tests R-01..R-18.
- **HMAP boundary operating model:** [TOTSCo HMAP Integration Guide](./totsco-hmap-integration-guide.md), specifically §1 (locked-down interface) and Phase 3 (worked bidirectional example).
- **Locked-down interface ratification:** [Part 2 §6.3.1 Dedicated, locked-down HMAP interfaces](../part2-implementation/06-totsco-integration.md#631-dedicated-locked-down-hmap-interfaces--both-directions).
- **Outage publication:** [Part 2 §5.4 MAP Section — Field Reference](../part2-implementation/05-directory-api.md#54-map-section--field-reference) for the `map/outage[]` schema; [Part 2 §9.3](../part2-implementation/09-operations.md#93-outage-notification) for the operational rules.
- **Operational engagement contacts:** [Part 2 §5.6 CP Contact Object](../part2-implementation/05-directory-api.md#56-cp-contact-object).
- **Incident response coordination:** [Part 1 §10.6.5](../part1-framework/10-governance.md#1065-incident-response-coordination).
- **Architectural analysis (CSF vs OTA2 GPLB MDP V0.2):** `wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles.md` — the synthesis that grounds the CSF P2P / HMAP-boundary split documented here.

---

## 11. Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 | 2026-06-24 | First-draft CSF Message Delivery Policy as a standalone consolidation. Faithful summary of the ratified [Part 2 §4.7](../part2-implementation/04-message-api.md#47-message-delivery-policy), the [Part 1 §9 Retry Policy paragraph](../part1-framework/09-operational-excellence.md), the [§8.7 test suite](./onboarding-testing-process.md#87-retry--delivery-policy) (R-01..R-18), the [HMAP-boundary callout](./totsco-hmap-integration-guide.md) in the TOTSCo Integration Guide, and the compliance synthesis at `wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles.md`. No new policy claims — consolidation only. For TAG review. |

---

<!-- DOCUMENT: standalone/definitions | Standalone Documents — Definitions and Terminology -->

---
title: Definitions and Terminology
tags: [Overview]

---

# Definitions and Terminology

> Connected Services Framework (CSF) — Version 2.0

This document provides a single, consolidated reference for all acronyms, abbreviations, and special terminology used throughout the CSF documentation. It is intended for readers who are new to the CSF or the UK telecoms switching landscape.

---

## 1. Acronyms and Abbreviations

| Abbreviation | Full Term | Definition |
|---|---|---|
| BSS | Business Support System | The back-office systems used by a CP to manage customers, orders, billing, and operations. A MAP may integrate with a CP's BSS to automate message exchange. |
| CP | Communications Provider | An organisation participating in an industry process (e.g., OTS, SforB) that creates or consumes messages and sends or receives them via a MAP. CPs include retailers, wholesalers, and agencies providing services on behalf of other CPs. |
| CSF | Connected Services Framework | An open, free-to-use set of message communication standards that define how MAPs exchange messages securely and efficiently on a peer-to-peer basis, without reliance on a centralised hub. |
| DDG | Detail Design Group | The original industry group that documented the requirements for the technologies and processes of switching residential broadband and voice services, which Ofcom termed "One Touch Switch." |
| DKIM | DomainKeys Identified Mail | A message authentication standard defined in RFC 6376. It uses public/private key pairs to sign messages and verify that they have not been altered in transit. The CSF adapts DKIM — originally designed for email — for HTTP message signing between MAPs. |
| DNS | Domain Name System | The internet system that resolves domain names to IP addresses. In the CSF, DNS TXT records serve two critical purposes: publishing CP public keys for signature verification, and recording which MAP is authorised to act on behalf of each CP. |
| FCS | Federation of Communication Services | The UK trade body that publishes the Switching for Business (SforB/GPLB) process documentation on behalf of the GPLB Steering Group. |
| FQDN | Fully Qualified Domain Name | The complete domain name for a specific host on the internet (e.g., `api.mymap.com`). Used in the CSF to specify API endpoint addresses. Must comply with RFC 1035. |
| GPLB | Gaining Provider Led Business Switching | The original name for the industry process for switching business telecommunications services. Now branded as **Switching for Business (SforB)**. Ofcom has not mandated a single technical solution for this process. |
| HMAC | Hash-based Message Authentication Code | A cryptographic technique for verifying data integrity and authenticity using a secret key and a hash function. Referenced in the CSF in the context of API key security. |
| HMAP | Hub Managed Access Provider | A specialised MAP type that operates as a hub-and-spoke delivery mechanism (e.g., TOTSCo). An HMAP accepts messages and forwards them among its subscribed members without reading or processing the message body. |
| IAS | Internet Access Service | A broadband or internet connectivity service provided to end customers. One of the service types covered by the Switching General Conditions. |
| IETF | Internet Engineering Task Force | The international standards body that publishes RFCs defining internet protocols and standards used by the CSF (TLS, OAuth 2.0, DKIM, UUID, etc.). |
| IPG | Industry Process Group | A working group within TOTSCo responsible for generating and proposing changes to OTS and SforB process documentation. |
| JAM | JSON Asynchronous Message | The industry-wide messaging standard published on the OTA2 website. JAM defines the **envelope format** — addressing, routing, correlation, and audit data — used by all CPs and MAPs regardless of the underlying transport (CSF, TOTSCo Hub, or other). |
| JWT | JSON Web Token | A compact, URL-safe token format used in OAuth 2.0. JWTs carry signed claims (such as identity, scope, and expiry) and are used as bearer tokens in CSF API authentication. |
| KYC | Know Your Customer | The due-diligence checks an entity performs before establishing a commercial or technical relationship with a customer — typically identity verification, company registration evidence, ICO registration, anti-fraud screening, and any sector-specific obligations. In the CSF, KYC controls are the MAP's commercial responsibility; the framework does not impose its own KYC requirements on top of those a MAP already operates. MAPs joining TOTSCo already have KYC processes in place; TOTSCo's existing onboarding for MAPs and CPs (under both OTS and SforB/GPLB) carries this work forward unchanged when TOTSCo participates as an HMAP. |
| MAP | Managed Access Provider | An organisation that facilitates message exchange on behalf of one or more CPs by offering integration services, portals, and technical solutions. A MAP is the only entity authorised to exchange messages with other MAPs over the CSF. A CP can become a **MAP of 1** (serving only itself) by implementing the MAP rules. |
| MoU | Memorandum of Understanding | The agreement governing collaboration between MAPs and CPs participating in the CSF. Designed to be simple to join, with no licensing fees. |
| NBICS | Number-Based Interpersonal Communications Service | A voice telephony service provided to end customers. One of the service types covered by the Switching General Conditions. |
| OAuth | Open Authorisation | See **OAuth 2.0** below. |
| OG | Operations Group | A working group within TOTSCo responsible for operational aspects of OTS and SforB. |
| Ofcom | Office of Communications | The UK's communications regulatory authority. Ofcom mandates the Switching General Conditions and oversees both OTS and SforB processes. |
| OTA2 | Office of the Telecommunications Adjudicator | The industry body accountable for publishing and controlling the RCPID Standards and the JSON Asynchronous Messaging Specification (JAM). All documentation is published on the [OTA2 website](https://www.offta.org.uk/). |
| OTS | One Touch Switch | The Ofcom-mandated process for switching residential IAS and NBICS services between consumer CPs. All OTS messages must be routed via the TOTSCo Hub. |
| PKCE | Proof Key for Code Exchange | A security extension to the OAuth 2.0 Authorisation Code flow that prevents authorisation code interception attacks. Recommended for public clients. |
| PKI | Public Key Infrastructure | A framework for managing cryptographic key pairs and digital certificates. In the CSF, PKI is implemented via DKIM (RFC 6376) to sign and verify messages between MAPs. Each CP has a public key (published in DNS the CP owns) and a private key (held by whichever entity the CP has authorised to sign — typically the CP's MAP, or held in-house when the CP operates as a MAP of 1). The CP controls who is authorised to sign on its behalf via the DNS-published public key, and revokes that authorisation at any time by rotating the record. |
| RCPID | Retail Communications Provider Identifier | A unique identifier assigned to a CP brand for the purpose of message exchange. In the CSF, RCPIDs use the **UUIDv4** format (RFC 4122) and remain with the CP for the lifetime of that brand, even when changing MAPs. |
| RFC | Request for Comments | A publication series from the IETF that defines internet standards, protocols, and technical specifications. Key RFCs used by the CSF include RFC 8446 (TLS 1.3), RFC 6376 (DKIM), RFC 6749 (OAuth 2.0), and RFC 4122 (UUID). |
| RPO | Recovery Point Objective | The maximum acceptable amount of data loss measured in time. Used in CSF disaster recovery planning — defines how far back data can be recovered from. |
| RTO | Recovery Time Objective | The maximum acceptable length of time a system can be offline after a failure. Used in CSF disaster recovery planning — defines how quickly service must be restored. |
| SforB | Switching for Business | The current branding for the GPLB process — the industry process for switching business telecommunications services. This is the CSF's initial application. |
| SI | Systems Integrator | An organisation that provides technology solutions and integration services to CPs and MAPs. Several SIs have contributed to the CSF design. |
| SLA | Service Level Agreement | A formal commitment defining expected performance levels. The CSF defines SLAs for MAP-to-MAP transactions, including response times, fix times, and availability targets. |
| Switchable Asset Base | — | The total count of customer services across all of a MAP's CPs that can be switched as part of the Switching for Business (SforB) protocol. Comprises **IAS** (Internet Access Service — broadband, e.g. FTTP/FTTC/cable/fixed-wireless) and **NBICS** (Number-Based Interpersonal Communications Service — voice telephony, e.g. landline/VoIP). A single business customer may contribute multiple assets to the count (one IAS + one NBICS = two switchable assets). Used as input to the CSF capacity-planning formula in part1-framework §9.10 (`Messages/second = Total Switchable Asset Base ÷ 1,000`, minimum 2/s). |
| TAG | Telecom Technical Architecture Group | A consortium of telecoms industry stakeholders — including MAPs, SIs, and CPs — responsible for the development, publication, and change control of the CSF. The TAG steering group meets weekly (Wednesdays). |
| TLS | Transport Layer Security | A cryptographic protocol providing secure communication over networks. The CSF mandates **TLS 1.3** (RFC 8446) for all connections. Earlier versions must not be used. |
| TOTSCo | Telecoms One Touch Switching Company | The organisation operating the centralised hub for OTS message routing. TOTSCo also publishes OTS process and technical documentation. For SforB, TOTSCo may operate as an HMAP within the CSF. |
| UUID | Universally Unique Identifier | A 128-bit identifier standardised by RFC 4122. The CSF uses **UUIDv4** (random) for RCPIDs, providing 122 bits of randomness and a collision probability of approximately 1 in 2.71 x 10^18. |

---

## 2. CSF-Specific Terminology

### 2.1 The Three-Tier Registry Model

The CSF uses a three-tier model for distributing CP information across the network. Understanding the distinction between these three tiers is essential.

```
┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   Tier 1: CP Registry                                               │
│   ─────────────────                                                 │
│   Published by each MAP. Contains that MAP's CPs with full          │
│   metadata (RCPID, brand, PKI domains, contacts, resources).        │
│   Shared WITH OTHER MAPs via an OAuth 2.0-protected API.            │
│                                                                     │
│          │                                                          │
│          ▼  (each MAP collects all other MAPs' CP Registries)       │
│                                                                     │
│   Tier 2: Master Registry                                           │
│   ───────────────────────                                           │
│   Built PRIVATELY by each MAP. The converged view of ALL CP         │
│   Registries. Contains full routing, PKI signing domains, and       │
│   contact details for every CP in the entire CSF network.           │
│   Used internally for message routing and signature verification.   │
│                                                                     │
│          │                                                          │
│          ▼  (each MAP filters and simplifies for its own CPs)       │
│                                                                     │
│   Tier 3: Directory                                                 │
│   ────────────────                                                  │
│   A cut-down view shared with the MAP's OWN CPs. Contains           │
│   only brand names and RCPIDs — for drop-down lists, search,        │
│   and message addressing. Excludes routing, PKI, and operational    │
│   details.                                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

| Term | What It Is | Who Creates It | Who Sees It | Contains |
|---|---|---|---|---|
| **CP Registry** | A JSON document published by a MAP | Each MAP publishes one | Other MAPs (via API) | Full CP metadata, PKI signing domains, contacts, routing groups |
| **Master Registry** | The converged view of all CP Registries | Each MAP builds its own | Private to that MAP only | Everything from all CP Registries — used for routing and verification |
| **Directory** | A filtered extract from the Master Registry | Each MAP creates one for its CPs | The MAP's own CPs | Brand names, RCPIDs, supported processes — for selection lists only |

### 2.2 Entity Types

| Term | Definition |
|---|---|
| **Communications Provider (CP)** | Any party participating in an industry process — creating, consuming, sending, or receiving messages. CPs include retailers, wholesalers, and agencies. A CP does not need to understand the CSF — it interacts only with its MAP. |
| **Managed Access Provider (MAP)** | An organisation that facilitates message exchange on behalf of CPs. MAPs handle PKI signing, OAuth 2.0 authentication, CP Registry publication, message routing, and delivery guarantees. The only entity authorised to exchange messages over the CSF. |
| **MAP of 1** | A CP that acts as its own MAP — operating CSF infrastructure to exchange messages directly with other MAPs. Must comply with all MAP rules. Allows CPs to exchange messages for free without a third-party MAP. |
| **Hub MAP (HMAP)** | A specialised MAP that operates a hub-and-spoke model (e.g., TOTSCo). Accepts messages and forwards them without reading the message body. Not required to implement DKIM/PKI signing. |
| **Sponsor MAP** | An existing, onboarded MAP assigned (via round-robin rotation) to guide a new MAP through the onboarding process. Acts as a gatekeeper to the CSF network. Sponsor MAPs are **not expected to charge** for onboarding; an optional fee may be charged when significant time and effort is required, capped at **£3,000 + VAT** for a traditional (multi-CP) engagement or **£350 + VAT** for a `single-cp` (MAP-of-1) engagement. Charged once per MAP regardless of how many protocols it carries. See [Part 1 §7.2.1](../part1-framework/07-onboarding.md#721-sponsorship-framework) for the full fee model. |
| **New MAP** | An organisation seeking to join the CSF. Must complete the full sponsored onboarding process before publishing its CP Registry or exchanging production messages. |

### 2.3 Messaging Terms

| Term | Definition |
|---|---|
| **Envelope** | The outer wrapper of a JAM message containing delivery instructions: source RCPID, destination RCPID, routing ID, correlation ID, and audit data. Defined by the JAM Specification. The CSF is responsible for the envelope; the message body is defined by the industry process. |
| **Message Body** | The inner content of a JAM message containing the industry process payload (e.g., a Switch Match request, a Switch Order). Opaque to the CSF transport layer unless the MAP provides a hosted solution. |
| **Letterbox** | The REST API endpoint used by MAPs to send and receive messages. Accepts a JAM-formatted JSON message via HTTP POST over TLS 1.3 with OAuth 2.0 authentication. Returns HTTP 202 on successful acceptance. |
| **Routing ID** | A string in the JAM envelope that identifies the type of message (e.g., `businessSwitchMatchRequest`, `residentialSwitchOrderConfirmation`). Used by MAPs to route messages to the correct service endpoint. |
| **Routing Group** | A named collection of routing ID patterns (regular expressions) that determines which message types are accepted by a specific MAP service endpoint. For example, `businessSwitch.*` matches all SforB messages. |
| **Correlation ID** | A unique string in the JAM envelope used to link a response message back to the original request. The source always includes a correlation ID; the destination includes it only in response messages. UUIDs are recommended. |
| **Audit Data** | An array of name-value pairs in the JAM envelope used for regulatory reporting, diagnostics, and industry auditing. Each industry process defines its own audit requirements. |
| **Contact Object** | A reusable JSON structure (`contact` array) used at both the MAP level and the CP level in the CP Registry. Contains `type` (phone, email, url), `value`, `purpose` (sales, support, technical), `availabilityFrom`, `availabilityTo`, `availabilityDays`, and `comment`. Allows each entity to advertise its preferred contact methods and trading hours. The same structure is used for both MAP and CP contacts — MAP contacts are for MAP-to-MAP technical issues; CP contacts are for CP-to-CP operational escalations. |
| **Bit pipe** | Refers to a network provider that simply moves data without adding value or examining content. The CSF is, by design, a bit pipe for SforB (and other industry processes that may use it) — it carries the JAM envelope between MAPs and does not interpret the message body. This is what allows the same transport to carry multiple industry protocols, and what keeps end-consumer business state (customers, SORs, ServiceIdentities, billing) entirely with the CP rather than with the transport. |

### 2.4 Security Terms

| Term | Definition |
|---|---|
| **X-CSF-SIGNATURE** | The HTTP header that carries the DKIM signature of a CSF message. Contains the signing algorithm, selector (CP RCPID), domain, body hash, headers included, and the signature value. |
| **X-CSF-SIGNATURE-DATESTAMP** | The HTTP header containing the timestamp of when the signature was created (`yyyyMMddHHmmssS`). Embedded in the signature to protect against replay attacks. |
| **X_CSF_ROUTE** | An optional HTTP header recording the route a message has taken through the network. Each MAP adds a new header entry with a timestamp and MAP name. Used for diagnostics. |
| **Selector** | In DKIM, the identifier used (together with the domain) to locate the public key in DNS. In the CSF, the selector is always the CP's RCPID. |
| **Domain Key Record** | A DNS TXT record at `[RCPID]._domainkey.[cp-domain]` containing the CP's public key in RFC 6376 format. Used by receiving MAPs to verify message signatures. |
| **MAP Key Record** | A DNS TXT record at `[RCPID]._mapkey.[cp-domain]` containing the URL of the CP's MAP message endpoint. Used for routing verification and conflict resolution. Controlled by the CP. |
| **PERM_FAIL (8101)** | A CSF PKI error code indicating that message signature verification has permanently failed. Retrying will not resolve the issue. Returned with HTTP 403. |
| **TEMP_FAIL (8102)** | A CSF PKI error code indicating that message signature verification has temporarily failed (e.g., DNS lookup error). A retry may resolve the issue. Returned with HTTP 403. |
| **Client Credentials Flow** | The OAuth 2.0 flow used by the CSF for machine-to-machine (MAP-to-MAP) authentication. No user interaction is required — the MAP authenticates using a `client_id` and `client_secret`. |
| **Bearer Token** | An OAuth 2.0 access token included in the `Authorization` HTTP header (`Bearer {token}`) to authenticate API requests. Typically a JWT with a limited lifetime (e.g., 1 hour). |
| **Forward Secrecy** | A property of TLS 1.3 where session keys cannot be recovered even if the server's long-term private key is compromised. Mandated by the CSF. |

### 2.5 Error Code Series

| Series | Scope | Purpose |
|---|---|---|
| **9xxx** | Industry-wide | Validation and delivery error codes defined by the OTS/TOTSCo standards. Used by both the CSF and TOTSCo Hub for message validation failures and asynchronous delivery failures. |
| **8xxx** | CSF-specific | Error codes introduced by the CSF for PKI signing and verification failures. Currently defines `8101` (PERM_FAIL) and `8102` (TEMP_FAIL). Not sent to TOTSCo. |

### 2.6 Switching Process Terms

| Term | Definition |
|---|---|
| **Switch Match** | The process where a Gaining CP submits customer details to a Losing CP to identify and match the customer's existing services. The first step in the switching process. |
| **Switch Order** | The formal order to proceed with switching a customer's services from the Losing CP to the Gaining CP. Follows a successful Switch Match. |
| **Gaining CP (GCP/GRCP)** | The CP that is acquiring the customer — the initiator of the Switch Match. |
| **Losing CP (LCP/LRCP)** | The CP that currently serves the customer and will lose them as a result of the switch. |
| **In-Flight Order** | A Switch Order that has been submitted but not yet completed. The CSF includes mechanisms for transferring in-flight orders when a CP changes MAP. |
| **RCPID Status Request** | A CSF message sent by a new MAP to the old MAP when a CP transitions. Triggers the export of in-flight order data and signals the move. Validated via DNS to confirm the requesting MAP is the CP's new authorised provider. |
| **SOR** | Switch Order Reference — a reference number associated with a Switch Order. SORs have a validity period (typically 31 days) and cannot be transferred between MAPs; they must be re-issued. |

### 2.7 Operational Terms

| Term | Definition |
|---|---|
| **Onboarding** | The structured, multi-phase process by which a new MAP or CP is verified, tested, and granted access to exchange messages over the CSF. |
| **Sponsor** | See **Sponsor MAP** in Entity Types above. |
| **Conflict** | A state in the Master Registry where a CP appears in more than one MAP's CP Registry simultaneously. Resolved using DNS-based verification to determine the legitimate MAP. |
| **Conflict Resolution** | The process by which MAPs use DNS `_mapkey` lookups to determine which MAP legitimately represents a CP when duplicate entries exist. The CP controls routing through its DNS records. |
| **Feature Discovery** | The mechanism by which a MAP queries another MAP's CP Registry to identify which features, API versions, and industry processes are supported. Enables automatic negotiation of the highest compatible version. |
| **Exponential Backoff** | A retry strategy where the wait time between retry attempts increases exponentially (e.g., 1s, 2s, 4s, 8s). Used by MAPs when message delivery fails. Jitter (random variation) should be added to prevent thundering herd problems. |
| **Circuit Breaker** | An enterprise pattern where, after N consecutive failures to a destination, the MAP temporarily stops sending and raises an alert rather than continuing to retry. Prevents overloading a failing MAP. |

---

## 3. Key RFCs Referenced by the CSF

| RFC | Title | CSF Usage |
|---|---|---|
| [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) | UUID URN Namespace | UUIDv4 format for RCPIDs |
| [RFC 6376](https://datatracker.ietf.org/doc/html/rfc6376) | DomainKeys Identified Mail (DKIM) Signatures | Message signing and verification between MAPs |
| [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) | OAuth 2.0 Authorisation Framework | API authentication (Client Credentials flow) |
| [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) | TLS 1.3 | Mandatory transport encryption for all CSF connections |
| [RFC 8463](https://datatracker.ietf.org/doc/html/rfc8463) | Ed25519 for DKIM | Alternative signing algorithm (shorter keys than RSA) |
| [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035) | Domain Names — Implementation and Specification | FQDN format compliance for endpoint addresses |

---

## 4. Industry Standards and Governance Bodies

| Body | Role in CSF Context |
|---|---|
| **Ofcom** | UK communications regulator. Mandates the Switching General Conditions. Has mandated OTS via a single hub but has not mandated a single technical solution for SforB. |
| **OTA2** | Publishes and controls the RCPID Standards and JAM Specification — the foundational addressing and envelope formats used by the CSF. |
| **TOTSCo** | Operates the centralised OTS Hub. Publishes OTS process documents, message specifications, and the [Hub API Specification (v2.0)](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf). May operate as an HMAP within the CSF for SforB. |
| **GPLB-SG** | The **GPLB Steering Group** — an independent body of industry stakeholders working alongside the OTA2, that guides and facilitates the steering meetings and the publication of the SforB process documentation. Note: the steering group retains the historical "GPLB" label even though the **process** it stewards has been renamed from Gaining Provider Led Business switching to **Switching for Business (SforB)** as a more suitable name for the protocol. Publishes the SforB process documents, matching specifications, **SforB Response Codes**, and SLAs via FCS. |
| **TAG** | The Telecom Technical Architecture Group. Develops, publishes, and controls the CSF documentation. Meets weekly. Maintains autonomy over CSF changes. |
| **FCS** | Federation of Communication Services. Publishes the GPLB-SG documentation on its website. |

---

<!-- DOCUMENT: standalone/onboarding-testing-process | Standalone Documents — MAP Onboarding & Testing Process -->

---
title: MAP Onboarding & Testing Process
tags: [Testing]

---

# MAP Onboarding & Testing Process

> Connected Services Framework (CSF) — Companion Document — Version 1.0 (Draft)
>
> Maintained by the Telecom Technical Architecture Group (TAG). Referenced from [Part 1: Onboarding](../part1-framework/07-onboarding.md), [Part 1: Governance](../part1-framework/10-governance.md), and [Part 2: Getting Started](../part2-implementation/01-getting-started.md).

---

## 1. Purpose

This document is the practical handbook for any party preparing to deploy and operate a Managed Access Provider (MAP) on the Connected Services Framework (CSF). It exists to help engineers and project teams achieve a robust, production-ready deployment with minimal friction and maximum confidence.

It serves three distinct audiences working together:

| Audience         | What this document delivers                                                                                                                                                                         |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Developers**   | Concrete API behaviours, error responses, signing examples, and a public PKI test harness for round-tripping signatures end-to-end                                                                  |
| **Implementers** | A phased onboarding journey, environment expectations, status-flagging rules, and an exhaustive checklist tying CSF documentation chapters together                                                 |
| **Testers**      | A baseline test suite of positive, negative, and edge-case scenarios — covering both CSF transport and the SforB industry protocol — that every new MAP MUST pass before production access is granted |

The CSF is intentionally distributed and unlicensed. Trust in the network is earned through demonstrable conformance, not through a central certifying authority. This document is the basis for that demonstration.

> :memo: **Note**: This document significantly exceeds the requirements currently set forth by TOTSCo for hub onboarding. The CSF carries no central operator; therefore, the reception of MAPs depends on the meticulous deployment standards of each individual MAP. Extensive baseline testing should be regarded as a safeguard among peers rather than an administrative obstacle. It is anticipated that implementers utilising the CSF will adhere to the guiding principles by conducting comprehensive baseline testing for both the CSF transport and in relation to the specific protocol being implemented.  This process will facilitate a profound understanding for each new MAP integrating into the network, enabling them to benefit from the collective efforts of existing MAPs and to achieve the highest level of maturity possible through the completion of all requisite baseline tests.

## 2. How to Use This Document

The document is organised as a journey:

1. **Sections 3–5** describe the environment, status model, and traffic-flagging rules you must understand before starting.
2. **Section 6** describes the phased onboarding flow and which tests apply at each phase.
3. **Section 7** is the NowYoYo PKI Test Harness — copy-and-run examples for the area engineers find hardest to get right.
4. **Section 8** is the **TAG Baseline Test Suite** — every test case a new MAP must pass.
5. **Sections 9–11** cover exit criteria, bilateral testing, and ongoing regression obligations.

>:tip: **Engineers** should iterate Sections 3 → 8 in order during build. Implementers and testers should treat Section 8 as the contract that defines "ready for production".

## 3. Test Environments

The CSF supports **testing in production** as a first-class operating mode. There is no need for a separate CSF pre-production/test network. Instead, environments are distinguished by participants' status and by an explicit test flag in every message envelope.  This is more efficient for the MAPs because each exchange is peer-to-peer, and so each operator is clear whether the intended message is for test or production. This method allows multiple pseudo networks to coexist to suit specific needs and is ideal for onboarding new MAPs, as the sponsor MAP can ensure that all traffic is treated as a test while it is being evaluated.

### 3.1 Environment Types

| Environment                   | Provider                  | Purpose                                                                                                                                                                                                                                               |
| ----------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Local<br>Sandbox**          | Each MAP<br>in-house      | Unit, integration, and component tests within a single MAP's stack. Typically associated with Development                                                                                                                                             |
| **PKI Verification Endpoint** | NowYoYo (public, free)    | The hosted DKIM verification harness is documented in [Section 7](#7-pki-test-harness-nowyoyo). Used at any stage to debug signing. Other endpoint networks can also be made available if required to help the new team with their development phase. |
| **Virtual Test Host (VTH)**   | Sponsor MAP<br>(optional) | A simulated counterparty exposing CSF endpoints. Used for early connectivity testing, OAuth, registry and signing tests without involving live MAPs                                                                                                   |
| **Test Tenant**               | Sponsor MAP               | A real CSF endpoint operated by the Sponsor MAP under TEST status. Used for end-to-end SforB process tests with test CPs                                                                                                                                |
| **Production with TEST flag** | All MAPs                  | Full production network with `TEST` status applied to the new MAP and/or its CPs. Used for operational validation prior to going live                                                                                                                 |
| **Production**                | All MAPs                  | Full production network with `ACTIVE` status applied to all contributing MAPs and/or its CPs.                                                                                                                                                         |



### 3.2 Environment Sequencing

```mermaid
flowchart TB
    A["Local Sandbox"</br> MAP In-house Testing] --> B["PKI Verification </br>Endpoint"]
    B --> C["Sponsor MAP </br>Virtual Test Host"]
    C --> D["Sponsor MAP </br>Test Tenant"]
    D --> E["Production </br>w/ TEST flag"]
    E --> F["Production </br>Full Operations"]
```

Engineers SHOULD progress only when the prior stage is green. 
Skipping the PKI Verification Endpoint stage is the most common cause of long-running onboarding incidents and so MAP like NowYoYo have created an end point to help others with getting this right.

### 3.3 Required CSF Endpoints (under test)

A MAP under test MUST expose all four endpoints over TLS 1.3, even if their content is restricted or test-only:

| Endpoint            | Purpose                                                    | First-pass test                                                |
| ------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- |
| OAuth 2.0 token URL | Issue access tokens to peer MAPs (Client Credentials flow) | Successfully issue a bounded-scope token                       |
| Directory API URL   | Serve the MAP's CP Registry as JSON                        | Return a syntactically valid registry containing only test CPs |
| Letterbox URL (CSF) | Receive signed messages from CSF MAPs                      | Accept a signed test JAM message and return HTTP 202           |
| Service Status URL  | Report operational state                                   | Return current state to peers                                  |

> :tick: **Best Practice**: Even in test, separate the CSF letterbox endpoint from any HMAP letterbox endpoint (e.g. for TOTSCo). This habit avoids accidental cross-network exposure later as HMAP tend to be static and unlikely to change, whereas the CSF interface support versioning and feature releases as standard and is expect to evolve more quickly to support new industry protocols.


### 3.4 Sponsor MAP via the CP Registry

The CSF requires Sponsor MAP responsibilities to be distributed equally among all onboarded MAPs using a sequential FIFO rotation. MAPs join the rotation in the order they are onboarded — their position (`order`) is permanent and immutable. The mechanism supports concurrent sponsorships, which are needed when multiple new MAPs (whether single-CP or traditional multi-CP) are onboarding simultaneously.

This proposal defines a decentralised, self-service mechanism using the CP Registry JSON. No central coordination is needed.

#### Design Principles

- **FIFO rotation**: MAPs are allocated sponsorships in the order they joined the network. `order` is assigned at onboarding and never changes.
- **Forward pointer**: The token (`nextSponsor`) is a forward pointer — it identifies who is **next**, not who is current. The current sponsor is the MAP that most recently updated it. No majority consensus is needed.
- **Advance on acceptance**: The token advances when the Sponsor MAP **accepts** a new engagement, not when it completes one. This keeps the queue moving regardless of how long an individual onboarding takes.
- **Concurrent sponsorships**: Each MAP declares a `capacity` and tracks `active` engagements. If the designated MAP is busy, the next MAP in the rotation takes the overflow automatically.
- **Self-discoverable**: Any MAP — including a prospective new MAP — can find the current Sponsor by reading any onboarded MAP's registry.

#### Proposed Solution: `sponsorship` Object in the MAP Section

Add a `sponsorship` object to the `map` section of each MAP's CP Registry.

**Idle MAP — no active sponsorships:**

```json
{
  "map": {
    "name": "alphaMAP",
    "version": "2026-01-10T09:00:00Z00000",
    "sponsorship": {
      "order": 1,
      "nextSponsor": 2,
      "nextSponsorUpdated": "2026-01-10T09:00:00Z",
      "capacity": 1,
      "active": []
    }
  }
}
```

**MAP with an active sponsorship engagement:**

```json
{
  "map": {
    "name": "gammaMAP",
    "version": "2026-06-09T10:00:00Z00000",
    "sponsorship": {
      "order": 3,
      "nextSponsor": 4,
      "nextSponsorUpdated": "2026-06-09T10:00:00Z",
      "capacity": 2,
      "active": [
        {
          "id": "a3f91c2d-7e4b-4f8a-b1c2-9d3e5f6a7b8c",
          "type": "traditional",
          "opened": "2026-06-09T10:00:00Z"
        }
      ]
    }
  }
}
```

**MAP handling two concurrent onboardings (at capacity):**

```json
{
  "map": {
    "name": "gammaMAP",
    "version": "2026-06-09T10:05:00Z00000",
    "sponsorship": {
      "order": 3,
      "nextSponsor": 4,
      "nextSponsorUpdated": "2026-06-09T10:05:00Z",
      "capacity": 2,
      "active": [
        {
          "id": "a3f91c2d-7e4b-4f8a-b1c2-9d3e5f6a7b8c",
          "type": "traditional",
          "opened": "2026-06-09T10:00:00Z"
        },
        {
          "id": "b7e22d10-3c9f-4a1d-e5f2-8d4c0b7a3e29",
          "type": "single-cp",
          "opened": "2026-06-09T10:05:00Z"
        }
      ]
    }
  }
}
```

#### Field Definitions

| JSON Path | Description | Type | Required |
|---|---|---|---|
| `map/sponsorship` | Sponsor rotation metadata | Object | Yes |
| `map/sponsorship/order` | This MAP's permanent FIFO position in the rotation. Assigned at onboarding; **never changes** even if other MAPs leave the network — the `order` of a withdrawn or removed MAP is preserved for historical audit consistency, and the rotation simply skips entries whose `map/status` is not `ACTIVE`. | Integer | Yes |
| `map/sponsorship/nextSponsor` | The `order` number of the MAP designated as the **next** Sponsor after this MAP. Updated when this MAP **accepts** a new sponsorship engagement. | Integer | Yes |
| `map/sponsorship/nextSponsorUpdated` | Timestamp when `nextSponsor` was last updated (ISO 8601 UTC). The MAP with the most recent `nextSponsorUpdated` is the current active Sponsor. | DateTime | Yes |
| `map/sponsorship/capacity` | Maximum concurrent sponsorships this MAP will accept simultaneously. **Minimum: `1`** (every MAP MUST be willing to take at least one engagement at a time). **No upper bound** — capped only by the MAP's own operational capacity, which it determines for itself. A MAP that primarily takes `single-cp` (MAP-of-1) engagements will typically support a higher `capacity` because those engagements complete faster than traditional multi-CP onboardings. | Integer | Yes |
| `map/sponsorship/registrationURI` | **Optional.** A URI advertising the Sponsor MAP's own onboarding application page — for example a self-service portal, contracted onboarding form, or an HTTPS endpoint accepting a structured registration request. Allows prospective MAPs (and the TAG-published sponsor-registration page) a machine-readable entry point to begin the onboarding conversation. **Omit the field** if the MAP uses non-electronic registration (e.g. email-only, telephone, or the MAP's general `map/contact[]` entries). When omitted, prospective MAPs use `map/contact[]` as the contact channel. | URI | No |
| `map/sponsorship/active[]` | Array of currently open sponsorship engagements. Empty array when idle. | Object Array | Yes |
| `map/sponsorship/active[]/id` | UUIDv4 identifier for this engagement, generated by the Sponsor MAP on acceptance. | String (UUID) | Yes |
| `map/sponsorship/active[]/type` | Type of candidate: `traditional` (multi-CP MAP) or `single-cp` (MAP onboarding with a single CP, e.g. a MAP-of-1 migrating from TOTSCo SforB per [Part 1 §7.4](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration)). **Both types count as `1` against the MAP's `capacity`** — no reduced weighting for `single-cp` despite the typically faster completion. The equal-weighting rule keeps the rotation fair to small MAPs that operate at `capacity: 1`: such a MAP should not be expected to take additional engagements simply because some are MAP-of-1s. | String (enum) | Yes |
| `map/sponsorship/active[]/opened` | Timestamp when the Sponsor MAP accepted the engagement (ISO 8601 UTC). | DateTime | Yes |
| `map/sponsorship/active[]/candidateRef` | **Optional.** A non-identifying reference assigned by the Sponsor MAP for its own coordination — for example a ticket number from the Sponsor's own onboarding system when the MAP is handling several concurrent engagements. Free-form string; intentionally not standardised across MAPs because the value has no consumer outside the issuing MAP's own back-office systems. | String | No |

#### How to Determine the Current Sponsor

Any MAP — including a prospective new MAP — can determine who to contact:

1. Collect all active MAPs' CP Registries (or start with any single MAP's registry)
2. Read `sponsorship.nextSponsor` and `sponsorship.nextSponsorUpdated` from each
3. The entry with the **most recent `nextSponsorUpdated`** is authoritative — that MAP's `nextSponsor` value is the `order` of the designated next Sponsor
4. Check if the designated MAP has capacity: `active.length < capacity`
5. If at capacity, follow that MAP's `nextSponsor` to find the next available MAP in the chain

No consensus algorithm is needed. Only the current Sponsor should be advancing `nextSponsor`, so the most recently updated entry is inherently authoritative.

#### How the Rotation Works

**Step 1 — Assignment at onboarding**

When a new MAP is onboarded, the Sponsor MAP assigns it the next sequential `order` number. This is permanent.

Example network (4 active MAPs):

| MAP | `order` | Status |
|---|---|---|
| Alpha MAP | 1 | ACTIVE |
| Beta MAP | 2 | ACTIVE |
| Gamma MAP | 3 | ACTIVE |
| Delta MAP | 4 | ACTIVE |

**Step 2 — Accepting a sponsorship**

When a candidate contacts the designated Sponsor and the Sponsor accepts:

1. The Sponsor adds an entry to `active[]` with a new UUIDv4 `id`, the `type`, and `opened` timestamp
2. The Sponsor advances `nextSponsor` using: `nextSponsor = (order % totalActiveMAPs) + 1`, skipping any non-ACTIVE MAPs
3. The Sponsor updates `nextSponsorUpdated` to the current time and publishes the updated registry
4. All other MAPs detect the change within one polling cycle (up to 5 minutes)

The queue advances at acceptance — not at completion.

**Step 3 — Completing a sponsorship**

When onboarding completes:

1. The Sponsor removes the engagement entry from `active[]`
2. `nextSponsor` is **not changed** — it was already advanced at acceptance

**Step 4 — Concurrent onboardings (overflow to next MAP)**

If two candidates request sponsorship while Gamma MAP (order 3, capacity 1) is designated:

- Candidate A arrives. Gamma accepts: adds to `active[]`, sets `nextSponsor: 4`, updates `nextSponsorUpdated`
- Gamma is now at capacity. Candidate B arrives. Delta MAP (order 4) is now designated
- Delta accepts Candidate B: adds to `active[]`, sets `nextSponsor: 1`
- Gamma and Delta run their onboardings in parallel

If Gamma has `capacity: 2`, it can accept both Candidate A and Candidate B simultaneously, advancing `nextSponsor: 4` after the second acceptance.

#### Worked Example

**Starting state** — the most recently updated `nextSponsor` is Gamma's (from 2026-05-01), pointing to Delta as the designated next Sponsor. Gamma is therefore the current Sponsor.

```
Alpha MAP:  { order:1, nextSponsor:2, nextSponsorUpdated:"2026-01-10T...", active:[] }
Beta MAP:   { order:2, nextSponsor:3, nextSponsorUpdated:"2026-03-05T...", active:[] }
Gamma MAP:  { order:3, nextSponsor:4, nextSponsorUpdated:"2026-05-01T...", active:[] }  ← current (most recent)
Delta MAP:  { order:4, nextSponsor:1, nextSponsorUpdated:"2025-12-01T...", active:[] }
```

**Scenario: two new MAPs arrive simultaneously**

New MAP "Epsilon" (traditional) and New MAP "Zeta" (single-cp) both request sponsorship.

Gamma (capacity:1) accepts Epsilon:

```
Gamma MAP:  {
  order:3, nextSponsor:4, nextSponsorUpdated:"2026-06-09T10:00:00Z",
  active: [{ id:"abc...", type:"traditional", opened:"2026-06-09T10:00:00Z" }]
}
```

Delta is now designated. Delta (capacity:1) accepts Zeta:

```
Delta MAP:  {
  order:4, nextSponsor:1, nextSponsorUpdated:"2026-06-09T10:03:00Z",
  active: [{ id:"def...", type:"single-cp", opened:"2026-06-09T10:03:00Z" }]
}
```

Both onboardings proceed in parallel. Alpha MAP is designated for the next request.

When Gamma completes Epsilon's onboarding:

```
Gamma MAP:  { order:3, nextSponsor:4, nextSponsorUpdated:"2026-06-09T10:00:00Z", active:[] }
```

`nextSponsor` is unchanged. Epsilon is assigned `order: 5`. Zeta (when completed) is assigned `order: 6`.

#### Handling Edge Cases

**MAP leaves the network or is suspended:**
When advancing `nextSponsor`, skip any MAP whose `map/status` is not `ACTIVE` until finding the next active MAP.

**Designated MAP at capacity:**
A prospective candidate walks the chain: read the designated MAP's `nextSponsor` to find the next in line, and so on, until finding a MAP where `active.length < capacity`.

**Disagreement on nextSponsorUpdated:**
Timestamps are set by the writing MAP — no consensus is needed. If two MAPs somehow update simultaneously (extremely unlikely in a small network), the MAP with the lower `order` number takes precedence.

**Designated MAP receives no candidates for an extended period:**
There is **no maximum hold time** on the designated-sponsor position. A MAP that is designated but receives no candidate simply remains designated until a candidate arrives. The rotation is event-driven (advance on acceptance), so an idle period at the head of the rotation has no operational cost and no fairness concern — the next acceptance still advances the queue normally.

**Prospective MAP finding the Sponsor before joining:**
There are two discovery paths. The **primary** path is the TAG-published sponsor-registration page (URL to be published by the TAG), which lists the current designated Sponsor MAP and their registration contact and is updated whenever the rotation advances. The **fallback** is the in-band Directory bootstrap: the prospective MAP accesses any existing MAP's CP Registry, finds the entry with the most recent `nextSponsorUpdated`, checks capacity, and contacts that MAP's `map/contact[]` entries. The TAG page is the recommended path for human candidates; the Directory bootstrap remains available for automated tooling and as a fallback if the page is briefly unreachable.

#### Why This Works

- **FIFO enforced**: `order` never changes. The formula `(order % n) + 1` is deterministic and wraps correctly
- **No consensus needed**: The most recent `nextSponsorUpdated` is always authoritative — only the current Sponsor should update the pointer
- **Concurrent onboarding**: `active[]` + `capacity` handle multiple simultaneous engagements transparently; overflow falls naturally to the next MAP in the chain
- **Fast queue**: Advancing on acceptance means a long onboarding never blocks the rotation
- **Self-discoverable**: Any MAP can find the current Sponsor and any candidate can find them before even joining
- **Auditable**: `active[]/opened` and `nextSponsorUpdated` provide a clear operational history

#### Design Rules

The rules below govern the operation of the `sponsorship` rotation and the optional-field semantics. They complement the Field Definitions and the Edge Cases handling above, and apply to every MAP that publishes a CP Registry on the CSF.

| Rule | Statement |
|---|---|
| **Capacity bounds** | The minimum permitted `capacity` is **1** — every onboarded MAP MUST be willing to take at least one engagement at a time. There is **no upper bound** on `capacity`; a MAP sets the value to reflect its own operational throughput. A MAP that primarily takes `single-cp` (MAP-of-1) engagements MAY support a higher `capacity` because those engagements complete faster than traditional multi-CP onboardings. |
| **Engagement weighting** | A `traditional` engagement and a `single-cp` engagement each count as **`1`** against the MAP's `capacity`. No reduced weighting is applied to `single-cp`. The equal-weighting rule protects small MAPs operating at `capacity: 1`: such a MAP is not expected to take additional engagements simply because some are MAP-of-1s. |
| **`order` persistence** | A MAP's `order` is permanent. When a MAP withdraws or its `map/status` becomes non-`ACTIVE`, its `order` is **retained for historical audit consistency** and is not reassigned. The rotation skips entries whose `map/status` is not `ACTIVE`. |
| **Designated-position hold time** | There is **no maximum hold time** on the designated-sponsor position. A designated MAP that receives no candidate remains designated until a candidate arrives. The rotation is event-driven — advance occurs on acceptance — so an idle period has no operational cost and no fairness implication. |
| **`candidateRef`** | `active[]/candidateRef` is **OPTIONAL**. When present, it carries a non-identifying reference assigned by the Sponsor MAP for its own coordination — for example a ticket number from the Sponsor's internal onboarding system. The field is free-form and is not standardised across MAPs; consumers outside the issuing MAP MUST NOT rely on its semantics. |
| **`sponsorship.registrationURI`** | `sponsorship.registrationURI` is **OPTIONAL**. When present, it advertises the Sponsor MAP's own onboarding application page (self-service portal, contracted form, or structured registration endpoint), enabling prospective MAPs and the TAG-published sponsor-registration page to deep-link into that MAP's onboarding flow. A MAP that uses non-electronic registration (email, telephone, ticketing) omits the field; prospective MAPs then use the MAP's `map/contact[]` entries as the contact channel. |

The `sponsorship` object — its required fields, its two optional fields, and the rules in this section — forms part of the CP Registry API specification and is implemented by every MAP on the CSF.

---

## 4. Status Model and JSON Status Values

The CSF uses two distinct status fields. Both are JSON string values, both are observable to peer MAPs, and both have specific consequences during testing.

### 4.1 Per-CP Status (CP Registry — `processSupport[].status`)

Defined in the Directory API (see [Part 2 §5](../part2-implementation/05-directory-api.md)).

```JSON
  "processSupport": [
    { "process": "GPLB", "status": "ACTIVE" }
    ]
```

| Value     | Meaning                                                      | Appears in CP-facing Directory?                      | Messages allowed?                                                                  |
| --------- | ------------------------------------------------------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `ACTIVE`  | CP is live and available for production switching            | Yes                                                  | Yes — production messages                                                          |
| `TEST`    | CP is in onboarding or testing                               | **No** — MUST be excluded from CP-facing Directories | Yes, but every message MUST be flagged as test in the JAM audit envelope           |
| `SUSPEND` | CP is suspended (administration, dispute, planned migration) | **No** — MUST be excluded from CP-facing Directories | Outbound only — in-flight orders may transfer away; no new Switch Matches accepted |
> :tick: **Best Practise** requires the Sponsor MAP to ensure that no messages from a new MAP are treated as Production at ever each stage until they sign them off for completion.
### 4.2 Per-MAP Status (CP Registry — `map.status`, optional)

Defined in the Directory API (see [Part 2 §5](../part2-implementation/05-directory-api.md)). Used during MAP onboarding to mark an entire MAP as in test. When `map.status` is `TEST`, every CP under that MAP is treated as test regardless of its own per-CP status.

```JSON
  "map": {
    "name": "newMap",
    "status": "TEST",
    "version": "2026-04-28T10:30:00Z00000",
    ...
  }
```

| Value | Meaning | Effect on receiving MAPs |
|---|---|---|
| `ACTIVE` *(default if absent)* | MAP is fully operational | Normal operations |
| `TEST` | MAP is onboarding | Establish connectivity and pull registries, but exclude all of this MAP's CPs from the CP-facing Directory |
| `SUSPEND` | MAP is suspended (incident, dispute, administration) | Retain the registry data, mark all entries unavailable, queue messages for retry |

### 4.3 Process Status Casing — Compatibility Note

Existing OTS implementations have used both `Active` and `ACTIVE` casings. CSF MAPs MUST emit upper-case status values (`ACTIVE`, `TEST`, `SUSPEND`) and SHOULD parse case-insensitively for backward compatibility with TOTSCo-sourced data.

## 5. Test Traffic Flagging in the JAM Envelope

The envelope schema and the optional nature of `auditData` are defined in [Message API (Letterbox) §4.3 — Message Structure](../part2-implementation/04-message-api.md#43-message-structure); this section only specifies the CSF-wide conventions for **populating** that field during onboarding and bilateral testing.

Every message originated by, or routed on behalf of, a `TEST`-status CP or a `TEST`-status MAP MUST carry an explicit test marker in the JAM envelope's `auditData`:

```json
{
  "envelope": {
    "source": { "type": "RCPID", "identity": "...", "correlationID": "..." },
    "destination": { "type": "RCPID", "identity": "..." },
    "routingID": "businessSwitchMatchRequest",
    "auditData": [
      { "name": "test", "value": "true" }
    ]
  }
}
```

Rules of behaviour during onboarding:

- The **originating MAP** sets `auditData.test=true` whenever it sends on behalf of a CP whose registry status is `TEST` *or* whose own MAP status is `TEST`.
- The **originating MAP overrides** any contradictory flag set by the CP. The CP cannot opt out.
- The **receiving MAP** MUST preserve `auditData.test=true` end-to-end and MUST NOT clear it during forwarding through HMAPs.
- All test traffic MUST be excluded from production reporting, KPIs, and customer notifications.
- A MAP MUST NOT change a CP's status from `TEST` to `ACTIVE` until the exit criteria in [Section 9](#9-exit-criteria) have been satisfied.

> :memo: **Note**: The MAP-overrides-CP rule is what makes "testing in production" safe. Without it, a misconfigured CP could silently inject test traffic into live counterparties.

### 5.1 Telemetry Exclusion

Industry-wide telemetry collection (defined in [Part 1 §10.6.7 — Anti-Competitive Safeguards](../part1-framework/10-governance.md#1067-anti-competitive-safeguards)) is concerned **only** with production traffic between `ACTIVE` participants. To prevent onboarding, bilateral, or soak-test activity from polluting industry KPIs, every MAP MUST exclude a message from telemetry statistics if **any** of the following are true:

| Condition | Source of truth |
|---|---|
| Originating MAP carries `map.status = TEST` or `SUSPEND` | CP Registry — `map.status` |
| Destination MAP carries `map.status = TEST` or `SUSPEND` | CP Registry — `map.status` |
| Source CP carries `processSupport[].status = TEST` or `SUSPEND` for the message's process | CP Registry — `list[].identity[].processSupport[].status` |
| Destination CP carries `processSupport[].status = TEST` or `SUSPEND` for the message's process | CP Registry — `list[].identity[].processSupport[].status` |
| The JAM envelope's `auditData` contains `{ "name": "test", "value": "true" }` | JAM envelope on the message itself |

Any one of these conditions is sufficient to exclude the message from production telemetry. The `auditData.test=true` flag in particular is the **belt-and-braces** signal — it is set by the originating MAP regardless of registry state and survives end-to-end through any HMAP, so a receiving MAP can reliably exclude the message even if its registry view is momentarily stale.

> :tick: **Best Practice**: Test-flagged messages MAY still be retained for audit and onboarding evidence, but MUST be held in a logically separate store from the production telemetry corpus and clearly labelled as test data. They MUST NOT be aggregated into the figures contributed to the TAG's annual industry summary.

#### Sequencing of session and attempt metadata in `auditData`

The `auditData` array is also the place where session-level metadata SHOULD be carried so that production telemetry (once a message is in scope) can be counted by **customer journey** rather than by individual request. A SforB match journey often spans several `businessSwitchMatchRequest` attempts as the GRCP corrects the data; counting each as an independent event structurally inflates the industry's failure rate. The CSF accommodates a three-layer sequencing scheme — **GRCP-originated session IDs (Layer 1)**, **LRCP echo and enrichment (Layer 2)**, and **MAP-mediated session inference (Layer 3)** — using only the existing extensibility of `auditData`. No envelope, JAM, or SforB Message Spec change is required.

Recommended `auditData` field-name prefixes (full registry in [REVIEW.md §6.5](REVIEW.md#65-match-session-sequencing--auditdata-based-telemetry-proposal)):

| Prefix | Owner | Examples |
|---|---|---|
| `match*` | GRCP-originated (Layer 1) | `matchSessionID`, `matchAttemptSeq`, `matchAttemptReason` |
| `serviceMatch*` | GRCP-originated, service-match phase | `serviceMatchAttemptSeq`, `serviceMatchAttemptReason` |
| `lrcp*` | LRCP-originated (Layer 2) | `lrcpMatchAttemptCount` |
| `map*` | MAP-originated (Layer 3) | `mapSessionID`, `mapAttemptSeq`, `mapRetryFlag`, `mapDataChangeFlag`, `mapConcurrentGrcpCount` |

The `auditData.test=true` flag and any session/attempt fields are independent and complementary: the test flag governs **whether** a message is in production telemetry at all (this section); the session fields govern **how** the in-scope messages are aggregated into per-session KPIs ([REVIEW.md §6.5](REVIEW.md#65-match-session-sequencing--auditdata-based-telemetry-proposal)). MAPs implementing Layer 3 unilaterally SHOULD use the field-name prefixes above to avoid colliding with the eventual industry-standard names.

> :link: **Related**: The full proposal — including session-success-rate definitions, GRCP/LRCP/MAP responsibilities, the field-name registry, the SOR boundary rules, privacy treatment of `matchAttemptReason`, and the four-phase implementation strategy — lives in [REVIEW.md §6.5 — Match Session Sequencing](REVIEW.md#65-match-session-sequencing--auditdata-based-telemetry-proposal). The TAG is currently considering whether to advance it as a TOTSCo IPG bulletin or a GPLB-SG SforB Message Spec revision; until adopted, MAPs MAY implement Layer 3 unilaterally as a value-add, using the prefixes above.

## 6. Onboarding Phases

The five phases below align with [Part 1 §7.2.2](../part1-framework/07-onboarding.md). This section defines the gates between them.

### Phase 1 — Sponsor Selection

| Entry criterion | Exit gate |
|---|---|
| MAP candidate has formally requested onboarding via the TAG-published registration page (URL to be published by the TAG) or via the Directory bootstrap mechanism (§3.4) | Sponsor MAP assigned (next Sponsor) and onboarding agreement signed |

> :tick: **Best Practice**: Sponsor MAPs SHOULD publish, or share on first contact, a short summary of their registration process — including what evidence they will request, how they accept it, the channel used to share secrets, and the expected turnaround time. This makes the experience predictable for new entrants and reinforces the CSF principle that onboarding should be operational in days, not months.

> **Sponsor fee — free by default; capped when significant support is needed.** Sponsor MAPs are not expected to charge for onboarding. There is an option to charge a fee when significant time and effort is required, capped at **£3,000 + VAT** for a `traditional` (multi-CP) engagement or **£350 + VAT** for a `single-cp` (MAP-of-1) engagement. The option exists because the CSF expects the Sponsor MAP to apply a quality gate — all checks and baseline testing complete to TAG standards. Fees are charged once per MAP regardless of how many protocols it carries. See [Part 1 §7.2.1](../part1-framework/07-onboarding.md#721-sponsorship-framework) and [Part 1 §7.4.5](../part1-framework/07-onboarding.md#745-sponsor-map-programme--fast-track-for-single-cp) for the full fee model.






### Phase 2 — Initial Assessment & Registration

| Entry criterion | Exit gate |
|---|---|
| Sponsor MAP confirmed; capability self-assessment submitted | Sponsor sign-off on infrastructure plan; OAuth credentials minted with **provisional/restricted** scope; `map.status=TEST`, no CPs published yet |

Once the TAG has provided the new MAP candidate with the contact details of the assigned Sponsor MAP, the Sponsor MAP **may** require the candidate to complete its own formal registration process before any technical engagement begins. This is a normal commercial step and serves two purposes:

1. **Business verification** — confirming the candidate is a legitimate trading entity (company registration, VAT, ICO registration, trading history, fraud and credit checks where applicable). This complements the wider due-diligence expectation already captured in the Risk Register (see [Part 2 §9](../part2-implementation/09-operations.md)) and in [REVIEW.md §4](REVIEW.md).
2. **Secure information exchange** — providing a controlled channel through which sensitive material can be shared in both directions, including (but not limited to):
   - URL endpoints (OAuth token URL, Directory API URL, Letterbox URL, Service Status URL)
   - OAuth client IDs and client secrets
   - API keys, where used between the MAPs
   - PKI public-key fingerprints and DNS verification details
   - Operational and technical contact lists for incident handling

Each Sponsor MAP may have a different method for engaging at this stage — for example a self-service portal, a contracted onboarding form, a secure file-exchange channel, or a structured email-based exchange protected by encryption. These differences are expected and are **not** standardised by the TAG, since the registration process sits outside the technical scope of the CSF and reflects each Sponsor MAP's own commercial, legal, and security policies.

> :memo: **Note**: The candidate MAP should treat the Sponsor MAP's registration process as the gateway to all subsequent phases. Until it is complete, no OAuth credentials will be issued, no test endpoints will be shared, and no technical onboarding work can begin. Candidate MAPs are encouraged to ask the Sponsor MAP for a clear list of registration requirements at first contact, so that any documentation or evidence (e.g. company registration documents, ICO certificates, security policies) can be prepared in parallel.

### Phase 3 — Integration & Testing (the core build phase)

This is the phase in which **most of [Section 8](#8-tag-baseline-test-suite) is exercised**.

| Sub-phase | Tests required | Outcome |
|---|---|---|
| 3a — Connectivity | §8.1 (TLS), §8.2 (OAuth) | Bidirectional authenticated connectivity with the Sponsor MAP |
| 3b — Registry | §8.3 (Directory API) | New MAP can publish, and consume from, valid CP Registries |
| 3c — PKI | §8.4 (DKIM) and §7 (PKI Harness) | Round-trip signing and verification proven against the public NowYoYo verification endpoint |
| 3d — Letterbox | §8.5 (Letterbox API) | End-to-end JAM message exchange with HTTP 202 acknowledgements |
| 3e — Industry process | §8.6 (SforB) | Switch Match, Switch Order, and failure handling flows pass against test CPs |

Exit gate: All baseline tests in §8.1 to §8.6 pass against the Sponsor MAP. Provisional access is upgraded to **test** scope; obfuscated/test-only registry data may now be exchanged.

### Phase 4 — Operational Validation

| Entry criterion | Exit gate |
|---|---|
| Phase 3 sign-off | §8.7 (retry & delivery policy), §8.8 (conflict resolution), §8.9 (security/negative) all pass; SLA evidence collected over a continuous **72-hour** soak; bilateral connectivity tests with at least 50% of other MAPs completed |

> **MAP-of-1 variant (`single-cp` engagements).** For a candidate onboarding as a [MAP of 1](../part1-framework/04-architecture-overview.md) — tracked as `type: "single-cp"` in `sponsorship.active[]` (see §3.4) — the Phase 4 exit gate is modified per [Part 1 §7.4.9](../part1-framework/07-onboarding.md#749-phase-4-relaxation-for-map-of-1):
>
> - **72-hour soak waived** — a single-CP MAP has no meaningful production-scale traffic to soak, and the CP carries the operational risk directly.
> - **Bilateral ≥50% waived** — required only with the MAPs / HMAPs (including TOTSCo as HMAP) the candidate intends to exchange with at go-live.
> - §8.7 / §8.8 / §8.9 — **required, unchanged**.
> - §8.10 V-02 – V-05 — **required**; V-01 (72-hour soak) — **waived**.
>
> The Sponsor MAP records the waivers in the Phase 5 approval record.

### Phase 5 — Full Operations

| Entry criterion | Exit gate |
|---|---|
| Phase 4 sign-off | Sponsor MAP issues formal approval; `map.status` removed (or set to `ACTIVE`); first CP transitioned from `TEST` to `ACTIVE` only after passing the per-CP exit checks; TAG notified |

## 7. PKI Test Harness (NowYoYo)

PKI/DKIM signing is consistently the area that takes the longest to get right. To shorten that learning curve, NowYoYo Limited operates a free, public verification harness. It accepts CSF-formatted POSTs, verifies the signature using the published DNS keys, and either logs every step of the verification (the `.txt` endpoint) or returns a production-style response (the `.json` endpoint).

The harness uses two test CPs whose public keys live under `gplb-test.nowyoyo.net`:

| RCPID | Algorithm |
|---|---|
| `809b6e65-a6e7-40f6-8b52-04dd65b6fce1` | RSA-SHA256 (3072-bit) |
| `a73f0493-fd1f-4b5b-826c-1d6243d43365` | Ed25519-SHA256 |

> :bulb: Use the harness early and often. Most onboarding incidents are caught by the harness within minutes; missing them locally results in days of debugging against a live Sponsor MAP.


### Verification Testing Endpoint

There are 2 endpoints set up for testing.

`https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.txt`

Used in 1st-stage development. Success returns 200, failure gives 403.
The response body is a timed text log of all the detailed steps that the system used to verify the message. In the case of failure this should be valuable in identifying where things are going wrong.

`https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.json`

Used to submit messages to a *production-like* CSF endpoint. The errors are formatted in the same way as production CSF messages, success is **204**, failure is **403**. No further processing on the messages is performed.

> **Note**: These endpoints accept signed POST requests only. They are intentionally not browsable in a web browser — wrap them as `code` in any reference and use the `curl` examples below to exercise them.

### Examples

#### RSA — Success (200) at the `.txt` endpoint

```shell
curl -X "POST" -i "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.txt" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340391' \
     -H 'X-CSF-SIGNATURE: a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=h3YO8jlz2Gup/szefoH3RxO46IJmnk+8GJ4pxxRyfh+UJ0mZym64o0izGNG1x3GlmMiuHfZc5xP9xIANP+OIajX1udhTGuZkSfUU3L4MrvT/PYkAEfIMm7lFeCWPPgOr0bNIVjNVBrB41akN1iwcQjK0gD+/nUGLVXihdOFCj0xSRIypLPKPxXsZED6sfiBSlEiZcGsF9FCiV5OQQAwRoRhFQE4cnn00QE/S3NoN8/lX7i8OXIaTab6p/HCMIjirM6VBKrc+O0HEdekXn1DP7s0cwp/LkeXTWVloj+vkZREHqNkdIZGeab7N8vFgLrXmYJoR2LM+LQtqhq01KRVSY4hDWdbjD4cSJWkV9P/GWelFiuSNtYmWqTcrT0kqN7pMwVq1Ht4iuhrxH7h2hnCjYG12bEYiHPmarO+JJCPx5RawO0t2BRBxNfEXbp6boTQzZ//MrdW4mUDEyCQhs6s/OHd5x14Z2DJUTYRhugLwGkwSaVjt44y6X9RnB5d9j/Py;' \
     -d "hello"
```

```text
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Type: application/json
Content-Length: 5818
Date: Tue, 09 Sep 2025 17:07:39 GMT

0ms : Request Received
0ms : Checking Initial CSF MandatoryHeaders [X-CSF-SIGNATURE, X-CSF-SIGNATURE-DATESTAMP]
0ms : Parsing Header Signature: a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=h3YO8jlz2Gup/szefoH3RxO46IJmnk+8GJ4pxxRyfh+UJ0mZym64o0izGNG1x3GlmMiuHfZc5xP9xIANP+OIajX1udhTGuZkSfUU3L4MrvT/PYkAEfIMm7lFeCWPPgOr0bNIVjNVBrB41akN1iwcQjK0gD+/nUGLVXihdOFCj0xSRIypLPKPxXsZED6sfiBSlEiZcGsF9FCiV5OQQAwRoRhFQE4cnn00QE/S3NoN8/lX7i8OXIaTab6p/HCMIjirM6VBKrc+O0HEdekXn1DP7s0cwp/LkeXTWVloj+vkZREHqNkdIZGeab7N8vFgLrXmYJoR2LM+LQtqhq01KRVSY4hDWdbjD4cSJWkV9P/GWelFiuSNtYmWqTcrT0kqN7pMwVq1Ht4iuhrxH7h2hnCjYG12bEYiHPmarO+JJCPx5RawO0t2BRBxNfEXbp6boTQzZ//MrdW4mUDEyCQhs6s/OHd5x14Z2DJUTYRhugLwGkwSaVjt44y6X9RnB5d9j/Py
0ms : Tags present are :
	a : rsa-sha256
	q : dns/txt
	c : simple/simple
	s : 809b6e65-a6e7-40f6-8b52-04dd65b6fce1
	d : gplb-test.nowyoyo.net
	v : 1
	h : X-CSF-SIGNATURE-DATESTAMP
	bh : LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
	b : h3YO8jlz2Gup/szefoH3RxO46IJmnk+8GJ4pxxRyfh+UJ0mZym64o0izGNG1x3GlmMiuHfZc5xP9xIANP+OIajX1udhTGuZkSfUU3L4MrvT/PYkAEfIMm7lFeCWPPgOr0bNIVjNVBrB41akN1iwcQjK0gD+/nUGLVXihdOFCj0xSRIypLPKPxXsZED6sfiBSlEiZcGsF9FCiV5OQQAwRoRhFQE4cnn00QE/S3NoN8/lX7i8OXIaTab6p/HCMIjirM6VBKrc+O0HEdekXn1DP7s0cwp/LkeXTWVloj+vkZREHqNkdIZGeab7N8vFgLrXmYJoR2LM+LQtqhq01KRVSY4hDWdbjD4cSJWkV9P/GWelFiuSNtYmWqTcrT0kqN7pMwVq1Ht4iuhrxH7h2hnCjYG12bEYiHPmarO+JJCPx5RawO0t2BRBxNfEXbp6boTQzZ//MrdW4mUDEyCQhs6s/OHd5x14Z2DJUTYRhugLwGkwSaVjt44y6X9RnB5d9j/Py
0ms : Using the following Domain for Public Key Lookup: 809b6e65-a6e7-40f6-8b52-04dd65b6fce1._domainkey.gplb-test.nowyoyo.net
0ms : Received the following records:
	k=rsa; p=MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6/RekuGAsET2Ir8E4K5BU74MBXebo7QwrOnSGirtNgRLDcwP2R84Eeum9BLxZtiumUrmO6ja7DrteSZhzOyC09KM3b22zV43bm7nv/FF40+KpTDQ/FZ32W838UIZGgHOyICk37hlPvnGrVPg7rT6HAKsaj5W0zbvO5vKDUOz2r3bvrWo79YSxtVfGQ1pHhhZYV2dL1C0uiADbz5L1Cu0qCBjqGJQbYq4ALdaKTnAm2NG/N9W2i3IWJUQIyiTr11qtBrrR8sj2YhYeph6GTsOXggpAWZnEHZz+LKzD4roVqUxkByLWRLB2I5Ju/xPPtTjCDakfvGlsiWl5BMAhn79p0mW6hzcA4DT7Iz+nSV8K3XMU4rxs0AcaafcBsKREmfbGz4K3ycWHZ/Yrxb+PqYHy7NSK76mHsAjuU8nuKYtZGIYHwT4friS2R3HtXJ+olLmdZ+XnkpdvEGDb+ZVv/G9vYp020LZQBBd0hp1Ez8a/3F7jRt8xUJ0ljstWjbq+m3bAgMBAAE=
0ms : Have Public Key of RSA type and X.509 format.
0ms : RSA Key length is determined as 3072 bits.
0ms : Body is 5 bytes.
	[104, 101, 108, 108, 111]
0ms : Hashing Algorithm is specified as : SHA256
0ms : SHA256Hash of 5 byte body is : LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
0ms : Calculated hash and Signature hash are a match
0ms : Starting Signature Generation
0ms : h tag requests the following fields for the signature: [X-CSF-SIGNATURE-DATESTAMP]
0ms : Header 'X-CSF-SIGNATURE-DATESTAMP' contains 202412121340391
	Adding Header Value : [50, 48, 50, 52, 49, 50, 49, 50, 49, 51, 52, 48, 51, 57, 49]
	Adding CRLF : [13, 10]
0ms : Using the following as the signature line with an empty b tag
	a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=;
0ms : Prepending 'DKIM-Signature: '
	DKIM-Signature: a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=;
0ms : Proceeding with Signature Generation and Verification
1ms : Signature verification successful!
1ms : Result = Pass. Well done!
```

#### RSA — Success (204) at the `.json` endpoint

```shell
curl -X "POST" -i "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.json" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340391' \
     -H 'X-CSF-SIGNATURE: a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=h3YO8jlz2Gup/szefoH3RxO46IJmnk+8GJ4pxxRyfh+UJ0mZym64o0izGNG1x3GlmMiuHfZc5xP9xIANP+OIajX1udhTGuZkSfUU3L4MrvT/PYkAEfIMm7lFeCWPPgOr0bNIVjNVBrB41akN1iwcQjK0gD+/nUGLVXihdOFCj0xSRIypLPKPxXsZED6sfiBSlEiZcGsF9FCiV5OQQAwRoRhFQE4cnn00QE/S3NoN8/lX7i8OXIaTab6p/HCMIjirM6VBKrc+O0HEdekXn1DP7s0cwp/LkeXTWVloj+vkZREHqNkdIZGeab7N8vFgLrXmYJoR2LM+LQtqhq01KRVSY4hDWdbjD4cSJWkV9P/GWelFiuSNtYmWqTcrT0kqN7pMwVq1Ht4iuhrxH7h2hnCjYG12bEYiHPmarO+JJCPx5RawO0t2BRBxNfEXbp6boTQzZ//MrdW4mUDEyCQhs6s/OHd5x14Z2DJUTYRhugLwGkwSaVjt44y6X9RnB5d9j/Py;' \
     -d "hello"
```

```text
HTTP/1.1 204
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Date: Tue, 09 Sep 2025 16:41:31 GMT
```

#### RSA — Failure (403, body hash mismatch) at the `.json` endpoint

```shell
curl -X "POST" -i "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.json" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340391' \
     -H 'X-CSF-SIGNATURE: a=rsa-sha256; q=dns/txt; c=simple/simple; s=809b6e65-a6e7-40f6-8b52-04dd65b6fce1; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=h3YO8jlz2Gup/szefoH3RxO46IJmnk+8GJ4pxxRyfh+UJ0mZym64o0izGNG1x3GlmMiuHfZc5xP9xIANP+OIajX1udhTGuZkSfUU3L4MrvT/PYkAEfIMm7lFeCWPPgOr0bNIVjNVBrB41akN1iwcQjK0gD+/nUGLVXihdOFCj0xSRIypLPKPxXsZED6sfiBSlEiZcGsF9FCiV5OQQAwRoRhFQE4cnn00QE/S3NoN8/lX7i8OXIaTab6p/HCMIjirM6VBKrc+O0HEdekXn1DP7s0cwp/LkeXTWVloj+vkZREHqNkdIZGeab7N8vFgLrXmYJoR2LM+LQtqhq01KRVSY4hDWdbjD4cSJWkV9P/GWelFiuSNtYmWqTcrT0kqN7pMwVq1Ht4iuhrxH7h2hnCjYG12bEYiHPmarO+JJCPx5RawO0t2BRBxNfEXbp6boTQzZ//MrdW4mUDEyCQhs6s/OHd5x14Z2DJUTYRhugLwGkwSaVjt44y6X9RnB5d9j/Py;' \
     -d "hellox"
```

```json
{
  "errorText": "Body hash mismatch, calculated Gmu6Qx+5NH5pfydVjH9xKhOJfJX82h5QuFOpeF1zLTc= and from signature LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=",
  "errorCode": "8101"
}
```

#### Ed25519 — Success (200) at the `.txt` endpoint

```shell
curl -X "POST" "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.txt" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340391' \
     -H 'X-CSF-SIGNATURE: a=ed25519-sha256; q=dns/txt; c=simple/simple; s=a73f0493-fd1f-4b5b-826c-1d6243d43365; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=LiRX0EqzkcSD4nZwRHlPhtQge4vp3Kssh9Z/Ov4dAl3PHmrhOthDTMs3RoTUSnjPgweoY+wXsCDOPiOGcqAxCQ==;' \
     -d "hello"
```

```text
0ms : Request Received
0ms : Checking Initial CSF MandatoryHeaders [X-CSF-SIGNATURE, X-CSF-SIGNATURE-DATESTAMP]
0ms : Parsing Header Signature: a=ed25519-sha256; q=dns/txt; c=simple/simple; s=a73f0493-fd1f-4b5b-826c-1d6243d43365; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=LiRX0EqzkcSD4nZwRHlPhtQge4vp3Kssh9Z/Ov4dAl3PHmrhOthDTMs3RoTUSnjPgweoY+wXsCDOPiOGcqAxCQ==
0ms : Using the following Domain for Public Key Lookup: a73f0493-fd1f-4b5b-826c-1d6243d43365._domainkey.gplb-test.nowyoyo.net
0ms : Received the following records:
	k=ed25519; p=MCowBQYDK2VwAyEAqiCrokPReIFI1h4Jdp7RCRRVQ4Fltdyn429O4H2jYog=
0ms : Have Public Key of EdDSA type and X.509 format.
0ms : EdRSA Key length is 32 bytes
0ms : Body is 5 bytes.
0ms : SHA256Hash of 5 byte body is : LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
0ms : Calculated hash and Signature hash are a match
0ms : Proceeding with Signature Generation and Verification
1ms : Signature verification successful!
1ms : Result = Pass. Well done!
```

#### Ed25519 — Failure (403, body hash) at the `.txt` endpoint

```shell
curl -X "POST" "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.txt" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340391' \
     -H 'X-CSF-SIGNATURE: a=ed25519-sha256; q=dns/txt; c=simple/simple; s=a73f0493-fd1f-4b5b-826c-1d6243d43365; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=LiRX0EqzkcSD4nZwRHlPhtQge4vp3Kssh9Z/Ov4dAl3PHmrhOthDTMs3RoTUSnjPgweoY+wXsCDOPiOGcqAxCQ==;' \
     -d "hellox"
```

```text
0ms : Request Received
...
44ms : Have Public Key of EdDSA type and X.509 format.
44ms : EdRSA Key length is 32 bytes
45ms : Body is 6 bytes.
45ms : SHA256Hash of 6 byte body is : Gmu6Qx+5NH5pfydVjH9xKhOJfJX82h5QuFOpeF1zLTc=
45ms : Calculated hash and Signature hash (bh) are **not** a match
	Calculated hash is Gmu6Qx+5NH5pfydVjH9xKhOJfJX82h5QuFOpeF1zLTc=
	Signature hash (bh) is LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=
53ms : Result = Fail.
```

#### Ed25519 — Failure (403, signature mismatch via altered datestamp) at the `.txt` endpoint

```shell
curl -X "POST" "https://sec-key-test.csf.nowyoyo.net/csf/T/letterbox/2.0/post.txt" \
     -H 'X-CSF-SIGNATURE-DATESTAMP: 202412121340392' \
     -H 'X-CSF-SIGNATURE: a=ed25519-sha256; q=dns/txt; c=simple/simple; s=a73f0493-fd1f-4b5b-826c-1d6243d43365; d=gplb-test.nowyoyo.net; v=1; h=X-CSF-SIGNATURE-DATESTAMP; bh=LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=; b=LiRX0EqzkcSD4nZwRHlPhtQge4vp3Kssh9Z/Ov4dAl3PHmrhOthDTMs3RoTUSnjPgweoY+wXsCDOPiOGcqAxCQ==;' \
     -d "hello"
```

```text
0ms : Request Received
...
1ms : Calculated hash and Signature hash are a match
1ms : Starting Signature Generation
1ms : h tag requests the following fields for the signature: [X-CSF-SIGNATURE-DATESTAMP]
1ms : Header 'X-CSF-SIGNATURE-DATESTAMP' contains 202412121340392
1ms : Proceeding with Signature Generation and Verification
3ms : Signature verification has failed!
5ms : Result = Fail.
```

> :memo: **Note**: The signature failure example above demonstrates replay-attack protection in action. Changing only the `X-CSF-SIGNATURE-DATESTAMP` (without re-signing) breaks verification, exactly as the CSF requires.


## 8. TAG Baseline Test Suite

The TAG mandates the following baseline tests for every new MAP. Each test has an outcome classification:

- **P** — Positive (the happy path; behaviour MUST succeed)
- **N** — Negative (the system MUST reject and return the specified error)
- **E** — Edge case (boundary, race, or non-obvious behaviour the system MUST handle correctly)

This suite is significantly broader than the current TOTSCo onboarding because:

1. There is **no central validator** — every MAP must independently demonstrate correctness.
2. The CSF currently combines **two industry processes** (CSF transport and SforB business process), and tests must cover the interaction between them.
3. **PKI verification is the principal trust mechanism** — it must be exercised exhaustively.
4. **Conflict resolution** during CP-MAP transitions is unique to the CSF and needs explicit coverage.

### Scope and Extensibility — Other Industry Protocols

While this document currently codifies baseline tests for the **CSF transport** itself (Sections 8.1 to 8.5, 8.7 to 8.10) and the **SforB industry process** (Section 8.6), the CSF transport is process-agnostic by design. Other industry protocols that ride over the same transport — for example **OTS Port** (number porting), future bilateral notification flows, or any new process the TAG agrees to host — are equally in scope of this onboarding regime.

As each additional protocol is brought onto the CSF, the TAG MUST add a corresponding **§8.x baseline test set** for that protocol, alongside §8.6 (SforB). MAPs and CPs that elect to support that protocol are then required to pass the relevant §8.x set as part of their onboarding (or as a delta if they are already onboarded for other processes). MAPs that do not support the protocol are not required to run those tests.

This means the onboarding suite is intentionally **extensible at any point**:

- New protocol → new §8.x section, with its own positive, negative, and edge-case tests.
- Operational learning on an existing protocol → new test cases appended to that protocol's section, with the date of TAG adoption recorded.
- Cross-protocol interactions (e.g. a CP supporting both SforB and OTS Port simultaneously, or a CP transitioning between processes) → tests added to the most relevant section, with cross-references where useful.

> :memo: **Note**: A MAP supporting multiple industry protocols on the CSF MUST evidence onboarding for **each** protocol it carries. Sponsor MAPs SHOULD verify this scope explicitly during Phase 1, so the candidate is clear which §8.x sets apply to its proposed footprint. See [REVIEW.md §1.9](REVIEW.md) for the open action covering ongoing baseline expansion.

### 8.1 Connectivity & Transport (TLS 1.3)

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| C-01 | P | TLS 1.3 handshake against each of the four required endpoints | Successful handshake with TLS 1.3 negotiated |
| C-02 | P | Valid certificate chain to a trusted CA | Trust path validates without warnings |
| C-03 | N | Connect using TLS 1.2 | Connection rejected by the new MAP |
| C-04 | N | Connect using a self-signed or expired certificate | Connection refused; alert raised |
| C-05 | N | Attempt cleartext HTTP on any CSF endpoint | Connection refused or auto-redirected to HTTPS |
| C-06 | E | SNI requests for an unrelated host on the same IP | Server returns a certificate matching the requested host or refuses, never the wrong cert |
| C-07 | E | Long-lived idle connection across keepalive timeout | Reconnect succeeds without leaking session state |

### 8.2 OAuth 2.0 (Client Credentials)

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| O-01 | P | Token issued for a registered client with valid `client_secret` | HTTP 200 with bounded-lifetime bearer token |
| O-02 | P | Token used to call the Letterbox API | API accepts the token (subject to other validations) |
| O-03 | N | Invalid `client_secret` | HTTP 401, no token |
| O-04 | N | Expired token used on Letterbox API | HTTP 401 |
| O-05 | N | Token issued by a different MAP's authorisation server | HTTP 401 (issuer/audience mismatch) |
| O-06 | N | Token presented over HTTP (no TLS) | Connection refused before token is parsed |
| O-07 | E | Two concurrent token refreshes | No race; both tokens valid, no token reuse beyond expiry |
| O-08 | E | Clock skew of ±60 seconds between MAPs | Token still validates within the configured tolerance |
| O-09 | E | Client secret rotation under load | Old secret stops working only after grace period; no production impact |

### 8.3 CP Registry & Directory API

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| D-01 | P | Publish a registry containing one CP with `processSupport.status=TEST` | Registry validates against schema; peers can pull |
| D-02 | P | Update `map.version` timestamp on every change | Peers detect change and re-pull |
| D-03 | P | Pull peer registry and merge into Master Registry | Master Registry contains the union; conflicts marked |
| D-04 | N | Publish registry missing a mandatory field (e.g. `map.contact`) | Peer fails schema validation; new MAP is notified |
| D-05 | N | Publish a CP with malformed RCPID (not UUIDv4) | Peer rejects the CP entry |
| D-06 | N | Pull registry with stale OAuth token | HTTP 401; fall back to re-authentication |
| D-07 | E | Two CPs with identical brand names across different MAPs | Both appear in Directory; RCPID disambiguates |
| D-08 | E | Registry pulled at maximum recommended frequency (~60s) over 24h | No throttling; consistent freshness |
| D-09 | E | A CP appears with `status=TEST` in one registry and `status=ACTIVE` in another (rare conflict) | Receiving MAP excludes from its CP-facing Directory and raises an alert |
| D-10 | E | Registry contains a CP whose `_mapkey` DNS record points to a different MAP | Conflict-resolved per [§5.5](../part1-framework/05-directory-and-registry.md); DNS wins |
| D-11 | E | TEST CPs MUST NOT appear in the CP-facing Directory shared with the new MAP's own CPs | Directory excludes all `TEST` and `SUSPEND` entries |

### 8.4 PKI / DKIM Signing

These are the highest-stakes tests. Every test below MUST be runnable against the [NowYoYo PKI Test Harness](#7-pki-test-harness-nowyoyo) before being repeated against the Sponsor MAP.

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| K-01 | P | Sign + verify round-trip with RSA-SHA256 (2048-bit) | Verification passes |
| K-02 | P | Sign + verify round-trip with RSA-SHA256 (3072-bit) | Verification passes |
| K-03 | P | Sign + verify round-trip with Ed25519-SHA256 | Verification passes |
| K-04 | P | Sign + verify round-trip with RSA-SHA512 | Verification passes |
| K-05 | P | Verify against the public NowYoYo `.txt` endpoint | HTTP 200 with successful log |
| K-06 | P | Verify against the public NowYoYo `.json` endpoint | HTTP 204 |
| K-07 | N | Mutate one byte of the body after signing | HTTP 403, error code `8101`, body hash mismatch |
| K-08 | N | Mutate the `X-CSF-SIGNATURE-DATESTAMP` after signing | HTTP 403, error code `8101`, signature verification failure |
| K-09 | N | Submit RSA-1024 key (below minimum) | Verifier rejects with `8101` (key too short) |
| K-10 | N | `d=` in signature does not match the directory entry for the CP | HTTP 403, error code `8101` (domain not valid for CP) |
| K-11 | N | Missing mandatory tag (`b`, `bh`, `s`, `d`, `a`, `c`, `h`) | HTTP 403, error code `8101`, listing missing tag(s) |
| K-12 | N | DNS TXT record absent for the CP `_domainkey` | HTTP 403, error code `8102` (TEMP_FAIL) |
| K-13 | N | DNS TXT record present but malformed (`k=`/`p=` invalid) | HTTP 403, error code `8102` |
| K-14 | N | Signature uses SHA-1 (deprecated) | HTTP 403, error code `8101` |
| K-15 | N | Header casing wrong (`x-csf-signature-datestamp` lower-case in signature input) | Verification fails — surfaces case-sensitivity bug |
| K-16 | E | DKIM-Signature canonicalisation has trailing whitespace | Verifier still passes *only* if `c=simple/simple` is honoured exactly |
| K-17 | E | Body containing only whitespace, then signed | Verification passes — empty hash matches |
| K-18 | E | Replay the same signed message after 10 minutes | Receiver MAY accept or reject by configured window; behaviour MUST be documented |
| K-19 | E | Replay the same signed message after 24 hours | Receiver MUST reject (replay window exceeded) |
| K-20 | E | CP rotates DNS public key during onboarding | Old signatures fail; new signatures pass within DNS TTL + handling buffer |

### 8.5 Letterbox API (Message Send/Receive)

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| L-01 | P | POST a valid signed JAM message to the new MAP's letterbox | HTTP 202, no body |
| L-02 | P | POST to the new MAP for a CP it serves | Message delivered to that CP via the MAP's CP integration |
| L-03 | N | POST without `Authorization` header | HTTP 401 |
| L-04 | N | POST with malformed JSON body | HTTP 400 |
| L-05 | N | POST with envelope missing `source.identity` | HTTP 400, error code `9003` |
| L-06 | N | POST to a destination RCPID not in the new MAP's registry | HTTP 400, error code `9001` |
| L-07 | N | POST with `routingID` not supported by destination | HTTP 400, error code `9012` |
| L-08 | N | Destination CP `status=SUSPEND` for the requested process | HTTP 403, error code `9001` |
| L-09 | N | Source CP authorisation does not match originating MAP | HTTP 401, error code `9004` |
| L-10 | N | Send a message that is unsigned (missing `X-CSF-SIGNATURE`) | HTTP 403, error code `8101` |
| L-11 | N | Send a message via GET instead of POST | HTTP 405 |
| L-12 | E | Send a message of 100KB body | HTTP 202; no truncation |
| L-13 | E | Send a message of 1MB body | HTTP 202 if within published limits, otherwise documented rejection |
| L-14 | E | Send a message with `auditData.test=true` to a `status=ACTIVE` CP | Receiver routes but excludes from production reporting |
| L-15 | E | Burst of 100 messages in 10 seconds | All accepted, or rate-limited with HTTP 429 + `Retry-After` |
| L-16 | E | Same `correlationID` used twice within the retry window | Receiver MUST treat as idempotent (no duplicate downstream delivery) |

### 8.6 SforB Industry Process Tests

This onboarding and testing process document is **v1.0** of the TAG Baseline Test Suite — published by the TAG as a standalone supporting document for the CSF and for onboarding activities. The baseline is expected to iterate over time as additional tests are developed to support the Switching for Business protocol and as MAPs progress through onboarding and industry testing. The aim is to capture the lessons learnt during operation and to **raise the quality bar of entry** to the CSF network. The SforB industry-process tests below represent the agreed v1.0 baseline, which the TAG will evolve in subsequent revisions.

This baseline is also expected to **grow continuously** as the network goes live and operational experience surfaces additional cases (defects, near-misses, edge conditions, regulatory changes, GPLB-SG process refinements). Each new case agreed by the TAG MUST be added to this section and to the regression suite in [Section 11](#11-regression-suite-for-ongoing-compliance), with the date of adoption recorded. See [REVIEW.md §1.9](REVIEW.md) for the open action.

These tests verify the **interaction** between CSF transport and the SforB business process. The TAG's published test data assets and the Sponsor MAP's Virtual Test Host are used as counterparties.

| ID   | Type | Test                                                                                                          | Expected outcome                                                                       |
| ---- | ---- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| S-01 | P    | Send `businessSwitchMatchRequest` for a known test CP with valid asset data                                   | Receive `businessSwitchMatchResponse` with `match=true`                                |
| S-02 | P    | Send `businessSwitchOrderRequest` after a successful match                                                    | Receive `businessSwitchOrderResponse` with order accepted                              |
| S-03 | P    | Receive a `businessSwitchMatchRequest` and respond using cached customer data (without CP being online)       | Response within published SLA                                                          |
| S-04 | P    | Cancel an in-flight order before completion                                                                   | Cancellation acknowledged; downstream parties informed                                 |
| S-05 | N    | Send `businessSwitchMatchRequest` against a CP with `status=SUSPEND`                                          | Match request rejected with appropriate code                                           |
| S-06 | N    | Send `businessSwitchOrderRequest` without a preceding match                                                   | Order rejected with appropriate code                                                   |
| S-07 | N    | `businessSwitchMatchRequest` with corrupted asset data                                                        | Match rejected with the correct **SforB Response Code**                                  |
| S-08 | N    | Order request with destination CP whose `_mapkey` DNS record points to a different MAP                        | Sender re-routes via DNS; receiver rejects misrouted attempt                           |
| S-09 | E    | Match request crossing midnight (timestamp window edge)                                                       | No false rejections due to date rollover                                               |
| S-10 | E    | Match request to a CP that has just transitioned MAP (within DNS TTL)                                         | Either old or new MAP responds; conflict resolved by DNS                               |
| S-11 | E    | Concurrent matches and orders on the same business asset                                                      | SforB process tie-breaking rules apply (as defined by the GPLB-SG); no double-allocation |
| S-12 | E    | Test traffic (`auditData.test=true`) MUST NOT generate customer notifications, billing events, or KPI updates | Verified in receiving MAP's downstream reporting                                       |
| S-13 | E    | A CP appears in registries for OTS *and* SforB with different statuses                                          | Each process evaluated independently                                                   |
| S-14 | E    | Switch Match for a CP linked across OTS and SforB RCPIDs (R.26)                                                 | Linkage resolved if implemented; degrades gracefully if not                            |

### 8.7 Retry & Delivery Policy

This test set exercises the CSF MAP-to-MAP delivery policy ratified in [Part 2 §4.7](../part2-implementation/04-message-api.md#47-message-delivery-policy). Tests **R-01 to R-09** are behavioural (the original baseline) and validate response handling, error-code emission, and circuit-breaker activation. Tests **R-10 to R-17** were added when §4.7 was ratified and validate the concrete numerical values now codified in the framework — connection / response timeouts, exponential-backoff shape, and circuit-breaker activation / recovery thresholds.

The HMAP boundary is **out of scope** of this test set — see the standalone [TOTSCo HMAP Integration Guide §7](./totsco-hmap-integration-guide.md) for HMAP-specific tests. The R-tests below all assume CSF MAP-to-MAP P2P traffic.

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| R-01 | P | Receiving MAP returns HTTP 503 with `Retry-After: 30` | Sender retries no sooner than 30s |
| R-02 | P | Receiving MAP returns HTTP 429 with `Retry-After` | Sender backs off respecting header |
| R-03 | P | Transient network failure mid-POST | Sender retries with exponential backoff and jitter |
| R-04 | N | Receiving MAP returns HTTP 400 | Sender does **not** retry; raises `9006` delivery failure |
| R-05 | N | Receiving MAP returns HTTP 404 | Sender does **not** retry; raises `9007` delivery failure |
| R-06 | N | Sender exceeds maximum retry window | Sender raises `9008` and stops |
| R-07 | E | Circuit breaker opens after N consecutive failures | Subsequent sends fail fast and alert is raised |
| R-08 | E | Circuit breaker closes after recovery period | Normal sending resumes |
| R-09 | E | Long-lived 8102 (DNS) failure | Sender retries with backoff up to maximum window, then fails the message |
| **R-10** | **P** | **Connection timeout — sender attempts delivery to a destination IP that drops the SYN.** Measure the elapsed time before the sender treats the attempt as failed. | Attempt fails at **1 second ± 200 ms**. Sender records the failure, enters the retry schedule. Connection-time recorded in the audit log. |
| **R-11** | **P** | **Response timeout — destination accepts the TCP / TLS connection but never sends `HTTP 202` (or any response).** Measure the elapsed time before the sender abandons the attempt. | Attempt fails at **3 seconds ± 500 ms** after connection establishment. Sender records the failure, enters the retry schedule. Response-time recorded in the audit log. |
| **R-12** | **P** | **Exponential backoff shape — destination returns HTTP 5xx on every attempt for 5 minutes.** Capture all retry intervals observed by the sender. | Successive intervals show **geometric growth** (each interval ≥ 1.5× the previous) capped at a maximum (e.g. 60 s). Linear or fixed-cadence intervals MUST cause the test to fail. |
| **R-13** | **P** | **Jitter present — repeat R-12 with three independent senders against the same destination.** Compare retry timestamps across senders. | Retry timestamps **do not align**; observed pairwise variance ≥ ±15 % of the base interval. Aligned (no-jitter) timestamps MUST cause the test to fail. |
| **R-14** | **P** | **Circuit-breaker activation — destination returns HTTP 5xx (or times out) on N consecutive attempts.** Continue sending after the Nth failure. | After N (recommended 5) consecutive failures the circuit opens; subsequent sends fail fast within 100 ms without attempting the destination; an operational alert is raised; the sender's outbound queue continues queueing new messages without further delivery attempts to that destination. |
| **R-15** | **P** | **Circuit-breaker recovery — after the circuit has opened, wait the configured recovery period, then issue a single probe attempt to a destination that now responds normally.** | The probe attempt succeeds. The circuit transitions **half-open → closed**. Subsequent queued messages flow to the destination normally. A "circuit closed" event is recorded in the audit log. |
| **R-16** | **E** | **Half-open probe failure — after recovery period expires, probe attempt fails (destination still down).** | Circuit returns cleanly to the **open** state without flooding the destination with the queued backlog. Next recovery period begins. Alert state preserved (no false "recovered" notification). |
| **R-17** | **P** | **Bounded retry window — sender's configured maximum retry window expires while destination is still failing.** | Sender raises **`9008` Delivery Failure** for the originating message, increments the persistent-failure counter, and triggers the operational-escalation path: an alert is raised that names the destination RCPID, attempt count, and last error code. The sender MUST NOT continue retrying indefinitely. |
| **R-18** | **E** | **Operational engagement via `map/outage[]` — destination MAP publishes a P1 outage entry covering the failure window.** | Sender's retry policy downgrades (see Part 2 §9.3 Outage Notification): retries pause or reduce in frequency until the outage entry clears. No additional sender-side alerts are raised while the outage is active. |

### 8.8 Conflict Resolution & DNS

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| F-01 | P | CP appears in MAP A and MAP B registries during transition | Sending MAP routes per `_mapkey` DNS record |
| F-02 | P | CP rotates `_mapkey` to new MAP | Subsequent messages route to new MAP after DNS TTL |
| F-03 | N | `_mapkey` record absent | Sender raises `9005` (no valid route) |
| F-04 | N | `_mapkey` points to an unknown MAP | Sender raises `9005` |
| F-05 | E | Two `_mapkey` records present for the same RCPID | Behaviour MUST be defined: either reject (`9005`) or use deterministic ordering |
| F-06 | E | `_domainkey` rotated while messages in flight | In-flight messages either complete or fail with `8102`/`8101`; no silent corruption |

### 8.9 Security & Negative Edge Cases

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| Z-01 | N | Replay a previously-accepted message verbatim within 10s | Receiver MUST accept-or-reject per documented replay window; behaviour MUST be deterministic |
| Z-02 | N | Replay a previously-accepted message after 24h | Receiver MUST reject |
| Z-03 | N | Send from a MAP whose OAuth credentials have been revoked | HTTP 401 |
| Z-04 | N | Submit a message claiming a `source.identity` whose `_domainkey` is hosted on an unrelated domain | HTTP 403, error code `8101` |
| Z-05 | N | Submit a message with a `d=` value that resolves to a wildcard DNS entry | Verifier rejects (CP-specific selector required) |
| Z-06 | N | Send messages from an IP not associated with the registered MAP | Acceptable per CSF (DKIM is the trust mechanism), but logging MUST capture the discrepancy |
| Z-07 | E | DoS: 10× expected peak load | MAP either serves successfully or returns HTTP 429 with `Retry-After`; no silent drops |
| Z-08 | E | Body containing characters at byte boundaries (UTF-8 multibyte split) | Body hash unaffected; verification passes |
| Z-09 | E | TLS session resumption across restarts | New session established cleanly; no validation bypass |

### 8.10 Operational Validation

| ID | Type | Test | Expected outcome |
|---|---|---|---|
| V-01 | P | 72-hour soak at projected production load | All SLAs met; no resource leaks |
| V-02 | P | Service Status endpoint returns `available` | Other MAPs read and act on it |
| V-03 | P | Audit log contains every send/receive with correlation IDs | Logs retrievable for the CSF retention period |
| V-04 | E | Planned maintenance window | Service Status indicates `planned`; peers handle gracefully |
| V-05 | E | Unplanned outage: endpoint down for 5 minutes | Peers retry; message delivery resumes; nothing lost beyond documented retry window |

## 9. Exit Criteria

A new MAP is granted production status **only** when **all** of the following hold:

1. **All baseline tests in §8.1 to §8.9 pass** with evidence captured by the Sponsor MAP.
2. **Section 8.10 operational validation** has run for the full 72-hour soak window.
3. The **TAG hidden test set** (a confidential rotating subset known only to the TAG) has been executed by the Sponsor MAP and passed.
4. **Bilateral connectivity** has been demonstrated with at least 50% of currently onboarded MAPs (rising over time as the network grows).
5. **PKI verification** has been demonstrated against the public NowYoYo harness for **both** RSA and Ed25519 algorithms.
6. The new MAP has **published a complete CP Registry** with no `TEST` entries that should not be there.
7. The new MAP commits to the **Memorandum of Understanding** (MoU).
8. **TAG steering group** approval is recorded at a weekly meeting.

> :memo: **Note**: The hidden test set evolves continuously. New cases are added when an incident reveals a behavioural gap. This is intentional — onboarding rigour grows with the network's experience.

> **MAP-of-1 variant.** For `single-cp` engagements, the criteria above are amended per [Part 1 §7.4.9](../part1-framework/07-onboarding.md#749-phase-4-relaxation-for-map-of-1): criterion 2 (72-hour soak) is **waived**, and criterion 4 (≥50% bilateral coverage) is **replaced** with "bilateral with all MAPs and HMAPs the candidate intends to exchange with at go-live, including TOTSCo as HMAP if applicable." Criteria 1, 3, 5, 6, 7, 8 apply unchanged. The waivers are recorded in the Phase 5 approval record.

## 10. Bilateral Testing

When two MAPs need to establish a new direct relationship outside Sponsor MAP onboarding (for example, a previously-onboarded MAP adding support for a new feature or routing group), the bilateral test sequence is the relevant subset of §8:

| Stage | Tests |
|---|---|
| Connectivity | §8.1, §8.2 |
| Registry interchange | §8.3 |
| PKI | §8.4 (full suite, against NowYoYo harness then against the peer) |
| Letterbox | §8.5 (P-tests minimum) |
| Industry process | §8.6 (subset relevant to the new relationship) |

Bilateral tests do **not** require Sponsor MAP involvement, but the result MUST be reported to the TAG so the broader directory can be kept consistent.

## 11. Regression Suite for Ongoing Compliance

The TAG publishes a regression suite that all onboarded MAPs are expected to run on:

- **Every CSF version increment** (e.g. transport spec change, new error codes, schema additions)
- **Every internal release** that touches the CSF transport, signing, or directory pipeline
- **Quarterly**, as a baseline conformance check

Failure of any regression test MUST be reported to the TAG within one working day. The TAG may, in consultation with the steering group, mark a MAP's `map.status` as `SUSPEND` if regression failures threaten network integrity.

## 12. Tooling Reference

| Tool / Resource | Provider | Purpose |
|---|---|---|
| [NowYoYo PKI Test Harness](#7-pki-test-harness-nowyoyo) (`sec-key-test.csf.nowyoyo.net`) | NowYoYo (free, public) | Round-trip DKIM signing/verification with detailed logs |
| [CSF Verification Testing Endpoint Wiki](https://github.com/nowyoyo/csf-documentation/wiki/Verification-Testing-endpoint) | NowYoYo | Companion documentation for the test harness |
| Sponsor MAP Virtual Test Host | Each Sponsor MAP | End-to-end SforB process simulation |
| Java DKIM reference | Apache James jDKIM | Library implementation of RFC 6376 |
| .NET DKIM reference | MailKit | Library implementation of RFC 6376 |
| OpenAPI specification | TAG (`letterbox-openapi.yaml`) | Letterbox contract for tooling and mock generation |

## 13. References

- [Part 1 §7 — Onboarding](../part1-framework/07-onboarding.md)
- [Part 1 §10 — Governance](../part1-framework/10-governance.md)
- [Part 2 §1 — Getting Started](../part2-implementation/01-getting-started.md)
- [Part 2 §3 — PKI & DKIM Signing](../part2-implementation/03-pki-dkim-signing.md)
- [Part 2 §4 — Message API (Letterbox)](../part2-implementation/04-message-api.md)
- [Part 2 §5 — Directory API](../part2-implementation/05-directory-api.md)
- [Part 2 §7 — CP Transitions](../part2-implementation/07-cp-transitions.md)
- [REVIEW.md §1.8 — original scope for this document](REVIEW.md)
- [TOTSCo Hub API Specification v2.0](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf)

## 14. Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 (Draft) | 2026-04-28 | Initial publication. Replaces the placeholder reference in REVIEW.md §1.8. PKI test harness imported from public Gist. |

---

<!-- DOCUMENT: standalone/sg-faq | Standalone Documents — FAQ — GPLB Steering Group -->

---
title: FAQ — GPLB Steering Group
tags: [Standalone, FAQ, SG, GPLB]

---

# FAQ — GPLB Steering Group

> Connected Services Framework (CSF) — Standalone Companion Document — Version 2.0

These questions were originally proposed by the GPLB Steering Group and discussed on **8 April 2025**. The FAQ has since been updated to reflect the consolidations and ratifications in the framework — most notably the CP Emergency Migration (§8.2), MAP-of-1 Onboarding incl. TOTSCo → CSF migration (§7.4), the Sponsorship Object rotation rules (§5.4.2), the OTS-scope clarification, the Tier-3 dispute-resolution model, the bit-pipe / SOR definitions, and the anti-competitive safeguards (§10.6.7).

This document lives in the **standalone** section so it can grow over time without being tied to the Part 2 numbering. Cross-references below use paths relative to the standalone folder.

---

## Q1 — How will RCPIDs be assigned? Does the RCPID follow the CP or the MAP?

**The RCPID follows the CP — for life.**

RCPIDs are self-allocated by MAPs using UUIDv4 format after due diligence and onboarding. No MAP in the TAG group uses the allocated RCPID directly with their CPs — all use the branded name in search and drop-down lists. The RCPID is machine-readable only.

The RCPID stays with the CP brand permanently, enabling movement between MAPs, consolidation, mergers, and even a CP becoming a MAP of 1. All orders associated with the RCPID remain tied to it and can be migrated between MAPs — even in-flight — without impact on end consumers.

**OTS compatibility**: MAPs (including TOTSCo) can continue to use the 4-character OTS / GPLB `Rxxx` format internally, mapping to UUIDv4 for CSF SforB message exchange.

**Migration-specific rules.** For a CP migrating SforB traffic from TOTSCo to a CSF MAP-of-1, a **new UUIDv4 RCPID** is allocated and the legacy TOTSCo `Rxxx` is retired for SforB — see [§7.4.8 RCPID Allocation Rule](../part1-framework/07-onboarding.md#748-rcpid-allocation-rule). For an emergency migration triggered by a MAP failure, the same brand keeps its CSF UUIDv4 across the transition — see [§8.2.8 Fee Guidance](../part2-implementation/08-commercial-scenarios.md#828-fee-guidance) and the RCPID-continuity rules attached to it. **OTS RCPIDs are out of scope** — OTS is Ofcom-mandated to use TOTSCo, so a CP's OTS `Rxxx` continues at TOTSCo unchanged regardless of any SforB migration.

> See [RCPID Management](../part1-framework/08-rcpid-management.md) for the full normative reference.

---

## Q2 — If a CP moves from a MAP to TOTSCo, can they take their RCPID?

**Yes — and the reverse direction is now fully documented.**

TOTSCo is a MAP in the context of SforB, so any RCPID created by a MAP can be freely transitioned between MAPs (including to TOTSCo or to a CSF MAP-of-1). The TAG has ensured that CPs are not locked into any MAP in either direction.

The CP → TOTSCo direction has always been straightforward. The CP → CSF-MAP-of-1 direction (the strategically important escape path for a CP currently on TOTSCo for SforB) is now spelled out end-to-end in [§7.4 MAP-of-1 Onboarding (incl. TOTSCo → CSF Migration)](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration). Headlines:

- Capability checklist before migration begins (§7.4.4).
- Sponsor MAP fast-track for `single-cp` engagements (§7.4.5).
- Big-bang cutover — the industry directory carries a brand once per process (§7.4.7).
- In-flight order handling — drain on TOTSCo or reconcile from the CP's CRM (CP's choice).
- New UUIDv4 RCPID allocated for SforB; legacy TOTSCo SforB `Rxxx` retired (§7.4.8).
- Phase 4 relaxations for MAP-of-1: 72-hour soak and ≥50% bilateral coverage waived because the CP carries the operational risk directly (§7.4.9).

**Note** — OTS is out of scope. OTS is Ofcom-mandated to TOTSCo, so OTS RCPIDs do not migrate to CSF. Only SforB RCPIDs do.

---

## Q3 — Can a retail CP use multiple MAPs?

**Yes.** A CP can operate different brands across different MAPs, provided each RCPID (brand) is formally set up with its respective MAP. This allows CPs to trial going independent, use specialist MAPs for specific use cases, or segregate trading lines for governance reasons.

This is enabled by the CSF's **bit-pipe** principle (see [Definitions §2.3](./definitions.md)) — the CSF is the transport, not the business state. A CP brand with a CSF UUIDv4 RCPID on one MAP and a separate brand UUIDv4 on a different MAP is operationally normal. Different brands on different MAPs do not interfere with each other; the industry directory carries each brand once per process.

> See also [§7.4.2 Strategic context — the CP remains in control](../part1-framework/07-onboarding.md#742-strategic-context--the-cp-remains-in-control).

---

## Q4 — How is the directory created, shared, and how often is it updated?

Each MAP hosts its own **CP Registry** containing its CPs and metadata. Other MAPs collect these CP Registries (recommended maximum frequency: every 60 seconds) and converge them into a private **Master Registry** containing all CPs across the network.

From the Master Registry, each MAP derives a **Directory** — a filtered view containing just the brand names and RCPIDs — which is shared with its own CPs for drop-down lists and search-as-you-type. The Master Registry is near-real-time and includes status values, contact details, and controls not available in OTS. The CP Registry format is **a strict superset of TOTSCo's OTS / GPLB directory structure** so TOTSCo can ingest it with its existing parser; CSF-specific additions are additive and never breaking.

The three tiers are: **CP Registry** (what MAPs share with each other), **Master Registry** (the private, converged view used internally by each MAP for routing and PKI), and **Directory** (the simplified view shared with the MAP's own CPs).

**Sponsorship object** — as of CSF v2.x the CP Registry also carries a **`sponsorship` object** (see [§5.4 MAP Section — Field Reference](../part2-implementation/05-directory-api.md#54-map-section--field-reference) and [§5.4.2 Sponsorship Object — Rotation Rules](../part2-implementation/05-directory-api.md#542-sponsorship-object--rotation-rules)). The TAG (or a prospective candidate MAP) reads the `nextSponsor` forward pointer to find the current designated Sponsor MAP. The full mechanism is documented in [Onboarding & Testing Process §3.4 Sponsor MAP via the CP Registry](./onboarding-testing-process.md#34-sponsor-map-via-the-cp-registry).

**Filter URLs.** TOTSCo's pre-production Directory v2 already combines OTS and GPLB entries in one list and distinguishes them by `processSupport[].process`. MAPs that want a single-process view filter on an `identity` query parameter:

```
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=all
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=ots
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=gplb
```

The CSF's Master Registry follows the same convention.

> See [Directory & Registry](../part1-framework/05-directory-and-registry.md) and [Directory API](../part2-implementation/05-directory-api.md) for full details.

---

## Q5 — How does CP-to-CP communication work? Are contact details publicly available?

**No, contact details are not public.** All CP contact information is held in the registry, accessible only via OAuth 2.0-authenticated API calls. Only those CPs or MAPs that use the CSF network can access the contacts and only after they have been verified and onboarded by a Sponsor MAP and other members of the CSF — they are for operational purposes only.

The registry provides granular contact options:

- **OTS-compatible** customer-assist and sales-assist URLs (backward compatible).
- **Enhanced contacts** with phone, email, URL, ticketing-system links.
- **Availability hours and days** per contact method and purpose (sales, support, technical).
- **Preferred contact method** at any given time — enabling CPs to route escalations efficiently.

This eliminates the need for offline spreadsheets or specialised swivel-chair tools. A CP's agent can look up the other CP's preferred contact method in real time and raise queries accordingly.

**Why the CSF approach replaces the OTS CP-to-CP tool for SforB.** The TOTSCo OTS CP-to-CP tool has not been mandated for SforB, and feedback to date has been that it is not fit for purpose for business switching. The CSF's contact-object structure (see [§5.6 CP Contact Object](../part2-implementation/05-directory-api.md#56-cp-contact-object)) explicitly replaces the need for a separate industry tool — every contact a CP agent might need (sales, support, technical; phone, email, ticketing URL) is available via authenticated API in real time, with availability hours and days, in the same JSON shape across the whole industry.

---

## Q6 — Will MAPs publish reports? What information will be available to Ofcom?

**No regulatory reporting requirements** have been identified for SforB at this time (risk **RK1**, open — see [REVIEW.md §3.1](./REVIEW.md)). MAPs already collect KPIs for their own commercial relationships. The TAG aims to define a standard set of mandatory baseline statistics with open, consistent calculations; this will be published in a later version of the CSF.

A key improvement over OTS is the ability to track **in-session Switch Match failures** using an incremented counter in the audit envelope, enabling the industry to distinguish genuine failures from multiple retry attempts for the same sales opportunity.

**The TAG itself does not aggregate industry telemetry.** This was clarified by the G-6 telemetry-aggregation policy decision (closed 2026-06-16) and is codified in [§10.6.7 Anti-Competitive Safeguards](../part1-framework/10-governance.md#1067-anti-competitive-safeguards). The TAG's role is to define (i) the per-MAP telemetry format and (ii) the collect-and-deliver process to an independent body (Ofcom or OTA2) *if* one is requested by a regulator. Test traffic is excluded from production telemetry per the JAM audit `test=true` rule — see [Onboarding & Testing Process §5.1 Telemetry Exclusion](./onboarding-testing-process.md#51-telemetry-exclusion).

---

## Q7 — What due diligence is required for onboarding MAPs?

MAPs are expected to complete standard checks during onboarding:

- Credit checks and company registration.
- VAT registration and trading history.
- Fraud checks and ICO Data Protection registration.
- Check any security public-domain records for claims of ISO 27001, Cyber Essentials, or equivalent.

The TAG's [Onboarding and Testing Process](./onboarding-testing-process.md) outlines the specific checks. While the risk of fraudulent CPs masquerading as providers is low, baseline due-diligence guidance still needs to be established as an industry-wide standard (risk **RK2**).

For **MAP-of-1 candidates** (a CP taking on the MAP role for itself, including any CP migrating SforB from TOTSCo), the pre-migration capability checklist is at [§7.4.4 Pre-Migration Capability Checklist](../part1-framework/07-onboarding.md#744-pre-migration-capability-checklist) and the Sponsor MAP fast-track for `single-cp` engagements is at [§7.4.5 Sponsor MAP Programme — Fast-Track for single-cp](../part1-framework/07-onboarding.md#745-sponsor-map-programme--fast-track-for-single-cp). Sponsor MAPs are **not expected to charge** for `single-cp` engagements; where significant support is required, the fee is capped at **£350 + VAT** (compared with **£3,000 + VAT** for a traditional multi-CP engagement). One-off, charged once per MAP regardless of protocol footprint.

When onboarding a new MAP, the Sponsor MAP performs the same checks. The effort is typically large, and access to traffic is controlled through the tiered access model.

> See [Onboarding Phases](./onboarding-testing-process.md#6-onboarding-phases) for the full five-phase plan.

---

## Q8 — What are the data retention policies?

Data retention is a broader industry discussion and not limited to the CSF (see risk register **RK3**). Switching data is needed for reporting, investigations, and Ofcom Section 135 requests. No documented requirement for data retention exists under OTS or GPLB, but the CSF has recommended that all of its members retain audit and metadata on transactions for a **minimum of 2 years**.

For emergency-migration cases the CP Emergency Migration process has explicit audit and retention requirements at [§8.2.9 Audit and Retention](../part2-implementation/08-commercial-scenarios.md#829-audit-and-retention) — **five-year retention** for the emergency-event log entry, including trigger code, timestamps, RCPIDs of old/new MAP, all `rcpidStatusRequest` correlation IDs, and outcome (happy/unhappy path). All `rcpidStatusRequest` traffic itself is retained per [§9 audit-log requirements](../part2-implementation/09-operations.md).

---

## Q9 — If a CP is in test mode, how is this indicated to prevent accidental live switching?

All test traffic MUST be marked as test in the audit envelope. The onboarding MAP overrides this flag until the CP passes exit criteria — even if the CP sets it themselves.

Testing follows a structured process:

1. **Local testing**: CP tests against the MAP's Virtual Test Host using synthetic data (no messages exchanged with other MAPs).
2. **Exit criteria**: Hidden unit tests must be passed before production status is granted.
3. **Bilateral testing**: Only used for bilateral arrangements, with mandatory test flagging.

The full mechanism is documented in [Onboarding & Testing Process §4 (Status Model)](./onboarding-testing-process.md#4-status-model-and-json-status-values), [§5 (Test Traffic Flagging in the JAM envelope)](./onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope), and [§5.1 (Telemetry Exclusion)](./onboarding-testing-process.md#51-telemetry-exclusion). For MAP-of-1 candidates, the Phase 4 operational validation is relaxed — the 72-hour soak and ≥50% bilateral coverage are waived because the CP carries the operational risk directly (see [§7.4.9 Phase 4 Relaxation for MAP-of-1](../part1-framework/07-onboarding.md#749-phase-4-relaxation-for-map-of-1)). The MAP-overrides-CP test-flag rule remains unchanged for all MAP types.

> This is a significant improvement over OTS, which only requires basic connectivity testing and does not address message compliance.

---

## Q10 — Does the CSF recognise different MAP types? Can a MAP change type?

**A MAP is a MAP.** The CSF treats all participants equally — no charges, no licensing, no type restrictions.

The CSF is a **bit-pipe transport** (see [Definitions §2.3](./definitions.md)) — it carries the JAM envelope between MAPs and does not interpret the message body, which is what allows the same transport to carry multiple industry processes (SforB today, OTS Porting and other niche bilateral protocols in future). A CP can become a **MAP of 1** by implementing the MAP rules — see [§7.4 MAP-of-1 Onboarding (incl. TOTSCo → CSF Migration)](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration) for the dedicated onboarding path including the case of a CP migrating SforB from TOTSCo.

**Hub MAPs (HMAPs)** are a recognised specialisation — TOTSCo participates as an HMAP for SforB per [Part 2 §6 TOTSCo Integration](../part2-implementation/06-totsco-integration.md) and the bilateral [TOTSCo HMAP Integration Guide](./totsco-hmap-integration-guide.md) — but the same MAP rules apply at the CSF transport layer.

How any MAP forwards messages to its own CPs internally is outside CSF scope; the framework only governs MAP-to-MAP exchange.

---

## Q11 — What about high-volume message monitoring and suspension?

MAPs should handle peak loads relevant to their CP base. The CSF provides a minimum rate calculation:

**Messages/second = Total Switchable Asset Base ÷ 1,000** (minimum 2/s)

For suspicious or DoS-like patterns, the CSF allows MAPs to:

- Classify a CP as suspicious.
- Broadcast the classification through the directory.
- Implement standard anti-DoS patterns (rate reduction, circuit breakers).

The retry / circuit-breaker patterns are documented under [Onboarding & Testing Process §8.7 Retry and Delivery Policy](./onboarding-testing-process.md#87-retry--delivery-policy) — test IDs **R-01..R-18** (behavioural tests R-01..R-09 plus the ratification tests R-10..R-18 that validate the 1 s connection timeout, 3 s response timeout, exponential-backoff shape with jitter, circuit-breaker activation/recovery, bounded retry window, and operational-engagement escalation) and **F-01..F-06** in §8.8. The underlying delivery policy itself is now ratified in [Part 2 §4.7 Message Delivery Policy](../part2-implementation/04-message-api.md#47-message-delivery-policy).

> This is advantageous over a centralised model: CPs are distributed across MAPs, so each MAP handles only its proportional load.

---

## Q12 — What happens if a MAP exits the market?

The CSF has comprehensive business-continuity built in. The full process is at [§8.2 CP Emergency Migration](../part2-implementation/08-commercial-scenarios.md#82-cp-emergency-migration), which sets out:

- **Six triggers** ([§8.2.2](../part2-implementation/08-commercial-scenarios.md#822-triggers)): MAP failure (T1), MAP administration (T2), TAG-suspended (T3), TAG-removed (T4), MAP unresponsive (T5), CP-initiated (T6).
- **Happy and unhappy paths** ([§8.2.3](../part2-implementation/08-commercial-scenarios.md#823-happy-path--distressed-map-still-online) / [§8.2.4](../part2-implementation/08-commercial-scenarios.md#824-unhappy-path--distressed-map-offline)) — online-original-MAP completes the migration in **a few hours**; offline-original-MAP caps the outage at **≤ 2 working days**, using the CP's own CRM as the authoritative source of in-flight orders.
- **Timing targets** ([§8.2.5](../part2-implementation/08-commercial-scenarios.md#825-per-scenario-timing-targets)) and **Normal-vs-Emergency contrast** ([§8.2.6](../part2-implementation/08-commercial-scenarios.md#826-normal-transition-vs-emergency-migration--contrast)).
- An **Emergency RACI** ([§8.2.7](../part2-implementation/08-commercial-scenarios.md#827-emergency-raci)) for the case where the original MAP is offline or non-cooperative — distinct from the in-flight order RACI in §7.6.
- **Fee guidance** ([§8.2.8](../part2-implementation/08-commercial-scenarios.md#828-fee-guidance)) per trigger.
- **Audit and retention** ([§8.2.9](../part2-implementation/08-commercial-scenarios.md#829-audit-and-retention)) — emergency-event log entry with **5-year retention**.

Every MAP MUST support emergency on-boarding of an existing CP as a core capability.

> See [Commercial Scenarios](../part2-implementation/08-commercial-scenarios.md) for the detailed procedures.

---

## Q13 — How does the CSF support a CP currently using TOTSCo for SforB who wants to move to a CSF MAP-of-1?

This is the strategically important "TOTSCo → CSF" escape path. The full route is documented at [§7.4 MAP-of-1 Onboarding (incl. TOTSCo → CSF Migration)](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration). Headlines:

- **SforB only.** OTS is Ofcom-mandated to TOTSCo and stays at TOTSCo unchanged.
- **Same five-phase on-ramp** as a traditional new MAP onboarding (§7.2), with the **Phase 4 relaxations** noted in Q9 above for `single-cp` engagements.
- **Sponsor fees** are free by default; capped at **£350 + VAT** for `single-cp` engagements when significant support is needed (versus **£3,000 + VAT** for traditional multi-CP). The Sponsor MAP fast-track at §7.4.5 trims scope further where appropriate.
- **Big-bang cutover** — the industry directory carries a brand once per process, so the cutover is atomic.
- **In-flight orders** are either drained on TOTSCo or reconciled from the CP's CRM (CP's choice — see §7.6).
- **New UUIDv4 RCPID** allocated for SforB; legacy TOTSCo SforB `Rxxx` retired (§7.4.8).
- TOTSCo wind-down for the SforB element follows TOTSCo's commercial-exit terms; OTS contracts are unaffected.

The CSF treats this as a first-class industry-adoption journey.

---

## Q14 — Where does the CSF sit in relation to OTS, and can a CP migrate OTS to CSF?

**OTS stays at TOTSCo.** OTS is mandated by Ofcom to use TOTSCo as the single industry platform — there is no OTS migration to the CSF.

The CSF is the **business-switching** transport (SforB) and, over time, the transport for niche bilateral protocols and any future industry protocols the TAG adds to its baseline (for example, OTS Porting where Ofcom permits a non-mandated technical solution). A CP that operates both OTS and SforB on TOTSCo today can move only the **SforB** element to a CSF MAP-of-1; OTS continues on TOTSCo unchanged.

> See [§7.4.1 Definition and Scope](../part1-framework/07-onboarding.md#741-definition-and-scope) for the formal scope statement.

---

## Q15 — How are disputes between MAPs resolved?

Three tiers per [§10.6.4 Dispute Resolution](../part1-framework/10-governance.md#1064-dispute-resolution):

- **Tier 1 — direct between the MAPs**, using CP-Registry contact details. Target resolution within **5 working days**.
- **Tier 2 — TAG mediation** at the next weekly steering-group meeting.
- **Tier 3 — binding adjudication** by an external independent body appointed by the TAG. **OTA2 is the TAG's preferred candidate** for the standing Tier-3 adjudicator role, subject to OTA2's formal acceptance.

Interim measures during any dispute require both MAPs to **continue exchanging messages normally** — disputes cannot be used as a reason to block or degrade service to CPs.

---

## Q16 — What enforcement does the TAG have over a misbehaving MAP?

Graduated enforcement per [§10.7 Enforcement](../part1-framework/10-governance.md):

1. **Written warning** — 10 working days to remediate.
2. **Probation** — status flagged in the registry; voting suspended.
3. **Suspension** — CPs encouraged to migrate; the MAP cannot accept new CPs.
4. **Removal** — 30-day TAG remediation window before the MAP is removed from the Master Registry.

**CP continuity is the explicit priority over enforcement** — affected CPs invoke [§8.2 CP Emergency Migration](../part2-implementation/08-commercial-scenarios.md#82-cp-emergency-migration) under trigger T4 ("TAG-removed"). A draft additional clause on anti-competitive behaviour (proposal P-3) is awaiting legal review and may add specific anti-competitive-conduct triggers in a later CSF version.

---

## Q17 — Sponsor MAP rotation — how does it actually work?

Every onboarded MAP joins a decentralised FIFO rotation via a `sponsorship` object in its CP Registry (see [§5.4.2 Sponsorship Object — Rotation Rules](../part2-implementation/05-directory-api.md#542-sponsorship-object--rotation-rules) and the full mechanism in [Onboarding & Testing Process §3.4 Sponsor MAP via the CP Registry](./onboarding-testing-process.md#34-sponsor-map-via-the-cp-registry)).

Key rules:

- The token **advances on acceptance** of an engagement, not on completion — so long onboardings never block the queue.
- Concurrent sponsorships are supported via a per-MAP **`capacity` field** (minimum 1, no upper bound).
- A `single-cp` engagement (MAP-of-1) counts as `1` against capacity, the same as a `traditional` multi-CP engagement.
- Optional fields allow a Sponsor MAP to advertise a self-service registration URL (`sponsorship.registrationURI`) and attach an internal ticket reference per engagement (`active[].candidateRef`).

---

## Q18 — Can a CP self-register with a Sponsor MAP?

Two discovery paths.

**Primary** — the TAG-published sponsor-registration page (URL to be published by the TAG) which lists the current designated Sponsor MAP and a registration contact, updated whenever the rotation advances.

**Fallback** — read any existing MAP's CP Registry, find the entry with the most recent `nextSponsorUpdated`, and contact that MAP's `map/contact[]` entries (or its optional `sponsorship.registrationURI` if it provides one).

> See [§7.4.6 Finding your Sponsor MAP](../part1-framework/07-onboarding.md#746-finding-your-sponsor-map).

---

## Q19 — What does it cost?

**Transport: zero.** No CSF licensing fees, no per-message charges, no annual subscriptions, no MAP-participation fees.

| Cost item | Amount | Notes |
|---|---|---|
| CSF licensing | **£0** | The framework is open. |
| Per-message charges | **£0** | None. |
| MAP-participation fees | **£0** | None. |
| Sponsor MAP onboarding fee (traditional, multi-CP) | **Free by default; capped at £3,000 + VAT** | Optional fee only when significant time/effort is required. Charged once per MAP regardless of how many protocols it carries. |
| Sponsor MAP onboarding fee (`single-cp` / MAP-of-1) | **Free by default; capped at £350 + VAT** | Reduced cap reflects the reduced scope. |
| Ongoing DNS hosting | varies | Same component the CP is likely already running. |
| Ongoing TLS certificates | varies | Same. |
| Ongoing OAuth IdP | varies | Same. |
| Ongoing monitoring + on-call | varies | Same. |
| DKIM signing | one-off integration | Mature RFC 6376 libraries available off the shelf. |

The recurring saving from removing TOTSCo SforB subscription and per-unit charges is documented at [§7.4.11 Cost Model — Qualitative](../part1-framework/07-onboarding.md#7411-cost-model--qualitative).

---

## Q20 — Does the CSF interact with the SforB Response Codes that GPLB-SG controls?

**No.** SforB Response Codes (the 9xxx industry series and any SforB-specific codes) are controlled by GPLB-SG and published via FCS. The CSF transport carries the codes verbatim in the message body and does not interpret them.

The CSF's own error codes are the **8xxx series** — PKI verification errors only. The CSF's **bit-pipe** principle (see [Definitions §2.3](./definitions.md)) means the transport never inspects the message body; the SforB Response Codes therefore continue to be controlled by the SG without any CSF involvement.

---

## Q21 — How does the CSF align with the OTA2 GPLB Message Delivery Principles?

The CSF's delivery policy is now ratified in [Part 2 §4.7 Message Delivery Policy](../part2-implementation/04-message-api.md#47-message-delivery-policy). The CSF and the OTA2 [Switching for Business Message Delivery Principles V0.2](https://www.offta.org.uk/) describe different architectures — the GPLB principles are **hub-side** (TOTSCo intermediates between RCPs); the CSF is **peer-to-peer synchronous** (MAPs exchange directly). Both share **1 second connection timeout** and **3 second response timeout** as the narrow convergence point.

| Boundary | Delivery policy |
|---|---|
| **CSF MAP ↔ CSF MAP** (P2P) | CSF's own policy: 1 s / 3 s timeouts, **exponential backoff with jitter** (linear schedules synchronise retry storms — see §4.7.5), circuit-breaker, bounded retry window, operational-engagement escalation via `map/outage[]` / `map/contact[]` (see §4.7.3). |
| **CSF MAP ↔ TOTSCo** (HMAP boundary) | TOTSCo applies the GPLB hub schedules on its side (5/10/15/20/25 s for Match Requests within a 30 s window; 10/20/30/60 s then 60 s cadence for other messages within a 12-day window). The CSF MAP receives async failure notifications as a standard hub client. Locked-down per [§6.3.1](../part2-implementation/06-totsco-integration.md#631-dedicated-locked-down-hmap-interfaces--both-directions). |

The asymmetry is deliberate. CSF's P2P model has a synchronous response on every delivery attempt, so the hub-side queueing, retry-until-12-days, single-flight, and async failure-notification mechanisms are not applicable. Persistent failure escalates through inter-MAP operational engagement, not silent retry. The full architectural rationale is in the analysis report at [wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles](../../wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles.md).

---

## Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 | 2025-04-08 | First-draft SG FAQ — Q1–Q12, as discussed at the GPLB-SG meeting of 8 April 2025. |
| 2.0 | 2026-06-19 | Moved from `part2-implementation/10-sg-faq.md` to standalone so the FAQ can grow over time without being tied to the Part 2 numbering. Q1–Q12 expanded per the SG-FAQ audit ([[syntheses/audit-faqs-sg-and-totsco]]) — added cross-references to the consolidations completed since v1.0: §7.4 MAP-of-1 / TOTSCo migration, §8.2 CP Emergency Migration (six triggers, RACI, fee guidance, audit & retention), §5.4.2 Sponsorship rotation, §10.6.7 anti-competitive safeguards, the bit-pipe principle, and the Onboarding & Testing handbook. **NEW Q13–Q20 added**: TOTSCo → CSF migration path, OTS-vs-CSF scope, dispute resolution (Tier 1–3), enforcement (warning → removal), Sponsor MAP rotation mechanics, CP self-registration discovery, cost summary, and SforB Response Code ownership boundary. |
| 2.1 | 2026-06-23 | Audit verification pass — confirmed all SG-FAQ audit recommendations from [[syntheses/audit-faqs-sg-and-totsco]] (Q1–Q12 cross-reference additions + Q13–Q20 new questions) are reflected. Polish: Q11 retry/delivery references extended to test IDs **R-01..R-18** to reflect the §4.7 ratification's addition of R-10..R-18 (1 s/3 s timeouts, exponential backoff shape, circuit-breaker activation/recovery, bounded retry window, operational engagement). **NEW Q21 added**: how the CSF aligns with the OTA2 GPLB Message Delivery Principles V0.2 — two-tier scope (CSF MAP-to-MAP P2P vs HMAP boundary), pointer to [[syntheses/csf-compliance-with-gplb-message-delivery-principles]]. |

---

<!-- DOCUMENT: standalone/tag-steering-group-guidelines-for-conduct | Standalone Documents — TAG Steering Group — Guidelines for Conduct -->

---
title: TAG Steering Group — Guidelines for Conduct
tags: [Standalone, TAG, Governance, Conduct, CompetitionLaw]

---

# TAG Steering Group — Guidelines for Conduct

> Connected Services Framework (CSF) — Governance Companion — Version 1.0 (Draft)
>
> Maintained by the Telecom Technical Architecture Group (TAG). Adopted by reference in the [TAG Steering Group Terms of Reference](./tag-steering-group-terms-of-reference.md) (Appendix A).

---

## Document Control

| | |
|---|---|
| **Audience** | All TAG Steering Group members, observers, focus-group attendees, and anyone joining a TAG meeting or correspondence chain in any capacity. |
| **Status** | Draft v1.0 — for TAG review. |
| **Adopted by** | The [TAG Steering Group Terms of Reference](./tag-steering-group-terms-of-reference.md). Every meeting invite must cite or attach this document. |
| **Purpose** | Set the conduct rules that govern every TAG meeting, call, and exchange so the work stays focused on the Connected Services Framework (CSF) and industry architecture, and so the meeting environment does not become a route for competitive intelligence or commercial advantage. |

---

## 1. Why this document exists

You have been invited to participate in the **Telecom Technical Architecture Group (TAG)** for the purpose of developing the Connected Services Framework (CSF) and contributing to other industry-related architectural activities for UK telecommunications. As part of the TAG you will attend meetings and calls with people who, in their day jobs, may be actual or potential competitors of your business.

The TAG's value to the industry depends on three things being true at every meeting:

1. **The work serves the whole industry.** Technical contributions should improve the CSF and the wider industry architecture for every participant. They must not be a vehicle for any single MAP, CP, supplier, or organisation to gain commercial advantage.
2. **No competitive intelligence is gathered.** TAG meetings must not be used — directly, indirectly, or inadvertently — to discover another MAP's customer base, the commercial terms under which they serve those customers, or the methods they intend to use to win business.
3. **Competition law is respected at all times.** UK and EU competition law prohibits sharing competitively sensitive information (CSI) among competitors. These rules apply to TAG meetings exactly as they apply to any other multi-party industry forum.

These guidelines exist to keep all three things true. They are binding on every TAG participant.

---

## 2. Competition law — the rules

Competition law prohibits businesses from sharing or exchanging **competitively sensitive information (CSI)**. CSI is information which:

- one party (or other companies in their corporate group) receives about another party (or other companies in their corporate group);
- is **not in the public domain**; and
- may reduce uncertainty regarding that party's business decisions, activity, or existing or future business strategy.

It includes non-public, commercially sensitive information and strategic data.

### 2.1 Examples of CSI — never share or discuss

The list below is **not exhaustive**. If you are unsure whether something falls in scope, treat it as CSI until your organisation's competition counsel confirms otherwise.

- Wholesale or non-public retail pricing, tariffs, or pricing strategy.
- Discounts, costs (including staffing costs such as salaries or benefits), and margins.
- Plans for new products, services, tariffs, or offers.
- Plans or proposals for changes to the way services are sold or delivered.
- Future product characteristics, product development activities, or product roadmaps.
- Forecast traffic by voice/data.
- Future strategy — for example rollout plans, site deployments, or technology upgrades.
- Planned investments.
- Details of supplier relationships (including the terms and conditions of supply).
- Non-public financial information or information about a company's current commercial state.
- Non-public information about current or future sales volumes or turnover — including switching volumes, switching trends, market shares, demand, capacity, or budgets.
- Marketing strategy or plans.
- Information about commercially sensitive technologies or R&D programmes that are not publicly disclosed.
- **Details of a party's customer base — including the identity of any CP a MAP serves, the terms of supply, account values, or contractual arrangements with those CPs.**
- **Methods, processes, or commercial tactics a MAP or CP intends to use to acquire, retain, or migrate customers.**

The last two bullets above are emphasised because they are the points most likely to be touched in a TAG meeting if participants are not vigilant — and they are the points the TAG is most determined to protect.

### 2.2 What "CSI" is not

CSI is **not** the same thing as detailed technical contribution to the CSF. The architecture, message formats, JSON schemas, transport choices, sequencing, error codes, signing patterns, version conventions, and operational telemetry that underpin the CSF are exactly the things the TAG exists to discuss. None of these are CSI when they are about the **framework**; they only become CSI when they are about a **specific party's commercial implementation**.

> Test before you speak: *am I describing how the framework should work, or am I describing how my organisation specifically will deploy, price, sell, or win business with it?* The first is in scope; the second is not.

---

## 3. The TAG-specific guardrails

The general competition-law guidance above applies to any multi-party industry forum. The TAG has three additional guardrails that flow from the open and collaborative nature of the CSF:

### 3.1 No customer-base intelligence

A MAP's customer list — the CPs it serves, the terms under which it serves them, the renewal dates, the volumes, the commercial arrangements — is **off-limits at TAG meetings**, including off-the-record conversations, side chats, and post-meeting correspondence. No participant should request this information from another participant, and no participant should volunteer it.

If a technical question genuinely requires knowing that a CP exists on a MAP (for example, to design a migration path), that fact may be confirmed only from the public CP Registry that the MAP itself publishes under the CSF Directory API. Anything beyond what is published in the public registry is out of scope.

### 3.2 No sharing of business-acquisition methods

The methods, processes, sales motions, marketing campaigns, pricing tactics, or commercial structures a MAP or CP intends to use to **gain business** — to win new CPs, to migrate CPs from another MAP, to compete for a customer, or to retain customers under pressure — must not be discussed, hinted at, or asked about at TAG meetings.

This applies symmetrically: a MAP is no more free to share its own methods than it is to enquire about another MAP's methods.

### 3.3 Collective benefit over individual advantage

The default test for any TAG contribution is **collective benefit**. A proposal that improves the framework for the whole industry is in scope. A proposal that, on inspection, materially advantages one participant over another at the framework level — beyond the natural difference of who chooses to invest engineering effort — should be flagged, declared, and (if necessary) referred to the co-chairs for re-scoping.

This guardrail does not block any participant from later building commercial advantage on top of the CSF. It simply keeps the framework itself neutral.

---

## 4. Conduct at TAG meetings

### 4.1 Focus

Interactions and discussions must be limited to what is strictly necessary to achieve the TAG's legitimate objective: developing the CSF and contributing to industry architecture. Competition-law rules must be followed at all times during meetings and in any correspondence or exchange (in any medium) relating to the group.

### 4.2 Citing sources

To avoid uncertainty or ambiguity, individuals should cite the **public sources** of any information they rely on in discussion. Where a figure or claim comes from a public dataset, a published spec, a regulatory document, or a public corporate announcement, cite it. This removes any doubt about how the information was derived and keeps the discussion clearly within the public domain.

### 4.3 No recommendations on competitively sensitive topics

In addition to not discussing or sharing CSI, participants must not discuss, agree to, or recommend a course of action on competitively sensitive topics — **even in jest**. The focus must be on the CSF and the industry architecture, not on any participant's commercial activities.

### 4.4 Sensitive agendas — competition lawyer attendance

For meetings or calls on topics that, based on the proposed agenda, are considered potentially more sensitive, the default presumption is that the meeting should be attended by **at least one competition lawyer** (from a participant organisation or appointed jointly) to provide guidance as needed.

### 4.5 Individual responsibility

Every TAG participant is individually responsible for ensuring that documents they produce and discussions they contribute to **do not reveal CSI** pertaining to their organisation. Saying "we couldn't help it" is not a defence. This responsibility applies to standing members, observers, and **invited specialists / subject-matter experts** equally. Where an invited specialist is from a MAP or a CP, the invitation makes clear that their TAG contribution is on behalf of the industry challenge under discussion, not on behalf of their employer's commercial interests — and the specialist is expected to draw that line themselves throughout the session.

---

## 5. Do's and Don'ts

Every TAG participant **MUST** follow these.

### Do

- **Prepare and circulate an agenda in advance** to all parties (including their competition lawyers where appointed) and stick to it during the meeting. Seek advice from a competition lawyer if you are unsure whether a topic of conversation would be permitted.
- **Attach a copy of this document to every meeting invite** and note it in the agenda.
- **Provide a reminder at the start of each meeting** acknowledging the competition-law constraints on discussion and the need to stick to the agenda, not to disclose CSI, and not to make anti-competitive suggestions or recommendations (even in jest).
- **Ensure meetings and calls relate only to the common purpose** and include only the relevant individuals.
- **Keep a short record of every meeting or call**, including:
    1. The date and time of the meeting or call.
    2. The individuals who attended.
    3. The subject of the discussion.
    4. Any decisions adopted.
- **Stop the meeting or call immediately and consult a competition lawyer** before proceeding further if you consider that any party may be sharing CSI.

### Don't

- **Do not circulate, share, or discuss CSI** with any other party at any point, in any medium.
- **Do not participate in private or informal meetings or "off the record" discussions.** The TAG's records and conduct rules apply to every conversation that touches its work.
- **Do not misuse the TAG process** to discuss or influence parameters on which participants compete.
- **Do not recommend a course of action on competitively sensitive topics (even in jest)** — including but not limited to fixing prices or other parameters on which companies compete, sharing markets, sharing customers, sharing commercial opportunities, or boycotting third parties.
- **Do not use the meeting environment to gain access to another MAP's customers or CPs.** Direct questions about another party's CP list, contractual terms with CPs, or commercial relationships with CPs are out of scope.
- **Do not solicit, or volunteer, business-acquisition methods.** Sales tactics, pricing tactics, migration tactics, retention tactics, and marketing tactics are out of scope for TAG meetings.

---

## 6. What to do if something goes wrong

### 6.1 If you think CSI is being shared

Stop the meeting or call. State plainly that the discussion appears to be heading into CSI. Park the topic. Consult your own organisation's competition lawyer before proceeding further. Do not rely on the original speaker's view of whether what they said is CSI — the test is objective, not subjective.

### 6.2 If you have shared CSI yourself

Tell your own organisation's competition lawyer at the earliest opportunity. Then notify the TAG co-chairs so the meeting record can be updated and any necessary remediation (for example, a request that other participants disregard the information) can be coordinated.

### 6.3 If you are pressured by another participant

Decline. Use these guidelines as the public reason. Notify the TAG co-chairs. The TAG will not censure a participant for refusing to share CSI; it may censure (and ultimately exclude) a participant who repeatedly pressures others to share CSI.

### 6.4 If you are unsure

Ask. Contact the competition lawyer in your own organisation in the first instance. It is often possible to **recast** information — for example by aggregating data or expressing it as a range — so the substance can be shared without raising competition concerns. Your competition counsel can advise on the right framing.

---

## 7. The key test — remember this

> The defining test for CSI is whether the information is capable of **influencing another company's commercial or competitive behaviour, policy, or strategy** — or capable of affecting "normal competition" in the market. If it is, **do not share it**.

If you take only one thing from this document, take that test. Apply it before you speak, before you write, before you circulate any draft or any data. If the answer is "yes, this could influence another company's commercial behaviour", the information does not belong in a TAG meeting.

---

## 8. Acknowledgements and acceptance

By attending a TAG Steering Group meeting, focus-group session, or any TAG call, every participant is taken to have read and accepted these guidelines. This applies equally to:

- **Standing members** of the TAG Steering Group.
- **Observers** attending under §4.3 of the TAG Terms of Reference.
- **Invited specialists and subject-matter experts** — including key industry representatives and specialised technical representatives invited from MAPs, CPs, regulators, vendors, academia, or aligned industry bodies under §4.4 of the TAG Terms of Reference. Invited specialists **must explicitly acknowledge** these guidelines before joining the session they have been invited to. Acknowledgement is recorded in the meeting notes.

The co-chairs will reiterate the conduct rules at the opening of each meeting and will introduce any invited specialist by name, organisation, and the agenda item they have been invited to address — so the meeting record is unambiguous and so every other participant knows the basis of the specialist's presence.

These guidelines may be revised by the TAG Steering Group on the recommendation of competition counsel or in response to operational experience. Any revision is published in this document with a version bump and a dated change note in the Document Control table.

---

## Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 Draft | 2026-06-19 | First-draft TAG Steering Group Guidelines for Conduct. Adapted from the GPLB-SG *Guidelines for Conduct of Gaining Provider Led Business Steering Group Meetings v1.0* (CONFIDENTIAL). Retargeted to TAG meetings about the CSF and industry architecture; added the TAG-specific guardrails in §3 (no customer-base intelligence, no sharing of business-acquisition methods, collective benefit over individual advantage). For TAG review. |
| 1.1 Draft | 2026-06-19 | Extended §4.5 *Individual responsibility* and §8 *Acknowledgements and acceptance* to explicitly cover **invited specialists and subject-matter experts** — key industry representatives and specialised technical contributors invited under §4.4 of the TAG Terms of Reference to assist with specific TAG challenges. Invited specialists must explicitly acknowledge these guidelines before joining and are bound by them on the same footing as standing members and observers. |

---

<!-- DOCUMENT: standalone/tag-steering-group-terms-of-reference | Standalone Documents — TAG Steering Group — Terms of Reference -->

---
title: TAG Steering Group — Terms of Reference
tags: [Standalone, TAG, Governance, TermsOfReference]

---

# TAG Steering Group — Terms of Reference

> Connected Services Framework (CSF) — Governance Document — Version 1.0 (Draft)
>
> Maintained by the Telecom Technical Architecture Group (TAG). Companion to the [TAG Steering Group Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md), which is incorporated by reference as Appendix A.

---

## Document Control

| | |
|---|---|
| **Audience** | TAG Steering Group members and prospective members; observers; focus-group leads; industry bodies (Ofcom, OTA2, TOTSCo, FCS, NPESG, NICC) needing a reference for how the TAG operates. |
| **Status** | Draft v1.0 — for TAG review. |
| **Adopts** | The [TAG Steering Group Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md), attached as Appendix A and binding on every meeting. |
| **Purpose** | Define the purpose, scope, membership, working practices, and decision-making structure of the Telecom Technical Architecture Group (TAG) Steering Group so it operates predictably, accountably, and in the collective interest of the UK telecommunications industry. |

---

## 1. Purpose

The purpose of the **Telecom Technical Architecture Group (TAG) Steering Group** is to develop, publish, and maintain the **Connected Services Framework (CSF)** — the open peer-to-peer transport standard for the UK telecommunications industry — and to contribute to other industry-related architectural activities that benefit the wider industry.

The TAG exists to do **collective, neutral, technical work** for the industry as a whole. Its first delivered application is the CSF and its initial use case is **Switching for Business (SforB)**, but the group's remit is deliberately broader: any industry-architecture topic where shared technical contribution produces a better result for every participant than fragmented individual effort.

The TAG is **not**:

- A forum for any participant to gain access to another participant's customers (including Communications Providers (CPs) served by another Managed Access Provider (MAP)).
- A forum for any participant to share the commercial methods, sales tactics, or business-acquisition approaches they will use to win or retain business.
- A forum for any participant to gain competitive intelligence — directly, indirectly, or inadvertently — about another participant's commercial position.

These constraints are set out in detail in the [Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md) (Appendix A) and apply to every TAG meeting, call, and correspondence.

---

## 2. Status and reporting

The TAG Steering Group is an **independent industry technical group**. It recognises the role of relevant industry working groups and governance bodies — including Ofcom, OTA2, TOTSCo, FCS, NPESG, NPPCG, NICC, and any other body the steering group identifies — and will flag issues, requirements, or proposed changes to those bodies as appropriate.

The TAG does not replace any of those bodies. Where the work of the TAG produces an output relevant to another body's remit (for example, a JAM-envelope refinement that affects OTS, or an RCPID-management proposal that affects TOTSCo), the TAG packages that output for submission to the receiving body through its existing processes.

The TAG produces an **outward-facing record** (CSF specification documents, decisions, minutes, and meeting attendance lists) so the wider industry can see what the TAG has done, when, and why. The CSF and supporting documents are published openly under the TAG's open-source publication arrangements.

---

## 3. Scope of work

The TAG Steering Group will:

1. **Develop and maintain the CSF.** Agree the architectural principles, transport conventions, message envelope use, security model, identity and naming, directory and registry conventions, sponsorship and onboarding rules, and supporting operational practices that constitute the framework. Publish the framework openly.
2. **Manage the CSF change-control process.** Operate the version-adoption policy, deprecation notice periods, and feature-release cadence. Maintain backwards compatibility commitments to participating MAPs (including HMAPs such as TOTSCo) so existing integrations continue to work.
3. **Publish best-practice technical guidance.** Produce and submit for peer review high-level best-practice documents for the framework's primary applications — initially Switching for Business (SforB), and any future industry process the TAG agrees to support.
4. **Liaise with other industry bodies.** Identify requirements that need submission to other industry groups (OTA2, NPESG, TOTSCo, NICC, etc.) and present those submissions to the appropriate group in a timely manner.
5. **Champion industry-wide interests at the framework level.** Represent the collective interests of MAPs, CPs, Systems Integrators, and the wider industry in the CSF's design. Never represent a single participant's commercial interests through the framework.
6. **Stand up focus groups.** Identify and, where needed, create focus groups (for example, security working group, directory and registry working group, onboarding and test working group) to work on specific elements of the framework.
7. **Engage with the regulator.** Where appropriate, brief Ofcom on the progress of the CSF and on any regulatory areas that require guidance from Ofcom. The TAG remains an independent technical body; it does not have, nor does it seek, regulatory authority of its own.
8. **Keep the wider industry informed.** Publish progress and process proposals through appropriate channels (OTA2, NPESG, NPPCG, TOTSCo, trade associations, industry bodies) so that practitioners, prospective MAPs, prospective CPs, and observers all have visibility of where the framework is going.
9. **Operate a support mechanism for adoption.** Establish a route for MAPs, CPs, and HMAPs to surface adoption issues, early-life operational issues, and questions about the framework. Address these through the TAG's normal working process.
10. **Maintain longer-term governance.** Operate a stable governance structure — including the conduct rules in Appendix A — that allows the TAG to outlive any single contributor and any single application of the framework.

---

## 4. Chairing and attendance

### 4.1 Chairing

The TAG Steering Group is **co-chaired** by the **OTA2** representative and an **industry representative** drawn from the contributing organisations on a rotating basis. The co-chair pattern is intentional: it pairs an independent industry-body voice with a participant voice, so neither side is the sole owner of the chair.

### 4.2 Attendance — full members

Attendees are drawn from industry representatives able to contribute expertise and carry out work relevant to the TAG's activity. Specialisms anticipated include:

- **Regulatory** — understanding of Ofcom's switching framework, the General Conditions, and any obligations imposed on participating CPs and MAPs.
- **Operational switching** — practical experience of running OTS, SforB, or similar industry message-exchange operations.
- **Process design** — designing repeatable cross-organisation processes that work across many MAPs and CPs.
- **Technical architecture** — protocol design, identity, transport, security, distributed systems, and API design.
- **MAP operations** — running a MAP day-to-day and the operational concerns that come with it.
- **Systems integration** — building and integrating MAPs and CPs into the framework.

Every attending member represents their organisation, but their **contribution to TAG work is on behalf of the industry**, not on behalf of their employer's commercial interests. This is the central distinction that protects the TAG's neutrality.

### 4.3 Observer attendees

Invitations to attend the TAG Steering Group may be extended to additional parties as **Observers** — for example representatives from **TOTSCo**, MAPs, CPs, regulators, trade associations, or aligned industry bodies. Invitations are extended in a non-discriminatory manner, with equal access to all eligible parties.

- Observers may be invited to comment or contribute on specific discussions or reviews but are **not formally part of the decision-making structure** of the TAG Steering Group.
- The TAG Steering Group reserves the right to hold meetings or portions of meetings without observers, or to ask observers to leave for specific agenda items where the steering group considers it appropriate.
- Observers will only have access to documents in the public domain unless express agreement is reached for a specific contribution or review.
- Focus groups (for example, the process group) may extend invitations to observers at the focus-group lead's discretion; the same attendance conditions apply.

### 4.4 Invited specialists and subject-matter experts

In addition to standing members and observers, the TAG may **invite key industry representatives or specialised technical representatives from MAPs, CPs, and the wider industry** to assist with specific challenges, deliverables, or responsibilities the TAG is working on at the time. These are termed **Invited Specialists** (or, where the contribution is principally technical, **Subject-Matter Experts**). The mechanism exists so the TAG can draw on the right expertise at the right moment without having to extend full membership for what is sometimes a single agenda item.

**Who may be invited**

Anyone whose expertise is relevant to a TAG challenge — for example:

- Senior technical staff from a MAP or a CP with deep knowledge of an area under discussion (security, identity, routing, telemetry, operational resilience, billing interfaces, regulatory mapping, and so on).
- Representatives of industry bodies, standards organisations, or aligned working groups (OTA2, NPESG, NPPCG, NICC, FCS, IETF working groups, and others) whose context informs a TAG decision.
- Representatives of TOTSCo where a specific HMAP-related question is on the agenda.
- Regulatory representatives (for example, Ofcom officials) where a regulatory question needs a direct answer.
- Independent specialists, academics, vendors, or consultants whose expertise the TAG considers relevant.

**How invitations work**

- Invitations are issued **by the co-chairs** in consultation with the steering group, either on the co-chairs' initiative or on the request of any TAG member who has identified a need.
- An invitation is **topic-bounded** by default: the specialist is invited for a named challenge, deliverable, focus-group cycle, or finite period. The agenda entry that requires the specialist's input records why they are present.
- Invitations are extended in a **non-discriminatory** manner. Where two or more parties hold the same expertise, the TAG considers fairness across the industry when choosing whom to invite, and the meeting record explains the choice.

**Status and access**

- Invited specialists are **not standing members** of the TAG Steering Group and do not carry voting or decision-making rights unless the steering group later upgrades them to member status through the membership process in §9.
- Invited specialists may be granted access to non-public TAG working materials **only to the extent required** for the specific challenge they have been invited to address. Where the working material concerns areas outside the scope of their invitation, access is not granted.
- The co-chairs may ask invited specialists to leave for specific agenda items where the steering group considers it appropriate.

**Conduct binding**

- Every invited specialist **must read and accept the [Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md) (Appendix A) before joining**. Acceptance is recorded in the meeting notes. The competition-law and TAG-specific guardrails (no customer-base intelligence, no business-acquisition methods, collective benefit over individual advantage) apply to invited specialists exactly as they apply to full members.
- Where the invited specialist is from a MAP or a CP, the invitation makes clear that their TAG contribution is **on behalf of the industry challenge under discussion**, not on behalf of their employer's commercial interests. This is the same standard that applies to full members.

**Conflict of interest**

- An invited specialist **must declare** any conflict of interest at the start of the session, in the same terms as a full member (see §4.5). The co-chairs decide whether to proceed, restrict participation, or excuse the specialist for the affected item.

**Recording and reporting**

- The meeting notes record the specialist's identity, the organisation they represent, the agenda item or challenge they were invited to address, and the substantive contribution they made.
- The steering group reviews the use of invited specialists periodically to ensure the mechanism is being used proportionately and in line with these Terms of Reference.

### 4.5 Conflicts of interest

Every attendee — full member, observer, or invited specialist — **must declare** any conflict of interest in any discussion in which they participate, and must clearly indicate which organisation they are representing in that discussion. A standing item at the top of every agenda invites declarations.

A declared conflict does not automatically prevent participation; it is recorded so that the rest of the group can weigh contributions in context, and so the co-chairs can manage the discussion appropriately.

### 4.6 Conduct

All attendees — full members, observers, invited specialists, focus-group attendees, and corresponding parties — must adhere to the [TAG Steering Group Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md) (Appendix A). The guidelines apply to every meeting, every call, every side conversation, and every piece of correspondence touching TAG work.

The conduct guidelines explicitly prohibit:

- Using TAG meetings to gain access to another MAP's CPs, customer base, or commercial relationships with those CPs.
- Sharing or soliciting the methods, processes, sales motions, or commercial tactics any MAP or CP intends to use to win, retain, or migrate business.
- Discussing, agreeing, or recommending action on competitively sensitive topics — even in jest.

These guardrails are the central condition of TAG membership. Persistent or material breach is grounds for the co-chairs to ask a member or observer to leave the group.

---

## 5. Meeting scheduling and planning

- Meetings are scheduled on a **weekly** basis as default (currently Wednesdays), with ad-hoc additional meetings as required and agreed by the co-chairs. The frequency may be adjusted by agreement when the volume of work, the availability of attendees, or industry urgency justifies a different pattern.
- A **standing agenda** is circulated in advance of each meeting. The agenda includes any standing items, the topics for discussion, and the indicative time allowed for each. Amendments to incorporate new items are accepted before the meeting at the co-chairs' discretion.
- A **copy of the Guidelines for Conduct** is attached to every meeting invite and noted in every agenda, as required by §5 of the guidelines themselves.
- The opening item of every meeting is a **competition-law reminder** acknowledging the conduct constraints on discussion.

---

## 6. Decision-making

The TAG operates by **consensus** wherever consensus is achievable. Where consensus cannot be reached on a substantive technical question, the co-chairs may:

1. **Defer** the decision to allow further offline work, peer review, or focus-group input.
2. **Escalate** the decision to a named working group or external industry body where the decision properly belongs.
3. **Record a majority view** along with the dissenting view in the meeting record, so the decision is explicit and the dissent is preserved.

Decisions of the steering group are recorded in the meeting notes. Where a decision changes a published artefact (for example, the CSF specification or a published best-practice document), the change-control process for that artefact is followed in addition to the meeting record.

---

## 7. Meeting notes

Meeting notes and actions are recorded for every meeting, so a record of activity and progress is in place. The notes may be in a simple bullet-point format and must include, at minimum:

1. The date and time of the meeting or call.
2. The individuals who attended — full members, observers, and any invited specialists — and the organisation each represented. For invited specialists, the agenda item or challenge they were invited to address is also recorded.
3. The subject of the discussion (matching the agenda).
4. Any decisions adopted, including any recorded dissent.
5. Any actions raised, with named owners and target dates.
6. The competition-law reminder confirmation (a single line acknowledging that the reminder was given at the opening of the meeting).

Notes are circulated to all attendees within a working week of the meeting and are archived as part of the TAG's open governance record.

---

## 8. Working artefacts

The TAG produces and maintains the following artefacts as part of its work. The list is indicative; further artefacts may be added by agreement.

- **The CSF specification** — the open peer-to-peer transport standard, published openly under the TAG's open-source arrangements.
- **CSF supporting documents** — onboarding and test process, TOTSCo HMAP integration guide, CP Rights Charter, definitions, and similar companion documents.
- **Best-practice publications** — high-level technical best-practice for the framework's primary applications (initially SforB).
- **Industry submissions** — papers and proposals submitted to other industry bodies on behalf of the TAG.
- **Meeting record** — agendas, minutes, attendance, and decisions, as set out in §7 above.

All TAG artefacts are produced collectively. No individual contributor or single organisation owns any TAG artefact for commercial purposes.

---

## 9. Membership changes

Membership is by **invitation of the co-chairs** in consultation with the existing steering group. The TAG welcomes contributions from any organisation able to contribute technical expertise consistent with §3 (scope of work) and willing to operate within Appendix A (guidelines for conduct).

A member or observer may **resign** at any time by notifying the co-chairs. The co-chairs may **ask a member or observer to leave** the group where the conduct rules in Appendix A are persistently or materially breached, where a declared conflict of interest cannot be managed, or where the participant is no longer contributing.

Changes in membership are recorded in the meeting record and reflected in the participant list.

---

## 10. Glossary

| Abbreviation | Explanation |
|---|---|
| CP | Communications Provider |
| CSF | Connected Services Framework — the open peer-to-peer transport standard developed by the TAG |
| FCS | Federation of Communication Services |
| GPLB | Gaining Provider Led Business (the original name for the SforB process) |
| HMAP | Hub Managed Access Provider — a specialised MAP type (for example, TOTSCo when participating in the CSF) |
| IAS | Internet Access Service (e.g. broadband) |
| MAP | Managed Access Provider |
| NBICS | Number-Based Interpersonal Communications Service (voice) |
| NICC | Network Interoperability Consultative Committee |
| NPESG | Number Porting Executive Steering Group |
| NPPCG | Number Porting Process (and) Commercial Group |
| Ofcom | Office of Communications (the UK communications regulator) |
| OTA2 | Office of the Telecommunications Adjudicator |
| OTS | One Touch Switch — process mandated by Ofcom for residential switching |
| SforB | Switching for Business — the renamed GPLB process |
| SI | Systems Integrator |
| TAG | Telecom Technical Architecture Group — the body whose steering group these Terms of Reference define |
| TOTSCo | Telecoms One Touch Switching Company |

---

## 11. Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 Draft | 2026-06-19 | First-draft TAG Steering Group Terms of Reference. Adapted from the GPLB-SG *Terms of Reference v1.1 (29 August 2024)*. Re-scoped to the TAG (Telecom Technical Architecture Group) and the CSF; added explicit guardrails in §1 (no customer-base intelligence, no business-acquisition methods, collective benefit over individual advantage) consistent with Appendix A. Co-chair model preserved (OTA2 + rotating industry chair). Conduct guidelines moved into a standalone companion document and referenced as Appendix A. For TAG review. |
| 1.1 Draft | 2026-06-19 | Added §4.4 *Invited specialists and subject-matter experts* — formalises how the TAG can bring in key industry representatives or specialised technical representation from MAPs, CPs, regulators, vendors, academia, and aligned industry bodies to assist with specific challenges and responsibilities the TAG is working on at the time. Renumbered the subsequent sub-sections; updated §7 to require meeting notes to capture the agenda item the specialist was invited to address. The Conduct Guidelines companion was updated in parallel to make explicit that invited specialists are bound by the same rules and must acknowledge them before joining. |

---

## Appendix A — Guidelines for Conduct of TAG Steering Group meetings

The conduct rules that govern every TAG meeting, call, and exchange are published as a separate companion document so they can be cited and attached individually:

**[TAG Steering Group — Guidelines for Conduct](./tag-steering-group-guidelines-for-conduct.md)**

Every TAG meeting invite must attach a copy of, or cite a link to, that document. Every TAG agenda must note it. Every TAG meeting must open with a verbal reminder of its central tests:

- Is what I am about to discuss strictly necessary to design or develop the CSF, or another industry architecture topic in the TAG's scope?
- Does it touch any participant's customer base, supplier relationships, pricing, plans, methods of gaining business, or any other competitively sensitive information?
- Would a competition lawyer, if present, raise an objection?

If the answer to the first question is "no", or to the second or third is "yes", the topic does not belong in a TAG meeting. Pause; consult; redirect.

---

<!-- DOCUMENT: standalone/totsco-faq | Standalone Documents — FAQ — TOTSCo Integration -->

---
title: FAQ — TOTSCo Integration
tags: [Standalone, FAQ, TOTSCo, HMAP, Integration]

---

# FAQ — TOTSCo Integration

> Connected Services Framework (CSF) — Standalone Companion Document — Version 2.0

These questions were proposed by TOTSCo as part of integration discussions held on **18 November 2025**. The FAQ has since been updated to reflect the consolidations and ratifications in the framework — most notably the locked-down per-MAP HMAP interface model (see the [TOTSCo HMAP Integration Guide](./totsco-hmap-integration-guide.md)), the CSF-mirrors-TOTSCo directory shape, the OTS/GPLB filter URLs, and the active surfacing of the upside of collaboration for TOTSCo.

This document lives in the **standalone** section so it can grow over time without being tied to the Part 2 numbering. Cross-references below use paths relative to the standalone folder.

---

## Q1 — Registering CSF Endpoints

**Impact: Zero to Low**

No new MAP or CP connections are anticipated — existing OTS connectivity is already operational. Any new MAP or MAP-of-1 must register with TOTSCo following existing procedures (IP allowlisting, OAuth 2.0 / API-key credentials, JAM Specification compliance).

The only addition is a **Directory API endpoint URL** for TOTSCo to retrieve the MAP's CSF registry. The same OAuth 2.0 credentials and IP security mechanisms apply.

As the CSF matures, some CPs may onboard as **MAP-of-1s** — a CP operating its own MAP infrastructure (see [Part 1 §7.4](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration)). Such MAPs also register with TOTSCo using TOTSCo's existing procedures. The volume is anticipated to be modest and the registration process is unchanged.

> See [Part 2 §6.3 Registering CSF Endpoints](../part2-implementation/06-totsco-integration.md#63-registering-csf-endpoints) and the [TOTSCo HMAP Integration Guide](./totsco-hmap-integration-guide.md) for the full operating model — including the **dedicated, locked-down HMAP interface** that each CSF MAP exposes exclusively for TOTSCo, and the per-MAP dedicated CSF letterbox URLs that mirror TOTSCo's existing per-partner pattern.

---

## Q2 — The CSF CP Registry — How would TOTSCo use it?

**Impact: Medium**

TOTSCo collects each MAP's CP Registry (anticipated fewer than 10 MAPs initially) and converges them into a Master Registry. This can be merged with the existing TOTSCo directory or maintained separately.

The CSF CP Registry is JSON-formatted and **a strict superset of the TOTSCo OTS / GPLB directory structure**, making convergence straightforward. Parsers that don't recognise the CSF-specific additions ignore them; the underlying TOTSCo-compatible shape is unchanged.

Key benefits for TOTSCo:

- SforB process contacts (warranty period and ongoing support) are already included.
- MAP-to-CP, CP-to-MAP, CP-to-CP, and MAP-to-MAP contact points are built in.
- Eliminates the need for paper-based spreadsheets for support contacts.

Virtualised test CPs with synthetic data are available for integration testing.

**Sponsorship object.** As of CSF v2.x, the CP Registry also carries a `sponsorship` object (see [§5.4.2 Sponsorship Object — Rotation Rules](../part2-implementation/05-directory-api.md#542-sponsorship-object--rotation-rules)) used by CSF MAPs to coordinate the rotation for onboarding new MAPs. **TOTSCo participating as an HMAP is exempt from the sponsorship rotation** — onboarding of new CPs to TOTSCo continues under TOTSCo's existing procedures; the `sponsorship` object is a CSF-internal coordination mechanism.

---

## Q3 — Handling Different RCPID Formats

**Impact: Low**

The SforB Message Specification defines identity fields as strings (up to 256 characters). UUIDv4 (36 characters) fits within this constraint.

- **CSF → TOTSCo**: Uses TOTSCo's 4-character RCPID from the TOTSCo directory.
- **TOTSCo → CSF**: Uses the UUIDv4 RCPID from its Master Registry (collected from CSF CP Registries).

TOTSCo automatically acquires all UUIDs when collecting MAP registries. Both platforms already accept UUIDv4 for correlation IDs. TOTSCo uses the **same 4-character RCPID format for both OTS and GPLB (SforB) today**, so this translation is no different from any existing TOTSCo-internal lookup.

**OTS RCPIDs remain at TOTSCo.** OTS is mandated by Ofcom to use TOTSCo as the single industry platform — no OTS migration to the CSF is contemplated. The translation between TOTSCo's 4-character RCPID and the CSF's UUIDv4 RCPID applies only at the **SforB** transport boundary. For CPs that operate both OTS and SforB, the OTS `Rxxx` is independent of any SforB UUIDv4 the CP might also hold on a CSF MAP — TOTSCo retains exclusive control of its OTS allocation.

---

## Q4 — Are modifications needed to the TOTSCo API?

**Impact: Zero**

**No.** TOTSCo uses the industry JAM Specification — the same standard used by the CSF. The CSF validates envelopes identically, uses OAuth 2.0 over TLS 1.3, and returns HTTP 202 for accepted messages.

The CSF's 8xxx PKI error codes are not sent to TOTSCo. The industry 9xxx codes are fully honoured.

The CSF is a **bit-pipe transport** (see [Definitions §2.3](./definitions.md)) — it carries the JAM envelope between MAPs and **does not interpret the message body**. This means the JAM messages TOTSCo sends to CSF MAPs (and vice versa) traverse the network unchanged at the body level; the CSF only validates the envelope and the OAuth token. No API modifications on TOTSCo's side are required.

---

## Q5 — Distinguishing message flow between standard MAPs and CSF MAPs

**Impact: Low to Medium**

TOTSCo can distinguish between its directly managed CPs (paying subscribers) and CPs discovered through CSF registries (guests). A MAP may have CPs interacting via both TOTSCo and CSF — TOTSCo allocates RCPIDs for its managed CPs and discovers additional CPs through registry collection.

The message flow in each direction is illustrated in [§6.7 (CSF → TOTSCo)](../part2-implementation/06-totsco-integration.md#67-message-flow-csf-to-totsco) and [§6.8 (TOTSCo → CSF)](../part2-implementation/06-totsco-integration.md#68-message-flow-totsco-to-csf) of the TOTSCo Integration chapter. **In the CSF, CP + MAP are treated as a single endpoint at the transport layer** — the MAP (or MAP-of-1) handles all CSF message exchange; the CP gives internal instructions and receives internal nudges. The flow visible to TOTSCo is therefore CSF-MAP-to-TOTSCo (or TOTSCo-to-CSF-MAP) at all times; TOTSCo never needs to interact with a CSF CP directly.

A fully worked bidirectional example (NowYoYo / BBBX ↔ Red Company) and a Mermaid sequence diagram are in the [TOTSCo HMAP Integration Guide §Phase 3 Test](./totsco-hmap-integration-guide.md).

---

## Q6 — CP-to-CP communications tool

**Impact: Zero to Low**

The OTS CP-to-CP tool was not designed for the kinds of contact patterns SforB requires (multi-purpose, hours-aware, multi-channel). The CSF's `contact[]` array on every CP and MAP (see [§5.6 CP Contact Object](../part2-implementation/05-directory-api.md#56-cp-contact-object)) provides exactly that — phone / email / URL with purpose tags (sales, support, technical), availability hours and days, and free-text usage notes — all retrieved via authenticated API.

**TOTSCo can re-use this directly.** When forwarding to a CSF-side CP, the destination contact details are available in real time from the CSF MAP's published registry. This eliminates an industry pain point without TOTSCo having to build or maintain a CP-to-CP tool itself. CPs already have the tools and contacts they need for sales and technical support; the CSF registry simply makes them discoverable and machine-readable in a single uniform shape across the whole industry.

---

## Q7 — Availability and Latency Guarantees

**Impact: Zero to Low**

In the peer-to-peer model, messages travel directly between two MAPs — no forwarding or routing hub — significantly reducing overall latency.

The CSF implements enterprise-grade delivery patterns:

- Retry with exponential backoff and jitter.
- Respect for `503 Service Unavailable` and `429 Too Many Requests` with `Retry-After`.
- Circuit-breaker patterns after consecutive failures.

SforB SLAs are significantly longer than OTS (no 60-second Switch Match response requirement), allowing the industry to tolerate lower message rates and support retry policies.

The CSF's industry-wide availability target — **99.95%** ("three nines and a five") — is **deliberately aligned with the TOTSCo Availability Target** so industry-wide SLAs remain consistent across both transports. See [Onboarding & Testing Process §8.7 Retry and Delivery Policy](./onboarding-testing-process.md#87-retry--delivery-policy).

---

## Q8 — Outage Calendar

**Impact: Zero**

The CSF considers traditional outage calendars to be outdated. Modern SaaS and cloud infrastructure should achieve full resilience and near-100% availability. When a CP is temporarily unavailable, the MAP queues and retries.

The CSF registry includes service status URLs and API endpoints for real-time operational monitoring — a more effective alternative to manual outage notifications.

The CSF's `map/outage[]` array in the CP Registry (see [§5.4 MAP Section — Field Reference](../part2-implementation/05-directory-api.md#54-map-section--field-reference)) carries ITIL-priority outage entries with start/end timestamps, affected services, descriptions, and escalation contacts. **TOTSCo collecting the CSF registries automatically receives a real-time outage view** for every CSF MAP — strictly more useful than a static outage calendar. See [§9.4 Outage Notification](../part2-implementation/09-operations.md#94-outage-notification) for the operational rules.

---

## Q9 — Diagnostics

**Impact: Zero**

Audit records and diagnostics remain integral to both OTS and SforB. Through CSF registries, TOTSCo gains direct access to every CSF MAP's diagnostic contacts for prompt issue resolution.

Diagnostic support in the CSF includes:

- The JAM envelope's `auditData[]` array (correlation IDs, session metadata, test flag) — see [Onboarding & Testing Process §5](./onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope).
- The optional `X-CSF-ROUTE` HTTP header that records the route a message has taken through the network (each MAP appends a timestamp + MAP name) — useful for HMAP-bridged messages.
- The structured **9xxx industry error codes** and the CSF-specific **8xxx PKI codes** returned in synchronous responses.
- Per-MAP service-status URLs and operational contact details in the registry.

---

## Q10 — Support and Ticketing Arrangements

**Impact: Zero to Low**

The CSF registry provides CP and MAP support hours, contact points (phone, email, URL), and purpose tags (sales, support, technical). URLs can link to targeted web forms or ticketing systems.

The CSF's contact object (used at both MAP and CP level — see [§5.6](../part2-implementation/05-directory-api.md#56-cp-contact-object)) uses a single uniform structure across the industry: `type` (phone, email, URL), `value`, `purpose[]` (sales, support, technical), `availabilityFrom` / `availabilityTo` / `availabilityDays[]`, and a free-text `comment`. This means **TOTSCo's existing support tooling can consume CSF MAP and CP contact data with no additional parsing** — the same JSON structure CSF MAPs expect.

---

## Q11 — Service-Level and other commitments

The TAG is prepared to define and agree specific SLAs with TOTSCo once concerns are understood. The CSF already operates to the same availability standards expected of all OTS MAPs.

TAG governance now publishes an **annual aggregated transparency summary** of network activity (see [§10.6.7 Anti-Competitive Safeguards](../part1-framework/10-governance.md#1067-anti-competitive-safeguards)) — volumes, participants, success rates. Test traffic is excluded from production telemetry per the JAM audit `test=true` rule. TOTSCo as an HMAP can rely on the same transparency view if it elects to participate in the transparency-reporting flow; this is optional and there is no obligation.

---

## Q12 — What benefits does TOTSCo get from being an HMAP on the CSF?

TOTSCo gains four concrete benefits as an HMAP on the CSF:

1. **Real-time outage and service-status view.** TOTSCo collecting CSF registries automatically receives every CSF MAP's `map/outage[]` and `map/serviceStatusServiceURI` data, replacing the need for any outage-coordination spreadsheet (see Q8 above). Strictly richer than any static outage calendar.
2. **Real-time CP-to-CP contact data.** Every CSF-side CP publishes a contact object (phone, email, ticketing URL with purpose tags) reachable via authenticated API; eliminates an industry pain point without TOTSCo building or maintaining a CP-to-CP tool (see Q6 above).
3. **Bridge revenue / participation positioning.** TOTSCo remains the SforB hub for CPs who choose to stay on the TOTSCo subscription model; the CSF interoperability is a **value-add** for those CPs, not a competitor. The framework is a market-expansion mechanism for TOTSCo, not a market-share threat.
4. **Industry standing as a forward-looking participant.** Being an HMAP on the open framework signals to industry, regulators, and TOTSCo's own customers that TOTSCo is supporting industry transformation, not blocking it. Reputationally significant in the v2.0 publication cycle.

---

## Q13 — Will TOTSCo's existing OTS commercial relationships be affected?

**No.** OTS is **mandated by Ofcom** to use TOTSCo as the single industry platform. The CSF does not interact with OTS at any level — see [§7.4.1 Definition and Scope](../part1-framework/07-onboarding.md#741-definition-and-scope) for the formal scope statement.

TOTSCo's OTS subscriptions, OTS RCPID allocation, and OTS hub operations continue exactly as today. The CSF integration is **strictly for SforB and other non-OTS protocols**; the OTS hub and the SforB hub on TOTSCo's side are operationally independent and the CSF interaction touches only the SforB side.

---

## Q14 — Will TOTSCo lose SforB CPs to CSF MAP-of-1s?

**Some CPs may choose to migrate SforB traffic to a CSF MAP-of-1; most won't.**

The migration path documented at [§7.4](../part1-framework/07-onboarding.md#74-map-of-1-onboarding-incl-totsco--csf-migration) is technically demanding — it requires the CP to run TLS 1.3, OAuth 2.0, DNS management, the Letterbox and Directory APIs in-house, plus 24×7 on-call cover. Most CPs prefer to remain with TOTSCo's managed service.

The CSF supports this co-existence:

- A CP staying with TOTSCo continues exactly as today, with the **additional** benefit that CSF MAPs become reachable via TOTSCo's HMAP role.
- A CP that chooses to migrate SforB to a CSF MAP-of-1 retains the right to do so (the framework explicitly supports it), but takes on the operational obligations that come with running their own MAP.

**For TOTSCo, the CSF is a market-expansion mechanism, not a market-share threat** — it brings new CSF-MAP CPs into reachability with TOTSCo's customers, not the other way around.

---

## Q15 — Does the CSF impose any new obligations on TOTSCo's OTS operations?

**None.** The CSF interaction touches TOTSCo only at the SforB transport boundary. OTS message routing, OTS RCPID allocation, OTS process flows, OTS commercial arrangements, and OTS regulatory reporting all continue exactly as today and are explicitly out of CSF scope (see [§7.4.1 Definition and Scope](../part1-framework/07-onboarding.md#741-definition-and-scope) and [Part 2 §6.1 Overview](../part2-implementation/06-totsco-integration.md#61-overview)).

The CSF transport is process-agnostic — it carries JAM envelopes between MAPs and does not interpret the message body — so it cannot retroactively impose process-layer obligations of any kind.

The **locked-down HMAP interface** that each CSF MAP exposes exclusively for TOTSCo (see the [TOTSCo HMAP Integration Guide §1](./totsco-hmap-integration-guide.md)) provides an additional architectural commitment: CSF version increments do not propagate through the dedicated TOTSCo endpoints, so TOTSCo's integration is a one-time build, not an evergreen one.

---

## Q16 — How does the CSF's "bit-pipe" model preserve TOTSCo's operational control?

The CSF is defined as a **bit pipe** in [Definitions §2.3](./definitions.md): *"a network provider that simply moves data without adding value or examining content"*. This has three practical consequences for TOTSCo:

1. **TOTSCo's internal CP-to-MAP relationships are unchanged.** The CSF carries TOTSCo-originated messages between TOTSCo and CSF MAPs, but how TOTSCo serves its own CPs internally is unaffected.
2. **Process-layer business state stays with the parties.** Customers, SORs (Switch Order References), ServiceIdentities, billing, and support live with the CP and (for TOTSCo's CPs) with TOTSCo. The CSF carries the envelope; it does not see the body.
3. **Industry-process control stays with the industry bodies.** TOTSCo continues to control OTS process documentation; GPLB-SG continues to control SforB process documentation; the TAG controls CSF transport only.

The bit-pipe principle is what makes TOTSCo's existing operating posture safe under CSF integration: every layer above the transport is owned by TOTSCo or by its industry counterparts, not by the CSF.

---

## Q17 — How does CSF participation enhance TOTSCo's value proposition for SforB CPs?

TOTSCo's SforB hub already provides a managed service to its subscribed CPs. By participating in the CSF as an HMAP, TOTSCo **extends that managed service's reach**: subscribed CPs gain direct interoperability with CSF MAPs (and the CSF MAPs' CPs) without TOTSCo needing to negotiate bilateral connections with each one. TOTSCo CPs get:

- **Wider counterparty reach** — every CSF-connected CP becomes addressable through TOTSCo, with no additional commercial work for the CP.
- **Real-time contact data** for every CSF-side CP they need to operationally reach — replacing the OTS CP-to-CP tool, which is not mandated for SforB.
- **Future-protocol readiness** — when the TAG adds new industry protocols to the CSF baseline (for example, OTS Porting), TOTSCo CPs can adopt them via TOTSCo's HMAP role without additional bilateral integration.
- **Continued use of TOTSCo's existing JAM tooling** — the CSF uses the same JAM envelope, OAuth 2.0, and TLS 1.3, so TOTSCo's existing implementation just works at the CP side; no CP-side code change is required.

---

## Q18 — What message delivery policy applies at the HMAP boundary between TOTSCo and a CSF MAP?

The CSF's [Part 2 §4.7 Message Delivery Policy](../part2-implementation/04-message-api.md#47-message-delivery-policy) explicitly addresses this. The HMAP boundary is **asymmetric** by design:

- **TOTSCo's hub-side behaviour follows the OTA2 GPLB Message Delivery Principles V0.2** — the same delivery rules TOTSCo already applies for any hub-mediated SforB traffic. Match Requests fail-fast in 30 seconds (linear retries at 5/10/15/20/25 s); other SforB messages retry for up to 12 days (initial burst at 10/20/30/60 s then 60 s cadence). Single-flight per endpoint with queue ageing; async failure notifications back to the sender's pre-configured failure endpoint. **No change for TOTSCo** — this is hub behaviour today.
- **The CSF MAP receives those async failure notifications as a standard TOTSCo hub client** — exactly how any TOTSCo-subscribed MAP handles them now. No new mechanism to design.
- **The 1 s connection timeout and 3 s response timeout are aligned across both sides** — universal good practice irrespective of transport.
- **The HMAP interface is locked-down per [§6.3.1](../part2-implementation/06-totsco-integration.md#631-dedicated-locked-down-hmap-interfaces--both-directions).** CSF version increments — including any future change to §4.7 itself — do **not** propagate through the dedicated TOTSCo endpoints. The asymmetric behaviour at the boundary is stable and bilateral by design.

Critically, the GPLB hub schedules **do not** propagate into the wider CSF P2P transport. On the CSF MAP-to-MAP side, the CSF retains exponential backoff with jitter (the industry-standard distributed-systems pattern); persistent failure escalates via inter-MAP operational engagement (`map/outage[]` / `map/contact[]`) rather than silent multi-day queueing. See the analysis report at [wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles](../../wiki/syntheses/csf-compliance-with-gplb-message-delivery-principles.md) for the full architectural framing.

For TOTSCo this means: **integrate the HMAP interface exactly as you would any other hub-side delivery target**. No new delivery semantics; no surprise behaviour. The CSF's own delivery policy is something the CSF MAP applies on its side of the boundary, and it stays there.

---

## Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 | 2025-11-18 | First-draft TOTSCo FAQ — Q1–Q11, as discussed in the TOTSCo integration meeting of 18 November 2025. *"Impact: Zero / Zero-to-Low"* framing throughout. |
| 2.0 | 2026-06-19 | Moved from `part2-implementation/11-totsco-faq.md` to standalone so the FAQ can grow over time without being tied to the Part 2 numbering. Q1–Q11 expanded per the TOTSCo-FAQ audit ([[syntheses/audit-faqs-sg-and-totsco]]) — added cross-references to the consolidations completed since v1.0: the **locked-down HMAP interface** model, the **superset CSF directory shape**, the dual OTS/GPLB filter URLs, the §5.4.2 sponsorship-rotation exemption for HMAPs, the bit-pipe principle, the updated §6.7/§6.8 message-flow grouping, the `map/outage[]` real-time view, the uniform contact-object structure, and the §10.6.7 annual transparency summary. **NEW Q12–Q17 added** to actively surface the upside of collaboration that the original *"Impact: Zero"* framing left implicit: HMAP benefits, OTS-unaffected, market-expansion-not-threat, no-new-OTS-obligations, bit-pipe operational preservation, and CSF-as-value-add for TOTSCo's SforB CPs. |
| 2.1 | 2026-06-23 | Audit verification pass — confirmed all TOTSCo-FAQ audit recommendations from [[syntheses/audit-faqs-sg-and-totsco]] (Q1–Q11 cross-reference additions + Q12–Q17 new questions) are reflected. **NEW Q18 added**: what message delivery policy applies at the HMAP boundary — codifies that TOTSCo's hub-side delivery follows the GPLB MDP V0.2 (no change for TOTSCo); the CSF MAP receives async failure notifications as a standard hub client; the locked-down interface (§6.3.1) keeps the asymmetric boundary stable. Cross-references the new [Part 2 §4.7](../part2-implementation/04-message-api.md#47-message-delivery-policy) ratification and the [[syntheses/csf-compliance-with-gplb-message-delivery-principles]] analysis. |

---

<!-- DOCUMENT: standalone/totsco-hmap-integration-guide | Standalone Documents — TOTSCo HMAP Integration Guide — joining the CSF as a Hub MAP -->

---
title: TOTSCo HMAP Integration Guide — joining the CSF as a Hub MAP
tags: [Standalone, TOTSCo, HMAP, Integration]

---

# TOTSCo HMAP Integration Guide — joining the CSF as a Hub MAP

> Connected Services Framework (CSF) — Companion Document — Version 1.0 (Draft)
>
> Maintained by the Telecom Technical Architecture Group (TAG). Companion to [Part 2 §6 — TOTSCo Integration](../part2-implementation/06-totsco-integration.md).

---

## Document Control

| | |
|---|---|
| **Audience** | TOTSCo executive sponsors; TOTSCo programme management; TOTSCo Hub engineering and operations teams; offshore implementation partners; commercial / legal stakeholders reviewing the integration scope. |
| **Status** | Draft v1.0 — for TOTSCo review. |
| **Companion to** | [Part 2 §6 — TOTSCo Integration](../part2-implementation/06-totsco-integration.md), which sets out the framework-side view; this document is the **TOTSCo-side build-and-commission handbook**. |
| **External references** | [TOTSCo Hub API Specification v2.0 (April 2026)](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) — the canonical TOTSCo transport specification this guide is mapped against. |
| **Purpose** | Show TOTSCo, in concrete and actionable terms, exactly what it needs to do to become a **Hub Managed Access Provider (HMAP)** on the CSF — what changes, what does not, what it costs, how long it takes, and what the industry gains. |

---

## 1. Executive Summary

The Connected Services Framework (CSF) is the open-standard peer-to-peer transport for **Switching for Business (SforB)** and any future industry protocols the TAG adds to its baseline (for example, OTS Porting). TOTSCo participates in the CSF as a **Hub MAP (HMAP)** — a specialised MAP role that bridges TOTSCo's centralised hub model with the CSF's distributed peer-to-peer network. TOTSCo retains exclusive control of its own hub and its commercial relationships with subscribed CPs; the CSF integration is a **transport bridge**, not a replacement of TOTSCo's role.

> **Locked-down HMAP interface.** Each CSF MAP exposes a **dedicated HMAP interface exclusively for TOTSCo**. This interface is not used by any other MAP or HMAP. The deliberate design intent is to give TOTSCo a **locked-down, steady-state** interface that does not change as the wider CSF evolves. CSF version increments, feature releases, and routing-group additions made by the TAG have **zero impact** on the TOTSCo HMAP interface — every exchange continues to work exactly as it does today. This is the single most important architectural commitment the CSF makes to TOTSCo, and it is the operating model assumed throughout this guide.
>
> **Message delivery at this boundary.** The HMAP interface inherits TOTSCo's hub-side delivery policy — the OTA2 GPLB Switching for Business Message Delivery Principles bind TOTSCo's outbound delivery to its destination RCPs. The 1 s connection / 3 s response timeouts apply on both sides; TOTSCo applies its own linear / fixed-cadence retry schedules (5/10/15/20/25 s for Match Requests; 10/20/30/60 s + 60 s cadence for other messages); the CSF MAP receives async failure notifications from TOTSCo as a standard hub client. These hub schedules **do not propagate** into the wider CSF P2P transport because the interface is locked down. See [Part 2 §4.7.4 The HMAP Boundary](../part2-implementation/04-message-api.md#474-the-hmap-boundary) for the full bindings.

The integration is **operationally small** because most of the work TOTSCo would normally do for a new hub partner has already been done:

| Already done | Why |
|---|---|
| Same **JAM message envelope** as CSF | TOTSCo's existing Hub API v2.0 is built on JAM; the CSF reuses the same envelope verbatim ([§6.6 API Compatibility](../part2-implementation/06-totsco-integration.md#66-api-compatibility)) |
| Same **OAuth 2.0** over **TLS 1.3** transport security | The CSF mandates the same client-credentials flow that TOTSCo's CPs and MAPs already use to connect to the TOTSCo Hub today |
| Same **HTTP 202** acceptance semantics | Identical to TOTSCo's Hub API |
| Same **9xxx synchronous error codes** | Industry standard; CSF inherits without modification |
| **MAPs and CPs already connect to TOTSCo** — their commercial, security, and **KYC (Know Your Customer)** controls are in place | TOTSCo's existing onboarding for OTS MAPs and CPs satisfies the CSF-MAP onboarding requirement; no new MAP-side commercial work is needed. **KYC** refers to the standard due-diligence checks (identity verification, company registration, anti-fraud, ICO registration) a hub or MAP runs before accepting a new commercial partner; the CSF imposes no additional KYC obligations on top of those already operated by TOTSCo and its MAPs |
| **TOTSCo already routes JAM messages** to those MAPs and CPs | The bidirectional transport already works; the CSF integration simply adds new MAPs that TOTSCo's existing flows reach via the same OAuth-secured letterbox calls |
| **CSF CP Registry intentionally mirrors TOTSCo's directory structure** | The CSF CP Registry was designed by the TAG to be a strict superset of the TOTSCo OTS/GPLB directory shape so TOTSCo can ingest it without transformation. CSF-specific fields (`contact[]`, `outage[]`, `signing[]`, `resource[]` extensions) may be consumed for the value they add or ignored entirely without breaking existing TOTSCo code — see §3 for the side-by-side format comparison |

What remains for TOTSCo to do is bounded and well-defined. The TAG anticipates this is **low-effort work** because each item leverages infrastructure TOTSCo already operates — the integration is genuinely additive rather than transformative. TOTSCo's own engineering teams are best placed to estimate the specific effort against their internal resourcing model:

| # | What TOTSCo needs to do | Risk |
|---|---|---|
| 1 | Add a **Directory API client** to pull each CSF MAP's CP Registry (read-only, OAuth-secured, JSON over HTTPS) | Low |
| 2 | **Converge the collected registries** into TOTSCo's existing Master Registry (or maintain alongside as a parallel CSF zone) | Low |
| 3 | Implement **RCPID translation** between the CSF UUIDv4 format and TOTSCo's existing 4-character RCPID format (used for both OTS and SforB/GPLB today), at the SforB-traffic boundary | Low |
| 4 | Configure **routing rules** so SforB messages destined for a CSF-side CP are sent to the correct CSF MAP letterbox URL | Low (largely configuration) |
| 5 | Expose **dedicated, per-MAP CSF letterbox endpoint URLs** for inbound traffic from each CSF MAP — the same per-partner dedicated-endpoint pattern TOTSCo already operates for OTS and SforB today (see [§6.3 Registering CSF Endpoints](../part2-implementation/06-totsco-integration.md#63-registering-csf-endpoints)) | Low (configuration only) |
| 6 | End-to-end **integration testing** with two or more CSF MAPs | Low — test harnesses and patterns provided (see §7) |
| 7 | **Operational commissioning** (service-status, outage feed, diagnostics, regression suite) | Low — most monitoring is reuse of existing TOTSCo stack |

> **Why the work is low effort**: Each item reuses an existing TOTSCo capability. Item 1 is a standard REST-over-OAuth client that TOTSCo's engineers have implemented many times. Item 2 is JSON merging into a backward-compatible structure (the CSF CP Registry is designed as a superset of the TOTSCo directory shape). Item 3 is a lookup table at the SforB boundary. Item 4 is configuration of an existing routing engine. Item 5 is endpoint provisioning that mirrors TOTSCo's existing per-partner dedicated-endpoint operating model. The items above introduce no new technology and no new operational paradigm — everything builds on infrastructure TOTSCo already runs every day for OTS and the existing SforB hub. Once commissioned, the recurring operational cost of HMAP participation is approximately the same as TOTSCo's existing hub-operator cost.

The remainder of this guide breaks the work into a five-phase plan, defines the test gates between phases, sets out the operational-commissioning checklist, and closes with the industry-level benefits the integration unlocks. **TOTSCo's engineering and programme-management teams own the effort sizing** against their own resourcing model — this guide describes the scope, not the schedule.

---

## 2. Strategic Context — Why TOTSCo should integrate

### 2.1 The collective industry benefit

UK business switching is being accelerated by the introduction of SforB. The industry's adoption rate depends on how easily Communications Providers (CPs) can participate. Today, MAPs and CPs can already exchange SforB traffic using the TOTSCo Hub. The Connected Services Framework (CSF), designed by the Telecom Technical Architecture Group (TAG), gives the industry **two additional complementary routes** into SforB on top of the existing TOTSCo Hub route:

- **Managed via a CSF MAP**: a CP subscribes to a CSF MAP and exchanges through that MAP's standard CSF outbound. The CSF supports multiple competing MAPs with commercial choice.
- **Self-served as a MAP-of-1**: a CP runs its own MAP infrastructure, exchanging messages directly with every other MAP on the CSF network.

These additional routes are intended to unlock **rapid SforB expansion**. Many smaller business CPs need to become compliant in a short window; offering them more than one route — without losing the existing TOTSCo Hub option — is the lever that makes industry-wide adoption practical.

By participating as an HMAP, **TOTSCo becomes a first-class peer** in this network — TOTSCo's subscribed SforB CPs can exchange messages with every CSF-side CP through a single TOTSCo connection, and CSF-side CPs can reach every TOTSCo-subscribed CP through their own MAP's standard CSF outbound. The industry as a whole sees an inflection: SforB can now scale not just by adding more TOTSCo subscribers, but by adding more *MAPs* — each of which carries one or more CPs.

> **Industry benefit**: SforB adoption accelerates because the framework removes the single biggest objection any new entrant has — *"do I have to commit to a long-term contract with a single hub operator before I can switch a single customer?"* The answer becomes *"no — you can onboard with a CSF MAP through a digital journey very quickly and exchange with the industry tomorrow, and renegotiate later if your needs change. A CP on the CSF can move to another MAP using the framework's built-in seamless migration process, become a MAP-of-1, or move to a MAP / operate as a CP on TOTSCo. This is about timing and choice, with the freedom to move as your business changes."*

### 2.2 TOTSCo's positioning

TOTSCo's existing role as the **Ofcom-mandated single platform for OTS** is unchanged by the CSF. OTS continues to operate as today — same hub, same RCPIDs, same processes, same commercial arrangements. **This integration touches the SforB side only.** It positions TOTSCo as a forward-looking industry participant who supports the open framework while continuing to deliver the regulated OTS service.

Four direct benefits to TOTSCo:

| Benefit | What it is |
|---|---|
| **Real-time outage and service-status view** | The CSF CP Registry carries every CSF MAP's `map/outage[]` array (ITIL-priority entries with start/end timestamps, affected services, escalation contacts) and `map/serviceStatusServiceURI`. TOTSCo collecting CSF registries automatically receives a real-time outage view of every CSF MAP — strictly richer than any static outage calendar. See [§5.4 Field Reference](../part2-implementation/05-directory-api.md#54-map-section--field-reference). |
| **Real-time CP-to-CP contact data** | Every CSF-side CP publishes a `contact[]` object (phone / email / ticketing URL with purpose tags, availability hours, and free-text notes — [§5.6](../part2-implementation/05-directory-api.md#56-cp-contact-object)). TOTSCo's existing support tooling can consume this with no additional parsing because the JSON structure is uniform across the industry. This **eliminates** the long-standing OTS pain point that the OTS CP-to-CP tool is not fit for SforB — without TOTSCo having to build a CP-to-CP tool itself. |
| **Bridge revenue and participation positioning** | TOTSCo remains the SforB hub for any CP who chooses the managed route. The CSF interoperability is a **value-add** for those CPs — they gain reachability to every CSF-side CP through their TOTSCo subscription. The framework is a *market-expansion* mechanism for TOTSCo, not a *market-share* threat. |
| **Industry standing as a forward-looking participant** | Being an HMAP on the open framework signals to the industry, to Ofcom, and to TOTSCo's own customers that TOTSCo is supporting industry transformation rather than blocking it. This is reputationally significant in the v2.0 publication cycle. |

### 2.3 OTS is unaffected

This guide describes the integration of TOTSCo's **SforB (GPLB) hub** with the CSF. TOTSCo carries both **OTS** and **GPLB (SforB)** traffic today; the CSF integration only touches the SforB side. OTS is **out of scope**:

- OTS is mandated by Ofcom to use TOTSCo as the single industry platform. The CSF makes no claim on OTS traffic.
- A CP that uses TOTSCo for OTS only is unaffected by the CSF — their TOTSCo subscription, RCPID allocation, and message flows continue as today.
- A CP that uses TOTSCo for both OTS and SforB can choose to move only their **SforB** traffic to a CSF MAP, MAP-of-1, or any future arrangement — OTS continues on TOTSCo. See [Part 1 §7.4.1](../part1-framework/07-onboarding.md#741-definition-and-scope) for the formal scope statement.

**TOTSCo's directory carries both networks side-by-side today.** The TOTSCo pre-production Directory v2 already combines RCPID, brand, and `processSupport[].status` entries for both OTS and GPLB in a single response. MAPs that want a single-process view filter by an `identity` query parameter:

```
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=all
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=ots
https://preprod.otshub.totsco.co.uk/directory/v2/entry?listType=RCPID&identity=gplb
```

We assume the same filter pattern will apply in production. The CSF's own Master Registry follows the same shape (process-tagged entries co-existing in one list), so TOTSCo's existing filtering logic carries forward unchanged.

Throughout this guide, every reference to "messages", "registries", and "RCPIDs" refers to the **SforB (GPLB)** transport only unless explicitly stated otherwise.

---

## 3. What stays the same

Before describing the changes, this section enumerates what TOTSCo does **not** need to change. The list is deliberately long to make clear how much of the integration is already done.

| Item | Why it stays the same |
|---|---|
| **JAM message envelope format** | CSF reuses the JAM Specification published by OTA2 (the same one TOTSCo uses today). Envelope fields, structure, validation — identical. |
| **OAuth 2.0 transport security** | CSF mandates the same client-credentials flow TOTSCo's CPs and MAPs already use. Same token endpoints, same scopes, same bearer-token semantics. |
| **TLS 1.3** | CSF mandates TLS 1.3 for all transport — same as TOTSCo Hub API v2.0. |
| **HTTP 202 acceptance** | CSF MAPs return HTTP 202 on successful acceptance of a message at the letterbox — identical to TOTSCo's existing behaviour. |
| **9xxx synchronous error codes** | CSF inherits the industry-standard 9xxx series for synchronous transport errors. TOTSCo's existing error handling carries over without change. |
| **TOTSCo Hub** | Operates unchanged. Same Hub API, same RCPIDs (4-character format, used by both OTS and GPLB/SforB today), same Hub-mediated routing. No CSF interaction for OTS. |
| **TOTSCo's existing MAP commercial relationships** | All OTS MAPs already connected to TOTSCo continue under their existing arrangements. The CSF integration does not require any of them to change anything on the TOTSCo side. |
| **TOTSCo's existing SforB CPs** | CPs subscribing to TOTSCo for SforB continue as today. Their RCPIDs do not change. Their messages still flow through the TOTSCo Hub. The CSF integration simply gives them *additional* reachability to CSF-side CPs through TOTSCo's HMAP role. |
| **TOTSCo's existing CP onboarding controls** | KYC, credit checks, VAT, ICO registration, fraud checks, contractual terms — all unchanged. The CSF does not impose any of its own due-diligence requirements on TOTSCo's CPs. |
| **TOTSCo's commercial pricing for SforB** | The CSF imposes no pricing constraints. TOTSCo's commercial offering remains TOTSCo's commercial decision. |
| **Ofcom regulatory reporting for OTS** | Unchanged. OTS regulation is unaffected. |
| **TOTSCo's existing message-routing infrastructure** | The CSF integration adds *additional* routing destinations (the CSF MAPs) without removing or modifying any existing routing logic. |
| **TOTSCo's CP-to-CP routing for its own subscribers** | Unchanged. The CSF only changes how TOTSCo reaches CSF-side CPs (and how CSF MAPs reach TOTSCo-side CPs). |

> **Reassurance summary**: The integration is **additive**. Nothing in the existing TOTSCo Hub setup is being changed or removed.

### 3.1 Side-by-side directory format — TOTSCo vs CSF

The CSF CP Registry was deliberately designed to **mirror the TOTSCo directory structure** so TOTSCo can consume it with its existing parser. The CSF adds a small number of optional fields (`signing[]`, expanded `resource[]`, `contact[]`, `outage[]`); TOTSCo may use them or ignore them — either choice is supported by the JSON contract and neither breaks existing code.

**TOTSCo format (today):**

```json
"list": [
    {
        "listType": "RCPID",
        "identity": [
            {
                "id": "RTLL",
                "name": "NowYoYo",
                "processSupport": [
                    {
                        "process": "OTS",
                        "status": "ACTIVE"
                    }
                ],
                "resource": [
                    {
                        "name": "salesAssistURL",
                        "type": "URL",
                        "value": "https://nowyoyo.com/ots/sales-assistance/"
                    },
                    {
                        "name": "customerAssistURL",
                        "type": "URL",
                        "value": "https://nowyoyo.com/ots/customer-assistance/"
                    }
                ]
            }
        ]
    }
]
```

**CSF format (superset — extra fields are additive, never breaking):**

```json
"list": [
    {
        "identity": [
            {
                "id": "c42569a5-d0ed-46f7-b9df-4ea0ba6a29c8",
                "name": "Red Company ISP",
                "processSupport": [
                    {
                        "process": "GPLB",
                        "status": "ACTIVE"
                    }
                ],
                "resource": [
                    {
                        "name": "customerAssistURL",
                        "type": "URL",
                        "value": "https://gplb.red-company.com/customerAssistURL.html"
                    }
                ],
                "signing": [
                    {
                        "domain": "gplb-test.nowyoyo.net",
                        "routingID": [
                            "businessSwitch.*"
                        ]
                    }
                ]
            }
        ]
    }
]
```

> **What this means for TOTSCo's parser**: identical top-level structure (`list[]/identity[]/processSupport[]/resource[]`). The `id` value is wider for CSF (UUIDv4 instead of 4-character) but both are valid `string` values under the JAM specification. The `signing[]` block is CSF-only; TOTSCo can ignore it without code changes. CSF MAPs publish the same `processSupport[].process` values (`OTS`, `GPLB`) that TOTSCo already uses, so process-based filtering is identical on both sides.

---

## 4. What needs to change

Five concrete deliverables. Each is small. Items 1–4 are mandatory; Item 5 (per-MAP dedicated endpoints) follows the same per-partner operating pattern TOTSCo already runs for every OTS and SforB partner.

> **Architectural commitment.** The CSF MAP-side HMAP interface presented to TOTSCo is **locked down**. Once a MAP and TOTSCo have agreed the interface contract, no CSF spec increment, feature release, or routing-group addition modifies it. TOTSCo's build below is a one-time integration, not an evergreen one. See §1 for the architectural commitment in full.

### 4.1 Item 1 — Directory API client

**What**: A small Directory API client that, on a polling schedule, retrieves each CSF MAP's CP Registry as a JSON document over HTTPS using OAuth 2.0.

**Why**: The CSF is decentralised; there is no central registry. Every CSF MAP publishes its own CP Registry containing the metadata for its own CPs and itself (contacts, status, signing keys, routing groups, sponsorship, outage). TOTSCo collects these into a private converged view ([§6.4 Directory Collection](../part2-implementation/06-totsco-integration.md#64-directory-collection)).

**How**:

- TOTSCo provisions OAuth 2.0 client credentials with each CSF MAP (the same way MAPs already provision credentials with TOTSCo).
- TOTSCo polls each MAP's Directory API endpoint (typical URL form: `https://api.{mapdomain}/directory`) using `GET` over HTTPS with a bearer token.
- Recommended polling frequency: 5 minutes (the CSF supports anything from 60 seconds upward — see [Part 2 §5](../part2-implementation/05-directory-api.md)). Hourly polling is acceptable for steady-state operations.
- Response is `application/json`; TOTSCo parses and stores.

> **Technical note**: This is a standard REST-over-OAuth pattern TOTSCo's engineers have implemented many times. No new libraries are required; any HTTP client + JSON parser will do. The initial CSF MAP set is anticipated to be **fewer than 10 MAPs** in the first 12 months, so the polling load is trivial.

### 4.2 Item 2 — Master Registry convergence

**What**: Merge the collected CSF CP Registries into TOTSCo's existing Master Registry, or maintain them as a parallel store keyed by RCPID.

**Why**: TOTSCo needs to know which CSF MAP serves each CSF-side CP so it can route SforB messages correctly. It also benefits from the contact, outage, and service-status data each CSF MAP publishes about itself (Section 2.2 benefits).

**How**:

- Each CP Registry has two main sections: `map` (the publishing MAP's metadata) and `list` (the CPs that MAP serves).
- For each CP, TOTSCo records: the CP's UUIDv4 RCPID, brand name, supported processes (`processSupport[]` — typically `GPLB` / SforB), the publishing MAP's name, the MAP's CSF letterbox URL, and the contact entries.
- For each MAP, TOTSCo records: name, status, contact entries, outage array, service-status URIs, routing groups, and connectivity endpoints.
- The CP Registry format is **deliberately backward-compatible with TOTSCo's existing OTS directory structure** — convergence is JSON-level merging, not transformation.

> **Best practice**: TOTSCo may choose to maintain the CSF MAPs and CPs as a logically separate "CSF zone" inside the Master Registry so that OTS operations remain unaffected by any CSF directory updates. The CP Registry schema supports this naturally — each CP's RCPID format (4-char OTS vs UUIDv4 CSF) is unambiguous.

### 4.3 Item 3 — RCPID translation

**What**: At the SforB-traffic boundary, translate RCPIDs between the CSF UUIDv4 format and the TOTSCo 4-character RCPID format.

**Why**: CSF MAPs send messages using UUIDv4 RCPIDs (per [Part 1 §8 RCPID Management](../part1-framework/08-rcpid-management.md)). TOTSCo's hub internally uses 4-character RCPIDs (e.g. `RTLL`, `BBBX`) for its own clients — the **same 4-character format is used by TOTSCo for both OTS and GPLB (SforB) today**, so this translation is no different from any OTS-style lookup TOTSCo already performs. Both formats are valid `source.identity` / `destination.identity` values under the JAM Specification (which allows strings up to 256 characters), so the translation is purely a Hub-side lookup, not an envelope rewrite.

**How** ([§6.5 RCPID Format Handling](../part2-implementation/06-totsco-integration.md#65-rcpid-format-handling)):

- For a CSF→TOTSCo flow: the inbound JAM envelope carries a UUIDv4 in `destination.identity`. TOTSCo looks up the UUIDv4 in its Master Registry, identifies that this is a TOTSCo-served CP, and routes the message to that CP using its existing internal mechanism. The 4-character RCPID is the TOTSCo-internal handle; the CSF MAP never sees it.
- For a TOTSCo→CSF flow: TOTSCo's own CP sends a SforB message with a 4-character `destination.identity` (the TOTSCo-internal RCPID of the destination CSF-side CP). TOTSCo translates this to the UUIDv4 RCPID before forwarding to the CSF MAP. The CSF MAP receives a standards-compliant UUIDv4 in its inbound message.
- The translation table is maintained by TOTSCo internally as part of Master Registry convergence (each CSF-side CP's UUIDv4 is paired with whatever 4-character handle TOTSCo allocates to that CP for its existing addressing).

> **Technical note**: The translation is **one-way visible** — TOTSCo's CPs see only the 4-character format they are already familiar with; CSF MAPs see only the UUIDv4 format. Each side speaks its own dialect; the Hub bridges. This pattern is identical to how email gateways translate between internal and external address representations.

### 4.4 Item 4 — Routing rules

**What**: Configure TOTSCo's existing message-routing layer so that outbound SforB messages with a CSF-side destination are routed to the correct CSF MAP's letterbox URL.

**Why**: TOTSCo's existing hub knows how to route messages between its own subscribed MAPs. The CSF integration adds new routing destinations: CSF MAPs that are not commercially subscribed to TOTSCo but are reachable through the standard CSF Directory API.

**How**:

- For each CSF MAP in the converged Master Registry, TOTSCo records the CSF letterbox URL (`map/connectivity/services[].url` for the service with `messaging` type and `GPLBMessages` routing group).
- When TOTSCo receives a SforB message destined for a CSF-side CP, the existing routing layer looks up the destination CP's MAP and posts the JAM envelope to that MAP's letterbox URL.
- The post uses OAuth 2.0 (with the credentials provisioned in Item 1) and TLS 1.3. The response is HTTP 202.

This item is largely configuration of TOTSCo's existing routing engine; no new routing technology is introduced.

### 4.5 Item 5 — Dedicated per-MAP CSF letterbox endpoints

**What**: Expose dedicated TOTSCo letterbox URLs for CSF MAPs to deliver SforB messages into the TOTSCo Hub — **one dedicated endpoint per CSF MAP**, mirroring the per-partner dedicated-endpoint pattern TOTSCo already operates for OTS and SforB partners today.

**Why** ([§6.3 Registering CSF Endpoints](../part2-implementation/06-totsco-integration.md#63-registering-csf-endpoints)): TOTSCo's standard operating pattern is to provision a dedicated endpoint for each CP and MAP on its network. When TOTSCo acts as an HMAP on the CSF, the same pattern applies: TOTSCo creates a dedicated endpoint per CSF MAP through which it routes messages to that MAP's CPs. This:

- Matches the **locked-down HMAP interface commitment** in §1 — each MAP has its own contract with TOTSCo and is unaffected by changes to any other MAP's interface.
- Lets TOTSCo iterate or retire one MAP's CSF relationship without touching the others.
- Keeps the OTS / direct-SforB inbound endpoints fully separated from the CSF inbound endpoints.

**How**:

- TOTSCo provisions a per-MAP HTTPS endpoint (e.g. `https://csf.totsco.org.uk/letterbox/<map-handle>`) backed by the same hub infrastructure.
- TOTSCo publishes each per-MAP URL to the corresponding CSF MAP via the standard onboarding handover documented in [§6.3](../part2-implementation/06-totsco-integration.md#63-registering-csf-endpoints).
- Each endpoint accepts the same JAM envelope, the same OAuth 2.0, the same TLS 1.3 — the only difference is the URL path.

This item is configuration only — DNS provisioning, TLS certificate issuance, and endpoint routing — no new code.

> **Why the per-MAP pattern matters**: HMAP endpoints are deliberately static. Each CSF MAP exposes a dedicated HMAP interface exclusively for TOTSCo (locked down, see §1), and TOTSCo reciprocates with a dedicated CSF inbound endpoint exclusively for that MAP. The two endpoints form a bilateral, contract-frozen pair. Changes elsewhere in the CSF — at other MAPs, in newly added routing groups, in envelope conventions — never reach the pair.

---

## 5. Step-by-step integration plan — 5 phases

The five phases below align with TOTSCo's typical large-programme delivery rhythm. Each phase has an entry criterion, an exit gate, and a clear set of deliverables. **TOTSCo's programme-management team owns the scheduling** — this guide describes the scope and the gates between phases, not the calendar duration.

### Phase 1 — Discovery and Planning

| Entry criterion | Exit gate |
|---|---|
| TOTSCo executive sign-off on the integration | TOTSCo engineering team has identified the CSF MAPs in scope for the first wave and has read access to their published CP Registries (or, before any MAPs are live, has read the CSF spec) |

**Activities**

- Read [Part 1 of the CSF](../part1-framework/01-introduction.md) and [Part 2 §5 Directory API](../part2-implementation/05-directory-api.md) and [Part 2 §6 TOTSCo Integration](../part2-implementation/06-totsco-integration.md). Read the [TOTSCo Hub API v2.0 specification](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) alongside, noting the JAM-envelope and OAuth-flow equivalence.
- Inventory the CSF MAPs in scope for the first wave (the framework anticipates < 10 MAPs in the first 12 months).
- Decide whether to maintain CSF MAPs / CPs in TOTSCo's existing Master Registry or in a parallel store (see §4.2 Best Practice).
- Confirm the per-MAP CSF letterbox URLs (Item 5) and obtain the necessary DNS / certificate provisioning lead time.
- Identify the operational contacts who will own the CSF integration once live (escalation, on-call, monitoring).

**Deliverables**

- Integration design document (one-pager: the five items above, the chosen registry model, named operational owners)
- TOTSCo internal RACI for the build
- Cost-and-effort estimate confirmed against this guide's §1 figures

### Phase 2 — Build

| Entry criterion | Exit gate |
|---|---|
| Phase 1 sign-off | Items 1–4 (and Item 5 if chosen) build-complete in TOTSCo's pre-production environment; unit and component tests passing |

**Activities**

- Build Item 1 (Directory API client).
- Build Item 2 (Master Registry convergence).
- Build Item 3 (RCPID translation).
- Build Item 4 (Routing rules).
- Configure Item 5 (per-MAP dedicated CSF letterbox URLs).
- Provision OAuth 2.0 client credentials with each in-scope CSF MAP.

**Deliverables**

- Items 1–5 in TOTSCo's pre-production environment
- Pre-production OAuth credentials with each in-scope CSF MAP
- Component test results
- Cut-over plan from pre-production to production

### Phase 3 — Test

| Entry criterion | Exit gate |
|---|---|
| Phase 2 sign-off | All §7 test patterns pass against at least two CSF MAPs; bilateral handshake confirmed with each |

**Activities**

- Run the test patterns in §7 of this guide against each in-scope CSF MAP:
  - Directory pull (Item 1)
  - Master Registry merge (Item 2)
  - RCPID translation round-trip (Item 3)
  - Outbound message routing (Item 4)
  - Inbound message receipt at the dedicated CSF letterbox URL (Item 5)
- Run the **bidirectional worked example** below to confirm end-to-end traffic in both directions.
- Confirm that all messages are marked with `auditData.test=true` while in test mode (per [§5 Test Traffic Flagging](../standalone/onboarding-testing-process.md#5-test-traffic-flagging-in-the-jam-envelope)).

#### Worked example — bidirectional SforB exchange via TOTSCo HMAP

This would normally be looked up in the MAP Registry; here it is shown inline so the test team can run the exchange end-to-end. The intent is to confirm that a TOTSCo-side CP (already established on the TOTSCo Hub) can exchange messages with a CSF-side CP, with TOTSCo acting as the HMAP between them. TOTSCo may instead use its own Virtual CP (VCP) if it prefers.

**TOTSCo Hub Transport** (TOTSCo-side CP, already live on the Hub today)

| Field | Value |
|---|---|
| Brand | NowYoYo |
| RCPID | `BBBX` |

This CP is managed by the NowYoYo MAP, which has an established connection with TOTSCo and can already send and receive messages within the TOTSCo Hub among `BBBX`, `BBBY`, and other locally-served brands.

**CSF Peer Transport** (CSF-side CP, behind a CSF MAP)

| Field | Value |
|---|---|
| Brand | Red Company |
| RCPID | `c42569a5-d0ed-46f7-b9df-4ea0ba6a29c8` (UUIDv4) |
| `oauthTokenURL` | `https://map.gplb-test.nowyoyo.net/csf/oauth2/token` |
| `url` | `https://map.gplb-test.nowyoyo.net/csf/B/letterbox/2.0/post` |

> **Credential setup**: TOTSCo will need credentials established in the normal way with the CSF MAP providing the Red Company endpoint — TLS 1.3 with OAuth 2.0 plus IP allowlisting.

**Test 1 — TOTSCo → CSF**: `BBBX` sends a `businessSwitchMatchRequest` to the TOTSCo Hub in the normal way, but with `destination.identity` set to the CSF-side CP. TOTSCo routes the message via the dedicated CSF letterbox endpoint to the receiving CSF MAP, which delivers it to Red Company.

**Test 2 — CSF → TOTSCo**: Red Company sends a `businessSwitchMatchRequest` from the CSF MAP via the dedicated HMAP interface to TOTSCo. TOTSCo then routes the message onto `BBBX` via the NowYoYo MAP using the connection already established for OTS/SforB.

The sequence diagram below shows both directions of the exchange:

```mermaid
sequenceDiagram
    autonumber
    participant BBBX as TOTSCo-side CP<br/>"NowYoYo" — RCPID BBBX
    participant TOTSCo as TOTSCo Hub<br/>(HMAP on CSF)
    participant CSFMAP as CSF MAP<br/>(Red Company's MAP)
    participant RED as CSF-side CP<br/>"Red Company"<br/>RCPID c42569a5…

    rect rgba(34,75,125,0.07)
    note over BBBX,RED: Test 1 — TOTSCo → CSF
    BBBX->>TOTSCo: businessSwitchMatchRequest<br/>dest = c42569a5… (UUIDv4)<br/>auditData.test = true
    TOTSCo->>TOTSCo: Lookup UUIDv4 → routing rule<br/>identifies CSF MAP letterbox
    TOTSCo->>CSFMAP: POST /csf/B/letterbox/2.0/post<br/>OAuth 2.0 / TLS 1.3
    CSFMAP-->>TOTSCo: HTTP 202
    CSFMAP->>RED: Deliver to Red Company
    RED->>CSFMAP: businessSwitchMatchResponse
    CSFMAP->>TOTSCo: POST response to TOTSCo dedicated letterbox
    TOTSCo->>BBBX: Deliver response on TOTSCo Hub
    end

    rect rgba(15,158,140,0.07)
    note over BBBX,RED: Test 2 — CSF → TOTSCo (reverse)
    RED->>CSFMAP: businessSwitchMatchRequest<br/>dest = BBBX (4-char)
    CSFMAP->>TOTSCo: POST to per-MAP dedicated<br/>CSF letterbox on TOTSCo
    TOTSCo-->>CSFMAP: HTTP 202
    TOTSCo->>BBBX: Route via NowYoYo MAP<br/>(existing TOTSCo connection)
    BBBX->>TOTSCo: businessSwitchMatchResponse
    TOTSCo->>CSFMAP: POST response to CSF MAP letterbox
    CSFMAP->>RED: Deliver to Red Company
    end
```

**Deliverables**

- Signed-off test report
- Confirmation from each in-scope CSF MAP that bilateral handshake is complete
- Any observed defects logged and triaged

### Phase 4 — Operational Commissioning

| Entry criterion | Exit gate |
|---|---|
| Phase 3 sign-off | TOTSCo is operationally ready to handle production CSF traffic; monitoring, alerting, on-call, and outage-feed integration all in place; the dedicated CSF letterbox URL is reachable from production CSF MAP IP ranges |

**Activities**

- *(Optional, value-add)* Wire the CSF MAPs' `map/outage[]` arrays into TOTSCo's existing operational dashboard so the operations team has a real-time view of CSF MAP service status. The `map/outage[]` array is **optional** in the CSF CP Registry — when populated by a CSF MAP it gives TOTSCo a free real-time outage feed that can materially reduce delivery-failure investigation time.
- *(Optional, value-add)* Wire the CSF MAPs' `map/serviceStatusServiceURI` into TOTSCo's existing monitoring stack. Also optional in the CSF schema; when present it provides a programmatic health probe per MAP.
- Set up alerting on inbound message receipt failures, OAuth token expiries, and Directory API pull failures.
- Document the production cutover plan (which CSF MAPs go live in which order; how to roll back if a defect is found in production).
- *(Recommended, not required)* Configure the regression suite to run quarterly against the live CSF MAPs (per [Onboarding & Testing Process §11](../standalone/onboarding-testing-process.md#11-regression-suite-for-ongoing-compliance)). Because the HMAP interface is locked down (§1), this is a periodic sanity check rather than a change-detection regimen.

**Deliverables**

- Operations runbook (alert thresholds, escalation, rollback procedure)
- Operational dashboard updated to include CSF MAP status
- Quarterly regression suite scheduled
- Go-live readiness sign-off

### Phase 5 — Production Operations (Ongoing)

| Entry criterion | Steady-state |
|---|---|
| Phase 4 sign-off | TOTSCo operates as an HMAP on the CSF in production; cutover messages flagged appropriately |

**Activities (steady state)**

- Operate the CSF inbound and outbound flows alongside the existing TOTSCo OTS and SforB flows.
- *(Optional)* Run the quarterly regression suite as a periodic sanity check.
- **No action required for CSF version increments** announced by the TAG. The locked-down per-MAP HMAP interface (§1) is intentionally insulated from CSF spec changes — envelope changes, new routing groups, and feature releases do not propagate through the dedicated TOTSCo endpoints. If a CSF MAP voluntarily chooses to expose a new interface in addition to the locked-down HMAP one, that is a bilateral conversation between that MAP and TOTSCo and only proceeds under TOTSCo's own change-control process.
- Report any incidents to the TAG via the standard TAG incident-coordination route.

**Deliverables**

- Operational HMAP service on the CSF
- Continued operation of the OTS hub and the SforB hub for TOTSCo's directly-subscribed CPs

---

## 6. Architecture sketch

The diagram below shows the end-state architecture. Note that the OTS Hub (top) is unaffected; the CSF integration adds the new flows shown at the bottom.

```mermaid
flowchart TB
    subgraph OTS["TOTSCo OTS Hub — UNCHANGED (Ofcom-mandated)"]
        OTS_CP[OTS-only CPs]
        OTS_Hub[OTS Hub<br/>Existing letterbox]
        OTS_CP <-->|OTS messages| OTS_Hub
    end

    subgraph TOTSCo_SforB["TOTSCo SforB Hub — extended for HMAP"]
        SforB_CP[TOTSCo-subscribed<br/>SforB CPs]
        SforB_Hub[SforB Hub<br/>Existing letterbox]
        CSF_LB[NEW: Per-MAP dedicated<br/>CSF letterbox URLs<br/>one per CSF MAP]
        SforB_CP <-->|SforB messages| SforB_Hub
        SforB_Hub <-->|Internal routing| CSF_LB
    end

    subgraph CSF["CSF — Distributed peer-to-peer"]
        MAP_A[CSF MAP A]
        MAP_B[CSF MAP B]
        MAP_1[MAP-of-1 CP]
        Directory[CP Registries<br/>published by each MAP]
        MAP_A --- Directory
        MAP_B --- Directory
        MAP_1 --- Directory
    end

    CSF_LB <-->|JAM over OAuth 2.0 + TLS 1.3| MAP_A
    CSF_LB <-->|JAM over OAuth 2.0 + TLS 1.3| MAP_B
    CSF_LB <-->|JAM over OAuth 2.0 + TLS 1.3| MAP_1

    Directory -.->|Periodic pull<br/>OAuth-secured| TOTSCo_Master[TOTSCo Master Registry<br/>NEW: CSF zone added]
    TOTSCo_Master -.->|Routing decisions| SforB_Hub
```

**Reading the diagram**:

- The OTS Hub (top box) is untouched.
- The SforB Hub gains new internal routes to a set of per-MAP dedicated CSF letterbox URLs (right-hand side of the SforB Hub box). Each CSF MAP has its own URL — the same per-partner pattern TOTSCo already uses for OTS and direct-SforB partners.
- The CSF (bottom) is the existing distributed peer-to-peer network of CSF MAPs and MAP-of-1 CPs, each publishing their own CP Registry.
- The dotted arrow on the bottom-right shows the periodic registry pull — the only outbound TOTSCo→CSF flow that does not carry JAM envelopes.
- The two-way arrows between the CSF letterbox URL and each CSF MAP are the actual SforB message exchanges, using the JAM envelope, OAuth 2.0, and TLS 1.3 already familiar to TOTSCo's infrastructure.

---

## 7. Testing — patterns and gates

This section gives the offshore team a copy-and-run-style test plan. The patterns assume the team has access to TOTSCo's pre-production environment and OAuth credentials with at least two in-scope CSF MAPs. The CSF transport-level tests in [Onboarding & Testing Process §8](../standalone/onboarding-testing-process.md#8-tag-baseline-test-suite) are the canonical reference; the subset below is what an HMAP integration needs.

### 7.1 Test T-01 — Directory pull (Item 1)

| | |
|---|---|
| **Purpose** | Confirm TOTSCo can authenticate with a CSF MAP's Directory API and retrieve its CP Registry as well-formed JSON. |
| **Steps** | (a) Request an OAuth 2.0 access token from the CSF MAP's token endpoint using TOTSCo's provisioned `client_id` / `client_secret`. (b) Use the bearer token to call `GET https://api.{mapdomain}/directory`. (c) Validate the response is `application/json` and parses into the expected `map` + `list` shape. |
| **Pass criteria** | HTTP 200, valid JSON, `map.name` present, `list[]/identity[]` array (may be empty in pre-production), no schema-validation errors. |
| **Fail handling** | HTTP 401 → re-check credentials. HTTP 403 → confirm IP allowlist. HTTP 404 → confirm endpoint URL. |

### 7.2 Test T-02 — Master Registry merge (Item 2)

| | |
|---|---|
| **Purpose** | Confirm TOTSCo's converged Master Registry correctly absorbs a new CSF MAP's CP entries without disturbing existing OTS / direct-SforB entries. |
| **Steps** | (a) Capture the Master Registry state before pulling the CSF MAP's CP Registry. (b) Pull the CSF MAP's CP Registry. (c) Re-capture state. (d) Diff. |
| **Pass criteria** | New entries appear in the CSF zone (or alongside, per chosen architecture). Existing OTS / direct-SforB entries unchanged. Conflict detection: a CSF MAP claiming an RCPID that TOTSCo already serves is logged and flagged for manual resolution. |

### 7.3 Test T-03 — RCPID translation round-trip (Item 3)

| | |
|---|---|
| **Purpose** | Confirm that translation between a CSF UUIDv4 RCPID and a TOTSCo 4-character RCPID is consistent in both directions. |
| **Steps** | (a) Pick a CSF-side CP with a UUIDv4 RCPID. (b) Translate to the TOTSCo-internal 4-character form. (c) Translate back. (d) Confirm round-trip equivalence. |
| **Pass criteria** | Round-trip returns the original UUIDv4. No collisions with existing TOTSCo OTS 4-character RCPIDs. |

### 7.4 Test T-04 — Outbound message routing (Item 4)

| | |
|---|---|
| **Purpose** | Confirm TOTSCo can deliver a SforB JAM message to a CSF MAP's letterbox and receive HTTP 202. |
| **Steps** | (a) Construct a `businessSwitchMatchRequest` with `auditData.test=true`, `source.identity` being a TOTSCo 4-character RCPID, `destination.identity` being a CSF UUIDv4 RCPID. (b) POST to the CSF MAP's letterbox URL with OAuth bearer token. |
| **Pass criteria** | HTTP 202, empty body, no errors. The receiving CSF MAP confirms receipt at the destination CP within its SLA. |
| **Fail handling** | HTTP 400 → check envelope shape. HTTP 401 → re-check OAuth. HTTP 403 → check destination CP `status=ACTIVE` and `processSupport[].status=ACTIVE` for GPLB. HTTP 9001 (synthetic) → check destination RCPID is in the registry. |

### 7.5 Test T-05 — Inbound message receipt (Item 5)

| | |
|---|---|
| **Purpose** | Confirm CSF MAPs can deliver a SforB message to TOTSCo's dedicated CSF letterbox URL with the expected envelope and credentials. |
| **Steps** | (a) Coordinate with a CSF MAP to send a `businessSwitchMatchRequest` to TOTSCo's dedicated CSF letterbox URL. (b) Confirm the message is received, parsed, translated (Item 3), and forwarded to the TOTSCo-side destination CP. |
| **Pass criteria** | HTTP 202 returned to the CSF MAP. Internal Hub queue records the message. Destination CP receives via TOTSCo's existing internal mechanism. |

### 7.6 Test T-06 — End-to-end SforB exchange (composite)

| | |
|---|---|
| **Purpose** | Confirm the full bidirectional flow operates end-to-end. |
| **Steps** | (a) TOTSCo-side CP sends a `businessSwitchMatchRequest` for a CSF-side CP. Confirm delivery and `businessSwitchMatchResponse` returns. (b) Reverse: a CSF-side CP sends a `businessSwitchMatchRequest` for a TOTSCo-side CP. Confirm delivery and response. (c) Confirm correlation IDs are preserved end-to-end. (d) Confirm `auditData.test=true` is preserved on every hop. |
| **Pass criteria** | Both directions complete within the published SLAs. Correlation IDs match across the round-trip. Test flag survives end-to-end through the HMAP bridge. |

### 7.7 Test gates for production cutover

A CSF MAP relationship goes to production only after T-01 through T-06 pass. The relationship is announced to the TAG by both TOTSCo and the CSF MAP for inclusion in the TAG's published bilateral-connectivity record.

---

## 8. Operational commissioning

### 8.1 Monitoring

TOTSCo's operations team should wire the following CSF-supplied data into the existing operational stack. The three CSF MAP-published fields below (`map/outage[]`, `map/serviceStatusServiceURI`, `map/contact[]`) are **optional in the CSF CP Registry schema**, but each is a useful value-add for TOTSCo when a MAP populates it.

| Source | Optional? | Use |
|---|---|---|
| `map/outage[]` from each CSF MAP's CP Registry | Optional (value-add) | Real-time outage view of every CSF MAP — fed into TOTSCo's operational dashboard; reduces delivery-failure investigation time |
| `map/serviceStatusServiceURI` from each CSF MAP | Optional (value-add) | Programmatic service-status checks; alert on red status |
| `map/contact[]` from each CSF MAP | Optional (value-add) | Escalation contacts for inter-MAP incident handling |
| HTTP error codes on TOTSCo's dedicated CSF letterbox URLs | Mandatory | Alert on rising 401 / 403 / 9xxx rates |
| OAuth token refresh failures | Mandatory | Alert; investigate |
| Directory API pull failures | Mandatory | Alert if persistent; CSF MAPs may have legitimate maintenance windows |

### 8.2 Availability target

The CSF mandates **99.95%** availability ("three nines and a five") — deliberately aligned with the TOTSCo Availability Target so industry SLAs remain consistent. TOTSCo's existing infrastructure already operates at this level for OTS; the CSF letterbox endpoint should inherit the same operational treatment.

### 8.3 Incident response coordination

When a CSF MAP raises an incident affecting traffic to / from TOTSCo:

- The CSF MAP records the incident in its `map/outage[]` array (priority P1 / P2 / P3, start time, affected services, description). TOTSCo sees this on the next Directory pull.
- TOTSCo's operations team uses the CSF MAP's `map/contact[]` escalation entries to coordinate directly.
- If the incident is security-related, the CSF mandates **24-hour vulnerability notification** and **72-hour breach notification** (per [Part 1 §10.6.5](../part1-framework/10-governance.md#1065-incident-response-coordination)). TOTSCo's operations team follows its existing incident-response process and notifies the TAG via the standard route.

### 8.4 Regression suite

Because the HMAP interface is locked down (§1), TOTSCo is **not obliged** to run the CSF regression suite on a fixed cadence. Two triggers are worth supporting:

- **Every internal TOTSCo release** that touches the CSF letterbox, Master Registry, or routing layer — this is a normal change-control regression and protects against TOTSCo-side drift.
- *(Recommended, optional)* **Quarterly** as a baseline conformance check. The HMAP interface itself is static, so this is a sanity check rather than a change-detection regimen. TOTSCo may choose any schedule that fits its release cycle, including skipping the check entirely.

The regression subset to run is documented in [Onboarding & Testing Process §11](../standalone/onboarding-testing-process.md#11-regression-suite-for-ongoing-compliance).

If a failure is observed, it is reported to the TAG within one working day. The TAG may, in consultation with the steering group, coordinate with TOTSCo to investigate.

### 8.5 Diagnostics

For incident diagnosis, TOTSCo has the following CSF-supplied diagnostic data available:

- The `auditData[]` array in the JAM envelope (correlation IDs, session metadata, test flag)
- The optional `X-CSF-ROUTE` HTTP header (records the route a message has taken through the CSF, useful for bridged messages)
- The structured 9xxx (industry) error codes in synchronous responses
- Per-MAP service-status URLs and operational contact details in the registry
- TOTSCo's own existing audit-log infrastructure carries forward unchanged

---

## 9. Why this is low-effort work

TOTSCo's engineering and programme-management teams own the effort estimate against TOTSCo's own resourcing model. This guide does not prescribe numbers; it describes the **scope** and the **reasons that scope is small**. Five observations support the low-effort framing:

| # | Observation | Why it lowers the effort |
|---|---|---|
| 1 | **Same JAM envelope, same OAuth 2.0, same TLS 1.3, same HTTP 202** as TOTSCo already uses | Zero new protocol work. Items 1, 4, 5 inherit existing TOTSCo capabilities. |
| 2 | **CP Registry schema is backward-compatible** with TOTSCo's existing OTS and SforB directory structure (the CSF was designed as a superset) | Item 2 is JSON-level merging, not transformation. |
| 3 | **Routing engine is TOTSCo's existing routing engine** | Item 4 is configuration; no new routing technology. |
| 4 | **RCPID translation is a lookup table** at the SforB boundary | Item 3 is a small persistence layer over the converged registry, not an algorithmic challenge. |
| 5 | **Monitoring, alerting and on-call infrastructure already exists** at TOTSCo for OTS and the existing SforB hub | Operational commissioning (Phase 4) is primarily configuration of additional inputs to existing dashboards. |

> **Ongoing operational cost**: approximately the same as TOTSCo's existing hub-operator cost. The CSF integration adds a small additional polling load (< 10 CSF MAPs anticipated in the first 12 months) and a small additional inbound traffic stream on the per-MAP dedicated CSF letterbox URLs.

> **No recurring CSF licensing fee.** The CSF framework is published as an open standard with no per-message, per-MAP, or per-CP charges. TOTSCo's commercial offering to its own subscribed CPs is unchanged.

The TAG is available to support TOTSCo's internal effort estimation if useful — including walkthroughs of the test patterns in §7, reference-implementation pointers, or clarifications of the CP Registry schema in §5 of [Part 2 §5 Directory API](../part2-implementation/05-directory-api.md). Outreach is via the standard TAG steering-group contact route.

---

## 10. Risks and mitigations

| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| TOTSCo's existing OTS infrastructure is impacted | Very Low | High | The CSF integration is operationally separated via the per-MAP dedicated letterbox URLs (Item 5) and the locked-down HMAP interface commitment (§1); OTS is out of scope ([§7.4.1](../part1-framework/07-onboarding.md#741-definition-and-scope)). Risk reduces to near zero with Item 5 in place. |
| RCPID collision (a CSF MAP claims an RCPID TOTSCo already serves) | Low | Medium | Conflict-detection logic in Item 2 (T-02 test). Master Registry merge logs and flags any conflict for manual resolution; the CSF conflict-resolution mechanism uses DNS as the tiebreaker ([§5.5 Conflict Resolution](../part1-framework/05-directory-and-registry.md)). |
| CSF MAP fails to publish a valid CP Registry | Low | Low | Directory pull failures alert TOTSCo's operations team (§8.1). The CSF mandates registry validity through its baseline-test suite; a non-compliant MAP would be flagged at onboarding. |
| OAuth credentials with a CSF MAP get out of sync | Low | Low | Standard OAuth token refresh and rotation. TOTSCo's existing OAuth-management infrastructure carries forward. |
| TOTSCo encounters a defect in the CSF spec during build | Low | Low | The TAG meets weekly; spec defects are triaged at the steering-group meeting. TOTSCo as an HMAP participant has standing to raise issues directly. |
| A CSF MAP withdraws or is removed mid-integration | Low | Low | The CSF carries built-in graceful degradation — a withdrawn MAP's CPs migrate via [CP Emergency Migration §8.2](../part2-implementation/08-commercial-scenarios.md#82-cp-emergency-migration). TOTSCo's CSF zone is updated automatically on the next Directory pull. |
| Future CSF spec versions impose additional obligations on TOTSCo | Very Low | Low | The HMAP interface presented to TOTSCo is **locked down** (§1) — CSF version increments do not propagate through the dedicated per-MAP endpoints. Even if a MAP voluntarily offers a new interface, TOTSCo opts in bilaterally, on its own timetable, through its existing change-control process. The CSF's broader version-adoption policy ([Part 1 §10.6.3](../part1-framework/10-governance.md#1063-version-adoption-policy)) still applies to MAPs that wish to migrate, but it is not an obligation on TOTSCo. |

---

## 11. Collective benefits for the industry

This integration is a meaningful inflection point for UK business switching. The benefits flow in three directions.

### 11.1 For TOTSCo

(Repeated from §2.2 for the management-summary reader.)

| Benefit | Concrete impact |
|---|---|
| Real-time outage and service-status view | Operational dashboard automatically populated from CSF MAPs |
| Real-time CP-to-CP contact data | Replaces the OTS CP-to-CP tool for SforB without TOTSCo building one |
| Continued SforB hub revenue | CPs who prefer the managed-MAP route remain on TOTSCo |
| Industry standing | Forward-looking participant in the open framework |

### 11.2 For TOTSCo's own subscribed CPs

| Benefit | Concrete impact |
|---|---|
| Wider counterparty reach | Every CSF-connected CP becomes addressable through the TOTSCo subscription, with no additional commercial work for the CP |
| Real-time contact data for CSF-side CPs | Replaces ad-hoc spreadsheets and out-of-band support routing for SforB |
| Future-protocol readiness | When the TAG adds new industry protocols to the CSF baseline (e.g. OTS Porting), TOTSCo CPs can adopt them via the TOTSCo HMAP role without additional bilateral integration |
| Continued use of existing TOTSCo tooling | Same JAM envelope, same OAuth 2.0, same TLS 1.3, same HTTP 202 — no change to CP-side code |

### 11.3 For the wider industry — SforB acceleration through MAPs

The CSF's MAP model is the **scaling mechanism** for SforB adoption. Before the CSF, every SforB participant had to negotiate a relationship with the centralised hub. After the CSF, the industry has three concurrent routes:

1. **Continued TOTSCo subscription** (the existing managed route)
2. **Subscription to a CSF MAP** (a different managed route, with commercial choice)
3. **MAP-of-1 self-service** (CPs operating their own MAP)

Each route accelerates adoption for a different segment of the industry:

- Tier-1 CPs already on TOTSCo continue without change. Adoption is preserved.
- Mid-tier CPs gain a commercial-choice route (multiple CSF MAPs competing for their business). Adoption widens.
- Technically-capable CPs (or specialist SforB operators) can self-serve via MAP-of-1. Adoption deepens.

**TOTSCo's HMAP role makes all three routes interoperable.** Without TOTSCo's HMAP participation, the framework would fragment into "TOTSCo CPs" and "CSF CPs". With TOTSCo's HMAP participation, the framework is a single industry network with multiple commercial models — exactly the outcome the SforB process aims for.

> **The industry-level argument**: SforB cannot accelerate without simultaneous expansion of all three routes. TOTSCo's HMAP integration is the single most significant unlock for that expansion. The integration is low-cost for TOTSCo (this guide is the evidence) and high-value for the industry. The framework is designed to make TOTSCo's continuing role *easier*, not harder.

---

## 12. Frequently Asked Questions — pointers

The most common questions from TOTSCo and from CPs are answered in two existing FAQ documents that this guide does not duplicate:

- **[FAQ — TOTSCo Integration](../standalone/totsco-faq.md)** — answers TOTSCo's own questions about impact, API modifications, RCPID handling, service levels, diagnostics. Read alongside this guide.
- **[FAQ — GPLB Steering Group](../standalone/sg-faq.md)** — answers the GPLB Steering Group's questions about RCPID assignment, multi-MAP CPs, directory mechanics, due diligence, test mode, and high-volume handling. Useful background for the integration design.

Both FAQs are companion reading. Where they overlap with this guide, the guide takes precedence as the more current and operationally-detailed view.

---

## 13. References

### CSF documents (this repository)

- [Part 1 §6 Security Overview](../part1-framework/06-security-overview.md) — OAuth 2.0 and DNS records per CP
- [Part 1 §8 RCPID Management](../part1-framework/08-rcpid-management.md) — UUIDv4 allocation, OTS/GPLB compatibility
- [Part 1 §10 Governance](../part1-framework/10-governance.md) — TAG, dispute resolution, incident response coordination
- [Part 2 §5 Directory API (CP Registry)](../part2-implementation/05-directory-api.md) — the JSON schema TOTSCo will consume (designed as a superset of the TOTSCo directory shape)
- [Part 2 §6 TOTSCo Integration](../part2-implementation/06-totsco-integration.md) — the framework-side view this guide is the TOTSCo-side companion to
- [Part 2 §8 Commercial Scenarios](../part2-implementation/08-commercial-scenarios.md) — CP Emergency Migration; covers the case where a CSF MAP withdraws mid-integration
- [Part 2 §10 FAQ — GPLB Steering Group](../standalone/sg-faq.md)
- [Part 2 §11 FAQ — TOTSCo Integration](../standalone/totsco-faq.md)
- [Onboarding & Testing Process](../standalone/onboarding-testing-process.md) — full TAG baseline test suite, status model, regression suite
- [Definitions](./definitions.md) — terminology including HMAP, MAP-of-1, KYC, bit pipe

### External documents

- [TOTSCo Hub API Specification v2.0 (April 2026)](https://totsco.org.uk/wp-content/uploads/2026/04/TOTSCo-API-specifications-v2-Clean.pdf) — TOTSCo's canonical transport specification. The integration described here uses the same JAM envelope, OAuth 2.0, and TLS 1.3 transport that v2.0 specifies; the CSF integration adds inbound and outbound JAM exchanges with new MAPs on the standard TOTSCo letterbox pattern.
- [JSON Asynchronous Messaging Specification (JAM)](https://www.offta.org.uk/) — published on the OTA2 website; the message envelope shared by OTS, SforB, and CSF
- [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) — OAuth 2.0 framework
- [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) — TLS 1.3

---

## 14. Document Control

| Version | Date | Description |
|---|---|---|
| 1.0 Draft | 2026-06-17 | First-draft TOTSCo HMAP Integration Guide. Companion to [Part 2 §6](../part2-implementation/06-totsco-integration.md). Author: TAG. For TOTSCo review. |
| 1.1 Draft | 2026-06-19 | TOTSCo-feedback revision. Added locked-down HMAP interface architectural commitment (§1, §4, §5). Reframed Item 5 as per-MAP dedicated endpoints matching TOTSCo's existing per-partner operating pattern. Added side-by-side TOTSCo vs CSF directory format comparison (§3.1) and OTS/GPLB filter URLs (§2.3). Removed all DKIM/PKI material (former Item 6, §4.6, §7.7, §9 row 5, references) — the HMAP interface is intentionally low-cost and TOTSCo will not use PKI. Replaced Phase 3 generic end-to-end test with the NowYoYo/BBBX ↔ Red Company worked example and a bidirectional Mermaid sequence diagram. Phase 5 rewritten to remove the "respond to CSF version increments" obligation. §8.1, §8.4, Phase 4 clarify that `map/outage[]`, `map/serviceStatusServiceURI`, `map/contact[]`, and quarterly regression cadence are optional value-adds. KYC defined inline and in `definitions.md`. §6.3 references relabelled to "Registering CSF Endpoints" throughout. |

---
