practice

Pending Contract

also called Pending Pact, WIP Contract

A consumer expectation a provider has not yet satisfied, verified and reported without failing the provider's build, so the red light sits with the team whose change is not yet safe to ship.

contract-testingpactcideployment-gatecross-team

A consumer team adds an expectation to its contract for a feature the provider has not built. The provider's build goes red. The provider team, who changed nothing, now owns someone else's work in their pipeline, and within a quarter they propose deleting contract testing.

This is the single most common reason contract testing is abandoned, and it is a configuration problem rather than a flaw in the idea. A pending contract is verified and reported, and does not break the provider's build, because it was never something the provider claimed to support.

Why it matters

A deployment gate only survives if its red lights are actionable by the team that sees them. Failing a provider's build for a consumer's unimplemented wish inverts that, and the predictable response is to route around the gate.

The important asymmetry is that pending does not make the consumer deployable. Its can-i-deploy check still fails, because the provider genuinely cannot serve what it needs. The signal moves to the right team without being discarded, which is what distinguishes this from simply ignoring failures.

Implementation patterns

  • Enable the pending feature in provider verification (enablePending or the equivalent in your language binding) so only previously supported interactions can fail the build.
  • Use work-in-progress verification with branches. The provider verifies the consumer's feature-branch contract in pending mode and publishes the result, so the consumer gets feedback while the provider stays green. A contract stops being work-in-progress once the provider's main branch has verified it.
  • Gate deployment on can-i-deploy, scoped to the environment you are deploying into, so the question is "is this version compatible with what is actually running there" rather than "did the suite pass".
  • Verify selectively by deployed version once the matrix grows: with 12 consumers and 3 environments, naive verification is 36 runs and can add 10 to 20 minutes to a build.
  • Keep provider states as ordinary test fixtures in the provider's repository, so the investment survives a change of tooling.
  • Write the break-glass policy before you need it. The broker sits in every team's deployment path, and the first time it is unavailable somebody will ship without an answer.

Industry example

Pending pacts and work-in-progress pacts are documented features of the Pact broker, introduced in 2020 to address exactly this failure, and the project's own documentation is explicit that the mechanism does not make the consumer deployable. The underlying practice is older: consumer-driven contracts were described by Robinson in 2006, and the broker's contribution is the deployment gate rather than the test format. The distinction matters in interviews, because teams often adopt the test format and skip the gate, which leaves them with extra tests and no new guarantee.

Failure scenarios

  • Pending used as a mute button. If nobody watches the pending list, expectations accumulate for years and the contract stops describing anything real.
  • Provider states rotting. The provider's schema moves, the fixtures no longer represent reachable data, and verification passes against states that cannot occur in production.
  • A gate nobody honours. The first release waved through after a red can-i-deploy converts the mechanism into decoration.
  • Broker downtime blocking every deployment, with no documented override, so an availability problem in a test tool becomes a release freeze.
  • Mistaking contract tests for behaviour tests, which produces both a slow build and a false sense of safety, since a contract verifies message agreement and nothing about semantics, authorisation or performance.

Trade-offs

What the arrangement buys is independent deployment without a shared staging environment: a definite answer about compatibility with what is actually running, rather than with whatever happened to be deployed in staging that afternoon. What it costs is a verification matrix that grows with other teams' output, provider states as a permanent maintenance burden, and another service in the deployment path. Below roughly four or five consumer-provider pairs, a shared integration test and a conversation are cheaper, because the coordination the gate automates is coordination you can still do by talking.

When not to use it

For a provider with a single consumer in the same repository, the type system and a compile step already do this job, and the broker is pure overhead. For a public API with unknown consumers, contracts cannot be collected at all and the right tools are versioning, additive-only evolution and usage telemetry. And pending should never be the permanent state of a contract: if an expectation has been pending for two quarters, the honest conclusion is that the feature is not happening and the expectation should be deleted.

Interview question

Q: Your organisation adopted contract testing a year ago. Consumer teams like it, provider teams want it removed because their builds break for changes they did not make, and two releases last month went out despite a failing compatibility check. Diagnose the situation and tell me what you would change first.

What a strong answer covers: naming the pending-pacts misconfiguration as the cause of the provider complaint, and fixing it before arguing about value · distinguishing verification failure from deployability, and where each red light belongs · treating the ignored gate as the more serious problem, because a gate that does not stop deployments is worse than no gate · the matrix cost and selective verification · provider-state maintenance as the real ongoing expense · and the boundary of what contract testing proves.

Quick check

Quiz: A consumer's new expectation is pending on the provider. Can the consumer deploy? — No. can-i-deploy still fails, because the provider does not support the interaction; pending only protects the provider's build.

Flashcard: What does enabling pending pacts change about a provider's build? — It fails only for interactions the provider was already known to support, so a brand-new consumer expectation is reported rather than breaking the build.