Skip to content

fix(acp): cancellation cannot interrupt an idle connection read #777

Description

@PierrunoYT

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions