Run now on a triage routine releases its stale branch first, like the sweep (#1643) - #1649
Conversation
… sweep (#1643) Run now on either triage routine was a plain start outside the sweep, so it never reached the release the sweep does before firing a pinned job. A leftover copy of the triage branch made every click abort in seconds as "triage already pending", until someone deleted the branch by hand. The card now asks the sweep for that one routine — `only: { pinned: <branch> }`, scoped to the picked project — the way the plan click does since #1640. The sweep finds the job by the branch it declares, never by name; a switched-off routine stands the click down with a reason; the named job takes the tick outright, so neither a full queue nor the rotation index borrows it, and the rotation keeps its turn.
|
🤖 automated Dogfooded on the rig ( 1. Switched-off click stands down (free). With "Add quick-win work to AI Queue" unticked and the rig picked, Run now started nothing. Card note and daemon log both said 2. The click releases the stale branch, then starts (one run, $0.65). Ticked the routine back on via the card's own checkbox, clicked Run now again:
Net: the card reaches the same release-then-start as the sweep, the concurrency/quota/opt-out gates hold, and the sweep's note lands on the card instead of a navigation. Two things the dogfood shows that this PR does not change (noted, not fixed):
Restored afterwards: |
🤖 automated
Fixes #1643.
What changed
Run nowon either triage routine was a plainstart()from the card, outside the sweep — so it never reached the release the sweep does before firing a pinned job (releasePinned, #1293). A leftover copy oftf-triage-quickmade every click abort in ~19 s as "triage already pending", $0.16–0.18 a time, until someone deleted the branch by hand.The card now asks the sweep for that one routine, the way the plan click does since #1640:
AutoPmOnlygains{ pinned: <branch> }. The card sends{ only: { pinned: job.pinnedBranch }, projectId }for any routine that declarespinnedBranch;'drain'and'plan'are unchanged. The three routings now live in onenarrowedSweep(job, projectId)inRoutineWork.tsx, decided by what the job declares (drains/fansOut/pinnedBranch).{ pinned }against the enabled rotation bypinnedBranch, so an unticked box stands the click down (<label> is switched off); a branch no job pins at all is told apart (no routine is pinned to <branch>), since that is a dashboard older than its daemon rather than a setting.named): mode ispmhowever full the queue is, it outranks the maintenance calendar and the rotation index, and it does not advance the rotation. That is the same set of rules Run now on the planning routine spends the concurrency, not one agent (#1204) #1640 gave the plan click, now expressed once rather than per kind.Why this direction
#1643 offered two fixes: call
releasePinnedfrom the card, or route the click through the narrowed sweep. This is the second, for the reason the issue gives — it keeps one start path, and it is where #1640 already went. It also fixes the rest of what a card-fired triage skipped (the concurrency and quota gates, the stand-down reasons on the card) rather than only the release.Keyed on the branch rather than the job's name, following the no-name-matching reasoning on
AutoPmJob.drains/fansOut/pinnedBranch: the card sends whatever the job it renders declares, and the sweep matches on that same declared datum, so no string anywhere has to agree with a name and a rename cannot unhook it. A'pinned'literal would not do — two jobs pin a branch — and a name would have widenedonlyinto "run any rotation job through the sweep", which is a different (and bigger) change than this issue asks for.What this does not do.
releaseStalePinnedBranchis deliberately conservative (#1293): it deletes only when the branch has PR history and none is open. A branch that never had a PR — exactly the dogfood repro on #1643 (tf-triage-quickatmain, zero commits, no PR, held by the first triage's retained worktree) — comes backunprovenand is kept, so on that branch the click now reaches the release and the release still declines. Whether "no PR, no commits past main" should count as stale is a data-safety call for the seam, not this PR; andgit branch -Drefuses anyway while a worktree has the branch checked out. (The emptytf-triage-quicka misfired click had pushed to this repo's origin was deleted by hand at 01:55, so a gemstack quick triage is no longer pre-blocked.)Spec changes
src/auto-pm.SPEC.md— Flows: a new sentence that the two triage routines work on one fixed branch and that a leftover copy whose PR is closed/merged is deleted before firing, from the schedule or from Run now (a branch with an open PR or no PR history is kept). Rationales: a triage's Run now goes through the pass to get the same release the schedule gets.dashboard/components/RoutineWork.SPEC.md— the Run now flow now says the two triage routines ask the sweep too, and why; "every other routine's Run now is one agent started directly".FEATURES-SPEC.md— "Release a pinned routine branch left behind by a closed PR — before the schedule fires the routine, and before its 'Run now' does".Verified
auto-pm.test.ts— a sweep narrowed to a pinned job releases the branch then starts exactly one agent (with the rotation on another job's turn and concurrency 3); a switched-off pinned routine stands the click down, an unknown branch is named as such, and the cap still holds; a narrowed sweep never falls through to the drain or another rotation job, and the next scheduled tick still gets the job it was owed.RoutineWork.test.tsx— each pinned routine's Run now callssendAutoPmSweep({ only: { pinned }, projectId })and neverstart().quota.test.ts— the object form travels to the loop untouched.tickand the pinned line innarrowedSweep, tests kept): exactly the 3 new node tests and the 1 new card test failed, everything else stayed green. Restored from the commit.pnpm typecheckexit 0;pnpm testwith the bundle built: node 1547/1547, dashboard 797/797. (A fresh worktree withoutdist/fails 8daemon.test.tscases with "the dashboard bundle is not installed" — unrelated; they pass afterpnpm build.)~/Projects/tf-1334-dogfoodhas the stale-branch condition ready if wanted.