Skip to content

fix(rpc): gc keeps a Windows endpoint whose socket secret cannot be read - #4293

Open
code-yeongyu wants to merge 6 commits into
mainfrom
fix/4199-gc-keeps-unreadable-secret
Open

code-yeongyu wants to merge 6 commits into
mainfrom
fix/4199-gc-keeps-unreadable-secret

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Part of a desktop issue (tracked internally) (senpi PR S3 in the approved #4199 design's plan; design test 7, lifecycle half).

Summary

senpi host gc (and the budgeted pass ensureHost schedules) no longer removes a Windows endpoint whose socket secret is missing, empty, short or long. Such an endpoint is kept with the new reason credential_unavailable.

Root cause

packages/coding-agent/src/modes/rpc/host-gc-evidence.ts:104-110: on win32 the pipe name is derived from the socket secret. socketSilence caught a failed or invalid secret read and returned socket_absent, the same verdict as a pipe that is provably gone, so the third part of gc's evidence passed and the endpoint directory was deleted. A failed credential read says nothing about whether a host still serves the pipe under the key whose file was lost; the approved design requires credential failure to stay unknown and never authorize teardown.

Fix

socketSilence returns credential_unavailable when the win32 secret cannot be read or has the wrong length; endpointInUse reports it for the public socket and for every .next-* successor bind, and gcEndpoint keeps the endpoint without running the stale-engine judgement (that judgement needs the same secret). A valid secret behaves as before, so normal dead-endpoint cleanup is unchanged. docs/rpc.md and the host-gc.ts reason table list the new reason.

RED

bun run --cwd packages/coding-agent test test/suite/regressions/desktop-4199-gc-keeps-endpoint-without-secret.test.ts on the unchanged code, all four cases (missing, empty, short, long):

AssertionError: expected { inUse: undefined, …(1) } to deeply equal { inUse: 'credential_unavailable' }
+   "silence": "socket_absent",
Tests  4 failed (4)

GREEN

The new regression plus test/rpc-host-gc-evidence.test.ts and test/documentation.test.ts pass. The real-host cases in test/rpc-host-gc.test.ts need the workspace build (their spawned host imports @earendil-works/pi-ai/dist), so they ran in CI rather than in this unbuilt checkout.

Windows coverage

The changed branch runs only on win32; the regression simulates the platform the way the #1370 regression does. Native receipts 27 and 28 of the design are not part of this PR.

Risks

A Windows endpoint that really is dead but lost its secret file now stays on disk until its secret is restored or the user removes it; that is the design's choice (no deletion from a broken credential read).

Gates (exact head fae8ce6)

Gated push: bun run check rc=0; the new regression, test/rpc-host-gc-evidence.test.ts and test/documentation.test.ts rc=0; node scripts/check-pr-changelog.mjs --base origin/main rc=0.

QA

The changed branch runs only on win32, so a real-CLI senpi-qa run on macOS cannot reach it; none was run. The simulated-platform regression and CI's Windows jobs are the evidence.

On win32 the pipe name derives from the socket secret. gc's socket probe read a missing or invalid secret as socket_absent, proof that nothing listens, and removed the endpoint even though a live host may still serve the pipe under the key whose file was lost. The probe now reports credential_unavailable and gc keeps the endpoint.

Part of sisyphuslabs/omo-desktop-app#4199
@code-yeongyu
code-yeongyu marked this pull request as ready for review October 26, 2026 00:17

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant