A campaign umbrella has no safe status to sit in
How it surfaced
frank-optimize-b4, holding the -O3 W1 campaign, was asked why it held two
working/ entries. Its answer was correct and is the bug report:
The umbrella is what announces
ir_codegen.incownership, and parking it would put it back inunfinished/, whichready/nextdo scan — recreating exactly the dispatch problem you caught an hour ago. A container ticket for an active campaign has nowhere safe to sit exceptworking/.
Both halves are true, which is what makes it structural rather than a mistake:
| status | why the umbrella cannot sit there |
|---|---|
working/ |
a live lock, per-agent, meant to be short. An umbrella sits for the length of a campaign, so the lock never clears and every staleness heuristic reads it as abandoned |
unfinished/ |
scanned by ready/next — a second agent gets dispatched onto the campaign's own files |
backlog/, urgent/, backlog_new/ |
same, and ranked higher |
blocked/ |
not scanned, but a false claim: nothing blocks it |
done/ |
false while slices remain |
Measured, 2026-08-30
Of 4 tickets in working/, one is a campaign container —
feature-opt-o3-register-pressure, 77 lines matching umbrella/campaign/slice
vocabulary, versus 0 and 2 for the others. So this is one instance today and a
recurring shape: Track O has a campaign now, S is becoming one, M is planned as
one. The letters for work-tags (O, S, M) exist precisely to make campaigns visible,
and the status vocabulary was never extended to match.
The gap in one line
status conflates "is someone on this" with "is this a unit of work", and a
container answers yes and no. Nothing in the vocabulary can say the second thing.
Options (do not pick one without the owner or a T decision)
- A
type: umbrella(orcontainer: true) frontmatter field thatready/nextannotate rather than rank — precedent exists: the ranker already prints[!! DO NOT CLAIM — the ticket says so]and[parked — re-claim, do not duplicate], so the display path for "visible but not claimable" is already built and this is a new reason, not a new mechanism. Cheapest, and keeps the umbrella in a scanned status where it stays visible. - A
campaign/folder unscanned likefloat/. Clean, but adds a folder and splits campaign tickets from their lane's queue — andfloat/'s own lesson is that unscanned means genuinely invisible, which is right for parked float work and wrong for a live campaign. - Leave it in
working/and teach the staleness checks about it. Least change; keeps a permanent entry in the one folder whose whole meaning is "short-lived".
Recommendation: (1). It reuses the annotation path, needs no folder, and makes the container's status honest rather than a workaround an agent has to explain each time it is asked.
Note
Do not pair this with a "ticket prose states a prio that disagrees with frontmatter" check. That was proposed the same night, from a real instance, and measured across all 380 ranked + working tickets: 1 states a prio in prose at all, and that 1 disagrees. One finding, ever, is not a check — it is a fix, and it is applied in this same commit. See face 134a.
Deprioritised 2026-09-02 — the Track T tooling backlog was cut as a pile
This ticket is not being called wrong. It was moved as part of a pile, not judged individually, and nothing here disputes its finding.
Owner decision. 73 of the 74 open track: T tickets were filed between
2026-08-31 and 2026-09-02, 58 on one day. The pile was too large to work through
and returned almost nothing, and a ticket nobody will fix does not sit neutrally
— it stays in the ranker forever at zero value, which is the argument CLAUDE.md
already makes for a terminal folder over a low prio.
Four were kept in the ranker on a purely structural test — an active umbrella or
a hard blocked-by: edge from live work:
umbrella-one-full-tier-run-with-no-red-tier,
feature-t-freebsd-image-and-runner, and the two regression-test-core-* reds
that block the umbrella.
Kept, not deleted, for two reasons: so the finding is not rediscovered and refiled from scratch by the next agent who trips over it, and so it can be pulled back if what it touches becomes load-bearing.
To revive it: move it to the owning lane's backlog, set status: backlog,
and say in the ticket WHAT CHANGED to make it matter now. Restoring it because it
reads well is how the pile comes back.