fix(automation): triage owns routing for every portal issue
The Report Issue button (older deployed build) stamps claude-queue at creation, so triage skipped those issues and they went straight to auto-fix (e.g. #37, a large localization feature that should be interactive). Triage now claims a portal issue until it carries a new `triaged` marker (or is in progress/done) — claude-queue is no longer a skip reason. On routing to interactive it strips the stray claude-queue; on claude-queue it adds triaged. Manual queue still works for NON-portal issues (triage never claims those). Resilient regardless of which button build is deployed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
8a614878d2
commit
aec6d2971f
2 changed files with 29 additions and 11 deletions
|
|
@ -106,17 +106,23 @@ before a release tag deploys them to prod.
|
||||||
## Issue label lifecycle
|
## Issue label lifecycle
|
||||||
|
|
||||||
```
|
```
|
||||||
portal ──(triage)──▶ claude-queue ─▶ claude-working ─▶ claude-pr | claude-failed
|
portal ──(triage)──▶ triaged + claude-queue ─▶ claude-working ─▶ claude-pr | claude-failed
|
||||||
└────▶ interactive (stops here — handle with Claude interactively)
|
└─────▶ triaged + interactive (stops here — handle with Claude interactively)
|
||||||
```
|
```
|
||||||
|
|
||||||
- A `portal` issue with no decision label yet is triaged once (`maxTriagePerRun`
|
- **Triage owns routing for every `portal` issue.** Each untriaged portal issue is
|
||||||
per run). Triage adds `claude-queue` or `interactive` and posts a breakdown.
|
triaged once (`maxTriagePerRun` per run); triage adds `triaged` plus `claude-queue`
|
||||||
|
or `interactive` and posts a breakdown. Triage skips an issue only once it carries
|
||||||
|
`triaged`, `interactive`, `claude-working`, `claude-pr`, or `claude-failed`.
|
||||||
|
- **`claude-queue` alone does NOT skip triage on a portal issue.** The Report Issue
|
||||||
|
button may stamp `claude-queue` at creation; triage still claims the issue and
|
||||||
|
decides routing (stripping the stray `claude-queue` if it routes to `interactive`).
|
||||||
|
This is why triage works even if an older button build is deployed.
|
||||||
- `claude-queue` → `claude-working` → `claude-pr` (PR opened) or `claude-failed`.
|
- `claude-queue` → `claude-working` → `claude-pr` (PR opened) or `claude-failed`.
|
||||||
- To retry a failed issue, re-add `claude-queue`.
|
- To retry a failed issue, re-add `claude-queue` (and remove `claude-failed`).
|
||||||
- To queue any manually-created issue for Claude (skipping triage), add
|
- To queue a **non-portal** issue for Claude (skipping triage), add `claude-queue`
|
||||||
`claude-queue` directly. To force human handling, add `interactive`.
|
directly — triage never claims issues without the `portal` label.
|
||||||
- Triage is skipped for issues that already carry any decision label.
|
- To force a portal issue straight to fix, add `triaged` + `claude-queue` yourself.
|
||||||
|
|
||||||
## Releasing
|
## Releasing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -145,12 +145,16 @@ if [ ! -d "$WORKDIR/.git" ]; then
|
||||||
git -C "$WORKDIR" config user.email "claude-autofix@pelagiamarine.com"
|
git -C "$WORKDIR" config user.email "claude-autofix@pelagiamarine.com"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DECISION_LABELS="claude-queue interactive claude-working claude-pr claude-failed"
|
# Triage OWNS routing for every portal issue. It claims a portal issue until it has
|
||||||
|
# been triaged (`triaged`) or is already in progress/done. NOTE: claude-queue is
|
||||||
|
# deliberately NOT a skip reason — the Report Issue button may stamp claude-queue at
|
||||||
|
# creation, and triage must still decide claude-queue vs interactive itself.
|
||||||
|
TRIAGE_SKIP_LABELS="interactive claude-working claude-pr claude-failed triaged"
|
||||||
|
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
# Phase 1: triage new portal issues
|
# Phase 1: triage new portal issues
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
dl_json=$(printf '%s\n' $DECISION_LABELS | jq -R . | jq -sc .)
|
dl_json=$(printf '%s\n' $TRIAGE_SKIP_LABELS | jq -R . | jq -sc .)
|
||||||
to_triage=$(issues_by_label portal | jq -c --argjson dl "$dl_json" \
|
to_triage=$(issues_by_label portal | jq -c --argjson dl "$dl_json" \
|
||||||
'[ .[] | select((.labels|map(.name)) as $have | ($dl | any(. as $d | $have|index($d))) | not) ] | sort_by(.number)')
|
'[ .[] | select((.labels|map(.name)) as $have | ($dl | any(. as $d | $have|index($d))) | not) ] | sort_by(.number)')
|
||||||
to_triage=$(printf '%s' "$to_triage" | jq -c ".[:$MAX_TRIAGE]")
|
to_triage=$(printf '%s' "$to_triage" | jq -c ".[:$MAX_TRIAGE]")
|
||||||
|
|
@ -212,13 +216,21 @@ while [ "$t" -lt "$n_triage" ]; do
|
||||||
|
|
||||||
if [ -z "$label" ]; then
|
if [ -z "$label" ]; then
|
||||||
log "Triage for #$num produced no valid decision; leaving for a human"
|
log "Triage for #$num produced no valid decision; leaving for a human"
|
||||||
|
# Mark triaged + strip any button-stamped claude-queue so it is NOT auto-fixed.
|
||||||
|
set_labels "$num" "claude-queue" "triaged"
|
||||||
add_comment "$num" "$BOT_MARKER
|
add_comment "$num" "$BOT_MARKER
|
||||||
[Claude triage] Could not auto-triage this issue. A human should review it and add either \`claude-queue\` or \`interactive\`."
|
[Claude triage] Could not auto-triage this issue. A human should review it and add either \`claude-queue\` or \`interactive\`."
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Label FIRST so a comment failure cannot trigger a re-triage that double-posts.
|
# Label FIRST so a comment failure cannot trigger a re-triage that double-posts.
|
||||||
add_labels "$num" "$label"
|
# Mark `triaged` so triage won't re-claim it. For interactive, strip any
|
||||||
|
# claude-queue the Report Issue button may have stamped so the fix phase ignores it.
|
||||||
|
if [ "$label" = "interactive" ]; then
|
||||||
|
set_labels "$num" "claude-queue" "interactive triaged"
|
||||||
|
else
|
||||||
|
add_labels "$num" claude-queue triaged
|
||||||
|
fi
|
||||||
# No bot marker on the breakdown: it is genuine refined requirements and SHOULD
|
# No bot marker on the breakdown: it is genuine refined requirements and SHOULD
|
||||||
# be fed to the fix stage (comments_block includes it).
|
# be fed to the fix stage (comments_block includes it).
|
||||||
note=${breakdown:-"(no breakdown produced)"}
|
note=${breakdown:-"(no breakdown produced)"}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue