Skip to content

A pinned routine's commitless branch is never released on a repo where the name never had a PR #1650

Description

@suleimansh

🤖 automated

Residue of #1643, found while dogfooding #1649 (write-up: #1649 (comment)).

What #1649 fixed. A triage's Run now now goes through the sweep, so the stale-branch release (releaseStalePinnedBranch, #1293) runs before the start. On the rig that worked: the leftover tf-triage-quick was deleted and the agent proceeded.

What it cannot fix. The release is deliberately conservative (src/stale-branch.ts): it deletes the branch only when its name has PR history and no PR is open. A branch with no PR history at all comes back unproven and is kept — the seam cannot tell "an agent still working toward its handoff" from "a leftover that never had a PR".

The triage routines make that leftover every time they finish:

  • triage-quick / triage-consensual write only TODO_AGENTS.md, which lives on tf-data, so they push there directly and commit nothing on their own branch.
  • A commitless branch skips the handoff (handoff skipped: the session committed nothing) — no push, no PR.
  • The run's worktree is reclaimed, but the branch tf-triage-quick stays, at main, with zero commits.
  • The next firing (scheduled or clicked) finds it, the prompt's guard says "branch already exists — triage already pending", and the agent aborts in seconds (~$0.18 each time).

So on any repo where the name has ever had a PR (the rig: PR #6), the loop is self-healing since #1649. On a repo where it never had one — a fresh project, or any project after the triage prompt changed to queue-only (#1644), which is what took the PR away — it jams forever on the second triage, exactly as in #1643, and the only way out is still git branch -D tf-triage-quick by hand. Seen on gemstack's origin on 2026-08-23 (an empty tf-triage-quick pushed by a misfired click, deleted by hand).

Options — this is a data-safety policy, so it wants a human decision rather than a fix-by-default:

  1. Count "no commits past main" as stale. Extend the seam: a branch with no PR history and no commits unique to its base holds nothing, so release it. Risk: an agent that started seconds ago and has not committed yet looks identical — mitigated in practice by git branch -D refusing while that agent's worktree has the branch checked out (the in-flight guard triage-quick jams after its first run: a closed PR's pinned branch blocks every later firing #1293 already relies on), but not on the remote copy.
  2. Have the triage delete its own branch when it ends commitless. The routine knows it never needed the branch; the daemon's settle path already knows handoffSkip === 'no-commits'. No seam policy change; the leftover never exists. Does not help with branches other tools leave behind.
  3. Drop the pinned-branch guard for queue-only triages. Since A triage queues work and never does it (#1641) #1644 the triage changes one file on tf-data; two overlapping triages cannot corrupt each other the way two queue rewrites on one branch could. Then there is nothing to release. Biggest change to the prompts' contract (triage-quick jams after its first run: a closed PR's pinned branch blocks every later firing #1293's reason for the pin was duplicate triage, which A triage queues work and never does it (#1641) #1644's queue-only rule makes cheap rather than harmful).

I lean to 2 as the smallest correct change, with 3 as the question worth asking Rom: whether the pin still buys anything after #1644.

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