Repository navigation
fix(sandbox): end runs that stay paused beyond a pause budget - #234
Merged
Merged
Conversation
A paused run keeps its runner, admission and frozen container, and the pause clock had no limit. `docker pause` also freezes the sandbox's `timeout --signal=KILL`, so the documented hard lifetime "including paused time" never fired for a paused container; a forgotten paused tab held its capacity for as long as its WebSocket answered pings. - SIMULATION_MAX_PAUSED_SECONDS (default 600, below the hard lifetime) bounds the total paused time of a run. - When the budget runs out while paused, the runner ends the run like the runtime timeout: notice, termination, then onExit releases runner, admission and container and the client receives the stopped status. - Pause/Resume SSOT, SECURITY, INSTALL_SERVER and ARCHITECTURE describe the actual semantics; Compose passes the value through. Co-Authored-By: Claude Opus 5.5 <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.
Root cause (verified)
SimulationTimeoutManagerstops the runtime clock during a pause, and nothing bounded the paused time.docker pausefreezes every process of the container via the cgroup freezer, including PID 1, thetimeout --signal=KILLhard lifetime. The documented "7200 s wall clock, including paused time" therefore never fired for a paused container.Proof on the old code:
tests/integration/paused-run-budget.test.ts(real Docker): the container stayedPausedand the run never ended; the test timed out.tests/server/services/sandbox-runner-pause-budget.test.ts: 2 of 3 cases red.Fix
SIMULATION_MAX_PAUSED_SECONDS(default 600 s, min 10) bounds the total paused time of a run. A run that pauses and resumes repeatedly cannot extend its hold that way.SANDBOX_MAX_LIFETIME_SECONDS.SandboxRunnerstarts a budget timer on a committed pause and clears it on resume, stop and reset.--- Simulation stopped: paused longer than N s ---;terminationRequestedandSIGKILLof the run process;onExit, which releases runner and admission;docker rm -f;simulation_status: stopped.PAUSED → STOPPEDis now also possible server-side, and the new section 7.2 describes the pause budget;SECURITY.md,INSTALL_SERVER.md(incl. the variable table) andARCHITECTURE.md: the hard lifetime applies to running sandboxes; paused ones are bounded by the backend.Tests
tests/integration/paused-run-budget.test.ts(integration-docker, real frozen container): after the pause budget the run ends with the notice andonExit, and the container is removed.tests/server/services/sandbox-runner-pause-budget.test.ts:tests/server/routes/simulation-paused-run-end.test.ts: a paused session whose run ends releases admission and runner over the real WS route and reportsstopped.Existing tests are unchanged.
npm run check,npm run test:unit,npm run check:docs, Knip,git diff --check,docker compose configand the full./run-tests.sh(incl. toolchain, Docker, E2E, build, audit, Sonar) are green, also after rebasing onto #233. The pre-push gate is green as well.Product decision documented in the SSOT: a default of 10 minutes total pause per run. The maximum run time is 5 minutes, so this is generous for debugging and still frees capacity reliably.
🤖 Generated with Claude Code