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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions