Skip to content

feat(miner-hands): git-worktree-per-attempt isolation primitive - #4547

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
jeffrey701:feat/miner-worktree-allocator
Jul 10, 2026
Merged

feat(miner-hands): git-worktree-per-attempt isolation primitive#4547
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
jeffrey701:feat/miner-worktree-allocator

Conversation

@jeffrey701

Copy link
Copy Markdown
Contributor

What & why

Closes #4269.

The roadmap's stated concurrency primitive for parallel attempts: each coding-agent attempt runs in its own git worktree so multiple attempts (same or different issues) never collide on a shared working directory. This is greenfield — grep -rln "worktree" scripts/ .github/ has zero hits, so there was no existing pattern in the repo's own tooling to mirror.

New file packages/gittensory-engine/src/miner/worktree-allocator.ts (path coordinated with #4262's src/miner/ home), split into a pure planning layer and thin injected-exec wrappers — mirroring the SpawnFn injection convention from #4262/#4266 — so all naming/collision/lifecycle logic is unit-testable without shelling out to git in CI.

Deliverables

  • Pure planning layerplanWorktree({ repoPath, attemptId }) computes the deterministic worktree path (<repo>/.gittensory-worktrees/<slug>) and branch (gittensory/attempt/<slug>). Pure, no IO.
  • Collision handling — naming is keyed on the attempt id, never a random suffix. Two concurrent attempts with distinct ids can never be handed the same path or branch; the same id always maps to the same location, so a crashed attempt's worktree is identifiable and cleanable after the fact. Ids are slugified to a filesystem- and git-ref-safe token and length-capped (64), rejecting an id that sanitizes to nothing.
  • Injected-exec wrappersaddWorktree() runs git worktree add -b <branch> <path> <base> and removeWorktree() runs git worktree remove --force <path>, both through an injected WorktreeExecFn (a real child_process spawn in prod, a fake in tests). Failures surface git's stderr with a stable git_worktree_*_exit_<code> fallback.
  • Cleanup / retention policyshouldRetainWorktree(attemptOk) encodes it: a succeeded attempt's worktree is removed once it concludes; a failed attempt's is retained for post-mortem (its deterministic name makes it findable). removeWorktree({ retain }) honors it (no exec, removed: false when retained).
  • Driver seam shape — the planned path is a plain string, so the CodingAgentDriver interface (feat(miner-hands): define the CodingAgentDriver interface seam #4262) can accept it as its "scoped working directory" with no retrofit.

Tests

test/unit/worktree-allocator.test.ts covers the pure naming/collision logic (determinism, sanitization, edge-separator trimming, length cap, empty-id rejection, no-collision across ids) and both exec wrappers via a fake exec that records calls and returns scripted results (exit-0 success, stderr surfacing, empty-stderr fallback, retain-skips-exec, remove success/failure). 100% line + branch coverage of the new module; paths are asserted cross-platform. Because the exec is injected, a follow-up real-git integration test (gated on git availability, per the issue's optional checkbox) drops in against the same seam without touching the primitive.

Notes

  • No production dependencies added; the module is pure + injected-exec.
  • No changes to src/services/** or any guarded path.

Add packages/gittensory-engine/src/miner/worktree-allocator.ts: the
concurrency primitive for parallel coding-agent attempts. Each attempt
runs in its own `git worktree` so concurrent attempts (same or different
issues) never collide on a shared working directory.

The module splits into a PURE planning layer and thin injected-exec
wrappers, mirroring the SpawnFn injection convention (JSONbored#4262/JSONbored#4266) so all
naming/collision/lifecycle logic is unit-testable without shelling out to
git in CI:

- planWorktree(): deterministic worktree path + branch, keyed on the
  attempt id (never a random suffix). Two concurrent attempts with
  distinct ids get distinct paths/branches; the same id always maps to
  the same location, so a crashed attempt's worktree stays identifiable
  and cleanable after the fact. Slugs are sanitized to a filesystem- and
  git-ref-safe token and length-capped.
- addWorktree(): `git worktree add -b <branch> <path> <base>` through the
  injected exec; returns the plan plus git's stderr on failure.
- removeWorktree() + shouldRetainWorktree(): retention policy — a
  SUCCEEDED attempt's worktree is removed once it concludes; a FAILED
  attempt's is RETAINED for post-mortem (its deterministic name makes it
  findable).

The exec is injected (a real child_process spawn in prod, a fake in
tests), so the driver seam (JSONbored#4262) can accept the planned path as its
scoped working directory without retrofitting.

Covered by test/unit/worktree-allocator.test.ts (pure naming/collision
logic and both exec wrappers via a fake exec; 100% line + branch).

Closes JSONbored#4269
@jeffrey701
jeffrey701 requested a review from JSONbored as a code owner July 10, 2026 00:56
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. labels Jul 10, 2026
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.07%. Comparing base (c6a5504) to head (e228acc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4547   +/-   ##
=======================================
  Coverage   94.06%   94.07%           
=======================================
  Files         425      426    +1     
  Lines       37774    37793   +19     
  Branches    13794    13800    +6     
=======================================
+ Hits        35533    35552   +19     
  Misses       1586     1586           
  Partials      655      655           
Files with missing lines Coverage Δ
.../gittensory-engine/src/miner/worktree-allocator.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb

loopover-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-10 01:08:30 UTC

3 files · 1 AI reviewer · no blockers · readiness 82/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This adds a small, well-isolated primitive (planWorktree/addWorktree/removeWorktree/shouldRetainWorktree) for per-attempt git worktree isolation, following the established injected-exec (SpawnFn-style) convention from the cli-subprocess-driver. The pure planning layer is deterministic and keyed on attemptId (no random suffix), and the test suite exercises success/failure paths for both add and remove, slug sanitization/truncation, and the retention policy. CI is green and the diff is self-contained (new module + barrel export + tests), with no wiring into a caller yet — this is explicitly a primitive, not the integration.

Nits — 5 non-blocking
  • worktree-allocator.ts:42-47 slugifyAttemptId doesn't collapse consecutive '.' runs, so an attemptId like "a..b" produces a slug containing '..', which git-check-ref-format rejects in branch refs — addWorktree would fail on such ids instead of the sanitizer producing a valid ref.
  • The 64-char slug cap (worktree-allocator.ts:39) means two distinct attempt ids sharing the same first 64 sanitized characters would collide on path/branch; worth a one-line comment noting this relies on attemptId uniqueness being encoded within that prefix.
  • No caller wires addWorktree/removeWorktree into the actual attempt-run lifecycle yet in this diff — worth confirming a follow-up PR is tracked for that integration so this primitive doesn't go unused.
  • In slugifyAttemptId, replace runs of '.' (or any git-invalid double-char sequences) the same way unsafe chars are handled, to keep the sanitizer's output guaranteed git-ref-safe rather than only 'usually safe'.
  • Consider a short doc comment on WorktreePlan clarifying the collision assumption (uniqueness within the 64-char sanitized prefix) so future readers don't need to re-derive it.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4269
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 117 registered-repo PR(s), 49 merged, 7 issue(s).
Contributor context ✅ Confirmed Gittensor contributor jeffrey701; Gittensor profile; 117 PR(s), 7 issue(s).
Gate result ✅ Passing No configured blocker found.
Linked issue satisfaction

Addressed
The PR adds worktree-allocator.ts with a pure planWorktree naming layer keyed deterministically on attempt id (no random suffix, collision-safe, slugified/length-capped), injected-exec addWorktree/removeWorktree wrappers mirroring the SpawnFn convention, and a shouldRetainWorktree policy that retains failed attempts and removes succeeded ones, plus unit tests covering naming/collision and exec suc

Review context
  • Author: jeffrey701
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 117 PR(s), 7 issue(s).
  • Related work: Titles/paths share 6 meaningful terms. (issue #4297, issue #4307)
Contributor next steps
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Check active issues and PRs before submitting.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gittensory approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 69bd6c2 into JSONbored:main Jul 10, 2026
10 checks passed
@loopover-orb loopover-orb Bot added gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. and removed gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. labels Jul 10, 2026
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. and removed gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(miner-hands): git-worktree-per-attempt isolation primitive

2 participants