Responsible API operations
An OpenAPI document is not compatibility evidence
Test supported consumer intent across source, wire, HTTP, semantic, operational, and effect boundaries—not only the API description.
An OpenAPI document can describe paths, operations, parameters, security schemes, media types, and schemas in a machine-readable form. That makes it useful design and tooling input. It does not prove that deployed clients can construct the intended request, that intermediaries preserve it, that the server interprets old inputs the same way, that response behavior remains meaningful, that generated clients still compile, or that retries and durable effects remain safe.
This note develops an illustrative quote-pricing change, an API-compatibility contract, narrow evidence states, an authority map, a decision order, and failure-shaped tests. It is a proposed method, not production experience or evidence about a real API, client, customer, quote, price, deployment, incident, compatibility result, or business outcome. Generator, gateway, protocol, runtime, dependency, data, authorization, and recovery behavior remains system-specific.
Research boundary and source notes
Use these sources narrowly:
- The OpenAPI Specification defines a language for describing HTTP APIs. Version 3.1.1 defines an OpenAPI document and its paths, operations, parameters, request bodies, responses, media types, Schema Objects, security requirements, links, callbacks, and related structure. It also explicitly discusses undefined and implementation-defined behavior. This supports freezing the exact description, dialect, references, extensions, and tool interpretations used by a compatibility check. It does not prove that a deployed implementation matches the document, that all tools interpret every construct alike, or that old consumers preserve their intended behavior.
- Google AIP-180 separates kinds of backwards compatibility. It distinguishes source compatibility, wire compatibility, and semantic compatibility, and notes that compatibility depends on consumers and deployment constraints. This supports testing compile-time use, serialized communication, and meaning as different claims. It does not establish one universal versioning policy, deprecation window, language matrix, or safe migration procedure for every API.
- RFC 9110 defines HTTP semantics. It describes request methods, status codes, representations, content negotiation, conditions, and the relationship between a client's intention and the server's response. This supports testing method, target, headers, representation, status, and cache or intermediary behavior together rather than validating payload shape alone. It does not define the application-specific meaning of a quote, price, authorization rule, retry, or durable effect.
All three source URLs returned HTTPS 200 during research on 2026-08-16:
- OpenAPI Initiative, OpenAPI Specification 3.1.1
- Google API Improvement Proposals, AIP-180: Backwards compatibility
- RFC Editor, RFC 9110: HTTP Semantics
The deployed API implementation, source-language bindings, code generators, serializer settings, gateway rules, client behavior, authorization policy, data contracts, dependency contracts, observability, deprecation policy, and recovery procedures remain controlling. The contract, states, example, ordering rules, and tests below are Alfred's proposed method.
Core thesis
An API description records intended interface structure. Compatibility requires old and new consumers to preserve supported intentions across source code, wire representation, semantics, operation, and authoritative effects.
Keep these claims separate:
- Document parsed: one parser accepted one exact OpenAPI document under one declared version and reference context.
- Description valid: selected structural and semantic validators found no blocking issue under their own rules.
- Diff classified: one tool categorized declared interface changes under one rule set.
- Client generated: one generator emitted source for one language and configuration.
- Source compatible: supported consumer source still compiles or type-checks against the changed interface.
- Wire compatible: old and new peers can serialize, transport, parse, and preserve required values.
- HTTP compatible: methods, targets, headers, status codes, representations, negotiation, redirects, and cache behavior remain valid for the supported exchange.
- Semantic compatible: previously supported inputs and outputs retain the application meaning consumers are entitled to rely on.
- Authorization compatible: old and new identities can perform only the intended operations under current policy.
- Operational compatible: timeouts, pagination, rate limits, retries, ordering, idempotency, and concurrency remain inside the declared contract.
- Effect compatible: authoritative writes and external effects remain singular, attributable, queryable, and recoverable across mixed versions.
- Population covered: the tested clients, versions, languages, regions, routes, data states, and intermediaries match the declared support boundary.
- Rollout compatible: mixed-version traffic and effects satisfy the exact scoped release rule.
- Retirement eligible: unsupported shapes and behaviors no longer exist inside the declared ambiguity and recovery horizon.
A valid document, clean diff, generated SDK, passing mock, successful request, HTTP 200, or green provider test proves only one layer.
Work one API change through the hard case
Consider an illustrative quote endpoint:
operation = POST /quotes
old_request = {items, currency}
new_request = {items, currency, pricing_mode?}
old_response = {quote_id, total, expires_at}
new_response = {quote_id, total, expires_at, price_basis}
protected_intent = obtain one reusable quote for the submitted items and currency
supported_consumers = web-v4, mobile-v7, partner-sdk-v2
candidate_change = add optional pricing_mode with default behavior
These names and versions are placeholders. They do not refer to a real API, partner, client, quote, price, customer, release, or result.
The new OpenAPI document adds optional pricing_mode, adds required response field price_basis, and continues to describe a 200 response. A schema-aware diff might classify the request addition as non-breaking. A generated client might compile. Yet materially different failures can remain:
- the server treats absent
pricing_modeas a new pricing path rather than the prior behavior; - one generated client serializes the optional field as
null, while the server distinguishesnullfrom absent; - a strict old response decoder rejects the newly required
price_basisfield even though the wire format permits unknown fields in another client; - an enum gains a value that old generated code maps to an exception or impossible branch;
- a gateway strips a header that selects currency or tenant context;
- a redirect changes
POSThandling for one client or intermediary path; Content-Typeremains accepted while response content negotiation selects a representation the client cannot decode;- an old client relies on a documented
404, but the changed implementation returns200with an empty object; - pagination defaults change, causing an old collector to skip or duplicate items;
- a timeout occurs after quote creation and the old retry path creates a second durable quote;
- rate-limit semantics or retry hints change while the consumer still owns the same deadline;
- a compatibility mock returns examples rather than exercising the deployed serializer, gateway, authorization, data, and dependency path;
- a server accepts the request but rounds totals under a different rule, preserving shape while changing meaning;
- the description is updated before every serving region and dependency revision has converged;
- telemetry groups new and old operation identities together, hiding which contract version produced an effect.
A safer change freezes the supported consumer and behavior boundary before editing the document. It records absence, null, unknown fields, enum evolution, defaults, errors, ordering, pagination, retries, and effect identity explicitly; exercises generated and handwritten clients against real serializers and representative gateways; verifies old-server/new-client and new-server/old-client combinations where they can occur; reconciles authoritative effects; and preserves unsupported or uncertain cells as blockers rather than averaging a test matrix into “compatible.”
Define an API-compatibility contract
description_identity: exact OpenAPI bytes, version, dialect, references, extensions, and checksum
implementation_identity: exact server code, configuration, serializer, schema, and dependencies
operation_identity: stable operation name plus method and target template
supported_consumers: client families, versions, languages, generators, and handwritten integrations
support_policy: declared compatibility promise, exclusions, deprecation, and retirement horizon
request_contract: parameters, headers, media types, absence/null rules, defaults, and validation
response_contract: status families, headers, media types, schemas, errors, and partial results
semantic_contract: preserved intent, invariants, units, ordering, rounding, and terminal meaning
http_contract: methods, redirects, conditions, negotiation, caching, and intermediary assumptions
authorization_contract: principal classes, scopes, resource policy, and denial semantics
operational_contract: deadlines, pagination, limits, retries, idempotency, ordering, and concurrency
effect_contract: stable intent identity, authoritative destination, duplicate rule, and reconciliation
compatibility_matrix: old/new client, server, gateway, data, dependency, and region combinations
test_authorities: compiler, serializer, gateway, server, destination, and consumer observations
missing_data_rule: absent cells, unavailable clients, stale fixtures, and conflicting observations
rollout_rule: minimum coverage, stop conditions, mixed-version limits, and authorized action
privacy: minimized fixtures, payload handling, evidence access, and retention
terminal_outcomes: compatible_scoped, incompatible_scoped, blocked, conflicted, or unknown
Before changing the interface, answer:
- Which consumer intentions and observable meanings are promised to remain stable?
- Which consumer versions, source languages, generators, handwritten clients, and intermediaries are supported?
- Can old and new clients meet old and new servers during rollout, rollback, restore, replay, or delayed work?
- Which exact OpenAPI version, JSON Schema dialect, reference graph, extension semantics, and tooling configuration controls each check?
- How does each consumer treat absent, explicit
null, unknown fields, unknown enum values, duplicate keys, numeric bounds, and additional properties? - Which defaults are applied by the client, gateway, server, storage layer, or dependency, and can they disagree?
- Which status codes, error bodies, headers, redirects, conditional requests, media types, and negotiation outcomes are part of supported behavior?
- Which units, rounding rules, ordering guarantees, pagination rules, and partial-result semantics affect application meaning?
- Who owns retry, which operations are safe to repeat, and which stable identity binds attempts to one intent?
- Which authorization change could preserve shape while changing allowed or denied behavior?
- Which authoritative destination establishes whether a request produced no effect, one effect, duplicates, or an uncertain effect?
- Which gateway, cache, region, feature state, data shape, dependency, and network conditions belong in the compatibility matrix?
- What minimum coverage and current evidence is required before a rollout decision is eligible?
- Which severe semantic, authorization, corruption, or duplicate-effect result stops rollout immediately?
- How are stale fixtures, skipped cells, unsupported consumers, unavailable environments, and conflicting authorities reported?
- What evidence allows a field, behavior, endpoint, or compatibility shim to be retired safely?
Match evidence to its authority
| Authority | Observation | Narrow conclusion | Evidence still missing |
|---|---|---|---|
| OpenAPI parser and validator | Exact document and reference graph parse under declared settings | One description is accepted by those tools | Deployed behavior, consumer interpretation, and effects |
| Diff classifier | Exact old and new descriptions produce one change classification | One rule set labels declared structural changes | Undeclared behavior, tool blind spots, and runtime meaning |
| Compiler or type checker | Supported consumer source builds against exact generated or handwritten interfaces | Source compatibility exists for tested source and configuration | Wire, semantic, authorization, operational, and effect behavior |
| Serializer pair | Old and new peers preserve required values through encoded fixtures | Wire compatibility exists for tested representations | HTTP path, business meaning, gateway behavior, and effects |
| Gateway and HTTP probe | Method, target, headers, representation, status, redirect, and negotiation match the fixture | One transport path obeys the declared HTTP exchange | Consumer interpretation, other paths, and durable effects |
| Deployed server | Exact request reaches one implementation and returns one response | One runtime path accepted and answered | Whether meaning and authoritative effects satisfy intent |
| Consumer observation | A supported client interprets the response and reaches its expected local state | One consumer path preserves tested behavior | Other versions, conditions, destinations, and delayed effects |
| Destination authority | Stable intent identity maps to terminal authoritative effects | Effects are absent, singular, duplicate, failed, or uncertain for scope | Full client-visible convergence and broader coverage |
| Release authority | Current evidence satisfies one versioned rollout rule | One bounded action is authorized | Whether the action completes and wider scope remains compatible |
Conflicts remain visible. document_valid + old_client_rejects, wire_passed + meaning_changed, response_200 + effect_unknown, or diff_clean + gateway_behavior_changed cannot be collapsed into a compatible result.
Proposed compatibility states
- Intent frozen: supported consumers, meanings, combinations, effect rules, and decision boundaries are explicit.
- Description identified: exact OpenAPI bytes, dialect, references, extensions, and tool settings are known.
- Description invalid: one required parser or validator rejects the declared description.
- Description ambiguous: implementation-defined or tool-divergent behavior affects a required path.
- Diff classified: one exact rule set produced one structural classification.
- Source passed: one supported consumer source fixture compiles or type-checks.
- Source failed: a supported consumer cannot build or preserve its public call shape.
- Wire passed: values survive serialization and parsing for one exact peer pair and fixture set.
- Wire failed: values are rejected, lost, coerced, or reinterpreted during encoding or parsing.
- HTTP passed: one exact method, target, representation, status, header, and intermediary path behaves as declared.
- HTTP failed: transport semantics or negotiation violates the supported exchange.
- Semantic passed: one supported intention preserves declared meaning and invariants.
- Semantic failed: shape survives while units, defaults, status meaning, ordering, rounding, or outcome changes.
- Authorization drifted: allowed or denied behavior differs outside the declared policy change.
- Operational drifted: timeout, retry, pagination, limit, ordering, or concurrency behavior leaves the contract.
- Effects pending: the request returned while required authoritative effects remain immature.
- Effects conflicted: client, server, ledger, or destination observations disagree.
- Effects reconciled: stable intent identities have known terminal destination states through the horizon.
- Coverage partial: one required client, version, language, gateway, region, data shape, or failure path is absent.
- Fixture stale: generated artifacts, examples, mocks, data, or dependencies no longer match the decision identity.
- Mixed-version blocked: old/new combinations cannot coexist safely for rollout or rollback.
- Compatible scoped: required source, wire, HTTP, semantic, authorization, operational, and effect evidence agrees for exact scope and horizon.
- Incompatible scoped: one supported cell violates a declared compatibility requirement.
- Outcome unknown: required evidence was lost, invalidated, skipped without policy, or cannot be reconciled.
Do not collapse description valid, diff clean, source passed, wire passed, semantic passed, effects reconciled, and compatible scoped.
Proposed decision order
1. Freeze supported consumers, intentions, semantics, scope, horizon, and release authority.
2. Identify exact old and new descriptions, implementations, generators, serializers, gateways, and dependencies.
3. Inventory every old/new combination reachable during rollout, rollback, restore, replay, and delayed work.
4. Record absent/null, default, unknown-field, enum, numeric, and additional-property behavior per consumer.
5. Record methods, targets, headers, media types, statuses, errors, redirects, conditions, and cache assumptions.
6. Record units, rounding, ordering, pagination, partial-result, authorization, and deprecation semantics.
7. Define stable operation and intent identity, retry ownership, duplicate handling, and destination authority.
8. Version the OpenAPI parser, validator, resolver, diff policy, generator, and tool configuration.
9. Generate or refresh privacy-safe request, response, error, and effect fixtures from declared cases.
10. Compile or type-check supported source fixtures; preserve each failure by consumer identity.
11. Exercise serializer pairs for old/new peers, including unknown, absent, null, boundary, and malformed values.
12. Exercise HTTP exchanges through representative gateways and intermediaries, not only in-process mocks.
13. Assert application invariants and consumer-visible meaning, not only response shape and status.
14. Exercise timeout, retry, pagination, concurrency, authorization, rate-limit, and partial-failure paths.
15. Reconcile authoritative effects by stable intent identity through the declared maturity horizon.
16. Preserve skipped, stale, partial, unsupported, and conflicting cells as explicit decision states.
17. Start the smallest mixed-version exposure allowed by the compatibility and recovery contract.
18. Re-establish document, implementation, route, population, semantic, and effect identity during rollout.
19. Retire old behavior only after supported consumers and delayed work leave the declared ambiguity horizon.
20. Report exact versions, tools, matrix cells, exclusions, conflicts, horizon, and terminal outcome.
Failure-shaped test matrix
| Failure-shaped test | Expected result | Advancement rule |
|---|---|---|
| The new optional request field is absent, but the server applies new behavior instead of the prior default. | semantic_failed |
Preserve old meaning for absence or version the behavior explicitly. |
One generated client sends null while another omits the field. |
wire_failed or semantic_failed by client |
Test both representations against the declared absence/null contract. |
| A response enum adds a value and an old client throws on decode. | wire_failed for that consumer |
Do not infer tolerance from the schema format; test generated runtime behavior. |
| The OpenAPI diff is clean, but the server changes cents to major currency units. | semantic_failed |
Assert units and invariants independently of structural diffing. |
| A gateway strips a required context header on one route. | HTTP_failed + coverage_scoped |
Test the representative intermediary path and reconcile affected effects. |
The server changes a declared 404 into 200 {}. |
semantic_failed |
Preserve status and error meaning or version the consumer contract. |
| New pagination defaults cause an old collector to miss one page. | operational_drifted |
Fixture-test cursor, ordering, limit, and completion behavior. |
| A timeout follows quote creation and an old client retries without stable intent identity. | effects_conflicted |
Block repetition until destination authority establishes a safe duplicate rule. |
| Old client/new server passes, but new client/old server sends an unsupported field during rollback. | mixed_version_blocked |
Test every reachable direction before exposure. |
| A mock passes while the deployed serializer rejects an unknown field. | fixture_stale or wire_failed |
Prefer exact deployed serializer evidence for the release decision. |
| A parser and generator disagree about an implementation-defined construct. | description_ambiguous |
Remove ambiguity or freeze and test one supported interpretation end to end. |
| Authorization tightens for one principal without an explicit policy migration. | authorization_drifted |
Treat permission semantics as compatibility evidence, not incidental runtime behavior. |
| One required mobile version has no current fixture or executable environment. | coverage_partial |
Hold or explicitly end support under the controlling policy; do not mark the cell passed. |
A 200 response arrives while the destination has no terminal quote record. |
effects_pending or effects_conflicted |
Wait for and reconcile the authoritative effect horizon. |
| Telemetry merges old and new operation revisions. | outcome_unknown |
Restore release and operation identity before making a rollout claim. |
| A direct personal identifier appears in a captured request fixture. | evidence_policy_failed |
Minimize or synthesize the fixture and rebuild authorized evidence. |
The server selects a new response media type when the old client sends a broad Accept value. |
HTTP_failed or wire_failed |
Test negotiation with exact client headers and decoders; broad acceptance is not proof of usable representation. |
A conditional update starts ignoring If-Match and overwrites a newer quote revision. |
HTTP_failed + semantic_failed |
Preserve precondition semantics and authoritative revision evidence before allowing the write path. |
| A redirect changes the effective method or drops an authorization or idempotency header. | HTTP_failed |
Exercise the exact client, redirect status, intermediary, and destination rather than assuming redirect equivalence. |
| A decimal total survives JSON parsing but loses required precision in one generated numeric type. | wire_failed + semantic_failed |
Assert exact units, bounds, scale, and rounding through the supported runtime pair. |
| A new response property is legal on the wire but an old strict decoder rejects unknown fields. | wire_failed for that consumer |
Run the old decoder; do not infer runtime tolerance from the description alone. |
| The response body keeps its schema while one documented error code changes retry meaning. | semantic_failed + operational_drifted |
Test status, error identity, retryability, and terminal meaning as one consumer contract. |
Read one compatibility claim as a timeline
Compatibility evidence is easier to audit when each observation keeps its time, identity, and authority. One synthetic sequence for the quote endpoint might look like this:
| Time | Observation | Narrow state and decision |
|---|---|---|
| 09:00 | The release authority freezes the old and new descriptions, implementations, gateway route, web-v4 fixture, protected quote intent, stable intent-key rule, and effect horizon. |
intent_frozen; no compatibility result exists yet. |
| 09:04 | The exact new description parses, the configured diff labels pricing_mode non-breaking, and a generated web-v4 fixture compiles. |
description_identified + diff_classified + source_passed; runtime and meaning remain unknown. |
| 09:08 | The old client omits pricing_mode; its request crosses the representative gateway and the new server returns 200 with a decodable body. |
wire_passed + HTTP_passed for one fixture; semantic and effect evidence remain open. |
| 09:09 | The client times out before it receives that body, while destination authority records one quote under stable intent Q-17. |
The first attempt has an authoritative effect, but the client-visible outcome is uncertain. |
| 09:10 | The old client's retry reuses Q-17; the new server returns the existing quote instead of creating another. |
Retry behavior is exercised, not yet fully reconciled through the horizon. |
| 09:14 | Destination authority maps both attempts to exactly one quote, with the old currency, item, rounding, and expiry invariants intact. The client decodes and presents the same reusable quote. | semantic_passed + effects_reconciled for this cell and horizon. |
| 09:17 | A required partner fixture sends explicit null, which the new server interprets differently from absence. |
semantic_failed + coverage_partial; the release cannot inherit the earlier cell's pass. |
| 09:20 | The discrepancy is preserved by consumer, representation, route, and implementation identity. | incompatible_scoped; hold the mixed-version rollout rather than averaging cells. |
The identifiers, times, versions, requests, responses, totals, and outcomes are illustrative. They show decision ordering, not a tested server or a default waiting period. A real system must derive supported cells, stable intent identity, semantic invariants, effect authority, and maturity horizon from its own contract and risk.
Keep each compatibility decision attached to its evidence
| Decision layer | Minimum useful evidence | What does not establish it |
|---|---|---|
| Source | Supported consumer source builds or type-checks against exact interfaces and configuration. | A schema parser accepting the document. |
| Wire | Exact peer pairs preserve required values, absence, null, unknown-field, enum, bound, and precision behavior. | Source compilation or example JSON alone. |
| HTTP | Representative method, target, headers, media types, statuses, conditions, redirects, caching, and intermediaries behave as promised. | In-process serializer success. |
| Semantic | Supported intentions preserve units, defaults, invariants, ordering, error meaning, and terminal interpretation. | Matching shape and 2xx status. |
| Authorization | Principal classes remain allowed or denied exactly under the declared policy migration. | Authentication success or schema validity. |
| Operational | Deadlines, limits, pagination, retries, idempotency, concurrency, and rate-limit behavior stay in contract. | One successful request. |
| Effect | Stable intent identities reconcile to absent, singular, duplicate, failed, or uncertain authoritative outcomes. | A response or server log without destination evidence. |
| Rollout | Every required reachable old/new cell passes the versioned rule with current identities and recovery evidence. | One client/server pair passing. |
| Retirement | Supported consumers and delayed work have left the declared compatibility, ambiguity, and recovery horizons. | Low observed traffic or elapsed deprecation time by itself. |
These layers can disagree without contradiction. A change can be source-compatible and wire-incompatible, wire-compatible and semantically incompatible, or semantically correct for one direct route while operationally unsafe through retries. Keep the disagreement; it identifies the authority or matrix cell that needs work.
Use examples and mocks for the question they can answer
Examples are useful for design review, documentation, fixture seeding, and explaining expected cases. Mocks are useful for deterministic consumer tests, rare error paths, and work that should not depend on a live service. Generated clients expose source and runtime assumptions that a hand-written request may miss. None should be dismissed merely because it is not the deployed path.
The problem is identity drift. An example can outlive the schema revision that shaped it. A mock can encode a status, default, header, or response ordering that the current server no longer emits. Generated source can be stale relative to generator version, templates, language runtime, serializer options, or the checked-in description. A contract test can bypass the gateway that changes headers, media negotiation, redirects, or caching. A provider test can exercise one implementation while release traffic reaches another configuration or dependency set.
Record the description checksum, reference graph, tool and template versions, generated artifact checksum, implementation and configuration identity, fixture origin, and route each observation used. Rebuild or invalidate evidence when a controlling identity changes. Preserve hand-written examples and mocks as narrow design and consumer evidence, but do not silently promote their result to deployed semantic or effect compatibility.
Give evidence separate retention and invalidation clocks
- Source horizon: preserve privacy-safe consumer source fixtures, generated-interface identity, compiler or type-checker version, generator inputs, and build result long enough to support the declared consumer and deprecation policy. Invalidate the result when the description, generator, template, language runtime, public call shape, or supported consumer revision changes.
- Wire horizon: preserve minimized encoded fixtures, serializer and parser identity, peer pair, edge cases, and results through the mixed-version and replay window. Invalidate on representation, dialect, serializer option, numeric type, unknown-field policy, or peer revision change.
- HTTP horizon: preserve the smallest useful traces or derived assertions for method, target, headers, media type, status, conditions, redirects, cache behavior, gateway, and route identity through rollout and recovery. Invalidate on intermediary, route, protocol, negotiation, authentication, or cache-policy change.
- Semantic horizon: preserve versioned invariants, units, defaults, ordering, errors, fixtures, and consumer-observed terminal meaning while that behavior is promised. Invalidate when business rules, data contracts, authorization semantics, dependency meaning, or support policy changes—even if the schema bytes do not.
- Effect horizon: preserve minimized stable intent references and authoritative terminal states through the longest supported timeout, retry, queue, replay, cancellation, reconciliation, and dispute window. Invalidate any aggregate that loses operation, destination, or implementation identity; do not shorten this horizon because a response arrived.
- Decision horizon: preserve matrix coverage, exclusions, conflicts, rule revision, authority, and selected action long enough to explain rollout and retirement. Re-evaluate when population, client support, implementation, gateway, data, dependency, recovery path, or release authority changes.
Retention does not authorize storing direct identifiers or full payloads. Use synthetic or minimized fixtures where they answer the test, separate access by purpose, and follow the controlling privacy and deletion policy. If required evidence is deleted, corrupted, or detached from identity, narrow the later claim or return outcome_unknown rather than reconstructing certainty.
A compact API-compatibility evidence card
Return evidence-shaped compatibility outcomes
| Result | Meaning | Required handling |
|---|---|---|
compatibility_blocked |
The supported intention, population, identity, authority, matrix, effect rule, or recovery boundary is missing before testing or rollout. | Name the missing prerequisite; do not use document validity as permission to proceed. |
compatible_scoped |
Every required evidence layer agrees for exact consumers, versions, routes, data states, dependencies, conditions, and horizon. | Report the scope and exclusions; a new population or revision needs a new decision. |
incompatible_scoped |
At least one supported matrix cell violates a frozen source, wire, HTTP, semantic, authorization, operational, or effect requirement. | Hold the affected action and preserve the failing cell rather than averaging it away. |
coverage_partial |
A required consumer, direction, representation, route, region, data state, dependency, or failure path was not tested. | Fill the cell or formally change support under the controlling policy; do not call it passed. |
evidence_conflicted |
Trusted description, tool, client, server, intermediary, consumer, or destination observations disagree. | Retain each observation and reconcile the disputed fact at its controlling authority. |
mixed_version_blocked |
A combination reachable during rollout, rollback, restore, replay, or delayed work cannot preserve the contract. | Prevent that combination or add a tested compatibility bridge before exposure. |
effects_pending |
Client or server evidence exists, but authoritative effects have not reached the declared maturity horizon. | Wait and reconcile by stable intent identity; do not repeat uncertain work blindly. |
retirement_blocked |
Old behavior, consumers, records, messages, retries, or recovery work may still exist inside the support or ambiguity horizon. | Keep the compatibility path or migrate under an explicit, verified plan. |
outcome_unknown |
Required evidence was lost, stale, invalidated, skipped without policy, or cannot be reconciled. | Preserve uncertainty and choose the safest authorized action; absence is not compatibility. |
Outcomes can coexist across layers: source_passed + wire_failed, HTTP_passed + semantic_failed, compatible_scoped + coverage_partial for a wider requested population, or rollout_blocked + effects_pending. A later result supersedes an earlier one only when description, implementation, consumer, route, data, dependency, scope, rule, and horizon identities align.
Compact mixed-version compatibility checklist
Use this before exposure and repeat the applicable checks when any controlling identity changes:
- Freeze the protected consumer intentions, semantic invariants, supported consumers, exclusions, deprecation promise, and recovery horizon.
- Identify exact old and new descriptions, dialects, references, extensions, implementations, configurations, schemas, dependencies, and checksums.
- Inventory every client, server, gateway, worker, data, dependency, region, rollback, replay, and delayed-work combination that can actually meet.
- Version parsers, validators, resolvers, diff rules, generators, templates, language runtimes, serializers, and mock or fixture origins.
- Test source fixtures for every supported generated and hand-written consumer; preserve failures by exact identity.
- Test absence, explicit
null, unknown fields, unknown enum values, bounds, precision, duplicate keys, defaults, and additional properties through real peer pairs. - Test methods, targets, headers, media types, negotiation, status and error meaning, conditions, redirects, authentication context, and cache behavior through representative intermediaries.
- Assert units, rounding, ordering, pagination, partial results, defaults, authorization, and terminal consumer meaning independently of schema shape.
- Define deadline and retry ownership, stable intent identity, idempotency scope, duplicate handling, and authoritative effect reconciliation.
- Exercise timeouts before and after acceptance, retries, rate limits, concurrency, cancellation, queue delay, dependency failure, and partial completion.
- Verify old-client/new-server and new-client/old-server directions wherever rollout, rollback, restore, replay, or delayed work can create them.
- Keep examples, mocks, generated artifacts, deployed serializers, gateway probes, consumer observations, and destination records attached to their narrow authorities.
- Treat skipped, stale, ambiguous, unsupported, partial, and conflicting matrix cells as decision states rather than green results.
- Minimize fixtures and traces; exclude credentials, direct identifiers, private payloads, and evidence without authorized retention.
- Freeze minimum coverage, severe stop conditions, maturity horizon, decision rule, release authority, and safe recovery actions before exposure.
- Start only the smallest mixed-version exposure allowed by the contract, then re-establish implementation, route, population, and evidence identity.
- Reconcile client-visible outcomes and authoritative effects by stable intent identity before widening exposure or repeating uncertain work.
- Give source, wire, HTTP, semantic, effect, and decision evidence separate invalidation, access, and retention rules.
- Retire old fields, behaviors, endpoints, clients, or shims only after supported consumers and delayed work leave every declared horizon.
- Report exact tools, revisions, matrix cells, exclusions, conflicts, horizons, authorities, and typed outcome without turning a narrow pass into universal compatibility.
Working takeaway
Do not call a change compatible because its OpenAPI document parses, a diff is clean, an SDK generates, a mock passes, or one request returns 200. Freeze the supported intention and population, then test source, wire, HTTP, semantic, authorization, operational, and effect behavior across every reachable mixed-version cell. Keep each observation attached to its authority and horizon. Until the required cells agree, report the narrow state—coverage partial, wire failed, semantic failed, effects pending, mixed-version blocked, evidence conflicted, or outcome unknown—not “backwards compatible.”