From 7b83161171313c780945147811e59b9f9aa1d7ec Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sat, 29 Aug 2026 12:47:34 +0000 Subject: [PATCH] docs(tasks): review-001 openapi-projection-fidelity remediation complete --- .../review-001-openapi-projection-fidelity.md | 103 +++++++++++++++--- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/tasks/adapters/review-001-openapi-projection-fidelity.md b/tasks/adapters/review-001-openapi-projection-fidelity.md index e9c9e24..a4660d7 100644 --- a/tasks/adapters/review-001-openapi-projection-fidelity.md +++ b/tasks/adapters/review-001-openapi-projection-fidelity.md @@ -1,7 +1,7 @@ --- 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 +status: completed depends_on: [review-001-gateway-stream-errors, review-001-gateway-publish-semantics] scope: moderate risk: medium @@ -50,26 +50,103 @@ sequencing note). Systematic diff of the projection against the runtime ## 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 +- [x] Generated-doc golden test asserted against hand-written expectations matching the routes tests' actual bodies (the review's gate for this unit) +- [x] `/subscribe` doc documents the 200 + `event:error` in-band contract (GW-12's asymmetry called out); `/search` statuses match reality +- [x] PRJ-04 decision landed (project-honest vs honor-`http_status`) and the enshrining test aligned +- [x] Deterministic doc generation (same registry → byte-identical doc, test) +- [x] `$ref`s in components or components removed; `expect`s replaced +- [x] `components.securitySchemes` declares the Bearer scheme +- [x] `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 +- docs/architecture/decisions/023-operation-error-schemas.md (error fidelity) +- src/gateway/routes.rs tests (the runtime oracle), src/gateway/error.rs (the mapping) ## 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. +> Sequenced after the gateway tasks; the documented contract now +> matches the settled runtime (review's Unit 6 ordering). The two +> decisions that shaped the implementation: +> +> - **PRJ-03 (doc-align, no runtime change)**: the doc maps dispatch-path +> `INVALID_INPUT`/`INVALID_OPERATION_TYPE` to `422` (the shared +> mapper's real output) and documents the axum extractor-rejection gap +> explicitly on the `400` responses (`text/plain` body, marked as a +> known runtime gap). Closing the extractor gap is a runtime change on +> routes.rs — another surface — so the doc states what the runtime +> actually does. +> - **PRJ-04 (project-honest, no runtime change)**: registry-declared +> `http_status` is still projected in the doc (so the declared codes +> stay visible), but every projection whose codes are not +> `HTTP_`-prefixed carries `x-runtime-behavior: 500` plus an +> explicit description note — the runtime mapper is purely code-driven +> and `ErrorDefinition.http_status` is never consulted. The enshrining +> test was rewritten to assert the annotation instead of the old +> behavior. Honoring `http_status` at runtime would change +> routes.rs/error.rs (another agent's surface) and the ADR-023 +> semantics — rejected here. ## Summary -> Filled on completion. \ No newline at end of file +**What landed** (`src/adapters/to_openapi.rs` overhaul, plus a one-line +version assertion in `src/server/adapter.rs` tests): + +- **PRJ-01** — `/search` 200 now documents the envelope + (`{request_id, result, output}` with the `operations` array under + `output`) and the real item fields (`name`, `namespace`, `op_type`; + no `description`). The `description`-field lie is gone from both the + schema and the summary. +- **PRJ-02** — `/schema` 200 documents the envelope wrapping a full + `OperationSpecOutput` component (`op_type`, `visibility`, + `input_schema`, `output_schema`, `error_schemas`, `access_control`, + `channel_open`, `publish_schema`). +- **PRJ-03** — 422 (`CallErrorInvalidInput`/`CallErrorInvalidOperationType` + oneOf) replaces the bogus 400 INVALID_INPUT on dispatch paths; + `/call`//`/batch`//`/subscribe`/`/schema` 400s document the + plain-text extractor-rejection bodies with an explicit gap note; + `/batch` 400 also covers the 100-op `BatchCapExceeded` JSON shape. +- **PRJ-04** — decision: **project-honest with annotation** + (`x-runtime-behavior: 500`); see Notes. Enshrining test replaced by + `operation_errors_projected_onto_call_with_runtime_behavior_annotated`. +- **PRJ-05** — `/subscribe` documents exactly `200` (SSE) + `400` + (extractor). The 200 description spells out the GW-12 asymmetry: + pre-dispatch denials and handler failures arrive as terminal + `event:error` frames carrying the serialized `CallError`, with the + `retry: 15000` hint and 15 s keep-alive comment frames — no HTTP error + statuses are structurally reachable. +- **PRJ-11** — the last library-side `expect`s are gone; all emission + paths use infallible construction (`as_object_mut` guards are gone + with the deleted mutation-based merge machinery, replaced by + `struct`-built JSON). +- **PRJ-12** — `gather_operation_errors` folds registry iteration into + `BTreeMap`/`BTreeMap` before anything is emitted; status + keys and per-status code enums are sorted. `same_registry_yields_byte_identical_docs` + pins determinism; `error_codes_are_sorted_within_each_status_key` + pins the ordering. +- **PRJ-14** — request bodies (`/call`, `/batch` items, `/subscribe`) + reference `#/components/schemas/CallRequest`; the doc now defines + `components.schemas` (19 components) + `components.responses` + (6 shared error responses) and every endpoint's status map references + them. No inline duplication of the `CallRequest` shape remains. +- **PRJ-15** — `/search` drops the unreachable 401/403 and documents the + real set (200/404/500/504); `components.securitySchemes.bearerAuth` + (HTTP bearer, ADR-004) is declared and applied via top-level + `security` + per-operation overrides. +- **ADR-045** — `info.version` bumped `1.1.0` → **`1.2.0`** (minor): + the overhaul is additive at the shape level (newly documented + statuses/envelope fields; nothing previously documented was removed + or retyped into a break). The `server::adapter` integration test was + aligned to the new version. +- **Golden test** — 31 tests in `src/adapters/to_openapi.rs` assert the + generated doc against hand-written expectations mirroring the routes + tests' actual bodies (envelope shape, item fields, status sets, code + enums, security scheme, print-level determinism), and the full doc + re-validates via `openapiv3`. + +**Verification:** `cargo test` (288 passed, including the full-surface +integration tests), `cargo clippy --all-targets -- -D warnings` (clean), +`cargo fmt --check` (clean) — verified in a clean worktree at HEAD +because other agents' in-flight edits were present in the shared tree. \ No newline at end of file