Commit Graph

13 Commits

Author SHA1 Message Date
18156ac9d2 Merge origin/develop: integrate connection-overlay (resolve adapter.rs test conflict, keep /openapi.json route test) 2026-07-01 20:17:06 +00:00
dd6aacc598 feat(http): complete to_openapi gateway projection with error fidelity and route wiring
Refine to_openapi to project operation-level errors (with http_status)
onto /call and /subscribe responses via oneOf merge with protocol-level
errors, preserving HTTP_<status> prefix codes without collision. Fix
BTreeMap→serde_json::Map for Value::Object compatibility. Wire GET
/openapi.json route test. Apply cargo fmt across the crate.
2026-07-01 20:11:09 +00:00
2695a19502 feat(http): implement to_openapi gateway projection (5-endpoint OpenAPI doc, info.version 1.0.0)
to_openapi(registry) -> OpenAPISpec generates the fixed 5-endpoint
gateway doc (/search, /schema, /call, /batch, /subscribe) — pure
projection (ADR-017 §5), gateway pattern (ADR-042). info.version is
1.0.0 tracking the gateway contract (ADR-045). /call responses carry
protocol-level errors (400/401/403/404/500/504) plus operation-level
errors mapped by http_status (ADR-023). GET /openapi.json wired to
serve the generated spec.
2026-07-01 19:52:57 +00:00
58e16d088b review(http): mark http/review-mcp completed + fix formatting across crate
Review-mcp verification complete: all 12 checklist items pass (from_mcp/to_mcp
conformance, ADR-037/041/014/023/034, feature gate isolation, GatewayDispatch
concrete struct, test coverage 223+5). Applied cargo fmt across crate.
2026-07-01 19:32:42 +00:00
b127699aad Merge feat/http-to-mcp: to_mcp gateway projection (4-tool gateway, rmcp StreamableHttpService)
Implements src/adapters/to_mcp.rs: ToMcpGateway rmcp ServerHandler with 4 fixed
gateway tools (search/schema/call/batch). search dispatches services/list (ACL-
filtered, excludes Subscriptions), schema dispatches services/schema, call/batch
dispatch via GatewayDispatch::invoke with ResponseEnvelope→CallToolResult mapping.
Bearer auth via shared middleware around nest_service. Identity survives rmcp
framing (research §6 #2 confirmed). Feature-gated behind mcp; stdio NOT built
(ADR-037). Pure projection. 16 unit tests.

# Conflicts:
#	crates/alknet-http/src/server/adapter.rs
2026-07-01 19:24:33 +00:00
31291bd2d9 Merge feat/http-gateway-endpoints: 5 fixed gateway endpoints (search/schema/call/batch/subscribe)
Implements src/server/gateway_routes.rs: POST /call, GET /search, GET /schema,
POST /batch, POST /subscribe (SSE). All delegate to GatewayDispatch::invoke; auth
via ResolvedIdentity extractor; errors mapped via call_error_to_http_response
(identity-aware 401/403 split). Internal ops → 404. /schema adds ACL pre-check.
/subscribe projects ResponseEnvelope as SSE. /batch loops over invoke. Wired real
handlers into adapter.rs replacing placeholder 501s. 157 tests pass.

Note: /subscribe SSE completes after single event (registry invoke returns single
ResponseEnvelope, no streaming handler yet — research §6 OQ#5).

# Conflicts:
#	crates/alknet-http/src/server/adapter.rs
2026-07-01 19:19:50 +00:00
64696fec97 feat(http): implement to_mcp 4-tool gateway projection (rmcp ServerHandler, StreamableHttpService at /mcp)
to_mcp is the MCP-direction gateway projection (ADR-041): exposes 4 fixed
gateway tools (search, schema, call, batch) over rmcp StreamableHttpService
nested into the axum Router at /mcp, not one MCP tool per registry operation.
The LLM discovers operations on demand via search+schema.

- ToMcpGateway implements rmcp ServerHandler (call_tool, list_tools, get_info)
- tools/list returns the 4 fixed gateway tools, never the registry's ops
- search dispatches services/list via GatewayDispatch::invoke, excludes
  Subscription ops (ADR-041 §2), returns names + descriptions
- schema dispatches services/schema, returns the full OperationSpec
- call dispatches via GatewayDispatch::invoke (shared spine), maps
  ResponseEnvelope -> CallToolResult::structured (Ok) /
  CallToolResult::structured_error (Err(CallError))
- batch loops over invoke, returns an array of results
- Bearer auth via shared bearer_auth_middleware applied around nest_service
  (rmcp simple_auth_streamhttp pattern); Identity read from
  RequestContext.extensions -> http::request::Parts.extensions
  (research §6 #2 identity-survives-framing assumption, confirmed via test)
- to_mcp is a pure projection (consumes registry, produces no entries)
- Feature-gated behind mcp; stdio NOT built (ADR-037)
- /mcp route wired in adapter.rs replacing the placeholder 501

cargo test -p alknet-http --features mcp: 172 passed
cargo clippy -p alknet-http --features mcp --all-targets: clean
cargo check -p alknet-http (no mcp): clean
2026-07-01 19:18:19 +00:00
5a629a48e5 feat(http): implement 5 gateway endpoints (search/schema/call/batch/subscribe)
Implement the sole HTTP invoke path (ADR-042/047) in
src/server/gateway_routes.rs: POST /call reads { operation, input },
resolves identity via the shared ResolvedIdentity extractor, dispatches
via GatewayDispatch::invoke, and returns ResponseEnvelope as JSON with
errors mapped via call_error_to_http_response. GET /search dispatches
services/list (AccessControl-filtered); GET /schema dispatches
services/schema with an ACL pre-check (unauthorized -> 403). POST /batch
loops over invoke returning an array; POST /subscribe projects the
response as SSE (text/event-stream) with data frames for call.responded
and an error event for call.aborted. Internal ops return 404. Wire the
real handlers into adapter.rs router, replacing the placeholder 501s.
2026-07-01 19:17:59 +00:00
384ad03619 feat(http): implement WebSocket upgrade handler (native EventEnvelope session, no length prefix, bearer auth) 2026-07-01 19:15:11 +00:00
ccbff3c7f8 Merge feat/http-bearer-auth-middleware: Shared Bearer auth middleware
Implements src/server/auth.rs: bearer_auth_middleware (from_fn_with_state over
Arc<dyn IdentityProvider>, stashes Option<Identity> in request extensions),
extract_bearer_identity (Bearer-only: no/malformed/Basic/unresolvable → None,
not an error), ResolvedIdentity axum extractor. Wired into HttpAdapter router
via route_layer around gateway/openapi/mcp routes, excluding /healthz. 11 tests.

# Conflicts:
#	crates/alknet-http/Cargo.toml
#	crates/alknet-http/src/server/adapter.rs
#	crates/alknet-http/src/server/mod.rs
2026-07-01 18:51:29 +00:00
36f74dd31b feat(http): implement shared Bearer auth middleware (resolve_from_token, stash Identity in request extensions)
Add src/server/auth.rs with bearer_auth_middleware axum layer that
extracts the Authorization: Bearer header, resolves via
IdentityProvider::resolve_from_token, and stashes Option<Identity> in
request extensions. Shared by HTTP gateway routes and the to_mcp rmcp
service (research §4.4). No token, malformed header, or failed
resolution all yield None (unauthenticated, not an error) — Bearer-only
auth mechanism (ADR-004).

Includes ResolvedIdentity axum extractor reading from extensions, and
wires the middleware into the HttpAdapter router around the
gateway/openapi/mcp routes (excluding the raw /healthz route).
2026-07-01 18:48:00 +00:00
3702da1aee feat(http): implement /healthz raw route and stealth decoy fallback
GET /healthz: raw route, no auth, no OperationContext, returns 200 OK
with plain-text 'ok' (ADR-036). Decoy fallback for unknown paths via
DecoyConfig: fake nginx 404 (default), static site serving, or redirect.
Decoy does not leak alknet presence (no alknet headers/format). Custom
routes take precedence over decoy (decoy is fallback only). Wire real
handlers into HttpAdapter router replacing placeholder 501s.
2026-07-01 18:40:01 +00:00
b313dcbf20 feat(http): implement HttpAdapter (ProtocolHandler for h2/http1.1, axum over QUIC)
Wires the axum Router (gateway endpoints + /healthz + /openapi.json + MCP +
custom routes via extra_routes merge ADR-046) and drives hyper's HTTP/1.1 or
HTTP/2 connection driver over a single QUIC bidirectional stream. The
QUIC-to-hyper bridge wraps the (SendStream, RecvStream) pair as a
TokioIo-compatible duplex and feeds it to hyper-util's auto Builder (which
auto-detects HTTP/1.1 vs HTTP/2). h3 ALPN is not registered (ADR-044).

Route handlers, healthz/decoy logic, openapi.json, the MCP route, and the WS
upgrade handler are wired as 501 Not Implemented placeholders for their
respective tasks. The router state holds Arc<OperationRegistry> +
Arc<dyn IdentityProvider>; the router is built once at construction and
cloned per connection (cheap Arc clone). DecoyConfig defaults to NotFound.

Adds hyper-util dependency (server, service, tokio features).
2026-07-01 18:07:56 +00:00