A sound implementation does not ask users to refresh until it works. Each phase has an input, an output, a timeout, and a terminal state. Versions are not always ordered numbers. Peers exchange supported sets and constraints and choose by one shared algorithm.
An API contract includes units, defaults, idempotency, error classes, and version windows—not only field types. Clients distinguish retryable, user-action, and permanent outcomes to avoid duplicate side effects.
Define the system contract first
Start from facts the data and protocol can guarantee, then decide what the interface may promise. Each rule below needs an owner, a bound, and a compatibility policy rather than an oral convention from one review.
- Hello carries versions, features, required features, and limits; both bind the selected result to the session and feature layers read one immutable snapshot.
- Define success, degraded, cancelled, and failed terminal states before UI, storage, and metrics consume the same state.
- Retries need an idempotency key, backoff, and deadline; after the deadline create a new task instead of reviving old callbacks.
The delivery standard for Protocol Version Negotiation Before Declaring a Connection Usable is a usable normal path, convergent failures, bounded resources, and a state users can understand. The result is a production capability that can be explained, degraded safely, and rolled back—not a demo that works once.
What can break that contract
Prioritize faults that silently preserve false facts: the interface looks recovered while a queue, permission, or counter has diverged. The defect often appears only on the next action.
- Feature-specific guessing yields inconsistent support, while continuing on an unknown major can misparse cancel or permission messages as data.
- A boolean failure cannot distinguish retryable, user-action, and permanent refusal, producing an endless loop.
- User or task IDs in metric labels create high-cardinality cost and leak unnecessary identity into diagnostics.
How to test the contract line by line
Observe both endpoints, persisted records, and operational signals during verification. One button state or one successful response cannot prove the complete loop.
- Generate every current, previous, and unknown-future pair; selection must be symmetric, required failures clear, fallback hidden correctly, and negotiation single-shot.
- Run one hundred start, fail, retry, and cancel cycles; handles, listeners, queues, and temporary data must return to baseline.
- Cover direct, relayed, weak-network, background-tab, and mobile paths; do not rely on averages or one successful screenshot.
The result must be correct, recoverable, and explainable. If any part depends on refreshing the page or an engineer guessing, the protocol loop remains incomplete.