Files
alkhttp/tasks/gateway/review-001-gateway-stream-errors.md
T
glm-5.3-flash 12b35e2c5f docs(tasks): decompose review 001 remediation Units 1-5 into taskgraph tasks
21 review-001 tasks across server/adapters/client/gateway/websocket/infra,
chunked from the 7-unit remediation plan in
docs/reviews/001-initial-implementation-review.md.

- Scope split by mechanism, not one-per-finding: 15 tasks in generation 1
  (parallelizable), 6 sequenced after their file-sharing precursors
- Deliberately deferred until dependent fixes land: projection/doc
  fidelity partial (Unit 6 beyond dependency hygiene), coverage backfills
  (COV-01..07 via in-task acceptance for forward.rs), and per-finding
  minors (OAI-06/07, HY-02/04/06/10/11, CON-08)
- Cross-crate WS-12 (alkcall demux 4 GiB discard alloc) noted for filing
  in alkcall, not here

taskgraph: validate clean, no cycles, 6 generations
2026-08-29 07:10:15 +00:00

3.2 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
review-001-gateway-stream-errors Gateway error-fidelity — SSE terminality, mappings, Retry-After, deadline (GW-03..GW-07, GW-12..GW-14) pending
narrow low component implementation
gateway
review-001

Description

Review 001 gateway error-fidelity findings (src/gateway/routes.rs, error.rs, dispatch.rs) — the response a caller sees must match the documented contract and match across transports:

  • GW-04: SSE error events are not terminal — the stream continues after Err (routes.rs:299-313) while the wire dispatcher treats Err as terminal; two transports disagree about stream semantics (http-server.md:219-223 documents terminal). Emit the error frame and end the stream (take_while).
  • GW-03: INVALID_OPERATION_TYPE → 500 on /call///batch (client fault reported as server fault; pollutes alerting) but 400 on /publish. Map consistently (400 or 422) and document in http-server.md.
  • GW-05: the 30 s DEFAULT_TIMEOUT deadline is recorded (dispatch.rs:34,165) but never enforced — a hung handler holds the request open indefinitely. Either enforce (tokio::time::timeout around Once-op invokes) or remove the dead metadata. Prefer enforcing; it is the documented contract.
  • GW-07: Retry-After machinery exists in call_error_to_http_response (error.rs:61-75) but the main gateway error path builds responses by hand (routes.rs:319-333) — retryable HTTP_429/HTTP_503 reach callers with no Retry-After despite the documented mapping. Route gateway error responses through the shared mapper.
  • GW-12: ACL denial on /subscribe surfaces as HTTP 200 + event:error while /call returns 401/403. ADR-049 makes 200-on-stream defensible, but the doc must call out the asymmetry — coordinate with review-001-output-projection (PRJ-05) which documents it.
  • GW-13: no SSE keep-alive/heartbeat (routes.rs:172) — quiet-but- alive streams (the normal state for subscriptions) die at LB/proxy idle timeouts. Add keep-alive + retry: field.
  • GW-14: stale module doc (routes.rs:1-9 claims /publish is "a separate module"; AGENTS.md §7's "5 gateway endpoints" framing is similarly stale — ADR-068 made it 6).

Acceptance Criteria

  • SSE stream ends after an error event (test); keep-alive present
  • INVALID_OPERATION_TYPE maps to the same status on /call, /batch, /publish; http-server.md table updated
  • Once-op invokes enforce the 30 s deadline (test with a hung handler)
  • Retryable errors carry Retry-After on all live error paths (test)
  • GW-14 docs fixed (module doc; AGENTS.md gateway-endpoint count if touched)
  • cargo test and cargo clippy --all-targets -- -D warnings pass

References

  • docs/reviews/001-initial-implementation-review.md (Part C, GW-03..GW-07, GW-12..GW-14)
  • docs/architecture/decisions/049-streaming-handler-for-subscriptions.md
  • docs/architecture/decisions/023-operation-error-schemas.md

Notes

Agent fills during implementation. Independent of review-001-gateway-publish-semantics (both touch routes.rs — sequence or coordinate to avoid churn).

Summary

Filled on completion.