Files
clean-architecture-backend-…/docs/adr/ADR-WEB-ADV-003-openapi-32-remains-experimental.md
T

56 lines
2.8 KiB
Markdown

# ADR-WEB-ADV-003: OpenAPI 3.2 is generated in parallel and stays experimental
- Status: Accepted
- Date: 2026-08-25
- Scope: `adapter:inbound:web``advanced.openapi`
## Context
Advanced Task 17 adds an OpenAPI 3.2 generation lane beside the Stable 3.1.2 snapshot.
Generating 3.2 is cheap. Adopting it is not, and the two get conflated because the generated
document looks fine. The value of an API description is entirely in what consumes it, and a document
in a version a client generator does not fully understand produces a client that compiles and is
wrong — which is worse than no document at all.
## Decision
**3.1.2 remains the release artifact.** `OpenApiVersionLane.STABLE_3_1.releaseArtifact()` is true and
`EXPERIMENTAL_3_2`'s is false. This is a property of the type, not a configuration setting.
**Generating 3.2 must not change the 3.1 snapshot.** Both are produced from the same model, so a
contributor that mutates it on the way to 3.2 changes the artifact that is actually shipped —
silently, and only when the experimental lane runs. `OpenApi32CompatibilityReport` compares the
snapshot hash before and after and makes a difference a promotion blocker.
**Four kinds of tool are checked separately.** A parser reports structural errors; a linter applies
style rules and accepts documents a parser rejects; a generator produces client code, and this is
where an unsupported construct surfaces — not as an error but as a method with the wrong signature;
a compile of that generated code is the only step that catches it. "OpenAPI 3.2 works" is not a
statement anybody can make. "This document is read correctly by these four tools at these versions"
is.
**Promotion requires an accepted ADR regardless of how green the matrix is.**
`promotionBlockers(false)` always contains that blocker. A machine-checkable matrix cannot decide
whether the consumer population is ready.
**Streaming description differences are reported separately.** They are the substantive difference
between the two versions for this application, and folding them into a pass/fail hides what
changed.
## Consequences
- The 3.2 document is published as an artifact of the experimental workflow, never of the release
workflow.
- A client generator that only understands 3.1 is unaffected, which is the point.
- Adopting 3.2 later is a documented decision with a named consumer matrix behind it.
## Alternatives considered
- **Switch to 3.2 and keep a 3.1 downgrade.** Rejected: the downgrade is lossy in exactly the
constructs 3.2 was wanted for, so it would ship a description that is wrong for both audiences.
- **Generate only 3.2 and let consumers cope.** Rejected: the failure mode is a generated client
that compiles and misbehaves.
- **Skip the client-compile step in the matrix.** Rejected: it is the only one that catches the
failure the others miss.