From 016af5d205d2684bbeaef1603564689c119c44b6 Mon Sep 17 00:00:00 2001 From: Xiwei Pan Date: Mon, 6 Jul 2026 14:20:06 +0800 Subject: [PATCH] fix(scoring): one rolling leaderboard PR; add reset_results; pluralize title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each scoring run opened a fresh bot/leaderboard- PR, so triggering the workflow twice produced duplicate identical PRs (e.g. #32/#33) with no dedup. Use a single rolling branch `bot/leaderboard`, force-updated every run, and create the PR only if one isn't already open (else update its title) — so there is at most one open leaderboard PR ever. Also add a `reset_results` workflow_dispatch input that wipes R2 results/ before scoring, to clear stale scored files (e.g. a pre-test-marker entry that keeps resurfacing on the board), and fix the "1 models/bugs" pluralization. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_018xw6L5yUrz33UrQpanbwnH --- .github/workflows/score-from-r2.yml | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/.github/workflows/score-from-r2.yml b/.github/workflows/score-from-r2.yml index a6282e1..331a23c 100644 --- a/.github/workflows/score-from-r2.yml +++ b/.github/workflows/score-from-r2.yml @@ -15,7 +15,12 @@ name: Score submissions from R2 (private → aggregate) # See intake/cloudflare-worker/README.md. on: - workflow_dispatch: {} # manual trigger (maintainer) + workflow_dispatch: # manual trigger (maintainer) + inputs: + reset_results: + description: "Wipe R2 results/ before scoring (clean the board of stale scored files)" + type: boolean + default: false schedule: - cron: "0 16 * * *" # daily sweep of R2 for new submissions (16:00 UTC). @@ -61,6 +66,12 @@ jobs: - name: Pull pending submissions + prior scored detail from R2 run: | mkdir -p incoming results/scored + # reset_results (manual): wipe the prior scored detail so the board is rebuilt from + # scratch — used to clear stale/test entries that predate a rule change. + if [ "${{ github.event.inputs.reset_results }}" = "true" ]; then + echo "reset_results: wiping s3://$BUCKET/results" + aws s3 rm "s3://$BUCKET/results" --recursive --endpoint-url "$R2_ENDPOINT" || true + fi # incoming/ = raw submissions to score; results/ = all prior scored detail, so the # rebuilt leaderboard reflects the FULL history, not just this batch. aws s3 sync "s3://$BUCKET/incoming" ./incoming --endpoint-url "$R2_ENDPOINT" @@ -102,12 +113,22 @@ jobs: MODELS=$(jq 'length' site/results.json) BUGS=$(jq '[.[].bugs_found] | add // 0' site/results.json) DATE=$(date -u +%Y-%m-%d) - TITLE="Update leaderboard — ${MODELS} models, ${BUGS} verified bugs (${DATE})" - BR="bot/leaderboard-${{ github.run_id }}" - git checkout -b "$BR" + [ "$MODELS" = 1 ] && MS="" || MS="s" + [ "$BUGS" = 1 ] && BS="" || BS="s" + TITLE="Update leaderboard — ${MODELS} model${MS}, ${BUGS} verified bug${BS} (${DATE})" + # One rolling branch → at most ONE open leaderboard PR ever. Each run force-updates + # it (and its PR) instead of opening a fresh bot/leaderboard- PR every time. + BR="bot/leaderboard" + git checkout -B "$BR" git add site/results.json git commit -m "$TITLE" - git push origin "$BR" - gh pr create --base main --head "$BR" \ - --title "$TITLE" \ - --body "Automated refresh of \`site/results.json\` from newly scored submissions in private R2. Certificates and rule identities stay private in R2 — only the aggregate counts change here (guarded by \`check_aggregate.py\`). Merging deploys the public site via publish-on-merge." + git push -f origin "$BR" + EXISTING=$(gh pr list --head "$BR" --state open --json number -q '.[0].number') + if [ -n "$EXISTING" ]; then + gh pr edit "$EXISTING" --title "$TITLE" + echo "Updated existing leaderboard PR #$EXISTING" + else + gh pr create --base main --head "$BR" \ + --title "$TITLE" \ + --body "Automated refresh of \`site/results.json\` from newly scored submissions in private R2. Certificates and rule identities stay private in R2 — only the aggregate counts change here (guarded by \`check_aggregate.py\`). Merging deploys the public site via publish-on-merge. This PR is force-updated by each scoring run, so there is only ever one open leaderboard PR." + fi