Repository navigation
[argus patch #170] Retire a quarantined open-mode sandbox without touching a netproxy it never had - #129
Merged
Conversation
…thout touching a netproxy it never had complete_absent_teardown retried the restricted-mode teardown strictly in every mode, so the socket proxy's refusal of the fixed deer-flow-netproxy-<digest> name kept the quarantine record and every new sandbox in that thread failed (atlas-nicholas 2026-10-26, atlas-daeun 2026-10-27). Patch bytedance#142 reads the sandbox's labels, but here the container is already gone. A restricted-mode process keeps the strict cleanup; an open-mode process runs it only when the sidecar's exact name is listed, and a failed listing keeps it. Records left before the patch retire on the next create in their thread. 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.
Patch bytedance#170, argus-edit, no switch. Extends bytedance#142 to the quarantine-retirement path, which bytedance#142 missed.
What broke
After an uncertain shell outcome the provider recycles the sandbox and keeps its quarantine record until a later create proves the container absent:
_create_sandbox[_async]->_retire_absent_quarantine->_complete_quarantined_teardown->LocalContainerBackend.complete_absent_teardown. That last step retried the restricted-mode teardown strictly in every mode, starting withdocker stop deer-flow-netproxy-<digest>. The per-stack socket proxy refuses names outside the stack's prefix:The strict cleanup raised, the record stayed, and every new sandbox in that thread failed until the user moved to another thread. Gateway journal: atlas-nicholas 2026-10-26 11:02-11:04 CET (18 refusals), atlas-daeun 2026-10-27 09:36-10:04 CET (19 refusals, thread 9a38e323, sandbox
2d29ba9b54e63aeb). In both cases the recycle itself stopped the container cleanly, so bytedance#142 was doing its job on the destroy path.bytedance#142's predicate (
_may_hold_restricted_resources) cannot be reused as is: it reads the sandbox container's labels, and on this path the container is already gone, so it answers "keep the cleanup".What changes
complete_absent_teardownasks_absent_sandbox_may_hold_restricted_resources(sandbox_id)first:docker ps -a --filter name=<proxy> --format {{.Names}}). The socket proxy allows this list and filters the response to the stack's prefix. The strict cleanup runs only when that exact name is listed (a sidecar left by an earlier restricted-mode process); a lookalike longer name does not count;Each skip logs one info line:
Retiring open-mode sandbox <id> without restricted cleanup: no network proxy <name> is listed.Verified on the host through atlas-daeun's own socket proxy:
docker ps -a --filter name=deer-flow-netproxy-c1a44b2434411cc2 --format {{.Names}}exits 0 with empty output, so it is not refused.Known limit, written into the ledger: an open-mode process no longer retries networks left by an earlier restricted-mode process whose sidecar is already gone. A network listing is not on the proxy's allowlist, so there is nothing to ask. Only a restricted-to-open config switch with a partly failed teardown leaves such networks, and they do not affect open-mode creation.
Records left before this fix
They are retired automatically. The record is an empty file per generation and carries no mode. The new decision reads only the process mode and the listing, so the next create in that thread retires the record. On 2026-10-28 atlas-daeun and atlas-nicholas each hold one.
Tests
New
backend/tests/test_aio_sandbox_quarantine_open_mode_retire.py(17), with an engine fake that answers like the socket proxy (inspect gives the bytedance#154GET /infodenial plus "no such object", list is allowed and filtered, everydeer-flow-*stop/rm/network rm is refused):/-prefixed, among others) stays strict behind the proxy, and is fully removed on a raw engine;Red on the base: the 6 open-mode cases fail without the code change; the strict-mode cases pass both ways, as intended.
Locally: the new file,
test_aio_sandbox_local_backend.py,test_aio_sandbox_sockproxy_info_probe.py,test_aio_sandbox_provider.pyandtest_quarantine_retire_race_regression.py(552 passed, 3 live deselected).ruff checkandruff format --checkare clean, andcheck_patches_ledger.pypasses.Ledger
PATCHES.md row and a
## Patch #170section. No config keys, no migrations. PATCHES.md will conflict textually with other open fork PRs that append rows.Not deployed, not merged, no pin bump.
🤖 Generated with Claude Code