From bd4b3bca9441043467919c28d05a1e03cb747232 Mon Sep 17 00:00:00 2001 From: weichen Date: Sun, 11 Oct 2026 02:18:01 +0000 Subject: [PATCH] Remove the empty -ws shell directory after each apply Why: relaxAndRemove cleared the per-exec id directory but left the -ws parent behind, so every conversation accumulated an empty husk - the live probe caught it in the workspace listing. Evidence: go test ./... green; TestOverlayCleansShellDir pins the behavior with a real bwrap roundtrip. Impact: One extra os.Remove of the (now empty) parent; failures are best-effort as before. Refs: Dev task feature/agent-s0-workspace-overlay (fix-up of #135). --- internal/tools/exec_workspace.go | 2 ++ internal/tools/exec_workspace_test.go | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/internal/tools/exec_workspace.go b/internal/tools/exec_workspace.go index c996cbe..765f2e1 100644 --- a/internal/tools/exec_workspace.go +++ b/internal/tools/exec_workspace.go @@ -386,6 +386,8 @@ func relaxAndRemove(root string) { return nil // 清理尽力而为:失败留给会话目录清理兜底 }) _ = os.RemoveAll(root) + // -ws 根目录在空时顺手移除(每会话一个壳,不清理会随会话累积)。 + _ = os.Remove(filepath.Dir(root)) } func (p *overlayProcess) Kill() error { return p.inner.Kill() } diff --git a/internal/tools/exec_workspace_test.go b/internal/tools/exec_workspace_test.go index 26a2f9a..ab9de17 100644 --- a/internal/tools/exec_workspace_test.go +++ b/internal/tools/exec_workspace_test.go @@ -231,3 +231,25 @@ func TestSandboxWorkspaceOverlayTimeoutDiscards(t *testing.T) { } func shortTimeout() time.Duration { return 1500 * time.Millisecond } + +// -ws 壳目录在空时移除(不随会话累积)。 +func TestOverlayCleansShellDir(t *testing.T) { + if _, err := exec.LookPath("bwrap"); err != nil { + t.Skip("bwrap not available") + } + old := workspaceOverlay + workspaceOverlay = true + defer func() { workspaceOverlay = old }() + dir := t.TempDir() + spec := ExecSpec{Bin: "/bin/bash", Args: []string{"-c", "echo hi"}, Dir: dir, Env: []string{"PATH=/usr/bin:/bin"}} + proc, err := sandboxBackend{}.Start(context.Background(), spec, &strings.Builder{}) + if err != nil { + t.Fatal(err) + } + if err := proc.Wait(); err != nil { + t.Fatal(err) + } + if _, serr := os.Stat(dir + "-ws"); !os.IsNotExist(serr) { + t.Fatalf("-ws shell dir must be removed when empty: %v", serr) + } +} -- 2.54.0