Skip to content

P2.5 — Concurrent Worktree Ownership (councilled 2026-07-10)

Council: fable tier, unanimous Claude>Codex>Gemini>Local>Grok. Report: llm-council/reports/2026-07-10_181242_strategic-decision-next-course-of-action.md. Memory: concurrent-worktree-ownership.md. Pairs with the already-ruled multi-session-ff-push-pattern.

Inserted BEFORE P3 because P3–P6 are themselves built by concurrent sessions. Andrew hard requirement: concurrent agents each OWNING a worktree is first-class, not an accident to avoid.

Model

One session ↔ one worktree ↔ one branch ↔ one ticket. Main checkout = integration landing zone only — nobody builds in it; landing = lease-pinned FF push to origin (see multi-session-ff-push-pattern). Branch name wt/WT-xxxx/<ticket> — git already refuses to check out the same branch in two worktrees, so the branch name IS a free hard lock, visible in git branch.

Authority split (the central ruling)

  • Local registry is THE lock. ~/.claude/worktree-identity/registry.json (already atomic: lock-file + temp-swap). A PC must be able to claim/commit even with the memory server unreachable — the house Wi-Fi has drifted to NSBE before, and a network drop must never block a local commit or fail open.
  • membus worktree-ownership scope is ADVISORY. Carries claim/renew/release/takeover events with provenance for fleet visibility (telegram, other agents). NOT the lock authority (rejected Gemini's SSOT and Local's transactional-bus proposals).
  • Cross-PC ownership is lease-based, never filesystem-lock-based.

Claim record (extend the WT registry entry)

repoId            # stable id for the repo (origin URL hash or path)
worktreePath      # absolute local path
branch            # wt/WT-xxxx/<ticket>
ticket            # board ticket
host              # COMPUTERNAME
sessionId / pid   # liveness
harnessKind       # claude|codex|agy|grok|ollama|odysseus
model
role              # implementer | reviewer-readonly | observer
state             # claimed | active | in-review | releasing | retired
lane              # owning lane's WT id — see governance-mode consolidation below
leaseExpiresUtc
lastHeartbeatUtc
allowedPaths      # optional path scoping within the worktree

Governance-mode lanes (usage-governor/docs/worktree-consolidation.md)

Under a restricted governor tier, live CLAUDE sessions collapse into priority lanes (GREEN=uncapped, YELLOW=5, RED=3, BLACKOUT=1). The lane cap counts Claude sessions only — Codex/Gemini/Grok/local harness workers are the offload targets and are NOT capped by it, BUT every harness job/worktree claim MUST carry a lane (owning lane's WT id): no orphan harness work. fleet-dispatch rejects (fails closed, like unknown-kind) a harness job with no lane owner; the membus worktree-ownership event carries lane so the telegram surface can render per-lane (not per-worktree) rows + queue depth under YELLOW+. The 3 RED lanes: COMMS (gov:build), MULTI-MODEL (gov:orch — this epic), OPS/GATE (gov:ops).

Lease renewal: UserPromptSubmit hook each turn (turn-based sessions); a 30–60s timer for detached loops only (too heavy for turn sessions).

Enforcement — PreToolUse hook (not just git hooks)

A PreToolUse hook blocks the agent BEFORE the git command runs — faster than pre-commit, catches mid-build clobbers (the QueueService incident a pre-commit hook never sees), wastes no tokens.

Deny, when the checkout's registered owner ≠ this session's WT id: git commit, git checkout, git reset, git clean, and file writes into that checkout. Fail-closed on unregistered repos. fleet-dispatch fails closed on unknown worktrees (mirrors the unknown-kind dead-letter pattern from P2).

STATUS: P2.5 PROPER SHIPPED 2026-07-11 (all council-reviewed + landed)

  • worktree-identity @0fae814 — registry ownership fields + lease + claim/release/list verbs + PreToolUse ownership enforcement (158 tests). Exe redeployed to C:\Tools.
  • membus @2cc5f5b — worktree-ownership scope, all-harness write (80 tests).
  • fleet-dispatch @fa8bc93 — signed lane on every job (fail-closed lane-less), worktree list/claim/release verbs (93 tests). Council (Codex) findings all fixed: dead-pid-lock (P1), -C target bypass (P2), local pwsh-quoting regression, ownership-event JSON escaping. Ownership enforcement inert until a session runs worktree claim (unregistered=lenient). NEXT: wire the UserPromptSubmit hook to auto-claim/renew per session + the fleet-dispatch worktree verbs into session bootstrap; then P3 briefs.

STATUS: Phase 1 SHIPPED 2026-07-10 (origin/master worktree-identity @60a7c24)

The clobber guard is LIVE fleet-wide: PreToolUseGuard (worktree-identity) + a PreToolUse hook (worktree-identity.exe hook-pretool, registered in settings.json Bash|PowerShell) denies broad git staging (add -A/--all/-u/./*/pathspec-magic incl. :! :^ exclude + dir globs), commit -a, commit --amend. CLAUDE.md carries the "## Concurrent worktrees" line. Council-reviewed (Codex+Gemini): closed bypasses = exclude-only pathspec, subshell/block hiding ($(git add -A)), dir globs, global-option-with-value, single-quote escape inversion. Shell-syntax-aware tokenizer. 142 tests + live 17/17 deny/allow verified; exe redeployed from the landed commit. NOTE (process): built by a Codex offload in its OWN worktree (wt/WT-2505/polyharness-p25) — Codex's spawned reviewer and Claude's council both hardened the same file concurrently and briefly collided (the exact hazard this fixes). Converged cleanly, but the lesson stands: Phase 2's reviewer-read-only rule and ownership lock are what prevent this. Phase 2 (leases/registry/membus/fleet verbs) still owed.

Smallest safe change — SHIP TODAY (hours, no new service)

Targets the two RECORDED failure modes; covers interactive sessions that never touch fleet-dispatch: 1. Owner marker + registry stamp per checkout; PreToolUse hook denies commits/writes in a checkout owned by another LIVE WT id. 2. Ban git add . / git add -A / git commit -a in shared checkouts — kills the sweep-uncommitted-files incident outright. Require explicit path staging. 3. One brief/CLAUDE.md line: new work = git worktree add first; never build in main.

Leases, membus broadcast, telegram enumeration follow in P2.5 proper.

Fleet surface

fleet-dispatch gains worktree list | claim | release verbs. Telegram command center subscribes to the membus scope and renders the acceptance matrix PC × repo × worktree × branch × owner × harness × model × state × lease. Takeover requires expired lease + dead pid (or explicit release); recorded as an event.

Later-phase rules seeded here

  • P4 reviewers are read-only — never commit to an author's worktree.
  • P5 DR standbys never auto-take ownership — takeover only on expired lease + policy.

Risks / hard rules

  • Worktrees share .git but NOT bin/obj/node_modules — GBs each on WorkWingman. Cap ~4–6 per repo per PC; shared NuGet/npm caches; janitor prunes artifacts.
  • Orphans = biggest operational risk. Crashed sessions leak dirty worktrees + stale branches. Lease expiry + dead-pid check + scheduled git worktree prune; a dirty stale worktree is MARKED, never auto-deleted.
  • NEVER put worktrees on OneDrive/SMB (unanimous). OneDrive syncing .git corrupts repos; SMB locking is unreliable. Each PC owns its clone + local-disk worktrees; cross-PC coordination via origin + membus only.
  • Windows: running Electron/dotnet processes hold file locks that block prune; long-path limits — keep worktree roots short (C:\wt\).

STATUS: P2.5 PROPER DONE 2026-07-11 (all CI green)

  • worktree-identity 0fae814 (158 tests): claim schema + lane, worktree claim/release/list, lease renewal via UserPromptSubmit hook, dead-owner takeover (lease cross-host / pid same-host), PreToolUse ownership enforcement. Exe redeployed to C:\Tools (ownership inert until a session runs worktree claim).
  • membus 2cc5f5b (80 tests): worktree-ownership scope, writable by ALL harnesses, advisory.
  • fleet-dispatch fa8bc93 (93 tests): signed Lane on every job, lane-less jobs fail closed, worktree list/claim/release verbs.
  • Council-reviewed (Codex); fixes applied: dead-pid lock (P1), -C ownership-target bypass (P2), local-verb PowerShell-quoting regression, ownership-event JSON serialization.
  • Next: P3 brief packs (propagate the claim/lane protocol into every harness's rules).

Build split (RED budget)

Claude writes this spec + reviews. Codex implements the C# (worktree-identity ownership fields, PreToolUse enforcement hook, fleet-dispatch worktree verbs, membus worktree-ownership scope producer/consumer). Tests run detached. Every commit passes the council review gate; Claude final.