Skip to content

Stale auto/{task-id} branches: taskrunner leaves orphan branches pointing at main after feature branch takes over #26

@stackbilt-admin

Description

@stackbilt-admin

Bug

When the taskrunner runs a task that ends up using a descriptive feature branch name (e.g. `auto/feature/memory-11-recency-filter`), a separate branch named `auto/{task-id}` is ALSO created, pointing at the current HEAD of `main` with zero commits. The task-id branch is never used by the PR and never cleaned up, so orphan branches accumulate on every target repo over time.

Concrete example

After task `8db68535-36dd-425f-9fa3-a2d7d9457b2d` (`memory#11: add RecallQuery.after?/before? ISO8601 recency filter`) completed on 2026-04-11:

```
$ gh api repos/Stackbilt-dev/stackbilt-memory/branches
[
{ "name": "auto/feature/memory-11-recency-filter", "commit": { "sha": "e798756…" } }, ← PR branch, real work
{ "name": "auto/8db68535", "commit": { "sha": "6a14cbd…" } }, ← stale, at main HEAD
{ "name": "main", "commit": { "sha": "6a14cbd…" } }
]
```

The branch `auto/8db68535` (named after the task id prefix) has zero commits and points at the same SHA as `main`. It's a leftover from the taskrunner's branch-creation step that got superseded when the task's actual work ended up on the feature-named branch instead.

Why this matters

  • Branch list pollution — every taskrunner task adds an orphan branch to the target repo. Over time (cc-taskrunner has 236+ completed tasks), branch lists become unreadable and repo search results get noisy.
  • No automated cleanup — the taskrunner doesn't track the task-id branches it creates, so they can't be garbage-collected after the task completes. Manual cleanup requires `gh api` iteration against every repo.
  • Confuses downstream tooling — anything that iterates over branches (dependabot, branch-protection automation, stale-branch reminders) sees these as real branches and may try to act on them.

Hypothesis

The taskrunner probably:

  1. Creates a default branch named `auto/{task-id}` at the start of every task (as a safety net in case the task doesn't provide a branch name)
  2. When the task script calls `git checkout -b auto/feature/memory-11-recency-filter` and does its work there, the task-id branch is abandoned
  3. No cleanup step ever removes the abandoned branch

Fix options

  • Delete the task-id branch after completion if it has no commits beyond `main`'s HEAD
  • Don't pre-create the task-id branch — wait until the task script explicitly needs a branch, then create the right one
  • Use a single branch naming convention consistently (either always task-id or always descriptive) so the two don't fork
  • Post-task cleanup sweep — a periodic job that finds and deletes `auto/*` branches with no commits

Operator impact

Minor on its own, but combines poorly with the `.gitignore` contamination bug (companion issue) to make every taskrunner PR feel noisy. The wiki pilot trial run exposed both in the same task.

Related

  • Observed on `Stackbilt-dev/stackbilt-memory` after task `8db68535-36dd-425f-9fa3-a2d7d9457b2d` during an AEGIS wiki pilot trial run on 2026-04-11
  • Companion issue on `.gitignore` contamination: [see separate filing]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions