Repository navigation
Conversation
…dges When ctxcop is paused (or an off switch is set), 13 handlers across the claudecode, codex, cursor and opencode adapters, and all three pi handlers, return before reading stdin. A bridge that writes a payload over the pipe buffer (~64KB) gets EPIPE, and with no stdin error handler Node throws an unhandled 'error' event that crashes the host (seen in pi). Drain stdin once in cmdHook after the handler replies, so every harness is covered and new handlers cannot regress it. Skipped when stdin is a terminal and for aider, which has no stdin hook. Add a stdin error handler to the pi and opencode bridges so an early-exiting hook fails open. Tests: build the binary and write 400KB to every harness hook event while paused; run each shipped bridge in node against a fake hook that exits unread. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Build the binary with .exe and set USERPROFILE, which os.UserHomeDir reads on Windows. Refs SECOPS-1421. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
govulncheck flags net/http in 1.26.6 (HTTP/2 server crash, HPACK encoder race), fixed in 1.26.9. CI takes its Go version from go.mod. Also add Unreleased changelog entries for this PR. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When ctxcop is paused (or an off switch is set), hook handlers return before reading stdin. A bridge that writes a payload larger than the pipe buffer (~64KB) gets EPIPE, and with no stdin error handler Node throws an unhandled
errorevent that crashes the host. Seen in pi with a 400KB provider payload.The drain now happens once in
cmdHook, after the handler replies, so every harness is covered and new handlers cannot regress it. It is skipped when stdin is a terminal and foraider, which has no stdin hook. The pi and opencode bridges also get a stdin error handler, so an early-exiting hook fails open.Affected handlers: all three pi handlers, plus 13 in the claudecode, codex, cursor and opencode adapters.
Test plan
go test -race -count=1 ./...passes (run with an isolatedHOME, see notes)gofmt -w .is cleango vet ./...is cleanTestPausedHooksDrainStdinbuilds the binary, pauses via a tempHOME, and writes 400KB to a pipe for 15 hook events across all harnesses. Without the drain, 14 of 15 fail withbroken pipe(Claude Codepre-tool-usereads stdin first).TestBridgeSurvivesEarlyExitHook(pi and opencode) runs the shipped bridge in node against a fake hook that exits unread. Each fails withwrite EPIPE ... Unhandled 'error' eventwhen its bridge fix is reverted.Ran the built binary in a real terminal pane while paused: a terminal on stdin returns immediately, and 400KB piped in exits 0 and returns
{}.Security checklist
Reviewer notes
HOMEand ctxcop paused, the existing redaction tests in the harness packages fail because they read the live pause sentinel. They pass with an isolatedHOME. Not fixed here; separate follow-up.🤖 Generated with Claude Code