# Contracts, handlers and adapters

Understand the separate responsibilities that let one operation serve several interfaces.

Source context: Source-guided
Source: https://github.com/lssm-tech/contractspec/blob/d58fa5b7de53a947811e5cc68346be028ce18528/packages/foundation/contracts-spec/src/operations/operation.ts

## The contract describes the behavior

An operation contract names a command or query and describes its data and requirements. The model includes metadata, input and output schemas, result definitions, policy, declared effects, transport hints and links to related presentations or tests.

A declaration is useful before it executes: another engineer can inspect its purpose and a tool can discover its shape. But an operation description is not a database implementation, and a policy field is not itself a trusted authorization decision.

## The handler performs the work

A handler is the application function bound to a registered operation. It reads or changes the resources your product owns and returns a result that the runtime can validate. It can use host-provided dependencies without putting those providers into the portable declaration.

Business invariants remain your responsibility. A valid input might still refer to an unavailable resource or request a transition the product does not allow. Model those outcomes deliberately and test them in the handler.

## The adapter translates an interface

Adapters connect transport-specific requests to the registry. REST handles HTTP input and responses; MCP registers tool shapes and returns tool results. They can call the same operation without having identical wire formats.

The host constructs the context behind those adapters. It establishes identity, binds policy and approval ports, and supplies persistence or provider implementations. Keeping that setup explicit is what lets the contract stay portable.

| Layer | Owns | Does not imply |
| --- | --- | --- |
| Contract | Meaning, shape and declared requirements | An implemented or authorized effect |
| Registry and runtime | Binding, common execution and result handling | A production identity system or database |
| Handler | Business implementation | Automatic correctness from its type |
| Adapter | HTTP, MCP or other interface projection | Identical transport semantics |
| Host | Trusted context and concrete dependencies | Authority from a browser-supplied role string |

## Follow a change through the layers

Suppose an export now requires a reason. The contract gains a required input field, callers must provide it, and the handler decides how that reason is used or recorded. Runtime validation can reject an old request shape, while a migration determines whether older consumers remain supported.

This makes a change easier to review: the declaration exposes the intended boundary, and the implementation diff shows the business consequence.

## Related examples

- [Write your first contract](https://lssm.co/examples/minimal-user-contract/): Follow user.create from an email schema to a typed handler. Start with the smallest maintained example.
- [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.

