Files
alkhttp/tasks/websocket/review-002-con18b-ws-polish.md
T
glm-5.3-flash e2c255d40c docs(tasks): decompose review-002 into 24 tasks (23 implementation + 1 bracketed follow-up)
Decomposition of docs/reviews/002-post-remediation-review.md per its
5-unit remediation plan:

- Unit 1 (security-critical): gw15-publish-body-cap,
  prj16-schema-via-call (CF-004 filed alkcall-side), fwd13-dot-segments,
  fwd16-missing-capability, oai11-ref-memoization
- Unit 2 (timeout/terminality): ws13-idle-progress,
  fwd15-stream-timeout, cli01-retry-after-budget, con17-mcp-pagination,
  con18-wss-sweep-exit
- Unit 3 (projection/docs): projection-truthfulness, mcp-batch-cap,
  gw16-status-drift
- Unit 4 (spec-import): yaml-normalization, oai13-path-item-wildcards,
  import-loudness-cluster, js01-placeholder-check,
  fwd17-19-contract-decisions
- Unit 5 (WS polish + tests): con18b-ws-polish,
  client-policy-wire-tests, cov-deployment-knobs, cov13-dead-code,
  srv11-srv12-router-ordering
- review-002-bracketed-followup: tentatively planned post-bulk pass
  (stale-check, OQA-18 enforcement decision, CON-08/09 close() lever,
  cross-crate re-checks) — deliberately not serialized against the
  bulk

Also: review-002 numbering repair (CON-14 was double-booked; MCP
pagination now CON-14, from_wss monitor renumbered CON-18, missing
CON-14 section added).

taskgraph: 66 valid, no cycles; 24 pending (all review-002);
gen-1/gen-2 parallel waves identified; workflow-cost hotspots are
prj16 (12.8) and ws13 (11.1), both carrying the reviewed slicing
guidance in their Notes.
2026-08-30 10:50:34 +00:00

73 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: review-002-con18b-ws-polish
name: WS small fixes — pre-send cap check, close reasons, custom-route knobs, axum-flavor tests (WS-14/15/17/18/19)
status: pending
depends_on: [review-002-ws13-idle-progress]
scope: moderate
risk: low
impact: component
level: implementation
tags: [websocket, review-002]
---
## Description
Five review-002 minor WS findings that all live in the two WS files
(`byte_adapter.rs`, `upgrade.rs`) — batched because each is small and
they share the review-002-ws13-idle-progress refactor context
(sequence after it; do not parallelize on the same file):
- **WS-14**: the byte-cap check can trip only *after* `poll_write` has
accepted into the channel (`byte_adapter.rs:326-334, 585-586`) — the
mux committed the chunk, then the pump 1011s and truncates. Move the
size check into `poll_write` **before** `try_send` so the mux sees
the write error instead of the wire.
- **WS-15**: `WriteMsg::CloseWith` hardcodes the reason "text messages
not supported" for idle-timeout (1001), inbound-size (1011), and text
(1002) closes (`:316-324`). Carry the reason in the variant; tests
assert numeric codes today, keep them and add reason asserts where
cheap.
- **WS-17**: bare-registry WS routes get no knob surface
(`upgrade.rs:104-111` hardcodes 60 s idle + private 64-session
semaphore). Add a `WsIdleTimeout`-style request extension mirroring
`ChannelsPolicy` (or document the fixed values in the module doc —
implementer's choice, but `upgrade.rs` docs must match reality).
- **WS-18**: write-side stall is unbounded (peer stops reading → write
pump parks in `ws_sink.send`, 64×16 MiB bounded but time-unbounded).
Add a write-progress timeout to the write pump (same knob family as
the read side — share the config surface WS-17 touches).
- **WS-19**: axum-flavor `AxumFraming` arms have no direct unit test
(cap-trip closes + idle-1001 are asserted on tungstenite only, via
shared generic code). Mirror one text→1002 and one cap-trip test
over `AxumFraming`.
## Acceptance Criteria
- [ ] WS-14: over-cap write rejected in `poll_write` pre-`try_send`;
test asserts the *stream* error, not a wire-level 1011
- [ ] WS-15: close reasons distinct per cause (idle / oversized /
text); existing close-frame tests updated with reason asserts
- [ ] WS-17: knob surface exists (extension or documented-fixed) and
`upgrade.rs` module docs match the implementation
- [ ] WS-18: write-progress timeout lands with the same config family;
test: a peer that stops reading (clog the sink) is evicted
within the knob (scaled test, tungstenite path)
- [ ] WS-19: two `AxumFraming` unit tests (text→1002, cap-trip) pass
- [ ] `cargo test`, `cargo clippy --all-targets -- -D warnings`,
`cargo fmt --check` pass
## References
- docs/reviews/002-post-remediation-review.md (Part B', WS-14/15/17/18/19)
- src/websocket/byte_adapter.rs:326-334 (WS-14), :316-324 (WS-15), :584-597 (WS-18), :782-1206 (WS-19 test target)
- src/websocket/upgrade.rs:104-111 (WS-17), :308-317 (the ChannelsPolicy extension pattern to mirror)
- tasks/websocket/review-001-ws-pump-consolidation.md (the generic pump these extend)
## Notes
Slice suggestion (per the review-001 lesson on WS agents): one slice
per finding with its own commit, in the order above (WS-14 is the only
behavior-correctness one; WS-18 is the only new mechanism). If WS-13
(chief-risk task) changed the read-loop shape, rebase-verify the cap
accounting comments before this task's slices — they cite
pre/post-extend order explicitly.