Skip to content

feat(queen): take open issues in priority order (specs/queen/priority.t27) - #534

Open
gHashTag wants to merge 1 commit into
fix/queen-worker-provider-and-prompt-sizefrom
claude/queen-priority
Open

gHashTag wants to merge 1 commit into
fix/queen-worker-provider-and-prompt-sizefrom
claude/queen-priority

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 5, 2026

Copy link
Copy Markdown
Owner

What changed

The Queen's round used to hand queend choose the open issues in GitHub's listing order and read no label, so a P0 listed after newer unlabelled work waited behind it. It now ranks them by the rule in gHashTag/t27 specs/queen/priority.t27 (gHashTag/t27#6367, commit c44c7aea32a5) before calling queend. queend choose (Swift, unchanged) still takes the first eligible candidate in the order it is given, so ordering its input is the whole change.

  • An issue with an open blocker (issue_dependencies_summary.blocked_by > 0) is not a candidate. The board (rememberIssues) still sees it.
  • Labels map to levels. CRITICAL: P0,priority/critical,critical. HIGH: P1,priority/high,high-priority. NORMAL: P2,priority/medium. LOW: P3,P4,priority/low. If an issue has several, the most urgent counts. An issue with no priority label is NORMAL and never ages.
  • Only the first 3 CRITICAL issues in a listing run as CRITICAL. Any later one runs as HIGH (capped).
  • A labelled issue moves up one level after 14 days open, at most one level, and never to CRITICAL. An aged issue loses a tie to a real one at the same level.
  • Ties keep the listing order. A repository with no priority labels and no blockers gets exactly the order it had before.
  • Each round logs one line, for example priority: top #10 CRITICAL (base CRITICAL, why=label, listing 2, age 4d); 1 blocked skipped.
  • The candidateOverride branch is unchanged.

Files

  • apps/server/src/api/services/queen-priority.gen.js: generated by t27c gen-js specs/queen/priority.t27 (t27c 0.4.0) and committed byte for byte. It is excluded from biome in biome.json, the same way as queen-contributor-policy.gen.ts, so the commit hook cannot reformat it.
  • apps/server/src/api/services/queen-priority.ts: cappedLevel, effectiveLevel, eligible, outranks and why mirror the spec functions one to one, because gen-js does not emit function bodies. It imports every constant from the generated file. rankIssues mirrors rank() in t27 scripts/tri_loop/queue.py (tri queue). The header names the source path and commit.
  • apps/server/src/api/services/queen-tick.ts: openIssues now also returns labels, createdAt and blockedBy, all taken from the same response, so there is no extra request. Existing fields are unchanged. runRound ranks the open issues and filters out blocked ones before building candidates.
  • Tests: tests/api/queen-issue-pages.test.ts and tests/api/queen-round.test.ts.

Rule source

gHashTag/t27 specs/queen/priority.t27 on branch claude/queen-priority (gHashTag/t27#6367, issue gHashTag/t27#6366). Spec blob fbbf548c.

Test output

Run from trios/agent-server/apps/server, with TRIOS_QUEEND_PATH set to a local swift build -c release --product queend:

$ bun test tests/api/queen-issue-pages.test.ts tests/api/queen-round.test.ts
 42 pass
 0 fail
Ran 42 tests across 2 files.

$ bun test tests/api/queen
 858 pass
 5 skip
 0 fail
Ran 863 tests across 55 files.

$ bun run typecheck      # tsc --noEmit
exit 0

$ t27c gen-js specs/queen/priority.t27 | diff - src/api/services/queen-priority.gen.js
(no difference)

New cases:

  • No labels: the listing order is unchanged.
  • An unlabelled issue never goes ahead of a P0 or a HIGH (the stokowski regression).
  • The 4th critical in a listing runs as HIGH.
  • A blocked issue is skipped.
  • An aged priority/low never passes unlabelled work.
  • With two labels, the more urgent one counts.
  • The log line.
  • openIssues passes labels, created_at and the blocker count through.
  • The generated header is intact and the rule file imports it rather than copying it.
  • In the round (real queend): it picks the P0 over newer unlabelled work, it moves past a blocked P0, and with no labels the listing order is kept.

Negative controls (each reverted after the run):

  • Restoring candidates = open.map(...) in runRound fails both round priority tests.
  • Reversing the sort comparator fails 7 of 14 tests in issue-pages.
  • Removing the unlabelled no-aging guard, or the critical counter, fails the matching test.

Do not merge without the owner: merging this branch deploys production.

🤖 Generated with Claude Code

….t27)

The round handed queend GitHub's listing order and read no label, so a P0
listed after newer unlabelled work waited behind it. It now ranks the open
issues by gHashTag/t27 specs/queen/priority.t27 (t27 PR #6367, commit
c44c7aea32a5) before `queend choose`, which still takes the first eligible
candidate it is handed:

- an issue with an open blocker (issue_dependencies_summary.blocked_by) is
  not a candidate;
- labels map to CRITICAL/HIGH/NORMAL/LOW, most urgent wins, unlabelled is
  NORMAL and never ages; at most 3 criticals per listing, the rest run HIGH;
  labelled work ages one level after 14 days, never to CRITICAL;
- ties keep the listing order, so a repository with no priority labels and
  no blockers sees exactly the order it had.

The vocabulary is `t27c gen-js` output committed verbatim as
queen-priority.gen.js (excluded from biome so the bytes stay the compiler's);
queen-priority.ts mirrors the spec's five functions. openIssues keeps label
names, created_at and the blocker count from the same response; the board
still remembers blocked issues. One log line per round names the top pick,
its level and why.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

✅ Tests passed — 2605/2668

Suite Passed Failed Skipped
✅ agent 87/87 0 0
✅ build 9/9 0 0
✅ cdp-protocol 5/5 0 0
✅ eval 93/93 0 0
✅ server-agent 280/280 0 0
✅ server-api 1452/1514 0 62
✅ server-browser 6/6 0 0
✅ server-integration 10/11 0 1
✅ server-lib 279/279 0 0
✅ server-pglive 27/27 0 0
✅ server-root 68/68 0 0
✅ server-skills 31/31 0 0
✅ server-tools 244/244 0 0
✅ shared 14/14 0 0

View workflow run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant