Skip to content

Concurrent worktree freshness fetches race on remote-tracking refs #1024

Description

@chubes4

Problem

Concurrent DMC worktree admissions run git fetch --quiet origin against the same primary repository without serializing the remote-tracking ref mutation. One fetch can fail because another process moved refs/remotes/origin/main between lock preparation and update. DMC then classifies this local concurrency race as unverified remote freshness and refuses safe worktree creation.

Reproduction evidence

While independent worktree operations were active for the same repository:

error: cannot lock ref refs/remotes/origin/main:
is at 698a2380... but expected d190efd9...

The failing operation returned worktree_freshness_unverified and recommended refreshing/retrying, even though connectivity was healthy and the remote ref had advanced successfully in the competing process.

WorktreeStalenessProbe::fetch() invokes git fetch --quiet origin before the repository mutation lock used by later worktree creation, so overlapping callers can mutate the same ref concurrently.

Expected

  • Freshness fetches for one primary repository are single-flight or execute under the repository mutation lock.
  • A ref-lock expected/actual mismatch caused by another successful local fetch is re-read and classified as converged when the resulting remote ref is valid.
  • Genuine authentication, connectivity, and timeout failures remain fail-closed.
  • Independent repositories continue fetching concurrently.

Acceptance criteria

  • A deterministic concurrent-fetch fixture reproduces the expected/actual ref race before the fix.
  • Exactly one fetch mutates a repository remote namespace at a time.
  • Waiting callers reuse or revalidate the completed result instead of issuing redundant fetches.
  • Diagnostics distinguish local fetch contention from remote freshness failure.

AI assistance

OpenAI gpt-5.6-sol via OpenCode captured the concurrent ref-lock error, inspected the freshness probe and lock ordering, searched existing trackers, and drafted this report. Chris Huber reviewed and remains responsible for it.

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