fix: feat: dev-poll checks priority-labeled issues before plain backlog (#555)

Add two-tier backlog pickup in dev-poll.sh:
1. in-progress issues (existing)
2. priority + backlog issues (FIFO within tier)
3. plain backlog issues (FIFO within tier)

The priority label coexists with backlog (not a replacement).
ensure_priority_label() auto-creates the label if missing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-22 13:41:57 +00:00
parent 04cd11cce4
commit 604d1f13ca
3 changed files with 46 additions and 3 deletions

View file

@ -93,6 +93,7 @@ Issues flow: `backlog` → `in-progress` → PR → CI → review → merge →
| Label | Meaning | Set by |
|---|---|---|
| `backlog` | Issue is queued for implementation. Dev-poll picks the first ready one. | Planner, gardener, humans |
| `priority` | Queue tier above plain backlog. Issues with both `priority` and `backlog` are picked before plain `backlog` issues. FIFO within each tier. | Planner, humans |
| `in-progress` | Dev-agent is actively working on this issue. Only one issue per project is in-progress at a time. | dev-agent.sh (claims issue) |
| `blocked` | Issue is stuck — agent session failed, crashed, timed out, or CI exhausted. Diagnostic comment on the issue has details. Also used for unmet dependencies. | dev-agent.sh, action-agent.sh, dev-poll.sh (on failure) |
| `tech-debt` | Pre-existing issue flagged by AI reviewer, not introduced by a PR. | review-pr.sh (auto-created follow-ups) |

View file

@ -7,7 +7,8 @@
#
# Priority:
# 1. Orphaned "in-progress" issues (agent died or PR needs attention)
# 2. Ready "backlog" issues (all deps merged)
# 2. Ready "priority" + "backlog" issues (FIFO within tier)
# 3. Ready "backlog" issues without "priority" (FIFO within tier)
#
# Usage:
# cron every 10min
@ -590,18 +591,38 @@ done
# =============================================================================
# PRIORITY 2: find ready backlog issues (pull system)
#
# Two-tier pickup: priority+backlog issues first (FIFO), then plain backlog
# issues (FIFO). The "priority" label is added alongside "backlog", not instead.
# =============================================================================
log "scanning backlog for ready issues"
BACKLOG_JSON=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
# Ensure the priority label exists on this repo
ensure_priority_label >/dev/null 2>&1 || true
# Tier 1: issues with both "priority" and "backlog" labels
PRIORITY_BACKLOG_JSON=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
"${API}/issues?state=open&labels=priority,backlog&limit=20&type=issues&sort=oldest") || true
PRIORITY_BACKLOG_JSON="${PRIORITY_BACKLOG_JSON:-[]}"
# Tier 2: all "backlog" issues (includes priority ones — deduplicated below)
ALL_BACKLOG_JSON=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
"${API}/issues?state=open&labels=backlog&limit=20&type=issues&sort=oldest")
# Combine: priority issues first, then remaining backlog issues (deduped)
BACKLOG_JSON=$(jq -n \
--argjson pri "$PRIORITY_BACKLOG_JSON" \
--argjson all "$ALL_BACKLOG_JSON" \
'($pri | map(.number)) as $pnums | $pri + [$all[] | select(.number as $n | $pnums | map(. == $n) | any | not)]')
BACKLOG_COUNT=$(echo "$BACKLOG_JSON" | jq 'length')
if [ "$BACKLOG_COUNT" -eq 0 ]; then
log "no backlog issues"
exit 0
fi
log "found ${BACKLOG_COUNT} backlog issues"
PRIORITY_COUNT=$(echo "$PRIORITY_BACKLOG_JSON" | jq 'length')
log "found ${BACKLOG_COUNT} backlog issues (${PRIORITY_COUNT} priority)"
# Check each for readiness
READY_ISSUE=""

View file

@ -27,6 +27,27 @@ ensure_blocked_label_id() {
printf '%s' "$_BLOCKED_LABEL_ID"
}
# ensure_priority_label — look up (or create) the "priority" label, print its ID.
# Caches the result in _PRIORITY_LABEL_ID to avoid repeated API calls.
# Requires: CODEBERG_TOKEN, CODEBERG_API (from env.sh), codeberg_api()
ensure_priority_label() {
if [ -n "${_PRIORITY_LABEL_ID:-}" ]; then
printf '%s' "$_PRIORITY_LABEL_ID"
return 0
fi
_PRIORITY_LABEL_ID=$(codeberg_api GET "/labels" 2>/dev/null \
| jq -r '.[] | select(.name == "priority") | .id' 2>/dev/null || true)
if [ -z "$_PRIORITY_LABEL_ID" ]; then
_PRIORITY_LABEL_ID=$(curl -sf -X POST \
-H "Authorization: token ${CODEBERG_TOKEN}" \
-H "Content-Type: application/json" \
"${CODEBERG_API}/labels" \
-d '{"name":"priority","color":"#f59e0b"}' 2>/dev/null \
| jq -r '.id // empty' 2>/dev/null || true)
fi
printf '%s' "$_PRIORITY_LABEL_ID"
}
# diff_has_code_files — check if file list (stdin, one per line) contains code files
# Non-code paths: docs/*, formulas/*, evidence/*, *.md
# Returns 0 if any code file found, 1 if all files are non-code.