Skip to content

fix(miner): check out baseBranch on the fresh-clone path so the first attempt succeeds (#9682) - #9903

Closed
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:fix/9682-fresh-clone-checkout
Closed

fix(miner): check out baseBranch on the fresh-clone path so the first attempt succeeds (#9682)#9903
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:fix/9682-fresh-clone-checkout

Conversation

@kai392

@kai392 kai392 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

ensureRepoClonedUnlocked's docstring promises both branches land on the base branch, but the fresh-clone branch returned right after git clone. A plain clone creates only origin's default-HEAD local branch, so the consumer's git worktree add -b <attempt> <path> <baseBranch> (worktree-plan.ts:80-84) can't rev-parse a bare non-default <baseBranch>. The first attempt against any repo whose base isn't the origin default fails with fatal: invalid reference: <baseBranch> (surfacing as blocked_worktree_preparation_failed), and only the second attempt — which hits the fetch+reset path that DWIM-creates the local tracking branch — works. This is reachable in production (attempt-cli.ts:578 passes the PR's real base; attempt-worktree.ts:88 defaults to "main", failing on the first attempt against any master-default repo).

How

After a successful git clone, run git checkout <baseBranch> in repoPath and return the identical { ok: false, repoPath, error: stderr || "git_checkout_failed" } shape the existing-clone branch already uses (repo-clone.ts:335-336). No fetch/reset is added — a fresh clone is already at origin's tip. The isUnsafeGitArgValue(baseBranch) guard still runs first.

Tests

Three named regression cases in test/unit/miner-repo-clone.test.ts, each failing against the current code:

  1. On the first-use path with baseBranch: "develop", the injected runGit receives ["checkout", "develop"] after ["clone", ...].
  2. A failing checkout on the fresh path returns { ok: false, error: "git_checkout_failed" } (and surfaces git's stderr verbatim when present).
  3. The fresh path emits exactly clone then checkout — no fetch/reset.

The existing per-repo concurrency test's pinned git-op sequence is updated to include the new checkout; its non-overlapping serialization guarantee is unchanged.

Closes #9682

@kai392
kai392 requested a review from JSONbored as a code owner July 29, 2026 20:43
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-29 20:51:06 UTC

2 files · 1 AI reviewer · no blockers · CI failing · unstable

🛑 Suggested Action - Fix Blockers

Review summary
This fixes a real bug: `ensureRepoClonedUnlocked`'s fresh-clone branch returned immediately after `git clone` without checking out `baseBranch`, so a plain clone only has origin's default-HEAD branch locally, and the consumer's `git worktree add -b <attempt> <path> <baseBranch>` fails to rev-parse a non-default base branch on the first attempt. The fix adds a `git checkout <baseBranch>` step using the same error shape as the existing-clone path, and is well-covered by three targeted regression tests plus an updated concurrency-guard test reflecting the new op sequence. The change is narrow, correctly scoped to the described issue (#9682), and traces cleanly to the real call sites (worktree-plan.ts, attempt-cli.ts, attempt-worktree.ts) cited in the description.

Nits — 3 non-blocking
  • repo-clone.ts's inline comment above the new checkout call is fairly long (4 lines) for what is a straightforward fix — could be trimmed since the docstring above `ensureRepoClonedUnlocked` already states the contract.
  • The new checkout error path doesn't distinguish 'baseBranch doesn't exist on origin' from other checkout failures, but this matches the existing fetch+reset path's behavior so it's consistent, not a regression.
  • Consider whether `checkoutFails`-style test coverage should also verify behavior when `baseBranch` equals the clone's default branch (checkout of an already-checked-out branch), though this is likely a no-op in git and low risk.

CI checks failing

  • validate
  • validate-tests

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9682
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low 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: 89 registered-repo PR(s), 43 merged, 7 issue(s).
Contributor context ✅ Confirmed Gittensor contributor kai392; Gittensor profile; 89 PR(s), 7 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The diff adds the required git checkout call and identical error-shape handling right after a successful clone, guarded by the pre-existing unsafe-arg check, and includes three named regression tests covering the checkout-succeeds, checkout-fails, and no-fetch/reset-on-fresh-path cases plus an updated concurrency test asserting the new command sequence.

Review context
  • Author: kai392
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, Cuda, JavaScript, Kotlin, MDX, Perl, Ruby, TypeScript
  • Official Gittensor activity: 89 PR(s), 7 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: success
  • config: 76c9444f465420fc9ebb0f22b459b0a68ca24b5a561dc6d694a3625cd28ddaf9 · pack: oss-anti-slop · ci: failed
  • note: diverted by the randomized close-audit holdout (calibration: randomized ε-holdout on would-close PRs with propensity logging #8831) — the deterministic pipeline would otherwise have closed this PR
  • record: b97e817b17366af0bb144f3c2b20a746caec63bd6e472a9b7c6e609b9bda0bcc (schema v5, head a9050f2)

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

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

… attempt succeeds (JSONbored#9682)

`ensureRepoClonedUnlocked`'s docstring promises both branches land on the
base branch, but the fresh-clone branch returned right after `git clone`.
A plain clone creates only origin's default-HEAD local branch, so the
consumer's `git worktree add -b <attempt> <path> <baseBranch>` cannot
rev-parse a bare non-default `<baseBranch>` -- the first attempt against
any repo whose base isn't the origin default fails with
`invalid reference` (surfacing as blocked_worktree_preparation_failed),
and only the second attempt (which hits the fetch+reset path that
DWIM-creates the local branch) works.

- After a successful clone, run `git checkout <baseBranch>` and return the
  identical `{ ok:false, error: stderr || "git_checkout_failed" }` shape the
  existing-clone branch already uses. No fetch/reset is added -- a fresh
  clone is already at origin's tip. The isUnsafeGitArgValue guard still
  runs first.

Tests: three named regression cases (checkout happens after clone on the
first-use path; a failing checkout returns git_checkout_failed / stderr;
the fresh path emits exactly clone+checkout, no fetch/reset). The existing
per-repo concurrency test's pinned git-op sequence is updated to include
the new checkout (its non-overlapping guarantee is unchanged). All new
assertions fail against the current code.

Closes JSONbored#9682

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1648 1 1647 0
View the top 1 failed test(s) by shortest run time
test/unit/miner-attempt-worktree.test.ts > prepareAttemptWorktree / cleanupAttemptWorktree (#5132) > returns ok:false with git's real stderr when git worktree add fails (e.g. an unknown base branch)
Stack Traces | 0.127s run time
AssertionError: expected undefined to be '/tmp/loopover-miner-attempt-worktree-…' // Object.is equality

- Expected:
".../cache/acme/widgets"

+ Received:
undefined

 ❯ test/unit/miner-attempt-worktree.test.ts:152:29

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 29, 2026
@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 29, 2026
@kai392 kai392 closed this Jul 29, 2026
@loopover-orb loopover-orb Bot reopened this Jul 29, 2026
@loopover-orb loopover-orb Bot closed this Jul 29, 2026
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

LoopOver had already started reviewing this pull request — closing it to dodge the one-shot review process is not allowed. Please open a new pull request with the issues addressed.

@loopover-orb loopover-orb Bot added the review-evasion Gittensor contributor context label Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context review-evasion Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

miner(repo-clone): a fresh clone never checks out baseBranch

2 participants