docs(architecture): record the loud unsupported-feature matrix in http-adapters spec (review 001 OAI-06 + review 002)

The OAI-06 matrix lived only in the completed review-001 task notes;
acceptance for the review-002 loudness cluster requires the successor
doc section. New 'Loud unsupported-feature handling' section on
from_openapi: refused/warned/projected feature tables covering cookie
params, style/explode forms, servers, webhooks, callbacks, security,
oneOf requestBodies, unresolvable or content-less requestBody refs,
path-template validation, collision rejection, ref-sibling warns,
discriminator/xml warns, error-projection mappings, and the OAI-17
error-bounding contract.
This commit is contained in:
2026-08-31 01:47:30 +00:00
parent 903a91f1d2
commit 2d53957f08
+52
View File
@@ -118,6 +118,58 @@ pub enum HttpAuthScheme {
}
```
#### Loud unsupported-feature handling (the OAI-06 matrix, review 001/002)
Features of an imported OpenAPI document that the single-endpoint HTTP
adapter deliberately does not model are handled **loudly at import**
refused with a feature-naming `SchemaParse` error, projected with a
documented mapping, skipped with a `tracing::warn`, or (where semantics
are faithfully preserved) accepted silently. Nothing that would change
the wire contract may vanish silently. The matrix, as landed:
**Refused at import (import fails; the error names the feature, its
location, the remediation, and the review item):**
| Feature | Where checked | Note |
|---|---|---|
| `in: cookie` parameters | operation + path-item parse | OAI-03 |
| Non-default parameter `style`/`serialize` forms (`spaceDelimited`, `pipeDelimited`, `deepObject`, `matrix`, `label`, `form+explode:false`, `simple+explode:true`) | operation + path-item parse; wire-equivalent defaults (`form`, `simple`) accepted | OAI-06 |
| `servers` overrides (document/path/operation level) — single `base_url` per import | shared `from_value` parse | OAI-06 |
| `webhooks` (anywhere in the document) | shared `from_value` parse | OAI-13 |
| `callbacks` (document/operation level) | import gate (`validate_import_loud_features`), not the shared parse — the published gateway doc's own `security` markers must round-trip inside `to_openapi` | OAI-14 |
| OpenAPI `security` requirements (document/operation level) — credentials come only from `Capabilities` + the configured `auth` scheme | import gate | OAI-14 |
| Top-level `oneOf` requestBodies (no `content` map — the media-typed body contract is unrepresentable) | operation parse | OAI-14 |
| Unresolvable parameter/`requestBody` `$ref`s; a resolved `requestBody` that still carries a top-level `$ref` or lacks `content` (a body-less op would fail every call on the gateway `body` input) | operation parse | OAI-04/OAI-15 |
| Unterminated/empty path-template placeholders (`/x{open`) | shared `validate_path_template`, both `from_openapi` import and `from_jsonschema` construction | OAI-09, JS-02 |
| Duplicate operationIds or `(path, method)` routes in one import batch | `reject_collisions` | OAI-05 |
| A declared `in: header` parameter named `Authorization` when the namespace has an auth scheme; a header parameter colliding (case-insensitively) with a configured `default_headers` key or an ApiKey `header_name``build_request` inserts defaults and credentials after header params, so the peer value would silently lose | `check_header_param_collisions`, import time (the adapter's `HttpServiceConfig` is visible there) | OAI-19 |
**Warned (import proceeds; the divergence is visible in logs):**
| Feature | Behavior | Note |
|---|---|---|
| `$ref` sibling keys — 3.0 semantics apply (ignored); a 3.1-authored constraint beside a `$ref` would otherwise silently overstate `/schema` | `tracing::warn` naming the location and dropped keys; no `openapi: 3.1` version gate — the 3.0-only reading is the documented stance | OAI-10 |
| Path items declaring only unsupported methods (`trace`) | skipped; `tracing::warn` names the path and methods | OAI-06 |
| `discriminator` / `xml` keywords inside consumed schemas | per-operation `tracing::warn` listing the keys — the adapter forwards JSON only | OAI-14 |
| Response keys that are neither concrete statuses nor 2XX/4XX/5XX class wildcards | dropped from the imported error schemas; unmapped statuses surface as synthesized `HTTP_<actual>` at call time | OAI-06 |
| Path-item-level unknown keys on a method-bearing path (mirroring OAI-06's trace-skip warn) | warn | OAI-13 |
**Projected (documented, tested mapping):**
| Feature | Behavior | Note |
|---|---|---|
| Error response class wildcards `4XX` / `5XX` | projected onto the first legal concrete status in the implied range (`HTTP_400` / `HTTP_500`), carrying the wildcard's payload schema; `default` is dropped (no implied range, never advertised as `HTTP_0`) | OAI-13 |
| Success envelopes declared under any 2XX key, the `2XX` wildcard, or `default` | precedence: concrete 2XX → `2XX``default`; SSE detection and output-schema selection follow the winner | OAI-06, OAI-13 |
| Response keys that are neither concrete statuses nor supported wildcards | dropped with `tracing::warn` (see above) | OAI-06 |
**Documented divergence (both entry points, tested):** the YAML/JSON
parity contract lives in ADR-051 §5 (duplicate keys rejected on the
YAML path, non-finite floats and non-string keys rejected with JSON
pointers, merge keys applied) — import errors quote at most the first 8
items of any spec-derived list and truncate each item at 128 chars
(OAI-17), so a pathological document cannot produce a
multi-megabyte error message.
The adapter:
1. Parses the OpenAPI document (`OpenAPISpec``paths`, `components`,