Address #126 review: one home for the middleware rationale
Build image / build-and-push (push) Successful in 20s

The why-a-controller-can't-reach-the-socket story was told in full in
deadlines.go, agent.go, the test, and CLAUDE.md. It lives in deadlines.go
now; the others say what they need to and point there.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
2026-08-22 23:09:36 -04:00
co-authored by Claude Fable 5
parent 2a903f6428
commit 68cb686d60
3 changed files with 13 additions and 22 deletions
+6 -12
View File
@@ -112,18 +112,12 @@ func TestEventStreamRefreshesDeadlinePerFrame(t *testing.T) {
// production middleware stack — which is where it was still broken.
//
// The two tests above passed while the deployed instance cut every agent turn
// at exactly 30s with "The connection dropped partway through." The difference
// is the middleware: the logging middleware in New replaces c.Writer with a
// wrapper that embeds the gin.ResponseWriter INTERFACE, which has no Unwrap. An
// http.ResponseController built from the handler's c.Writer unwraps layer by
// layer looking for SetWriteDeadline, can't see past that wrapper, and returns
// ErrNotSupported — putting the stream back on the server's absolute
// WriteTimeout. The first write past it fails, which cancels the request
// context and closes the socket under the client mid-frame.
//
// So: the same scenario as the first test, hosted on the engine New builds, in
// the order cmd/pansy runs it. Any future middleware that wraps the writer, or a
// reorder that puts one ahead of the controller capture, fails here.
// at exactly 30s: they host openEventStream on a bare engine, and it is the
// logging middleware in New that hides the socket from a ResponseController
// built in a handler (deadlines.go has the mechanism). So: the same scenario as
// the first test, hosted on the engine New builds, in the order cmd/pansy runs
// it. Any future middleware that wraps the writer, or a reorder that puts one
// ahead of the controller capture, fails here.
func TestEventStreamOutlivesWriteTimeoutBehindMiddleware(t *testing.T) {
got, err := streamFrames(t, authEngine(t, localCfg()), 300*time.Millisecond, 300*time.Millisecond, 3)
if err != nil {