# Bind external services deliberately

Keep a feature's requirements separate from credentials, tenant connections and provider behavior.

Source context: Source-guided
Source: https://github.com/lssm-tech/contractspec/blob/d58fa5b7de53a947811e5cc68346be028ce18528/packages/bundles/library/src/components/docs/architecture/ArchitectureIntegrationBindingPage.tsx

## Separate requirement, connection and binding

An application can describe the capability it needs without embedding a provider account in its contract. The integration model distinguishes a service definition, a tenant's configured connection and the application binding that selects a connection for a named slot.

This separation makes configuration review possible: you can ask what the product needs, which connection supplies it and where that connection may be used.

| Concept | Question it answers | Keep out of it |
| --- | --- | --- |
| Integration definition | What capabilities does this provider integration expose? | Tenant credentials |
| Tenant connection | Which account and environment are configured? | Unbounded permission inferred from an account name |
| Application binding | Which slot uses which connection? | An assumption that every workflow may use it |
| Host implementation | How is the actual effect executed? | Secrets in browser-visible configuration |

## Make the host responsibilities concrete

Choose how the host resolves credentials, checks the selected connection and supplies the provider client. Keep secrets behind references or server-side access paths. Derive tenant context from the trusted identity boundary rather than treating an incoming tenant identifier as authority.

A capability declaration does not establish that credentials are valid, quotas are configured or a remote service is reachable. Those checks belong to the selected implementation and environment.

## Progress from fixture to provider

Start with a fixture port to test the product behavior without external effects. Then run a provider-specific qualification in an appropriate test environment, including the relevant error, retry and duplicate-request cases.

Record which calls used real provider behavior. A deterministic local example can demonstrate your composition while leaving live service semantics untested.

## Review a provider change as a behavior change

When changing a provider, compare supported capabilities, result semantics, rate behavior, idempotency and operational evidence. An adapter that satisfies a TypeScript interface can still behave differently in ways users notice.

Keep the application contract stable where that is intentional, and make any changed behavior visible through versioning, tests and documentation. Portability is achieved through those explicit seams.

## Related examples

- [Draft freely. Send with approval.](https://lssm.co/examples/draft-and-send-agent/): Follow one contract boundary through a workflow and an in-memory MCP transport.

