scripts.worktrees
Reference › scripts › worktrees
scripts/worktrees.py is the worktree lifecycle manager: it creates, provisions, lists and garbage-collects the wt-* git worktrees used for parallel work. A human or an orchestrator runs it; it has no internal imports. The provisioning rule behind it is RUL-021 (a private virtual environment with proofs for every worktree), checked by check_worktree_envs; the toolchain pinning comes from worktree_toolchain and .env handling from provision_worktree_env.
Subcommands: create NAME makes wt-<NAME> with a branch (--branch, default feat/<name>), a base (--base, default master) and a parent directory (--workspace, default ~/workspace), then provisions the environment; --no-env skips uv sync and the provenance proofs. provision PATH re-provisions an existing worktree. list shows every worktree with merge and dirty state against --target. gc removes merged and clean wt-* worktrees; it is a dry run unless --apply is given. list_worktrees parses git worktree list --porcelain, _is_merged and _merged_via_merge_commit decide whether a branch has landed, and _dirty_count and _ahead_behind report state. _copy_untracked_config brings over the ignored files a fresh worktree needs. _provision_env builds the full private environment and then runs the proofs: _prove_provenance shows the worktree interpreter imports the worktree's own source, and _prove_gil_off shows that the GIL is genuinely off. _foreign_shebang_scripts finds scripts whose interpreter lives outside the worktree.
At a glance
| Source | scripts/worktrees.py |
| Lines of code | 512 |
| Classes | 1 |
| Functions | 20 |
| Imports (internal) | none |
| Imported by | none |
| Tests that import it | none |
Class diagram
Dependency diagram
No internal imports and no importers.
API
Classes
Worktree (dataclass)
Decorators: dataclass(frozen=True) · Line 65
One entry from git worktree list — path, branch, main-checkout flag.
| Attribute | Type | Default |
|---|---|---|
path |
Path |
|
branch |
str | None |
|
is_main |
bool |
Functions
| Function | Signature | Summary |
|---|---|---|
_run |
_run(args: list[str], *, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str] |
|
_repo_root |
_repo_root(start: Path | None = None) -> Path |
|
list_worktrees |
list_worktrees(repo: Path) -> list[Worktree] |
Parse git worktree list --porcelain — first entry is the main checkout. |
_is_merged |
_is_merged(repo: Path, branch: str, target: str) -> bool |
|
_merged_via_merge_commit |
_merged_via_merge_commit(repo: Path, branch: str, target: str) -> bool |
True only when a merge commit reachable from target carries the branch tip as a parent — the signature of our --no-ff merge convention. |
_dirty_count |
_dirty_count(wt_path: Path) -> int |
|
_ahead_behind |
_ahead_behind(repo: Path, branch: str, target: str) -> tuple[int, int] |
|
_copy_untracked_config |
_copy_untracked_config(primary: Path, wt_path: Path) -> None |
Bring over the gitignored files a fresh worktree cannot live without. |
_foreign_shebang_scripts |
_foreign_shebang_scripts(venv_bin: Path, own_venv: Path) -> list[tuple[str, str]] |
Scripts in venv_bin whose shebang interpreter lives outside own_venv (or no longer exists). uv hardlinks wheel-shipped scripts from its cache, so provisioning worktree B can rewrite the… |
_provision_env |
_provision_env(repo: Path, wt_path: Path) -> int |
RUL-021 provisioning: full private .venv + every proof we have a trap for. |
_prove_provenance |
_prove_provenance(wt_path: Path, env: dict[str, str]) -> int |
Proof 1 — the worktree python imports the worktree's own src (an inherited PYTHONPATH once made a full gate test another branch's source). |
_prove_gil_off |
_prove_gil_off(wt_path: Path, env: dict[str, str]) -> int |
Proof 2 — the GIL is genuinely off with the known re-enablers imported (a GIL-re-enabling wheel sneaking in re-enables it process-wide, the SPEC-023 false-green class; grpcio is retired and banned… |
_prove_primary_venv_intact |
_prove_primary_venv_intact(repo: Path) -> int |
Proof 3 — the PRIMARY venv survived this provisioning: no console script in the primary checkout may now point at a foreign or dead interpreter (see _foreign_shebang_scripts). |
cmd_create |
cmd_create(args: argparse.Namespace) -> int |
Mint ~/workspace/wt-<NAME> on a new branch and provision its env. |
cmd_provision |
cmd_provision(args: argparse.Namespace) -> int |
(Re-)provision an EXISTING worktree — .env, wheels, venv, proofs. |
cmd_list |
cmd_list(args: argparse.Namespace) -> int |
Print every worktree with merge/dirty/ahead-behind state vs target. |
_gc_keep_reason |
_gc_keep_reason(repo: Path, wt: Worktree, target: str) -> str | None |
Why this worktree must be KEPT, or None when removal is proven safe (wt-* name, --no-ff merge commit carries the tip, tree clean). |
_gc_remove |
_gc_remove(repo: Path, wt: Worktree) -> None |
Remove a merge-proven worktree and delete its LOCAL branch only. |
cmd_gc |
cmd_gc(args: argparse.Namespace) -> int |
Remove every merge-proven, clean wt-* worktree (dry-run by default). |
main |
main(argv: list[str] | None = None) -> int |
Source
Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/scripts/worktrees.py
#!/usr/bin/env python3
"""Worktree lifecycle manager — create, track, and garbage-collect worktrees.
The workflow this encodes (RUL-021 + the session-256 worktree merge plan):
- ``create <name>``: mint ``~/workspace/wt-<NAME>`` on a new branch off
``master``, then provision a FULL private environment (``uv sync --dev``
in the worktree — never a symlinked ``.venv``) and prove source
provenance (the worktree's python imports the worktree's own ``src``).
- ``list``: one line per registered worktree — branch, dirty count,
ahead/behind master, and MERGED/UNMERGED (``git merge-base
--is-ancestor``).
- ``gc``: remove every worktree whose branch tip is ALREADY AN ANCESTOR of
master AND whose tree is clean, then delete its local branch. Prints the
ancestry proof per removal. Unmerged or dirty worktrees are NEVER
touched (user ruling, session 256: deleting an unmerged branch restarts
the whole effort). Dry-run by default; ``--apply`` to act.
``gc --apply --quiet`` is wired into SessionStart (``.claude/settings.json``)
so merged worktrees disappear on their own — the "extra folders in my
workspace" never linger past their merge.
The main checkout is structurally exempt from gc: only linked worktrees
(``git worktree list --porcelain`` entries other than the first) whose
directory name starts with ``wt-`` are candidates.
"""
from __future__ import annotations
import argparse
import importlib.util
import os
import subprocess
import sys
from dataclasses import dataclass
from pathlib import Path
# Sibling module (kept split so this file stays under its line budget — see
# its own docstring for why): loaded the same way the tests load THIS
# module, so it works regardless of how worktrees.py itself got imported.
_toolchain_spec = importlib.util.spec_from_file_location(
"worktrees_toolchain", Path(__file__).resolve().parent / "worktree_toolchain.py"
)
assert _toolchain_spec and _toolchain_spec.loader
worktree_toolchain = importlib.util.module_from_spec(_toolchain_spec)
_toolchain_spec.loader.exec_module(worktree_toolchain)
def _run(
args: list[str], *, cwd: Path | None = None, check: bool = True
) -> subprocess.CompletedProcess[str]:
return subprocess.run(
args, cwd=cwd, capture_output=True, text=True, check=check, timeout=600
)
def _repo_root(start: Path | None = None) -> Path:
out = _run(
["git", "rev-parse", "--show-toplevel"], cwd=start or Path.cwd()
).stdout.strip()
return Path(out)
@dataclass(frozen=True)
class Worktree:
"""One entry from ``git worktree list`` — path, branch, main-checkout flag."""
path: Path
branch: str | None # None when detached
is_main: bool
def list_worktrees(repo: Path) -> list[Worktree]:
"""Parse ``git worktree list --porcelain`` — first entry is the main
checkout."""
out = _run(["git", "worktree", "list", "--porcelain"], cwd=repo).stdout
entries: list[Worktree] = []
path: Path | None = None
branch: str | None = None
for line in out.splitlines() + [""]:
if line.startswith("worktree "):
path = Path(line.split(" ", 1)[1])
elif line.startswith("branch "):
branch = line.split(" ", 1)[1].removeprefix("refs/heads/")
elif not line and path is not None:
entries.append(Worktree(path=path, branch=branch, is_main=not entries))
path, branch = None, None
return entries
def _is_merged(repo: Path, branch: str, target: str) -> bool:
res = _run(
["git", "merge-base", "--is-ancestor", branch, target],
cwd=repo,
check=False,
)
return res.returncode == 0
def _merged_via_merge_commit(repo: Path, branch: str, target: str) -> bool:
"""True only when a merge commit reachable from ``target`` carries the
branch tip as a parent — the signature of our ``--no-ff`` merge
convention.
Bare ancestry is NOT enough to call a worktree removable: a FRESH
branch (no commits yet) is also an ancestor of the target, and the
2026-07-27 incident (the RUL-021 gate telling the operator to delete
three actively-worked worktrees) plus this script's own first draft
both fell into exactly that hole. A fast-forward or squash merge won't
match either — those stay a deliberate by-hand removal.
"""
if not _is_merged(repo, branch, target):
return False
tip = _run(["git", "rev-parse", branch], cwd=repo).stdout.strip()
out = _run(
["git", "rev-list", "--merges", "--parents", target],
cwd=repo,
check=False,
).stdout
for line in out.splitlines():
parts = line.split()
if len(parts) >= 3 and tip in parts[1:]:
return True
return False
def _dirty_count(wt_path: Path) -> int:
out = _run(["git", "status", "--porcelain"], cwd=wt_path).stdout
return len([ln for ln in out.splitlines() if ln.strip()])
def _ahead_behind(repo: Path, branch: str, target: str) -> tuple[int, int]:
out = _run(
["git", "rev-list", "--left-right", "--count", f"{target}...{branch}"],
cwd=repo,
check=False,
).stdout.split()
if len(out) != 2:
return (0, 0)
return (int(out[1]), int(out[0])) # (ahead of target, behind target)
def _copy_untracked_config(primary: Path, wt_path: Path) -> None:
"""Bring over the gitignored files a fresh worktree cannot live without.
- ``.env`` (RUL-019: every entrypoint auto-loads it; the file only
exists in the primary checkout).
- ``vendor/wheels/*`` — the vendored free-threaded wheels are
GITIGNORED, so a fresh worktree's ``[tool.uv.sources]`` pins resolve
to nothing and ``uv`` falls back to sdist builds that re-enable the
GIL (the exact wt-QWEN incident RUL-021 documents). Hardlink from
the primary (copy across filesystems).
The codebase maps are not copied: both are tracked (RUL-030) and the
pre-commit hook regenerates them, so every checkout already has them.
"""
import shutil
env_file = primary / ".env"
if env_file.exists():
shutil.copy2(env_file, wt_path / ".env")
print("copied .env from primary checkout")
else:
print("NOTE: primary has no .env — entrypoints will run without one")
src_wheels = primary / "vendor" / "wheels"
if src_wheels.is_dir():
dst_wheels = wt_path / "vendor" / "wheels"
dst_wheels.mkdir(parents=True, exist_ok=True)
linked = 0
for whl in sorted(src_wheels.glob("*.whl")):
dst = dst_wheels / whl.name
if dst.exists():
continue
try:
os.link(whl, dst)
except OSError:
shutil.copy2(whl, dst)
linked += 1
print(f"vendored wheels: {linked} hardlinked/copied from primary")
def _foreign_shebang_scripts(venv_bin: Path, own_venv: Path) -> list[tuple[str, str]]:
"""Scripts in ``venv_bin`` whose shebang interpreter lives outside
``own_venv`` (or no longer exists). uv hardlinks wheel-shipped scripts
from its cache, so provisioning worktree B can rewrite the shared inode
and point checkout A's script at B's (later-deleted) venv — this
poisoned the primary's basedpyright-langserver via wt-ENGINE and
silently failed 39 rename/LSP tests."""
poisoned: list[tuple[str, str]] = []
if not venv_bin.is_dir():
return poisoned
for script in venv_bin.iterdir():
if not script.is_file():
continue
try:
with script.open("rb") as fh:
head = fh.readline(512)
except OSError:
continue
if not head.startswith(b"#!"):
continue
interp = head[2:].decode("utf-8", "replace").strip().split()[0:1]
if not interp:
continue
interp_path = Path(interp[0])
if "python" not in interp_path.name:
continue
if not str(interp_path).startswith(str(own_venv)) or not interp_path.exists():
poisoned.append((script.name, str(interp_path)))
return poisoned
def _provision_env(repo: Path, wt_path: Path) -> int:
"""RUL-021 provisioning: full private .venv + every proof we have a
trap for. Returns 0 on success."""
_copy_untracked_config(repo, wt_path)
# Scrub PYTHONPATH so nothing here ever resolves the main checkout,
# and force copy-mode installs: uv's default hardlink mode shares
# script inodes across venvs via its cache, letting this provision
# rewrite the PRIMARY checkout's console scripts (the basedpyright
# shebang-poisoning incident).
env = {k: v for k, v in os.environ.items() if k != "PYTHONPATH"}
env["UV_LINK_MODE"] = "copy"
# RUL-021 extended (2026-09-23): a Guix gcc shadowing /usr/bin/gcc on
# PATH, plus the C_INCLUDE_PATH/CPLUS_INCLUDE_PATH it leaks ahead of the
# 3.14t headers, silently drops native extensions from the build while
# `uv sync` still exits 0 (measured: janus_swi, cxpt, ctok,
# codemod-fast). Pin the DECLARED toolchain (env/toolchain.env) before
# syncing; an unusable declaration refuses the provision rather than
# letting the build fall back to whatever `gcc` leads PATH.
#
# RUL-040 (2026-10-20): UV_NO_EDITABLE=1 is required so a bare `uv sync`
# produces a proper non-editable install. Without it, a second coordinator
# session would silently revert to editable installs, undoing Mohamed's
# ruling ("if love install is sym links or in place, no, i want a propper
# install"). The env var is set in .envrc for interactive shells; this
# provisioner runs where .envrc never loads (worktrees, systemd units,
# container builds), so the flag must be explicit here.
try:
env = worktree_toolchain.pin_system_toolchain(env)
except worktree_toolchain.ToolchainDeclarationError as exc:
print(f"ERROR: {exc}", file=sys.stderr)
return 1
print("provisioning .venv (uv sync --dev --no-editable, UV_LINK_MODE=copy)...")
sync = subprocess.run(
["uv", "sync", "--dev", "--no-editable"],
cwd=wt_path,
env=env,
capture_output=True,
text=True,
timeout=1800,
)
if sync.returncode != 0:
print(sync.stdout[-2000:], file=sys.stderr)
print(sync.stderr[-2000:], file=sys.stderr)
print(
"ERROR: uv sync failed — worktree left in place; fix and re-run "
"`worktrees.py provision`",
file=sys.stderr,
)
return 1
# FAIL LOUD when `uv sync` reported success but a locally-sourced
# (path/directory/editable) package it names in uv.lock silently never
# got built — the exact failure mode a shadowed toolchain produces.
if worktree_toolchain.check_locked_packages_importable(wt_path, env) != 0:
return 1
if _prove_provenance(wt_path, env) != 0:
return 1
if _prove_gil_off(wt_path, env) != 0:
return 1
if _prove_primary_venv_intact(repo) != 0:
return 1
print(f"ready. Work with: cd {wt_path} && env -u PYTHONPATH .venv/bin/python ...")
return 0
def _prove_provenance(wt_path: Path, env: dict[str, str]) -> int:
"""Proof 1 — the worktree python imports the worktree's own src (an
inherited PYTHONPATH once made a full gate test another branch's
source)."""
wt_python = str(wt_path / ".venv" / "bin" / "python")
prove = subprocess.run(
[
wt_python,
"-c",
"import orchestrata_ultimate; print(orchestrata_ultimate.__file__)",
],
cwd=wt_path,
env=env,
capture_output=True,
text=True,
timeout=120,
)
resolved = prove.stdout.strip()
if not resolved.startswith(str(wt_path)):
print(
f"ERROR: source provenance FAILED — worktree python resolves "
f"{resolved!r}, expected a path under {wt_path}",
file=sys.stderr,
)
return 1
print(f"provenance OK: {resolved}")
return 0
def _prove_gil_off(wt_path: Path, env: dict[str, str]) -> int:
"""Proof 2 — the GIL is genuinely off with the known re-enablers
imported (a GIL-re-enabling wheel sneaking in re-enables it
process-wide, the SPEC-023 false-green class; grpcio is retired and
banned in .claude/banned-libraries.txt, so msgpack is the remaining
canary here)."""
wt_python = str(wt_path / ".venv" / "bin" / "python")
gil = subprocess.run(
[wt_python, "-c", "import msgpack, sys; print(sys._is_gil_enabled())"],
cwd=wt_path,
env=env,
capture_output=True,
text=True,
timeout=120,
)
if gil.stdout.strip() != "False":
print(
"ERROR: GIL check FAILED — expected sys._is_gil_enabled() == "
f"False after importing msgpack, got: "
f"{(gil.stdout + gil.stderr).strip()!r}",
file=sys.stderr,
)
return 1
print("GIL check OK: off with msgpack imported")
return 0
def _prove_primary_venv_intact(repo: Path) -> int:
"""Proof 3 — the PRIMARY venv survived this provisioning: no console
script in the primary checkout may now point at a foreign or dead
interpreter (see _foreign_shebang_scripts)."""
primary_venv = repo / ".venv"
poisoned = _foreign_shebang_scripts(primary_venv / "bin", primary_venv)
if poisoned:
for name, interp in poisoned:
print(
f"ERROR: primary venv script {name!r} shebang points at "
f"{interp} — poisoned by cross-venv inode sharing. Repair: "
f"uv sync --dev --reinstall-package <owning-package> in the "
f"primary checkout.",
file=sys.stderr,
)
return 1
print("primary venv scripts OK: no foreign shebangs")
return 0
def cmd_create(args: argparse.Namespace) -> int:
"""Mint ~/workspace/wt-<NAME> on a new branch and provision its env."""
repo = _repo_root()
name = args.name.upper()
branch = args.branch or f"feat/{args.name.lower()}"
wt_path = Path(args.workspace).expanduser() / f"wt-{name}"
if wt_path.exists():
print(f"ERROR: {wt_path} already exists", file=sys.stderr)
return 1
base = args.base
_run(["git", "worktree", "add", "-b", branch, str(wt_path), base], cwd=repo)
print(f"created {wt_path} on branch {branch} (base {base})")
if args.no_env:
print("SKIPPED env provisioning (--no-env) — RUL-021 requires a full")
print("private .venv before any test/gate runs in this worktree.")
return 0
return _provision_env(repo, wt_path)
def cmd_provision(args: argparse.Namespace) -> int:
"""(Re-)provision an EXISTING worktree — .env, wheels, venv, proofs."""
repo = _repo_root()
wt_path = Path(args.path).expanduser().resolve()
if not (wt_path / ".git").exists():
print(f"ERROR: {wt_path} is not a git worktree", file=sys.stderr)
return 1
return _provision_env(repo, wt_path)
def cmd_list(args: argparse.Namespace) -> int:
"""Print every worktree with merge/dirty/ahead-behind state vs target."""
repo = _repo_root()
target = args.target
for wt in list_worktrees(repo):
if wt.is_main:
print(f"{wt.path} [main checkout] branch={wt.branch}")
continue
if wt.branch is None:
print(f"{wt.path} DETACHED — resolve by hand")
continue
merged = _is_merged(repo, wt.branch, target)
dirty = _dirty_count(wt.path)
ahead, behind = _ahead_behind(repo, wt.branch, target)
state = "MERGED" if merged else "UNMERGED"
print(
f"{wt.path} branch={wt.branch} {state} "
f"dirty={dirty} ahead={ahead} behind={behind} (vs {target})"
)
return 0
def _gc_keep_reason(repo: Path, wt: Worktree, target: str) -> str | None:
"""Why this worktree must be KEPT, or None when removal is proven safe
(wt-* name, --no-ff merge commit carries the tip, tree clean)."""
assert wt.branch is not None
if not wt.path.name.startswith("wt-"):
return f"{wt.path}: name outside the wt-* convention — skipped"
if not _is_merged(repo, wt.branch, target):
return f"{wt.path}: branch {wt.branch} NOT merged into {target}"
if not _merged_via_merge_commit(repo, wt.branch, target):
return (
f"{wt.path}: tip is in {target} but NO merge commit references "
f"it (fresh branch, or a ff/squash merge) — remove by hand if "
f"truly merged"
)
dirty = _dirty_count(wt.path)
if dirty:
return f"{wt.path}: merged but {dirty} dirty file(s) — resolve by hand"
return None
def _gc_remove(repo: Path, wt: Worktree) -> None:
"""Remove a merge-proven worktree and delete its LOCAL branch only."""
assert wt.branch is not None
_run(["git", "worktree", "remove", str(wt.path)], cwd=repo)
_run(["git", "branch", "-D", wt.branch], cwd=repo)
print(f" removed worktree + deleted local branch {wt.branch}")
print(
f" (remote branch, if pushed, is untouched — "
f"`git push origin --delete {wt.branch}` to clear it)"
)
def cmd_gc(args: argparse.Namespace) -> int:
"""Remove every merge-proven, clean wt-* worktree (dry-run by default)."""
repo = _repo_root()
removed = 0
kept: list[str] = []
for wt in list_worktrees(repo):
if wt.is_main or wt.branch is None:
continue
reason = _gc_keep_reason(repo, wt, args.target)
if reason is not None:
kept.append(reason)
continue
tip = _run(["git", "rev-parse", wt.branch], cwd=repo).stdout.strip()[:12]
verb = "removing" if args.apply else "[WOULD remove]"
print(
f"{verb} {wt.path} — merge proven: {wt.branch} ({tip}) is a "
f"merge-commit parent in {args.target} history, tree clean"
)
if args.apply:
_gc_remove(repo, wt)
removed += 1
if not args.quiet:
for line in kept:
print(f"KEEP {line}")
if not removed and not kept:
print("no linked worktrees registered")
if not args.apply and removed:
print(f"{removed} removable — pass --apply to act")
return 0
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
description="Worktree lifecycle manager — create, track, and gc worktrees."
)
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("create", help="mint wt-<NAME> + branch + full env")
p.add_argument("name", help="worktree tag; dir becomes wt-<NAME-uppercased>")
p.add_argument("--branch", default=None, help="branch name (default feat/<name>)")
p.add_argument("--base", default="master", help="base ref (default master)")
p.add_argument(
"--workspace", default="~/workspace", help="parent dir for worktrees"
)
p.add_argument(
"--no-env",
action="store_true",
help="skip uv sync + provenance (env must be provisioned before use)",
)
p.set_defaults(fn=cmd_create)
p = sub.add_parser(
"provision", help="(re-)provision an existing worktree's env + proofs"
)
p.add_argument("path", help="worktree directory")
p.set_defaults(fn=cmd_provision)
p = sub.add_parser("list", help="show every worktree with merge/dirty state")
p.add_argument("--target", default="master")
p.set_defaults(fn=cmd_list)
p = sub.add_parser("gc", help="remove merged+clean wt-* worktrees")
p.add_argument("--apply", action="store_true", help="act (default: dry-run)")
p.add_argument("--target", default="master")
p.add_argument("--quiet", action="store_true", help="only print removals")
p.set_defaults(fn=cmd_gc)
args = parser.parse_args(argv)
return int(args.fn(args))
if __name__ == "__main__":
raise SystemExit(main())