Skip to content

fix(lane): show refusals and print no-backend commands in the worktree layout - #2578

Merged
mlorentedev merged 1 commit into
mainfrom
fix/lane-next-review-fixes
Oct 16, 2026
Merged

mlorentedev merged 1 commit into
mainfrom
fix/lane-next-review-fixes

Conversation

@mlorentedev

@mlorentedev mlorentedev commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Closes the round-1 FAIL of CLI-119-lane-next (review merged in #2573). Refs #2511, #2528.

  • lane exec / lane next no longer swallow errors: a refusal prints its text on stderr (Blocker).
  • No backend and no --agent: the commands print with --agent <agy|claude|pi> and a note, exit 0. No harness is privileged by a default; AC5 text is unchanged.
  • The printed worktree path comes from WORKTREE_ROOT + worktree.ResolveWorktreePath, and refuses when the root does not resolve.
  • An untypeable binary path is reported in the outcome instead of silently becoming dotf; LoadConfig rejects a base without <remote>/<branch>.
  • Handoff and runLaneNext split to 39 lines each (were 72 and 51).
  • Minors that stay open: CLI-119: lane next has three unhandled failure modes (start race, create-then-type stall, slug collision) #2576 (Find->Create race, create-then-type stall, slug collisions).

Verification: go build, go vet, GOOS=windows go vet, go test ./internal/lane ./internal/cmd ./internal/worktree, golangci-lint (0 issues), and all six features.json commands exit 0. Mutation: restoring SilenceErrors fails TestLane_RefusalsAreShownOnStderr. Dispositions in specs/CLI-119-lane-next/verification.md.

0.71.0 (#2520) is released and installed, which was the precondition for a live AC6 run. The re-review (dotf spec review CLI-119-lane-next) comes after this merges.

Knowledge

  • Lesson: none: the swallowed-error class is guarded by TestLane_RefusalsAreShownOnStderr
  • ADR: none: no new decision, AC5 text unchanged
  • Runbook: none: no operational change

Review triage

Reviewer: the PR reviewer guide (github-actions); CodeRabbit was rate limited. The first review run published nothing (the NaN attempt hung, Haiku returned no parseable review); a re-run produced it.

…the worktree layout

Round-1 review of CLI-119 failed on four findings:
- lane exec and lane next silenced their errors, so every refusal exited 1 with no output;
- lane next with no backend and no --agent errored instead of printing the commands;
- the printed worktree path ignored WORKTREE_ROOT and the branch slug;
- a binary path no shell reads alike silently became bare dotf.

Also reject a lane base without a remote/branch split, split Handoff and runLaneNext under 40 lines, disposition the minors in verification.md (#2576) and tick the stale contract boxes.
@mlorentedev
mlorentedev marked this pull request as ready for review October 16, 2026 01:59
@coderabbitai

coderabbitai Bot commented Oct 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 3 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: mlorentedev/dotfiles/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 67155943-dc16-493c-9402-d6a8ffcdef0f
📥 Commits

Reviewing files that changed from the base of the PR and between 26a2ba0 and 0d58541.

📒 Files selected for processing: 10
  • cli/internal/cmd/lane.go
  • cli/internal/cmd/lane_test.go
  • cli/internal/lane/handoff.go
  • cli/internal/lane/handoff_test.go
  • cli/internal/lane/queue.go
  • cli/internal/lane/queue_test.go
  • specs/CLI-119-lane-next/features.json
  • specs/CLI-119-lane-next/proposal.md
  • specs/CLI-119-lane-next/tasks.md
  • specs/CLI-119-lane-next/verification.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment on lines +106 to +118
func launch(o Options, b Backend, wt Worktree, found bool, out Outcome, p plan) error {
if err := writePrompt(o, p.file, p.prompt); err != nil {
return err
}
st, err := start(o, b, wt, found, out.Branch, out.Issue)
if err != nil {
return out, err
return err
}
if err := ensureLease(o, st.Worktree.Path, issue.Number, out.Agent); err != nil {
return out, err
if err := ensureLease(o, st.Worktree.Path, out.Issue.Number, out.Agent); err != nil {
return err
}
return b.Type(st.Pane, p.exec)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Dry-run Side Effect

REAL: On the herdr path with found && wt.Open and o.DryRun false, ensureLease runs. Unchanged by this PR, but the new launch helper writes the prompt before start. If start fails, the prompt file is left behind under PromptDir with no lease, and a later run overwrites it. Low impact: stale prompt file only.

Comment thread cli/internal/cmd/lane.go
Comment on lines +151 to 161
// selfBinary is the path of the running dotf, which the successor is told to
// run. An empty answer falls back to `dotf` on the pane's PATH, which may be a
// different release: say so rather than start it silently.
func selfBinary(c *cobra.Command) string {
self, err := os.Executable()
if err != nil {
_, _ = fmt.Fprintf(c.ErrOrStderr(), "lane next: cannot locate this binary (%v); the successor runs `dotf` from the pane's PATH\n", err)
return ""
}
return self
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Possible Issue

THEORETICAL: selfBinary prints a warning on stderr when os.Executable() fails, then returns "" so the successor runs dotf from PATH. The warning is emitted during option construction for every run, including dry runs, so it appears even when nothing is started. Only triggers when os.Executable errors, which is rare.

Comment on lines +254 to 256
"git -C " + o.Parent + " fetch " + remote,
"git -C " + o.Parent + " worktree add -b " + out.Branch + " " + dir + " " + o.Config.Base,
"cd " + dir,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shell Quoting

THEORETICAL: manualCommands joins o.Parent, dir and out.Branch into a shell line without quoting. A repo path containing spaces (for example /home/a b/repo) yields a printed command a person cannot paste as-is. plainWord guards only the prompt and dotf paths, not these. Only affects the printed no-backend commands.

@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

2511 - Partially compliant

Compliant requirements:

  • The prompt names the lane's ticket (the rendered prompt carries the issue number and title)

Non-compliant requirements:

  • dotf lane start with --avoid paths is not implemented; the PR adds lane next/lane exec only
  • No --avoid argument, no lane-overlap warning (AC3)
  • No per-repository worktree bootstrap declaration is read
  • No lane record for dotf mem thread or the handoff

Requires further human verification:

2528 - Partially compliant

Compliant requirements:

  • Unknown agent is refused with the known list
  • Without a backend, the exact commands are printed
  • Rerun with an open workspace starts no second agent

Non-compliant requirements:

  • The dotf pr land hook is not part of this diff; no evidence that landing triggers the successor
  • No test asserts that landing leaves the launch worktree in place

Requires further human verification:

  • Live herdr workspace and session start after a real landing

2576 - Partially compliant

Compliant requirements:

Non-compliant requirements:

  • Find->Create race
  • Create-then-Type stall
  • Slug collisions

Requires further human verification:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Possible Issue

REAL: Handoff with b == nil now returns noBackend from the if b == nil branch, but prepare runs first and resolveAgent returns the placeholder without an error. The placeholder is passed through LaunchArgv only when it is not the placeholder, so the path is consistent. However manualCommands returns an error when WorktreeRoot is empty, and noBackend then returns out with out.Note unset and out.Commands nil, so the error is surfaced only if the caller checks it. Verify runLaneNext returns that error to the terminal (it does via return err), so this is not silent.

if found && wt.Open {
	out.Note = "a workspace already shows " + out.Branch + "; no second agent started"
	if o.DryRun {
		return out, nil

⚙️ Agent run details
  • Model: anthropic/claude-haiku-5-5
  • Tokens: 42,574 in / 1,937 out / 44,511 total
  • Time cost: 27.5s
  • AI calls: 1

@mlorentedev

Copy link
Copy Markdown
Owner Author

Review triage

Reviewer: the PR reviewer guide (github-actions); CodeRabbit was rate limited. The first review run published nothing (the NaN attempt hung, Haiku returned no parseable review); a re-run produced it.

@mlorentedev
mlorentedev merged commit 94fea6b into main Oct 16, 2026
35 of 37 checks passed
@mlorentedev
mlorentedev deleted the fix/lane-next-review-fixes branch October 16, 2026 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant