mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-26 06:19:49 +00:00
fdcf0867cd
* fix(mcp): a /mcp stream whose client stops reading ends instead of pinning its handler (BUG-3808) The /mcp sibling of BUG-3637. mcp-go's GET stream, and a POST response it upgrades to SSE, write and flush with no deadline; the server sets no WriteTimeout and no timeout ends a tool call. A client that stopped reading pinned the handler, its session registration and the connection. mcpBoundWrites serves both MCP mounts (/mcp and /mcp/chatgpt) through #2172's deadline-arming stream writer, on every method, and cancels the request context when the stream goes dead: the library leaves its loop on a Write error, but a failed Flush returns none, so ctx.Done() is its way out. It fails closed like openSSEStream. Tests that drove /mcp through httptest.ResponseRecorder now use the deadline recorder. Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr * test(mcp): the dead-stream context cancellation is tested directly; the flush case is named for what it shows (BUG-3808) M2 (Dead not wired to the context) survived the integration test: frames still queued in mcp-go's channels after a failed Flush make the next Write fail on the sticky error, so the loop leaves anyway. The context is its only way out when nothing is queued, so that binding gets its own test. Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr * test(mcp): both MCP mounts refuse an unbounded writer (BUG-3808) Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr * test(mcp): cmd/pad's /mcp tests serve through a writer that takes a deadline (BUG-3808) Five cmd/pad tests drove /mcp through httptest.ResponseRecorder, which mcpBoundWrites now refuses. mcpRecorder is the cmd/pad twin of the server package's deadline recorder. Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr * fix(mcp): a header-only /mcp response is committed under a write deadline (BUG-3808) mcp-go's DELETE calls WriteHeader and returns; net/http commits that response in finishRequest, after mcpBoundWrites has returned and with the deadline openSSEStream cleared. mcpBoundWrites now arms one deadline for that final write; net/http clears it once the response is finished. Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr * test(mcp): the /mcp stall tests wait for the failed write, then bound only the release (BUG-3808) BUG-3824 changed stalledStreamServer to report the first failed write on the watched connection and split the stalled-reader timing in two: the buffer fill is the harness, the release after a deadline overrun is the code under test. The GET and DELETE stall pins had the same single 5s end-to-end budget that made BUG-3637's flaky under load; they now use the same two phases and require the failure to be a deadline overrun. Claude-Session: https://claude.ai/code/session_01Rj4CMyK2EqxerMihbGs3Kr