Commit Graph
16 Commits
Author SHA1 Message Date
glm-5.3-flash 5c16e68f75 chore(deps): prune unused deps, tighten tokio features, align tungstenite (HY-01, HY-05, HY-07, HY-08, HY-12)
- HY-01: openapiv3 -> dev-dependencies (test-only usage)
- HY-05: drop bytes (src sites renamed to axum::body::Bytes re-export),
  keep parking_lot (genuinely used); tokio "full" -> the seven features
  actually used (macros, rt-multi-thread, io-util, net, fs, time, sync)
- HY-08: test-support extends wss; dev tokio-tungstenite matches the
  wss feature set
- HY-12: tokio-tungstenite 0.28 -> 0.29 to match axum's tungstenite;
  duplicate roots in cargo tree -d: 9 -> 6 (tungstenite, cpufeatures,
  rand dupes collapsed)
- HY-07 ride-along: READ_SLOTS privatized
- CON-10 residue: verified already fixed (full_surface required-features)

Verified: cargo test (300), --all-features (371+36), --features mcp
(355+9), --features wss (316), check --no-default-features, clippy
(all-targets and --all-features, -D warnings), fmt --check
2026-08-29 14:06:36 +00:00
glm-5.3-flash 25975ac2a8 fix(websocket): configurable WS read idle timeout (WS-01) 2026-08-29 13:45:54 +00:00
glm-5.3-flash fa73684ebe fix(websocket): configurable WS session cap (WS-09) 2026-08-29 13:37:08 +00:00
glm-5.3-flash 4747a12c02 fix(websocket): retain WsPumps handle on the server path (WS-08) 2026-08-29 13:31:33 +00:00
glm-5.3-flash 4ef8499bbb fix(adapters): to_openapi runtime-truthful projection (PRJ-01..05, PRJ-11..15)
- /search, /schema: document the envelope wrapper and the real item/spec
  fields (PRJ-01/02); /search drops unreachable 401/403, documents 404
  (PRJ-15)
- error statuses: 422 for dispatch-path INVALID_INPUT /
  INVALID_OPERATION_TYPE; extractor 400s documented as the plain-text
  gap they are (PRJ-03); operation-declared errors projected by
  http_status with x-runtime-behavior: 500 on non-HTTP_* codes (PRJ-04
  project-honest decision) — no runtime changes
- /subscribe: 200+SSE only; event:error terminal contract documented
  (PRJ-05, GW-12)
-  components for requests/responses; CallRequest no longer inlined
  per-path (PRJ-14); all library expect() paths removed (PRJ-11)
- error projections folded into BTreeMaps: same registry =>
  byte-identical doc, sorted enums (PRJ-12)
- components.securitySchemes.bearerAuth + top-level security (PRJ-15)
- info.version 1.1.0 -> 1.2.0 (ADR-045 minor: additive documentation of
  the settled runtime contract)
- 31 unit tests incl. golden print-level assertions mirroring the routes
  tests' actual bodies and a determinism test

Verification: cargo test (288), clippy --all-targets -D warnings, fmt
--check, cargo doc --no-deps, cargo test --all-features (all green in a
clean worktree at HEAD; shared tree carries parallel agents' edits).
2026-08-29 12:47:10 +00:00
glm-5.3-flash 314472012d fix(server): hyper knobs, decoy fidelity, cache + builder fixes (SRV-04..SRV-10)
- SRV-04: TokioTimer on h1+h2 builder, header_read_timeout 10s,
  h1 keep-alive on, h2 keep-alive 30s/10s; concurrency boundary documented
- SRV-05: with_decoy rebuild keeps extra routes (clone, not take)
- SRV-07: method_not_allowed_fallback serves the nginx-shaped 405
- SRV-08: UTF-8 percent-decoding, literal '+', tokio::fs syscalls
- SRV-09: /openapi.json cached at construction, generic 500 body,
  to_openapi returns Result (expect removed)
- SRV-10: ChannelsPolicy extension injection point on the WS upgrade;
  single token resolution via route ordering (WS layer before the
  router-wide auth route_layer)

Verification: cargo test 265 passed; --all-features server::/to_openapi::
green; clippy + fmt clean on touched files (remaining tree noise is a
parallel agent's in-flight from_mcp/from_wss/forward work)
2026-08-29 10:47:44 +00:00
glm-5.3-flash a4df859771 fix(server): cap /mcp body size (SRV-03)
Add tests for the /mcp body cap and complete the task file.

- oversized POST /mcp with declared Content-Length > 8 MiB -> 413
  before any body read
- oversized chunked POST /mcp -> 413 (counting-stream cut mid-body;
  rmcp maps body errors to 500, so the middleware sources the status)
- normal-size initialize round-trip unchanged
- task file: status completed, Summary filled

Verified: cargo test (219), cargo test --features mcp --lib (257),
cargo test --all-features (269 + integration), clippy default and
--all-features (-D warnings), cargo fmt --check.
2026-08-29 09:42:42 +00:00
glm-5.3-flash a943d142c4 fix(server): cap /mcp body size (SRV-03)
The /mcp nest (to_mcp streamable HTTP service) collects the raw body
itself, so axum's extractor-based DefaultBodyLimit never applies and a
multi-GB chunked POST buffers entirely in memory (review-001 SRV-03).

Wrap the nest with an explicit counting-body middleware: 8 MiB cap
(headroom over the gateway's 2 MiB for JSON-RPC batch payloads),
Content-Length-declared oversizes rejected before reading, streaming
oversizes cut off mid-read and answered 413 (rmcp maps body-read errors
to 500, so the middleware sources the status itself).

Verification: cargo check (default + mcp + all-features); mcp test
suite pending tree unstuck from parallel agent's WIP.
2026-08-29 08:47:50 +00:00
glm-5.3-flash e4284a0d3c fix(server): auth-cover extra_routes + reserved-path rule (SRV-01, SRV-06)
- apply bearer_auth_middleware route_layer AFTER the extra_routes merge,
  so assembly-layer custom routes resolve the bearer token by default
  (ADR-046 §4); per-route opt-out via the route's own layer remains
- enforce RESERVED_PATHS per-method at build time: a probe MethodRouter
  occupied on all methods is pre-merged against extras, so a custom
  POST /search panics like a same-method overlap (ADR-046 §3)
- tests: auth resolves through an extra route; an extra route with its
  own layer opts out; reserved-path merge panics; non-reserved
  different-method merge stays legal; MCP bearer-gate test stays green
- ADR-046 §3: one sentence restating the per-method rejection rule

Verification: cargo test (215) ok, cargo test --all-features (260 +
integration) ok, clippy -D warnings (default + all-features) ok,
cargo fmt --check ok.
2026-08-29 08:28:15 +00:00
glm-5.3-flash 4a825d33e7 feat(infra): full-surface integration suite + docs sync + publish prep
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.
2026-08-28 16:07:56 +00:00
glm-5.3-flash 4ac337c3a5 feat(adapters): from_mcp + to_mcp behind the mcp feature (rmcp 1.8)
from_mcp (src/adapters/from_mcp/):
- tools/list discovery over streamable HTTP; per-tool
  HandlerRegistration (Mutation, Once, FromMCP leaf, Internal;
  ADR-015/022)
- structuredContent-preferred output, ContentBlock-union fallback,
  isError -> MCP_TOOL_ERROR with content blocks as details (ADR-023)
- bearer token flows via capabilities key 'mcp' (ADR-014 no-env-vars)
- 19 unit tests + tests/from_mcp_integration.rs (5 tests vs a real
  rmcp streamable-HTTP MCP server)

to_mcp (src/adapters/to_mcp.rs):
- 4 fixed gateway tools (search/schema/call/batch, ADR-041); Sub ops
  excluded from search and uncallable (MCP is request/response)
- identity survives rmcp framing: bearer_auth_middleware stashes
  Option<Identity> in http::request::Parts extensions, call_tool reads
  it back from RequestContext extensions
- StreamableHttpService nested at /mcp in HttpAdapter's router,
  bearer middleware around it (feature-gated)

Streamable HTTP only (ADR-037): rmcp default-features off, no stdio.
Default build compiles without rmcp (cargo tree: 0 hits).

Verified: cargo test (182 lib default / 218 all-features) + 5 MCP
integration + 10 WS, clippy -D warnings (both), fmt.
2026-08-28 14:14:09 +00:00
glm-5.3-flash 42239a0af5 feat(gateway,adapters): /publish endpoint (ADR-068) + to_openapi 6-endpoint projection
gateway-publish:
- GatewayDispatch::invoke_sink (internal:false, forwarded_for:None)
- POST /publish: NDJSON body, first line {operation, chunk} (OQ-02
  resolved: first-line convention; terminal errors = plain HTTP status
  + JSON body, not NDJSON lines); 404 internal/unknown, 401/403 ACL,
  400 INVALID_OPERATION_TYPE for non-Pub
- ADR-068 + open-questions.md updated with the OQ-02 resolution

adapter-to-openapi:
- src/adapters/openapi_spec.rs: OpenAPISpec model (JSON/YAML/from_str
  JSON-first per ADR-051, $ref resolution) shared by from/to_openapi
- src/adapters/to_openapi.rs: 6-endpoint projection, info.version
  1.0.0 -> 1.1.0 (minor: /publish addition per ADR-045), /publish
  NDJSON doc with 400 oneOf (INVALID_INPUT + INVALID_OPERATION_TYPE),
  ADR-023 error fidelity (protocol statuses, HTTP_<status> passthrough,
  internal-op exclusion)
- GET /openapi.json wired into HttpAdapter's router (bearer-auth layer)

Verified: cargo test (136 lib), test --all-features (136+10 WS),
clippy -D warnings (both), fmt. Doc validates against openapiv3.
2026-08-28 13:54:49 +00:00
glm-5.3-flash ea5ac83b57 feat(gateway): the 5 core gateway routes wired into the router
- src/gateway/routes.rs: /search /schema /call /batch /subscribe
- SSE projection: data frames per event, error event terminates,
  internal/unknown ops -> NOT_FOUND, query-op -> INVALID_OPERATION_TYPE
- /search + /schema ACL-filtered via services/list + services/schema
  discovery handlers; /batch ordered per-item envelope JSON
- gateway_router() merged into HttpAdapter's router under the shared
  bearer-auth route layer; decoy remains the fallback
- adapted to alkcall 0.1.1: OperationType::Sub, envelope error by value

Verified: cargo test (71 lib tests), clippy -D warnings, fmt.
2026-08-28 08:31:43 +00:00
glm-5.3-flash d070e548ad feat: server foundation (phase 1 core) — state, auth, healthz/decoy, gateway dispatch, HttpAdapter
Tasks completed: server-core-types, server-auth, server-healthz-decoy,
gateway-dispatch, server-adapter (5 of 17).

- src/server/state.rs: DecoyConfig + RouterState (alkcall type paths,
  6-endpoint reserved-path docs)
- src/server/auth.rs: bearer middleware + ResolvedIdentity extractor
  (10 tests: missing/malformed/basic/failed-resolution matrix)
- src/server/healthz.rs + decoy.rs: raw healthz; nginx-style 404,
  static site (path-traversal guarded), redirect decoys
- src/gateway/dispatch.rs: GatewayDispatch invoke/invoke_streaming
  (internal:false, forwarded_for:None, bounded deadline) +
  src/gateway/error.rs: CallError→HTTP status mapping (HTTP_<status>
  passthrough, retryable→Retry-After)
- src/server/adapter.rs: HttpAdapter ProtocolHandler — accept_bi →
  BiStream → TokioIo → hyper auto builder (h2 CONNECT enabled);
  integration tests over DuplexStream (request/response cycle, healthz,
  decoy 404)

Verified: cargo test (46 lib tests), clippy -D warnings, fmt,
test --all-features.
2026-08-28 07:35:02 +00:00
glm-5.3-flash 320ea87b08 docs: port architecture specs and ADRs from alknet-http; write new alkhttp ADRs 067-070
Phase 1 (SDD) — architecture documentation:

Ported specs (adapted for alkcall, producer/consumer terms, 6-endpoint
gateway, channels-over-WS, Sub/Pub operation types):
- overview.md, http-server.md, http-adapters.md, http-mcp.md
- README.md index (rewritten for alkhttp)

New ADRs:
- 067: WebSocket carries the channels protocol (8-byte chunk demux,
  channel 0 = alk/call, upgrade path /alk/channels)
- 068: gateway /publish endpoint for Pub operations (NDJSON body)
- 069: WebTransport out of scope in alkhttp (alknet concern)
- 070: from_wss consumer adapter (wss feature, tokio-tungstenite)

Ported ADRs (25, same numbers, port notes + amendments where the
extraction changed facts): 001-004, 010, 014, 015, 017, 022, 023, 027,
034, 036, 037, 039, 041, 042, 044, 045, 046, 047, 048, 049, 051, 066.

websocket.md rewritten for the channels session; open-questions.md
seeded (OQ-01 WS byte-stream adapter, OQ-02 /publish framing,
OQ-03 from_wss reconnect, OQ-04 browser client ownership).

Verified: cargo test, clippy -D warnings, fmt, doc --no-deps.
2026-08-27 14:19:24 +00:00
glm-5.3-flash 28c521b2f3 feat: scaffold crate with alkcall 0.1.1 dependency
Empty module tree (adapters, client, gateway, server, websocket) matching
the AGENTS.md subsystem map. Features: h2/http1 (default), mcp (rmcp),
wss (tokio-tungstenite, for the from_wss consumer adapter).

Verified: cargo check (default), cargo check --all-features.
2026-08-27 12:50:43 +00:00