chore: relabel handled issues so daily sweeps don't re-treat them

Now that tier 2 runs daily instead of weekly, an issue left carrying
ai-triage after a sweep would be re-selected and fully re-analysed the very
next morning, before there's been a working day to review the first PR.
Nothing previously dropped issues out of the ai-triage backlog once handled.

- issue-fix.md: new hard limit 6 — relabel every issue as the last action
  before moving to the next one. ai:fixed / ai:upstream / ai:needs-human
  replace ai-triage depending on outcome.
- daily_ai_fix.yaml: pre-create the three replacement labels once, up front
  (Claude never has to improvise a color or retry a missing-label error —
  wasted turns multiplied by batch size). Add a "Guard against repeat
  processing" step, same belt-and-braces pattern as the existing forbidden-
  paths guard: force-relabel to ai:needs-human anything the batch still
  finds carrying ai-triage after the run, independent of whether Claude's
  own relabeling succeeded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
alexbelgium
2026-07-23 14:52:42 +02:00
parent 17d29762d7
commit fecae3241f
2 changed files with 63 additions and 5 deletions

View File

@@ -24,6 +24,22 @@ anything that violates them gets blocked and flagged.
5. If the fix requires changing more than roughly 60 lines, or touching more
than three files, stop. Post the analysis, open no pull request, and say
plainly that the change is too large for an unattended fix.
6. **Relabel every issue before moving to the next one.** This sweep runs
daily over the same `ai-triage`-labelled backlog. An issue you have
already finished with must drop that label immediately — otherwise
tomorrow's sweep re-selects it, opens a second competing branch, and
burns another full read-the-source-and-fix pass on work that is already
done. Do this as your last action on the issue, right after commenting,
not batched at the end: `gh issue edit <n> --remove-label ai-triage
--add-label <replacement>`, where `<replacement>` is exactly one of:
- `ai:fixed` — you opened a draft pull request for it.
- `ai:upstream` — you reversed tier 1's call and the fault is upstream,
so no pull request.
- `ai:needs-human` — too large for an unattended fix (rule 5), or you
found no fix and are reporting what you ruled out.
A workflow step checks this after you finish and force-corrects to
`ai:needs-human` for anything still carrying `ai-triage` — treat that as
a bug in your run, not a safety net to lean on.
## Per add-on, do this in order
@@ -52,11 +68,13 @@ change. Add a `CHANGELOG.md` entry in the add-on's existing format.
and line, what the change does, how you verified it (or an explicit statement
that you could not verify it), and `Closes #<n>`.
**6. Comment on the issue.** Root cause, the fix in one or two sentences, and
the pull request link. Plain language — the reader is a Home Assistant user,
not a Go developer. If you found no fix, say what you ruled out and what you
would need to go further. Close with a note that this is automated analysis
pending Alex's review.
**6. Comment on the issue, then relabel it (hard limit 6).** Root cause, the
fix in one or two sentences, and the pull request link. Plain language — the
reader is a Home Assistant user, not a Go developer. If you found no fix, say
what you ruled out and what you would need to go further. Close with a note
that this is automated analysis pending Alex's review. Then remove
`ai-triage` and add the one replacement label that matches the outcome,
before starting the next issue.
## Meta-findings

View File

@@ -77,6 +77,20 @@ jobs:
git config user.name "claude-ai-fix[bot]"
git config user.email "claude-ai-fix[bot]@users.noreply.github.com"
# Created up front so issue-fix.md's per-issue relabel never has to
# improvise a color or retry a "label does not exist" error — that's a
# wasted turn multiplied by every issue in the batch.
- name: Ensure relabel targets exist
if: steps.batch.outputs.count != '0'
env:
GH_TOKEN: ${{ secrets.AI_PR_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
for l in ai:fixed ai:upstream ai:needs-human; do
gh label create "$l" --repo "$REPO" --color ededed --force >/dev/null 2>&1 || true
done
- name: Analyse and fix
if: steps.batch.outputs.count != '0'
uses: anthropics/claude-code-action@v1
@@ -94,6 +108,32 @@ jobs:
env:
GH_TOKEN: ${{ secrets.AI_PR_TOKEN }}
# Belt and braces. issue-fix.md instructs Claude to drop the ai-triage
# label off every issue it finishes with (hard limit 6), so tomorrow's
# sweep never re-selects and re-spends a full read-and-fix pass on
# work that's already done. Enforce it here in case a turn or timeout
# budget runs out before the relabel step of the last issue or two.
- name: Guard against repeat processing
if: always() && steps.batch.outputs.count != '0'
env:
GH_TOKEN: ${{ secrets.AI_PR_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
mapfile -t ISSUES < <(jq -r '.[].number' /tmp/ai-fix/batch.json)
for n in "${ISSUES[@]}"; do
STILL=$(gh issue view "$n" --repo "$REPO" --json labels \
--jq '[.labels[].name] | index("ai-triage") != null' 2>/dev/null) || {
echo "::warning::could not re-check issue #$n (deleted or transferred?), skipping"
continue
}
if [ "$STILL" = "true" ]; then
echo "::warning::issue #$n still carries ai-triage after the sweep, forcing it out of tomorrow's batch"
gh issue edit "$n" --repo "$REPO" \
--remove-label ai-triage --add-label ai:needs-human
fi
done
# Belt and braces. The prompt forbids these paths; this enforces it.
- name: Guard forbidden paths
if: always() && steps.batch.outputs.count != '0'