# Connection Packs

> Source: https://openwop.dev/spec/v2/core/connection-packs.html · OpenWOP, the open-source protocol for multi-agent workflow orchestration. CC BY 4.0.

> **Status: Stable.**
> **Normative home:** `connections`.

## Why this exists

A connection pack is a signed provider definition — the endpoints, scope catalog, and reach a connector's `auth.provider` string resolves against. The manifest is `schemas/v2/connection-pack-manifest.schema.json`; installation and signing follow [packs.md](https://openwop.dev/spec/v2/core/packs.html).

## Provider identity

A `provider.id` MUST be unique per host. Built-in provider definitions are the host's own pack for every rule in this document.

| Situation | Host behavior |
| --- | --- |
| Exactly one definition of bare id `P` | `P` resolves to it |
| An installed pack and a built-in both define `P` | the later registration MUST be refused with `connection_provider_conflict` |
| Two installed packs both define `P` | the later registration MUST be refused with `connection_provider_conflict` |
| No definition of `P` | the dependent connector or pack MUST be refused with `connection_provider_unresolved` |

A host MUST NOT choose between two claimants by comparing versions.

## The qualified form

A connector MAY name a provider by its qualified form `<packName>#<id>`. A qualified reference resolves only to the named pack's definition. A bare id resolves only when exactly one definition exists on the host.

## Resolution

A host advertising `connections.packsSupported` MUST resolve a connector's `auth: { type: "oauth2", provider: P }` (and any `host.oauth` invocation for `P`) against the definition selected above, to obtain its endpoints and scope catalog.

- An unresolvable provider MUST be refused when the dependent connector or pack is registered.
- On a publish-path host, resolution MUST run after the idempotency short-circuit: a byte-identical re-publish of an installed pack MUST succeed even when resolution inputs have since changed.

## Observation

A host advertising `connections.providerRead` MUST serve two reads under `manifest:read` (`schemas/v2/connection-provider-registry.schema.json`). The registry is host-global and carries no tenant data.

- `GET /connection-providers` lists every definition, built-ins included, each bare id once, and the pack registrations refused under §Provider identity, with the code and, for a conflict, the holder.
- `GET /connection-providers/{providerId}` resolves one reference; `?pack=<packName>` is the qualified form. An unresolvable reference answers `404` `connection_provider_unresolved`.
- A row carries ids, pack names and codes only, never an endpoint, a scope catalog or credential material.
- Refusals MAY be recomputed at each start.

A host advertising `packsSupported` SHOULD advertise `providerRead`.

## Errors

Both codes are in `spec/v2/errors.json`: `connection_provider_conflict` (two claimants for one bare id) and `connection_provider_unresolved` (no definition for the referenced id).

*Sources: RFCs 0095, 0177, 0233.*
