- path-item-level `parameters` parse into PathItem and merge into every
operation's input schema; operation-level entries override shared
name+in duplicates (last-insert wins)
- success sweep accepts `2XX` after concrete 2XX keys and before
`default` (SSE detection + output schema; concrete outranks wildcard)
- `4XX`/`5XX` error keys project to their class representative status
(`HTTP_400`/`HTTP_500`) instead of dropping silently; `default`
still drops loudly (no implied range)
- top-level `webhooks` fails import naming the feature (inbound
callbacks are outside the single-endpoint outbound adapter model)
- unbound-placeholder error names the parameter-merge state so the
diagnosis no longer dead-ends
Verification: cargo test (174 lib tests), cargo fmt
- build_error_schemas: default/wildcard response keys dropped with a
warn instead of emitting a dead HTTP_0 ErrorDefinition — /search
never advertises a code that can't match (the runtime mapper already
synthesizes HTTP_<actual> for unmapped statuses)
- check_parameter_style: non-default style/explode parameter forms
(spaceDelimited, pipeDelimited, deepObject, form+explode:false,
simple+explode:true) fail import with a feature-naming SchemaParse;
wire-equivalent defaults (form, simple) import unchanged — no more
silent "[1,2]" array mis-serialization
- servers overrides rejected at import at all three levels (document,
path, operation) — the adapter pins one base_url at assembly time
- trace-only paths: skip is now logged (warn naming path + methods),
documented-as-inert instead of silent
- detect_op_type + build_output_schema sweep 2XX/default keys for
text/event-stream — a default-declared SSE stream classifies as Sub
instead of returning one giant text body
Tests: 11 new (error-drop, style rejections + default accept, servers
3-level rejections + baseline, trace skip, SSE default/2XX detection).
Verified: cargo test (299), --all-features (370 + suites), clippy
--all-targets -D warnings (default + all-features), fmt --check.
Tasks: review-001-openapi-loud-degradation
- build_request takes the op's input_schema and rejects undeclared
input keys (INVALID_INPUT) before any outbound request is built;
explicit `additionalProperties: true` opts into catch-all input;
non-object inputs rejected (OAI-02)
- in: header parameters are stamped `wire: header` in the generated
input schema and sent as upstream request headers, not query params;
in: cookie fails import with a clear error (OAI-03)
- a spec parameter named `body` is rejected at import unconditionally
(OAI-07)
- FromJsonSchema::new returns Result and validates method/path template/
base_url at construction; registered visibility forced to Internal
like from_openapi; module doc corrected (OAI-09)
Verified: cargo test, cargo test --all-features, clippy (both feature
sets, -D warnings), cargo fmt --check
- index components/parameters + requestBodies in OpenAPISpec; resolve
bare $ref parameter and requestBody entries through the cycle-guarded
resolver; unresolvable refs abort spec parse loudly
- reject path placeholders with no matching input-schema property at
registration (no more silently percent-encoded literal placeholders)
- reject duplicate operationIds and path+method routes in one import
batch instead of silent last-write-wins registration
- also reject a parameter named 'body' shadowed by requestBody (OAI-07
adjacency, same code path)
Verified: cargo test (243), --all-features (322), clippy -D warnings
(default + all-features), fmt --check, doc --no-deps
Replace per-chunk parse_sse_frames with SseParser holding raw bytes
across chunks: reassembles frames split at TCP boundaries (the review's
silently-losing case), decodes UTF-8 per complete line so multi-byte
chars split across chunks survive, caps the buffer at 1 MiB
(SSE_EVENT_BUFFER_CAP) and dispatches a pending event at EOF.
forward_stream threads the parser through its unfold state and emits a
terminal error envelope on cap overflow. Existing single-chunk SSE test
assertions preserved; added multi-chunk, split-UTF-8, EOF-dispatch, and
cap tests.
Verified: cargo test (219 pass), clippy -D warnings, fmt --check.
Full-surface integration suite (tests/full_surface.rs, mcp feature):
- one HttpAdapter over real TCP (ProtocolHandler::handle path) serving
gateway endpoints, /openapi.json, /mcp, and the WS channels session
- gateway: search/schema/call/subscribe/batch/publish presence,
envelope shapes, error fidelity end-to-end
- from_openapi import -> Internal-by-default invisible from the wire ->
External facade composes it via env.invoke -> upstream HTTP API
called end-to-end (ADR-015 composition model exercised)
- to_openapi 6-path doc validated against openapiv3 over the wire
- to_mcp: MCP client connects to /mcp on the served adapter, lists the
4 gateway tools, search returns ACL-filtered ops (Sub excluded)
Production fix: the WS upgrade route was reserved but never wired into
HttpAdapter's router (the ws-upgrade-session tests built their own
router). Now wired with ws_bearer_auth (401 without a resolvable
token) around ws_upgrade_handler.
Docs sync: all 28 'Port notes' sections/blockquotes stripped from
ported ADRs/specs; OQ-01/OQ-02 statuses corrected to resolved in
overview.md, websocket.md, and the README table (open-questions.md was
already current).
Publish prep: cargo publish --dry-run --allow-dirty succeeds;
cargo doc --no-deps warning-free (ADR link targets fixed); feature
combinations (default / test-support / mcp / wss / all) compile
warning-free under clippy -D warnings.
Verified: cargo test (182 lib default), --all-features (227 lib + 29
integration), clippy -D warnings x3 feature sets, fmt, doc,
publish --dry-run.