docs(http): pre-decomposition sanity check fixes — /subscribe POST, direct-call cleanup, from_mcp output handling
Three issues found in the http crate spec sanity check that would have
caused problems during task decomposition, now fixed:
C1 — /subscribe GET→POST: the gateway's /subscribe is an invoke endpoint
carrying { operation, input } in the body, but was listed as GET (which
has no body). Flipped to POST with Accept: text/event-stream negotiating
the SSE response, consistent with /call's flat-JSON-body invariant.
Browsers using EventSource can't POST but use WebSocket for the
bidirectional path; the HTTP gateway's /subscribe is for non-browser
HTTP clients (fetch + ReadableStream). Touches ADR-042, ADR-047,
ADR-048, http-adapters.md, http-server.md.
C2 — stale direct-call references: three spots contradicted ADR-047
(which removed the POST /{service}/{op} direct-call surface) and
ADR-046 §3 (which states /{service}/{op} is no longer reserved).
Cleaned up in http-server.md (custom-routes intro + collision list) and
ADR-046 §6 (default-surface list).
W2 — from_mcp output handling: the spec's fallback for tools without
outputSchema was Type.Unknown(), but the correct fallback is the MCP
ContentBlock union (text|image|audio|resource|resource_link) — a
well-defined MCP type, not Unknown. Fixed http-mcp.md with the full
structuredContent-preferred-over-content-blocks logic (matching the TS
adapter and rmcp SDK), enriched references with specific rmcp source
files. Also added shared-dispatch-spine notes to http-mcp.md and
http-adapters.md cross-referencing the new research findings.
Research (docs/research/alknet-http-gateway-factoring/findings.md):
to_mcp and to_openapi share a dispatch spine (resolve → invoke → map).
Recommendation: extract a thin shared struct now, not a GatewayDispatch
trait — the server-integration layers (axum routes vs rmcp
StreamableHttpService) and wire-framing stay per-gateway. A third
gateway is not on the horizon; if one appears its server-integration
needs its own shape anyway.
Minor: WS route precedence note (websocket.md), OpenAPISpec
shared-type-not-shape clarification (http-adapters.md), date bumps.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-06-30
|
||||
last_updated: 2026-07-01
|
||||
---
|
||||
|
||||
# WebSocket — the Browser Bidirectional Path
|
||||
@@ -122,10 +122,16 @@ mechanism of ADR-046, but a deployment that passes no custom routes gets
|
||||
`/alknet/call`). The path must not collide with the reserved
|
||||
gateway/`/healthz`/`/openapi.json`/MCP/custom-route paths per ADR-046's
|
||||
collision rule; `/alknet/call` namespaces away from the reserved set
|
||||
naturally. The upgrade runs over HTTP/1.1 (the standard `Upgrade: websocket`
|
||||
header, RFC 6455) or HTTP/2 (the extended CONNECT protocol, RFC 8441);
|
||||
axum/hyper supports both, and the handler does not branch on which — the
|
||||
WS frame stream is the same once the upgrade completes.
|
||||
naturally. A deployment that builds a custom REST projection with
|
||||
`POST /{service}/{op}` routes (ADR-047 §4) coexists with the WS upgrade
|
||||
at `/alknet/call` — axum's `Router::merge` prioritizes specific routes
|
||||
over wildcards, so the WS upgrade's exact `/alknet/call` path wins over
|
||||
any `/{service}/{op}` wildcard a custom route projection might
|
||||
register, and the two do not collide. The upgrade runs over HTTP/1.1
|
||||
(the standard `Upgrade: websocket` header, RFC 6455) or HTTP/2 (the
|
||||
extended CONNECT protocol, RFC 8441); axum/hyper supports both, and
|
||||
the handler does not branch on which — the WS frame stream is the same
|
||||
once the upgrade completes.
|
||||
|
||||
### Framing: `EventEnvelope` over binary WS messages
|
||||
|
||||
|
||||
Reference in New Issue
Block a user