--- id: review-001-openapi-projection-fidelity name: to_openapi golden fidelity — runtime-truthful document (PRJ-01..PRJ-05, PRJ-11, PRJ-12, PRJ-14, PRJ-15) status: pending depends_on: [review-001-gateway-stream-errors, review-001-gateway-publish-semantics] scope: moderate risk: medium impact: component level: implementation tags: [adapters, review-001, to-openapi] --- ## Description Review 001 Part F: the `to_openapi` document describes responses the gateway does not emit. The runtime contract must be settled **before** this doc work — hence the gateway dependencies (per the review's sequencing note). Systematic diff of the projection against the runtime (routes tests are the oracle): - **PRJ-01/PRJ-02**: `/search` and `/schema` 200 responses are documented without the envelope wrapper (`{request_id, result, output}`) and with wrong item fields (`description` that doesn't exist; missing `namespace`/`op_type`/`visibility`/`access_control`/`channel_open`/ `publish_schema`). Clients generated from the doc are broken day one. - **PRJ-03**: documented 400 `INVALID_INPUT` vs runtime 422 (`error.rs:51`); axum extractor rejections are plain-text bodies with none of the documented `{code, message, retryable}` shape; no 422 in the doc at all. - **PRJ-04**: op errors declared at non-`HTTP_*` codes are projected under statuses the runtime never produces (`ErrorDefinition.http_status` is never consulted; `RATE_LIMITED` surfaces as 500). Either project honestly under 500 or honor `http_status` at runtime — with the review's note that `operation_errors_projected_onto_call` currently enshrines the wrong behavior. - **PRJ-05**: `/subscribe` documented statuses are structurally unreachable (always 200 + SSE per GW-12); in-band `event:error` frames undocumented. Document the 200+in-band-error contract. - **PRJ-11/HY-03**: remaining guarded `expect`s in `to_openapi` (`:440, :505, :512`) — replace with `if let` (convention). - **PRJ-12**: error dedupe iterates a `HashMap` → nondeterministic doc regeneration for identical registry state. Dedupe by `(code, status)` or sort. - **PRJ-14**: `schema_call_request()` inlined 4× and unused-in-practice `components.schemas` — use `$ref` or drop components so shape changes can't drift. - **PRJ-15**: `/search` documents 401/403 that cannot occur, omits the 404 that can; no `securitySchemes` anywhere despite Bearer being the contract (ADR-004). ## Acceptance Criteria - [ ] Generated-doc golden test asserted against hand-written expectations matching the routes tests' actual bodies (the review's gate for this unit) - [ ] `/subscribe` doc documents the 200 + `event:error` in-band contract (GW-12's asymmetry called out); `/search` statuses match reality - [ ] PRJ-04 decision landed (project-honest vs honor-`http_status`) and the enshrining test aligned - [ ] Deterministic doc generation (same registry → byte-identical doc, test) - [ ] `$ref`s in components or components removed; `expect`s replaced - [ ] `components.securitySchemes` declares the Bearer scheme - [ ] `cargo test` and `cargo clippy --all-targets -- -D warnings` pass ## References - docs/reviews/001-initial-implementation-review.md (Part F, PRJ-01..PRJ-05, PRJ-11, PRJ-12, PRJ-14, PRJ-15) - docs/architecture/decisions/042-openapi-gateway-pattern.md, 045-to-openapi-gateway-spec-versioning.md ## Notes > Agent fills during implementation. Sequenced after the gateway > tasks so the documented contract matches the settled runtime (review's > Unit 6 ordering). Bump `info.version` per ADR-045 if the gateway > description changes. ## Summary > Filled on completion.