Why contracts matter
The most expensive failures in component-based systems happen at boundaries. A component calls another component “too early”, retries too aggressively, assumes a specific ordering of callbacks, or interprets an error code differently. These are behavioural mismatches. They often bypass ordinary type checking because the data shapes are correct while the interaction is not.
Behavioural contracts are a way to make these expectations explicit. A contract is not a single sentence; it is a structured description of behaviour. It can be written informally (a protocol sketch) or formally (a state machine, a process calculus model, a set of temporal properties). The key is that the contract is explicit enough to be reviewed and, ideally, checked.
Assume/guarantee framing
Assume/guarantee is a contract style that separates two sides of boundary behaviour:
- AssumptionsWhat the component expects from its environment (ordering, timing, available resources, error handling).
- GuaranteesWhat the component promises when the assumptions hold (safety properties, responses, progress conditions).
The compositional benefit is that you can reason locally: if each component’s assumptions are satisfied by its environment (the other components and the glue), then the component’s guarantees become available as facts about the composed system.
Diagram: contracts at boundaries
What “compatibility” means
Compatibility is the question “can these components be connected safely?”. In a contract view, compatibility means that the environment of each component satisfies its assumptions. Note that this is a global question: the environment includes other components plus the glue (coordination and scheduling).
This is why composition can fail even when each component is correct in isolation. Each component may have assumptions that are individually reasonable, but incompatible when combined. A contract makes this failure diagnosable: the mismatch appears as an unsatisfied assumption.
Key definitions
- ContractA structured description of boundary behaviour: interaction, constraints, and expected responses.
- AssumptionA condition the environment must satisfy for the component to behave as specified.
- GuaranteeA property the component ensures when its assumptions hold.
- CompositionA way of connecting components; composition changes the environment and can invalidate assumptions.
- RefinementAn implementation respects a specification by being more constrained (fewer behaviours) or by strengthening guarantees.
Common pitfalls
- Contracts that omit error behaviourThe “happy path” is not enough; error paths are where mismatches appear.
- Unstated ordering expectationsIf callbacks must be sequential or idempotent, say so explicitly.
- Mixing functional and behavioural claimsA correct output is not enough if the interaction violates constraints.
- Using the contract as marketingA contract is a checkable boundary artefact; if it cannot be tested, it will drift.
Internal links
- Projects: behavioural contractsProject-style view and reading path.
- BRiCoSA building-block perspective on composition.
- Research: component modelsWhy glue and coordination matter.