Skip to content

Define idempotent worktree reuse and isolated recycle semantics #982

Description

@chubes4

Problem

Local managed worktree creation has no reuse or recycling contract. A request deterministically maps to <repo>@<branch-slug>; if that directory exists, creation fails with worktree_exists. If callers choose another branch name for the same task or equivalent content, DMC creates another isolated worktree. Duplicate task ownership is reporting-only.

This contributes directly to ghost-worktree accumulation: the 2026-07-28 cleanup incident found 403 managed worktrees and 27 duplicate-task groups, including tasks represented by 4-11 worktrees. Cleanup then has to infer which copy is authoritative after the fact.

Source evidence

  • Handle construction and existing-path refusal: inc/Workspace/WorkspaceWorktreeLifecycle.php:98-113, repeated under lock at :261-263.
  • New requests always call git worktree add: WorkspaceWorktreeLifecycle.php:284-308.
  • Duplicate task detection reports but does not prevent, adopt, or reuse: inc/Workspace/WorktreeContextInjector.php:352-400 and WorkspaceWorktreeLifecycle.php:987-1002.
  • Patch equivalence exists only during cleanup, not admission/reuse: inc/Workspace/WorkspaceWorktreeCleanupEngine.php:3353-3362.
  • Primaries already deduplicate by remote, proving an owning identity model exists: inc/Workspace/WorkspaceRepositoryLifecycle.php:198-221,515-530.

Desired contract

Make reuse explicit rather than silently weakening isolation:

  1. Same handle + same branch + clean compatible checkout: return/adopt the existing managed worktree idempotently.
  2. Same task + equivalent clean candidate: report a deterministic reuse candidate and require caller policy to reuse or create isolated work.
  3. Dirty, unpushed, live, mismatched-base, or incompatible-runtime worktrees: preserve isolation and refuse automatic reuse.
  4. Terminal clean worktrees: allow an explicit recycle operation that resets only after safety proof and records lineage.
  5. Always expose why reuse was accepted or refused, including task identity, HEAD/base identity, liveness, dirty/unpushed state, and context/bootstrap compatibility.

Acceptance criteria

  • Repeating the exact same add request is idempotent when the existing worktree is clean and compatible.
  • Task-backed admission can detect existing candidates before allocating another branch/directory.
  • Reuse never crosses dirty, unpushed, live, or incompatible context/runtime boundaries.
  • Recycled worktrees retain durable old/new lineage and task ownership evidence.
  • Callers can explicitly request isolated, reuse-compatible, or recycle-terminal behavior.
  • Tests cover exact-handle reuse, duplicate-task candidates, patch-equivalent candidates, live/dirty refusal, base drift, and context/bootstrap drift.
  • Hygiene reports preventable duplicate allocation separately from cleanup backlog.

Recommendation

Prefer conservative idempotent reuse for exact requests. Keep broader task/content recycling opt-in until compatibility dimensions are proven. Reuse should reduce repeated bootstrap and disk cost without allowing cross-task state leakage.

Incident evidence

  • Workspace: /Users/chubes/Developer
  • Initial worktrees: 403
  • Duplicate task groups: 27
  • Workspace subtree before cleanup: 271 GiB
  • Cleanup required several plan/apply/resume passes and still retained hundreds of stale/active-no-signal rows.

AI assistance

  • Model: OpenAI GPT-5.6 Sol
  • Tool: OpenCode
  • Used for: live incident reproduction, source inspection, duplicate search, and issue drafting. Chris directed the investigation and owns the recommendation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions