Repository navigation
server: end the uds worker's processes at gateway shutdown (CSRG-U6) - #98
Merged
Merged
Conversation
At shutdown the gateway killed its worker outright, so the worker never ended its executions, and nothing gives a pipe execution a parent-death signal on macOS. The CS-RG harness's uds shutdown case found a governed `sleep 30` outliving the gateway on the qualification Mac. The gateway now closes the worker's connection and waits for the worker, which ends its processes as it exits, as an in-process runner's processes end when the gateway exits. A worker still running 5 seconds later is killed; the close is bounded by the same grace. main stops the runner it started before it returns instead of dropping it. The process_status description and a runner comment now say that a tty process launched through DevGuard reports a signal death as 128 plus the signal, as the harness found on the Mac. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
A bounded correction found by the CS-RG harness on the qualification Mac (CSRG-U6 plan, step 8). Nothing here runs or claims a qualification.
No pin change. No change to the installed service.
Issue
Scope: CSRG-U6. The
faultssuite'sudsshutdown case failed on the Mac's check of #97. Tracked in #76 and novelKR/DevGuard#14. This PR does not close an issue.mainat2117800(#97's merge)b74e5c26b9826e3with the recorded patch, DevGuard6e7e065; both unchangedSummary
Before: in
udsmode, gateway shutdown (stdio EOF included) killed the worker outright, so the worker never ended its executions. A PTY execution ended on its terminal's hangup, but a pipe execution kept running, as nothing gives it a parent-death signal on macOS. On the Mac a governed/bin/sleep 30outlived the gateway until it ended by itself, about 30 seconds later, and only then was its DevGuard attempt released. The documentation already said that gateway shutdown ends the worker's processes.After: at shutdown the gateway closes the worker's connection and waits for the worker to exit. The worker ends its processes as it exits, as an in-process runner's processes end when the gateway exits. A worker still running 5 seconds later is killed, as before.
How.
RuntimeProcess::wait_exitcloses the connection, then has the wait task give the workerWORKER_EXIT_GRACE(5 seconds) before it kills it. The close is bounded by the same grace, so a worker that no longer reads cannot hold up shutdown. A connection lost while the gateway runs gets the same grace.mainnow stops the runner it started before it returns, instead of dropping it.Also found on the Mac. A
tty: trueprocess launched through DevGuard reports a signal death asexitedwith 128 plus the signal, such as 143 for SIGTERM, not 1: it inherits descriptors, so the pinned Codex PTY spawns it on its descriptor-keeping path. #97 corrected the integration guide; this corrects theprocess_statustool description and a runner comment to match.Contract changes
process_statusdescription adds "or 128 plus the signal number when it was launched through DevGuard". That is what such a process already reports.udsmode, gateway shutdown now waits for the worker to exit: usually well under a second, at most 5 seconds before the worker is killed, or 10 when its connection is stuck too.Tests
runtime::tests::a_stopped_worker_ends_its_processesstarts a real worker with a pipe and a PTY process that each count into a file.wait_exitmust return before the grace, so the worker exited by itself, and neither count may move afterwards. With the old immediate kill it fails: the pipe process kept counting, from 1 to 15 in 1.5 seconds, while the PTY process stopped.Verified in the cloud (Linux).
CODESPACE_RUNTIME_BIN:cargo test -p codespace-server --libpassed all 32 tests.cargo fmt --check,scripts/check_docs.py(19 paired documents) andscripts/ci_plan.pypass.7024f74(scripts, docs: CS-RG qualification harness and protocol (CSRG-U6) #97 changes no Rust code except one doc comment):cargo clippy -p codespace-server --all-targets -- -D warningsis clean with and without--features devguard.CI: passed on this head (run 38391100965): format and upstream pin, plan, policy scan, clippy (root and codex-adapters), codex-runtime unit tests, macOS contracts and integration. Linux isolation is not in the plan for the runner and server components this change touches. The documentation site build passed too (run 38391102081).
On the qualification Mac (macOS 27.0, Apple M1), on this head, in a minimal environment with Rust 1.95.0: release builds of
codespace-mcpandcodespace-codex-runtimefrom this head with--features devguard, the installed release0.1.0-6e7e065-94d85365, and the same fixture authority, launch helper anddevguard-qualifyas #97's check, whose sources did not change. Before each suite nothing was charged, nocodespaceinstance was active and memory pressure was normal. Afterwards nothing stayed charged, everycodespaceinstance was retired, and the service kept its process.faultsworker-killedinudsonly).shutdowninudsmode passed in 3.3 s withended_s[0.0, 0.0]for its two process groups, as in-process mode did. On #97's check it took 33.2 s with[null, 0.0], as the pipe execution's group had not ended. The case's successor gateway wrote its first log line 1.06 s after the first gateway's input closed (1.04 s in-process); that span holds the gateway's exit, the worker's stop included.matrix --release 0.1.0-6e7e065-94d85365udsgateway stops and the runner socket.authorityrestartedtargets were admitted after 35.6 s (in-process) and 33.7 s (uds), the fixture's recovery after its hold; those of every other phase within 0.12 s.verifyThe evidence is sealed on the Mac; MANIFEST.json SHA-256 by suite:
faults6057f26fb81a59f4f8ef6f8c12ff95235ae25c10b7503c7a6f2aaa5264ddae8b,matrix577962c15c89e70b4debfe93c2f7513876fa592c6d15ff86bf7535a585121a76,authoritydad385b738361ef883928329f3ed6879f9a874ebdc32f3bdd5aed464ba6dc679.Security scenarios
udsmode any more than in in-process mode.Out of scope