Skip to content

🐛 bug: contributor task prompts name the hive's own source branch as the PR base, not the target repository's default branch #6081

Description

@Danathar

Summary

Every contributor task prompt tells the agent to base its work on the branch
the hive binary was built from, regardless of which repository the issue is
actually in.

  • What the task prompt is. When a hive hands an issue to a contributor's
    agent ("clanker"), it sends a block of instructions telling it what to work on
    and which branch to open the PR against.
  • What's wrong. The branch in that instruction is the hive's own source
    branch — v4 — not the target repository's default branch. A self-hosted hive
    configured against any repo other than hive itself gets v4 stamped onto
    100% of its tasks.
  • Who notices. Anyone running a hive against their own repos. Observed on a
    self-hosted hive dispatching for Danathar/arch-bootc (default branch
    main): the agent reported No v4 branch exists in the repo (default is main). I'll base on main and flag this.
  • Why it matters more than that transcript suggests. That case self-corrected
    only because a missing branch is loud. In a repo that has a v4 branch
    which is not its default, the agent gets a branch that resolves, opens the PR
    against it, and the prompt's own verification step ("confirm the PR's base is
    v4 before you report done") confirms it. Wrong base, no error, anywhere.
  • Blast radius. Every self-hosted hive whose configured repos are not
    hivecommons/hive. hive-for-hive is unaffected — it works on this repo,
    which really does use v4, so the wrong value happens to be the right one.

Root cause

src/pkg/dashboard/contribute_ws.go:5311:

return buildTaskPromptBody(repoFull, issueRef, title, sourceHint,
    taskBaseBranch(title, upstreamBranch()))

upstreamBranch() (src/pkg/dashboard/api.go:405) is the branch this hive is
built from
, not anything about the task's repository:

func upstreamBranch() string {
    if versionBranch != "" && versionBranch != "unknown" {
        return versionBranch
    }
    return defaultUpstreamBranch   // api.go:381 — const = "v4"
}

taskBaseBranch passes it straight through for anything without a release-line
prefix in the title:

func taskBaseBranch(title, hubBranch string) string {
    if line := releaseLineFromTitle(title); line != "" {
        return line
    }
    return strings.TrimSpace(hubBranch)
}

So repoFull is available at the call site and simply never consulted.

The correct behaviour already exists, and is unreachable

buildTaskPromptBody has exactly the right wording for an unresolved base —
this is the baseHint default, before the if b != "" override replaces it:

Do not assume the branch the checkout is currently on is the right base: it may
be left over from a previous task. Resolve <repo>'s own default branch
('gh repo view <repo> --json defaultBranchRef'), start your work branch from it,
and open the PR against it.

That path can never execute, because upstreamBranch() cannot return empty —
it falls back to the "v4" constant. The fix is largely a matter of letting
this existing code run.

This is a regression of #4928

To be clear, #5729 fixed a genuine and well-evidenced problem: the checkout is
reused across tasks, so the branch left on disk answers the previous task, and
an agent follows the instruction it was given over the state it finds. Naming
the base in the prompt is right. The defect is only in which branch gets
named — the hive's own, rather than the target repository's.

Both constraints are satisfiable at once, since the call site already has
repoFull.

Suggested fix

Inherit upstreamBranch() only when the task's repo is the hive's own
repository; otherwise leave the base empty and let the existing
defaultBranchRef instruction do its job. Concretely, give taskBaseBranch the
repo and let it decline to inherit for a foreign one.

Preserve both existing behaviours:

Worth a test that a hive built from v4 dispatching for a repo whose default is
main does not emit v4 — the existing
src/pkg/dashboard/contribute_task_base_branch_test.go looks like the natural
home, and today's behaviour would presumably pass it, since it only ever
exercises a hive whose own branch is the right answer.

Observed

Self-hosted hive, served_sha df9b867, dispatching its own configured repos:

$ curl -s localhost:3001/api/config
{"org":"Danathar","primaryRepo":"Danathar/atomic-image-builder",
 "repos":["atomic-image-builder","zfs-kinoite-complex","arch-bootc","aurora-zfs-simple"]}

$ curl -s localhost:3001/api/version | jq -r .branch
v4

Agent output on a task for Danathar/arch-bootc:

● No v4 branch exists in the repo (default is main). I'll base on main and flag this.

None of those four repositories uses v4; the hive's own branch field is
where the value comes from.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions