From 38b90d20ab8b41850b846e3ce2e2a0b6ed719644 Mon Sep 17 00:00:00 2001 From: Weekendsuperhero <4048475+WeekendSuperhero@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:40:05 -0700 Subject: [PATCH] fix(pr-review): per-agent skip + no self-triggered shadow runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two field reports from the first live rounds: 1. A press re-ran ALL agents even when some had already cleared the exact head SHA — the same-SHA skip was all-or-nothing. Now each agent is skipped individually when its sticky marker covers the head SHA AND its positive label still stands (the verdict is read from the labels; no session spent). Agents that failed or errored at this SHA still re-run, so a press doubles as a re-roll of open verdicts; all-positive at the current SHA no-ops the whole press. muse:force re-runs everyone; hand-removing a positive label forces that agent. finalize counts skipped agents as positive for the muse:approved rollup and leaves their labels untouched. 2. Adding muse:reviewing used the app token, whose labeled event spawns a new run of the caller workflow — its jobs skip, but the newer (skipped) run replaced the live round in the PR checks view. All label writes now use github.token, whose events never trigger workflows: no more shadow runs mid-round. --- .github/workflows/reusable-pr-review.yml | 55 +++++++++++++++++++----- docs/muse-workflows.md | 11 ++++- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/.github/workflows/reusable-pr-review.yml b/.github/workflows/reusable-pr-review.yml index 65824dd..1484847 100644 --- a/.github/workflows/reusable-pr-review.yml +++ b/.github/workflows/reusable-pr-review.yml @@ -118,6 +118,7 @@ jobs: outputs: skip: ${{ steps.state.outputs.skip }} agents: ${{ steps.state.outputs.agents }} + skipped: ${{ steps.state.outputs.skipped }} round: ${{ steps.state.outputs.round }} steps: - name: Validate GitHub App secret configuration @@ -152,7 +153,10 @@ jobs: # (idempotent — `--force` updates color/description in place). - name: Re-arm trigger and bootstrap labels env: - GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }} + # github.token, never the app token: default-token events don't + # trigger workflows, so our own label writes can't spawn a newer + # (skipped) run that shadows this round in the PR checks view. + GH_TOKEN: ${{ github.token }} PR: ${{ github.event.pull_request.number }} PRESSED: ${{ github.event.label.name }} run: | @@ -201,14 +205,27 @@ jobs: echo "::error::Unknown agent '$a' (allowed: review, security, tests)"; exit 1 ;; esac done - echo "agents=$(printf '%s' "$AGENTS_JSON" | jq -c .)" >> "$GITHUB_OUTPUT" - gh api "repos/$GITHUB_REPOSITORY/issues/$PR/comments" --paginate --jq '.[]' | jq -s '.' > /tmp/all_comments.json - - ALL_CURRENT=true + gh api "repos/$GITHUB_REPOSITORY/issues/$PR/labels" --paginate --jq '.[].name' > /tmp/pr_labels.txt || : > /tmp/pr_labels.txt + has_label() { grep -qxF "$1" /tmp/pr_labels.txt; } + + # Per-agent skip: an agent that already reviewed THIS head SHA and + # whose positive label still stands doesn't burn another session — + # its verdict is read from the labels. Agents that failed (or never + # ran) at this SHA DO re-run on a press, so a press doubles as a + # re-roll of open verdicts. The force label re-runs everyone, and + # removing an agent's positive label by hand forces just that one. + RUN_AGENTS='[]' + SKIPPED_AGENTS='[]' MAX_ROUND=0 LAST_SHA="" for a in $(printf '%s' "$AGENTS_JSON" | jq -r '.[]'); do + case "$a" in + review) POS="review:approved" ;; + security) POS="security:clear" ;; + tests) POS="tests:sufficient" ;; + esac + BODY=$(jq -r --arg m "