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
+5 -6
View File
@@ -161,12 +161,11 @@ Conventions that follow from it:
lives in `commitScope` where no caller can forget it.
- **Request deadlines are extended through `responseController(c)`, never
`http.NewResponseController(c.Writer)`.** The logging middleware wraps the
writer in a type with no `Unwrap`, so a controller built from a handler's
writer can't reach the socket: every `SetWriteDeadline`/`SetReadDeadline`
returns `ErrNotSupported` — in production only. `captureController` is the
first middleware in `api.New` precisely so the controller exists before
anything wraps the writer. Corollary for tests: a deadline test must run
`http.NewResponseController(c.Writer)`.** A controller built in a handler
can't reach the socket — the logging middleware wraps the writer — so every
deadline call silently returns `ErrNotSupported`, in production only;
`internal/api/deadlines.go` has the mechanism and why `captureController`
must stay the first middleware. Corollary for tests: a deadline test must run
through `New()`, not `gin.New()` — the #78 fix shipped fully tested on a bare
engine and never worked on the live instance.