fix(#5188): re-trigger review via label after fix-agent push - #5551
fix(#5188): re-trigger review via label after fix-agent push#5551ggallen wants to merge 1 commit into
Conversation
PR Summary by QodoRe-trigger review by relabeling ready-for-review after fix-agent push
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
|
🤖 Finished Review · ✅ Success · Started 10:06 PM UTC · Completed 10:22 PM UTC |
Site previewPreview: https://1d246d28-site.fullsend-ai.workers.dev Commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Code Review by Qodo
1.
|
ReviewFindingsLow
Previous runReviewFindingsLow
Previous run (2)ReviewFindingsHigh
Low
Labels: PR fixes dispatch re-triggering for review agent after fix-agent push; modifies post-fix script in scaffold |
waynesun09
left a comment
There was a problem hiding this comment.
Review squad pass (Claude x2 + Grok + Gemini, 4 agents). fullsend-ai-review[bot] already correctly flagged a HIGH bug (label re-trigger calls run before GH_TOKEN is exported to PUSH_TOKEN, so they silently use the wrong ambient token and the whole fix no-ops) — not re-reported here.
Five new findings this round:
- HIGH: a second, even-quieter failure mode — if --remove-label fails for a transient reason (not just "label already absent"), the subsequent --add-label is idempotent and succeeds silently, so the warning never fires and there's zero log signal that re-dispatch didn't happen.
- HIGH: the new tests (perform_relabel_retrigger) reimplement the label-call logic in an isolated stub rather than exercising the real script, so they pass green today despite the real script having the already-confirmed GH_TOKEN bug — the test suite cannot catch this class of bug.
- MEDIUM (premature-decision): the core claim that GitHub doesn't refire the labeled webhook when re-adding an already-present label is asserted with no citation and no test; the cited precedents (post-code.sh, #2679) only ever add a label that was absent, so they don't actually validate this specific remove-then-add-when-present behavior.
- MEDIUM: the cancel-in-progress concurrency guard on the fix workflow can interrupt the remove/add sequence mid-flight, dropping the label with no automatic recovery until the next fix push.
- MEDIUM: the test stub doesn't validate argument construction, so an argument-order/quoting bug would pass silently.
Full detail inline. Given the compounding failure modes around the already-known GH_TOKEN bug, recommend addressing at least the two HIGH findings before merge.
6644a49 to
de825b7
Compare
|
🤖 Finished Review · ✅ Success · Started 1:23 AM UTC · Completed 1:37 AM UTC |
Superseded by updated review
|
Which is the relation with #5536? |
waynesun09
left a comment
There was a problem hiding this comment.
Review squad round 2 (Claude x2 + Grok + Gemini, 4 agents). All 6 round-1 findings verified genuinely fixed via direct re-inspection and mutation testing — GH_TOKEN export ordering, the sanitized ::notice:: on remove-label failure, the new structural ordering test, the honest unverified-assumption comment, the documented concurrency window, and the exact-match gh-invocation test assertions all hold up.
This round's mutation testing (deliberately mutating the fixed code to see if the new tests would catch it) surfaced:
- CRITICAL (test-only): the new run_gh_token_ordering_test is a static grep-based line-position check, not execution-based — commenting out the GH_TOKEN export, or wrapping it in a subshell where export doesn't propagate, both preserve the detected line ordering and pass the test while leaving the real authentication bug in place.
- MEDIUM: sanitization of the remove-label error message handles literal newlines and :: but misses percent-encoded %0A/%0D escapes, inconsistent with three sibling scripts in the same directory (post-retro.sh, install-precommit-tools.sh, extract-transcript-error.sh) that already strip these.
- Two LOW items: missing \r stripping in the same sanitization, and the new structural test's greps are unscoped to the relabel section specifically (works today only because the matched strings happen to be unique in the file).
Since the CRITICAL is a gap in test rigor rather than the shipped fix itself, and this PR already has two approvals, I don't think this needs to block merge — but the test gap is worth closing in a fast follow-up given it directly concerns the regression test for the bug this very PR fixed. Full detail inline.
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on PR_USER_LOGIN — the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai#5188). post-fix.sh now removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.sh's identical handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is re-added, hence the remove-then-add sequence. This supersedes fullsend-ai#5415, which attempted the same fix via an actor-identity-recognition function (is_org_bot()) extended across several dispatch-authorization gates. That approach was closed after review: it reintroduced a design (recognizing bots by name for dispatch authorization) that issue fullsend-ai#2669 had already evaluated and rejected in favor of label-based gating — "actors can be spoofed and the approach is fragile across workflow changes" — a decision PR fullsend-ai#2679 already implemented and shipped for the retro-to-triage handoff (closing fullsend-ai#2636). The label-based fix here needs no changes to the CEL-based dispatch path (internal/harnessdispatch), which already trusts label-added events unconditionally, and needs no forge-specific bot-identity logic, since labels work identically across GitHub and GitLab. A separate, unrelated bug that fullsend-ai#5415 also touched — the fix agent's own review-body content-attribution lookups missing the shared fullsend-ai-review[bot] identity — is tracked independently as fullsend-ai#5550, since it is not a dispatch-authorization question and is unaffected by this change. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
de825b7 to
b07a937
Compare
|
🤖 Finished Review · ✅ Success · Started 5:01 PM UTC · Completed 5:18 PM UTC |
|
@rh-hemartin Good question, sorry for the slow reply — this landed as a top-level comment rather than an inline review thread and I missed it. They're unrelated bugs, same family. #5536 is a different failure mode: dispatch routing here fires correctly for bot-authored PRs (it reads the author from the webhook event payload, which is in This PR only touches Both are instances of the same broader pattern (GitHub representing bot identities differently across webhook/REST/GraphQL/collaborator-permission APIs, and hardcoded format-specific matching breaking on the others), but they're separate bugs in separate code paths. |
There was a problem hiding this comment.
@ggallen why is this fix happening here instead of in the agents repo?
Also, since, as you say, this kind of functionality is used by multiple agents, I'd expect the introduction of a library script there to be reused by multiple agents.
rh-hemartin
left a comment
There was a problem hiding this comment.
Ops, I agree this change does not belong here.
|
@ifireball and @rh-hemartin,
Ah! Yes, this is exactly why #5588 is important. I'll move this there. Thanks for catching it! |
|
Closing this — you're both right, and there's concrete confirmation: #5588 ("delete agent files from scaffold embed") removes Re-implementing this fix (with everything learned in this PR's review — the GH_TOKEN ordering bug, the sanitization gaps, the execution-based test) against fullsend-ai/agents, and per @ifireball's suggestion, as a shared library helper rather than fix-specific logic. Will link the new PR here once it's up. Thanks both for catching this. |
|
🤖 Finished Retro · ✅ Success · Started 2:56 PM UTC · Completed 3:15 PM UTC |
Retro: PR #5551 — re-trigger review via label after fix-agent pushTimeline
What went well
What the review agent missed
Existing issues with new evidence
Autonomy assessmentThe review agent should not receive increased autonomy for scaffold/dispatch script changes. It approved this PR twice while humans identified a blocking architectural issue. The Proposals filed |
|
Follow-up: opened fullsend-ai/agents#469 with the fix re-implemented against the actual production script, as a shared library ( |
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that entire class of ordering bug structurally impossible, rather than merely tested against. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that entire class of ordering bug structurally impossible, rather than merely tested against. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that entire class of ordering bug structurally impossible, rather than merely tested against. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
pull_request_target.synchronize fires when the fix agent pushes, but its actor-identity authorization check is gated on the PR's original author, which for agent-authored PRs is the code agent's bot account regardless of who triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed and review is never re-dispatched after a fix-agent push (fullsend-ai/fullsend#5188). post-fix.src.sh now calls a new shared library, relabel-retrigger.lib.sh, which removes then re-adds the ready-for-review label after a successful push, forcing a fresh labeled webhook event. That path has no actor-authorization gate at all — label application itself already requires write access, so it needs no separate identity check — mirroring post-code.src.sh's existing handling of the PR-open case. GitHub does not fire a new labeled event when a label already present is simply re-added, hence the remove-then-add sequence. Verified live on a disposable PR in a personal fork: remove-then-add fires a second, genuinely distinct pull_request.labeled run; a plain re-add of an already-present label does not. Extracted as a library (retrigger_via_label) rather than inline script logic, per review feedback that this kind of dispatch-retrigger functionality should be reusable across agent post-scripts, not duplicated per-agent. The GitHub token is taken as an explicit argument and scoped to each gh invocation individually (GH_TOKEN="${token}" gh ...) rather than relying on the caller having exported GH_TOKEN into the shell environment at the right point in script execution — the library's parameter-passing design makes that class of ordering bug structurally impossible. retrigger_via_label checks whether the label was actually present before attempting removal, so a genuine --remove-label failure (while the label was present) escalates to a warning instead of being masked by the idempotent --add-label call silently no-op'ing as if the retrigger had succeeded. Added a bundled-script-has-relabel-retrigger presence check and a real NO_PUSH=false integration test (a genuine feature-branch commit pushed against a local bare repo standing in for GitHub) to post-fix-test.sh, so a transposed argument, wrong token, flipped NO_PUSH guard, or a deleted call site would fail CI instead of passing silently. This fix was originally attempted in fullsend-ai/fullsend#5551 against internal/scaffold/fullsend-repo/scripts/post-fix.sh, but that copy is being deleted from that repo (fullsend-ai/fullsend#5588) since agent scripts are now served from this repo via resolveAgentSource() — this repo's post-fix.sh is the actual production script, and it still had the original bug, unaffected by anything in #5551. Signed-off-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
What this fixes
After the fix agent pushes a commit to a PR, the review agent is never re-dispatched (#5188).
pull_request_target.synchronizefires on that push, but the dispatch routing's actor-identity check is gated onPR_USER_LOGIN— the PR's original author, which for agent-authored PRs is always the code agent's bot account, regardless of who actually triggered this fix run. GitHub App bots have no collaborator role, so that check always fails closed.The fix
post-fix.shnow removes then re-adds theready-for-reviewlabel after a successful push, forcing a freshlabeledwebhook event. That path has no actor-authorization gate at all — applying a label already requires write access, so no separate identity check is needed — mirroringpost-code.sh's existing handling of the PR-open case. GitHub does not fire a newlabeledevent when a label already present is simply re-added, hence the remove-then-add sequence.Why this approach, not identity recognition
This supersedes #5415, which attempted the same fix by extending an actor-identity-recognition function (
is_org_bot()) across several dispatch-authorization gates. @ifireball closed that approach out during review: it reintroduced a design — recognizing bots by name for dispatch authorization — that issue #2669 had already evaluated and explicitly rejected in favor of label-based gating ("actors can be spoofed and the approach is fragile across workflow changes"). PR #2679 already implemented that decision and shipped it for the retro→triage handoff, closing #2636.The label-based fix here has some concrete advantages the identity-based approach didn't:
internal/harnessdispatch) — itsIsAuthorized()already trustslabel-addedevents unconditionally, so this fix is already consistent there with zero Go changes.[bot]-suffixed App-login convention has no GitLab equivalent at all, so an identity-matching approach would need an entirely separate mechanism per forge.#2636 needs no further work — it's already fixed by #2679.
What's not in this PR
A separate, unrelated bug that #5415 also touched — the fix agent's own review-body content-attribution lookups (in
reusable-fix.yml,reusable-dispatch.yml, andpre-fetch-prior-review.sh) missing the sharedfullsend-ai-review[bot]identity — is tracked independently as #5550 (found by @waynesun09 during #5415's review). It's a content-attribution question ("whose review text do I trust"), not dispatch authorization, so it's unaffected by the labels-vs-identity discussion here and doesn't belong in this PR.#5463and#5480(identity-hardening follow-ups filed during #5415's review) are no longer relevant to dispatch authorization now that this PR doesn't useis_org_bot()for that purpose; they may still be relevant once #5550 is addressed.Test plan
bash internal/scaffold/fullsend-repo/scripts/post-fix-test.sh— new test cases cover the remove/add label sequence tolerating either call failing without the script exiting nonzero.go build ./...andgo test ./internal/scaffold/...— no regressions.Fixes #5188. References #2636, #2669, #2679, #5463, #5480, #5550. Supersedes #5415.
cc @ifireball @waynesun09 — this replaces #5415 per the discussion there; see the closing comment on that PR for the full rationale.