From 2d53957f08fbce3d22da2b9ac9e4401552c66464 Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Mon, 31 Aug 2026 01:47:30 +0000 Subject: [PATCH] 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. --- docs/architecture/http-adapters.md | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/docs/architecture/http-adapters.md b/docs/architecture/http-adapters.md index 648e43f..64198c0 100644 --- a/docs/architecture/http-adapters.md +++ b/docs/architecture/http-adapters.md @@ -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_` 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`,