Summary
Serve(ctx) documents context-driven shutdown, but cancellation cannot interrupt an idle blocking read from the ACP JSON-RPC transport. In the CLI, SIGINT cancels the context without closing stdin, so shutdown can remain blocked until the peer closes the pipe or sends more data.
This tracks AUD-011 from the July 18 codebase audit.
Affected code
internal/acp/jsonrpc.go:116-146
internal/cli/acp.go:71-76
internal/acp/jsonrpc_test.go:11-25
Current behavior
The serving loop blocks in ReadBytes while the peer is idle. Canceling the supplied context does not unblock that read. Existing tests close the pipe as well as canceling the context, which masks the cancellation problem.
Expected behavior
Canceling the context should promptly stop an idle ACP server without requiring the peer to send data or close its side of the transport.
Suggested implementation
- Give the connection an owned
io.Closer or explicit transport-close callback.
- Start a context watcher that closes the read transport when cancellation occurs.
- Ensure shutdown and transport closure remain safe and idempotent.
- Preserve the original protocol or transport error where appropriate.
Suggested tests
- Run
Serve with an idle io.PipeReader.
- Cancel the context without closing the writer.
- Assert that
Serve returns promptly.
- Cover concurrent cancellation and peer closure to detect double-close or shutdown races.
Summary
Serve(ctx)documents context-driven shutdown, but cancellation cannot interrupt an idle blocking read from the ACP JSON-RPC transport. In the CLI, SIGINT cancels the context without closing stdin, so shutdown can remain blocked until the peer closes the pipe or sends more data.This tracks AUD-011 from the July 18 codebase audit.
Affected code
internal/acp/jsonrpc.go:116-146internal/cli/acp.go:71-76internal/acp/jsonrpc_test.go:11-25Current behavior
The serving loop blocks in
ReadByteswhile the peer is idle. Canceling the supplied context does not unblock that read. Existing tests close the pipe as well as canceling the context, which masks the cancellation problem.Expected behavior
Canceling the context should promptly stop an idle ACP server without requiring the peer to send data or close its side of the transport.
Suggested implementation
io.Closeror explicit transport-close callback.Suggested tests
Servewith an idleio.PipeReader.Servereturns promptly.