agentleFS
komlukkomluk/scaffolding/skills/worktree-management/SKILL.md

worktree-management

Skill16 starsChanged 5 days agoMITView on GitHub

Scaffolding worktree lifecycle, diagnostics, and recovery. TRIGGER when: debugging worktree isolation, recovering a stuck worktree, or managing task isolation. SKIP: ordinary branch/commit/merge operations (use git-operations).

  • Deletes or force-pushes

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If a worktree has no new commits after an agent finishes, the changes are uncommitted — gitops must commit them BEFORE merge.

    line 20
  2. Very specific:

    When Agent Teams is enabled (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, see docs/agent-teams.md), multiple writer teammates may run …

    line 24
  3. Very specific:

    Per-teammate isolation: every writer gets its OWN worktree .scaffolding/worktrees/{task_id[:12]} AND its OWN unique SCAFFOLDING_TASK_ID.

    line 28
  4. Very specific:

    No two writers share a working tree or a /tmp/scaffolding-mtime-${TASK_ID}.json staleness store — sharing would trip …

    line 30
  5. Distinctive:

    Never delete remote branches here.

    line 129
  6. Very specific:

    REMOVE only if no uncommitted tracked changes AND the work is in origin/<default> (no commits ahead, patch-equivalent, or squash-merged: …

    line 143

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Worktree Management Skill

Purpose

Scaffolding.tool-specific worktree lifecycle management, diagnostics, and recovery procedures.

Live worktrees: !git worktree list 2>/dev/null || true

CRITICAL: Only gitops Touches Git

Other agents (developer, architect) do NOT commit. The worktree flow is:

  1. Agent writes code/tests in worktree
  2. gitops commits, merges to main, pushes, cleans up (MANDATORY)

If a worktree has no new commits after an agent finishes, the changes are uncommitted — gitops must commit them BEFORE merge.

Parallel Teammates: Isolation + Serialized Merge

When Agent Teams is enabled (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, see docs/agent-teams.md), multiple writer teammates may run concurrently. The worktree model makes this safe ONLY if both hold:

  • Per-teammate isolation: every writer gets its OWN worktree .scaffolding/worktrees/{task_id[:12]} AND its OWN unique SCAFFOLDING_TASK_ID. No two writers share a working tree or a /tmp/scaffolding-mtime-${TASK_ID}.json staleness store — sharing would trip file-staleness-check.sh between them and produce unattributable interleaved changes.
  • Serialized merge: gitops remains the SOLE committer and merges worktree branches to main ONE AT A TIME through the merging→merged states below. Parallel work is allowed; parallel committing/merging is not — only one merge is ever in flight.

Worktree Lifecycle

create_worktree() --> agent executes (no commit) --> gitops: commit
    --> gitops: merge_to_main() --> gitops: push --> gitops: cleanup

States (WorktreeStatus enum)

StatusMeaning
readyCreated, waiting for task execution
mergingMerge in progress
mergedSuccessfully merged to main
conflictMerge conflict detected
cleanupBeing removed
removedFully cleaned up

File Locations

ResourcePath
Worktrees directory.scaffolding/worktrees/ (local real dir, never on NFS)
Task worktree.scaffolding/worktrees/{task_id[:12]}/ — branch scaffolding/{task_id[:12]}
Worktree metadata.scaffolding/worktrees/{task_id[:12]}/worktree.json
Thread worktree.scaffolding/worktrees/threads/{id8}/
Named worktree.scaffolding/worktrees/<name>/ — plugin WorktreeCreate hook, branch worktree-<name> (/ in the name becomes +)

.claude/worktrees/ is no longer used.

Conversations inside a worktree

Inside a worktree, .scaffolding/conversations is a symlink to the same share target as the main checkout (readlink -f of the main link). A spec written from a worktree therefore lands on the share and survives worktree removal. The WorktreeCreate hook creates this link; the WorktreeRemove hook deletes only the link, never the target. Do not copy conversation files into a worktree, and do not rm -rf through the link.

The WorktreeRemove hook only removes registered worktrees under the main checkout's .scaffolding/worktrees/. Dirs without worktree.json are not platform-made; the platform sweep must leave them alone.

Diagnostics

List All Worktrees

git worktree list
ls -la .scaffolding/worktrees/

Find Uncommitted Changes

for d in .scaffolding/worktrees/*/; do
  changes=$(cd "$d" && git status --porcelain 2>/dev/null | wc -l)
  if [ "$changes" -gt 0 ]; then
    echo "UNCOMMITTED: $d ($changes files)"
  fi
done

Recovery Procedures

Force Remove Corrupt Worktree

git worktree remove --force .scaffolding/worktrees/{task_id[:12]}
git branch -D scaffolding/{task_id[:12]}
rm -rf .scaffolding/worktrees/{task_id[:12]}
git worktree prune

Recover Uncommitted Work

cd .scaffolding/worktrees/{task_id[:12]}
git add -A && git stash
cd /project/root && git stash pop

Post-Finish Cleanup (MANDATORY after every merge or discard)

Cleanup is the final step of every merge, for ANY worktree gitops worked in (.scaffolding/worktrees/..., ~/.cache/worktrees/..., anywhere). Do it for squash-merged PRs too.

# from the main checkout, never from inside the worktree
git -C <worktree> status --porcelain --untracked-files=no   # must be empty
git worktree remove <worktree>     # --force only for untracked build output (node_modules)
git branch -D <branch>
git worktree prune
  • Uncommitted tracked changes -> REFUSE, keep worktree + branch, report the files.
  • Report the cleanup in the final report.
  • Never delete remote branches here.

Note: Only merge and discard clean up. PR-open and keep actions leave the worktree intact (clean up after the PR is merged).

Sweeping stale worktrees: /worktree-gc

WorktreeRemove only sees worktrees made by worktree-create.sh. Plain git worktree add ones (e.g. ~/.cache/worktrees/<name>) and squash-merged branches are caught by scripts/worktree-gc.sh:

bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-gc.sh"                      # dry run
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-gc.sh" --apply              # remove
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-gc.sh" --all-repos ~/repos  # every repo under a dir

REMOVE only if no uncommitted tracked changes AND the work is in origin/<default> (no commits ahead, patch-equivalent, or squash-merged: remote ref gone + commit subjects in origin/<default>). Unsure -> KEEP.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.