From 72a8923c3dc19d1e2ab1d5dcd996abab86daed38 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 12 Sep 2026 00:40:12 +1000 Subject: [PATCH] Cover the keep gate for unmanaged worktrees --include-unmanaged lifts only the location gate, and nothing proved the keep gate still held behind it. - assert a dirty hand-made worktree survives --include-unmanaged alone --- cmd/agentws/prune_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/agentws/prune_test.go b/cmd/agentws/prune_test.go index 2c21066..8078067 100644 --- a/cmd/agentws/prune_test.go +++ b/cmd/agentws/prune_test.go @@ -746,6 +746,23 @@ func TestPruneRemovesUnmanagedWorktreeWithFlag(t *testing.T) { } } +// --include-unmanaged only lifts the location gate. A keep verdict is a separate +// gate, so a dirty hand-made worktree still needs --include-keep to be touched. +func TestPruneIncludeUnmanagedStillObeysKeep(t *testing.T) { + f := newFixture(t) + manual := f.addManualWorktree(t, "benvin/by-hand") + if err := os.WriteFile(filepath.Join(manual, "scratch.txt"), []byte("wip\n"), 0o644); err != nil { + t.Fatal(err) + } + + srv := fakeGitea(t) + out := runOpts(t, client(srv), pruneOpts{apply: true, includeUnmanaged: true}) + assertVerdict(t, out, "benvin/by-hand", verdictKeep, "dirty") + if !exists(filepath.Join(manual, "scratch.txt")) { + t.Error("--include-unmanaged must not remove a worktree classified keep") + } +} + // A worktree whose directory was deleted leaves only a registration behind: // there is nothing to lose, so it is prunable outright. func TestPruneStaleRegistrationWithMissingDirectory(t *testing.T) {