Skip to content

fix(#5188): re-trigger review via label after fix-agent push - #5551

Closed
ggallen wants to merge 1 commit into
fullsend-ai:mainfrom
ggallen:fix/5188-relabel-review-on-fix-push
Closed

fix(#5188): re-trigger review via label after fix-agent push#5551
ggallen wants to merge 1 commit into
fullsend-ai:mainfrom
ggallen:fix/5188-relabel-review-on-fix-push

Conversation

@ggallen

@ggallen ggallen commented Jul 23, 2026

Copy link
Copy Markdown
Member

What this fixes

After the fix agent pushes a commit to a PR, the review agent is never re-dispatched (#5188). pull_request_target.synchronize fires on that push, but the dispatch routing's actor-identity check is gated on PR_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.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 — applying a label already requires write access, so no separate identity check is needed — mirroring post-code.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.

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:

  • No change needed to the CEL-based dispatch path (internal/harnessdispatch) — its IsAuthorized() already trusts label-added events unconditionally, so this fix is already consistent there with zero Go changes.
  • No forge-specific bot-identity logic — labels work identically on GitHub and GitLab; GitHub's [bot]-suffixed App-login convention has no GitLab equivalent at all, so an identity-matching approach would need an entirely separate mechanism per forge.
  • No new spoofing surface — nothing here depends on trusting a login string.

#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, and pre-fetch-prior-review.sh) missing the shared fullsend-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.

#5463 and #5480 (identity-hardening follow-ups filed during #5415's review) are no longer relevant to dispatch authorization now that this PR doesn't use is_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 ./... and go 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.

@ggallen
ggallen requested a review from a team as a code owner July 23, 2026 22:04
@ggallen
ggallen requested review from ifireball and waynesun09 July 23, 2026 22:05
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Re-trigger review by relabeling ready-for-review after fix-agent push

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Toggle ready-for-review after fix-agent pushes to force a fresh labeled webhook.
• Avoid brittle actor-identity authorization on pull_request_target.synchronize for bot-authored
 PRs.
• Add shell-level regression tests for relabel sequencing and failure-tolerance behavior.
Diagram

graph TD
  A["Fix agent workflow"] --> B["post-fix.sh"] --> C["gh pr edit: remove+add label"] --> D["GitHub PR labels"] --> E["issues.labeled event"] --> F["Dispatch router"] --> G["Review agent"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Expand actor-identity authorization (bot allowlist)
  • ➕ Keeps dispatching on pull_request_target.synchronize without extra label churn
  • ➕ No need to perform additional GitHub API calls post-push
  • ➖ Brittle/forge-specific: bot logins differ across GitHub App vs GitLab and can change
  • ➖ Reintroduces a spoofing/maintenance surface area the project has previously avoided
  • ➖ Touches multiple auth gates/paths and is harder to reason about end-to-end
2. Dispatch review directly from post-fix (workflow_dispatch/repository_dispatch)
  • ➕ Deterministic re-run without relying on label webhook semantics
  • ➕ Can encode explicit context (PR number, head SHA) in the dispatch payload
  • ➖ Adds/expands privileged dispatch mechanisms in a security-sensitive script
  • ➖ Requires additional workflow plumbing and secrets/permissions review
  • ➖ May diverge from existing label-gated control-plane conventions
3. Change synchronize authorization to key off trigger source (not PR author)
  • ➕ Fixes the root cause for synchronize-based dispatch without label manipulation
  • ➕ More semantically correct than PR author checks when agents push
  • ➖ Still requires robust, forge-aware identity provenance and careful threat modeling
  • ➖ Likely requires Go/CEL path changes across dispatch implementations
  • ➖ Higher blast radius than the label-toggle approach

Recommendation: Prefer the PR’s label-toggle approach: it aligns with existing label-gated dispatch behavior (already trusted by the labeled-event path), avoids fragile bot-identity recognition, and keeps the change localized to post-fix.sh with explicit failure tolerance so a successful fix push is not blocked by a relabel hiccup.

Files changed (2) +103 / -6

Bug fix (1) +30 / -6
post-fix.shToggle ready-for-review label after push to re-dispatch review +30/-6

Toggle ready-for-review label after push to re-dispatch review

• Adds a new post-push step that removes then re-adds the 'ready-for-review' label to force a fresh 'issues.labeled' webhook. The remove is best-effort (silent on failure) and the add emits a warning but does not fail the run, matching the goal of not blocking a successful fix push on dispatch retriggering.

internal/scaffold/fullsend-repo/scripts/post-fix.sh

Tests (1) +73 / -0
post-fix-test.shAdd regression tests for relabel re-trigger behavior +73/-0

Add regression tests for relabel re-trigger behavior

• Introduces a test helper that mirrors post-fix.sh’s remove-then-add 'ready-for-review' sequence. Adds cases covering remove failure, add failure, and both failing, ensuring the script never hard-fails and only warns when re-add fails.

internal/scaffold/fullsend-repo/scripts/post-fix-test.sh

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 23, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:06 PM UTC · Completed 10:22 PM UTC
Commit: 6644a49 · View workflow run →

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Site preview

Preview: https://1d246d28-site.fullsend-ai.workers.dev

Commit: b07a93768f5acf0b9796c0d0a4e03b0a92de7d9c

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

qodo-code-review Bot commented Jul 23, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 61 rules

Grey Divider


Action required

1. GH_TOKEN exported too late ✓ Resolved 🐞 Bug ≡ Correctness
Description
In post-fix.sh, the new gh pr edit ... --remove-label/--add-label relabel block runs before
export GH_TOKEN="${PUSH_TOKEN}", so on runners without preexisting gh auth the relabel calls
will fail and the review re-dispatch won’t occur. This undermines the intended fix for #5188 and is
hard to diagnose because stderr is suppressed on both calls.
Code

internal/scaffold/fullsend-repo/scripts/post-fix.sh[R354-366]

+if [ "${NO_PUSH}" = "false" ]; then
+  gh pr edit "${PR_NUMBER}" --repo "${REPO_FULL_NAME}" \
+    --remove-label "ready-for-review" 2>/dev/null || true
+  gh pr edit "${PR_NUMBER}" --repo "${REPO_FULL_NAME}" \
+    --add-label "ready-for-review" 2>/dev/null || \
+    echo "::warning::Failed to re-apply ready-for-review label to PR #${PR_NUMBER} — review will not be re-dispatched"
+fi
+
+# ---------------------------------------------------------------------------
+# 6. Process structured output (fix-result.json)
# ---------------------------------------------------------------------------
export GH_TOKEN="${PUSH_TOKEN}"
Relevance

⭐⭐⭐ High

Repo precedent: authenticate gh calls early; unauthenticated gh api failures were fixed
similarly.

PR-#2346

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The relabel block executes at lines 354–360, but GH_TOKEN is only exported at line 365, so those
gh calls don’t see the token. The repo’s analogous logic in post-code.sh exports/sets GH_TOKEN
before any gh operations, indicating the intended pattern.

internal/scaffold/fullsend-repo/scripts/post-fix.sh[354-366]
internal/scaffold/fullsend-repo/scripts/post-code.sh[403-407]
internal/scaffold/fullsend-repo/scripts/post-code.sh[87-88]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`post-fix.sh` invokes `gh pr edit` to remove/re-add `ready-for-review` before `GH_TOKEN` is exported. On a GitHub Actions runner, `gh` typically relies on `GH_TOKEN` for non-interactive auth; if it’s not set yet, the relabel step will fail and the review agent won’t be re-dispatched.

### Issue Context
This block was added specifically to force a new `labeled` webhook event after a successful fix push. If the relabel calls can’t authenticate, the workflow silently regresses back to “no re-dispatch after fix push”.

### Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/post-fix.sh[354-366]

### Suggested fix
Move `export GH_TOKEN="${PUSH_TOKEN}"` to *before* the relabel block, or explicitly scope the token per command:
- `GH_TOKEN="${PUSH_TOKEN}" gh pr edit ... --remove-label ...`
- `GH_TOKEN="${PUSH_TOKEN}" gh pr edit ... --add-label ...`

(Prefer the export earlier so later `gh` calls remain consistent.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Remove-label errors fully hidden ✓ Resolved 🐞 Bug ☼ Reliability
Description
The relabel logic unconditionally ignores all --remove-label failures (2>/dev/null || true) even
though removal is required to force a new labeled event when the label already exists. If removal
fails for an unexpected reason (API/permission/transient failure) while the label remains present,
the subsequent add may be ineffective and the review won’t be re-dispatched, with no warning
indicating the remove step failed.
Code

internal/scaffold/fullsend-repo/scripts/post-fix.sh[R355-357]

+  gh pr edit "${PR_NUMBER}" --repo "${REPO_FULL_NAME}" \
+    --remove-label "ready-for-review" 2>/dev/null || true
+  gh pr edit "${PR_NUMBER}" --repo "${REPO_FULL_NAME}" \
Relevance

⭐⭐ Medium

Team sometimes prefers surfacing gh failures, but this PR explicitly treats remove failure as
silent/acceptable.

PR-#279
PR-#1487

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script explicitly states removal is required to force a new labeled event, but the remove
command’s stderr is discarded and failures are always ignored. Since post-code.sh always adds
ready-for-review on PR creation, the label is often already present, making remove a critical step
of the intended re-trigger path.

internal/scaffold/fullsend-repo/scripts/post-fix.sh[351-357]
internal/scaffold/fullsend-repo/scripts/post-code.sh[535-544]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The relabel mechanism depends on successfully removing `ready-for-review` first, but the script suppresses stderr and always swallows the remove command’s failure. That hides unexpected errors which can prevent the desired re-dispatch while leaving no signal in logs.

### Issue Context
The script’s own comment states removal is necessary to force a new `labeled` event when the label is already present. Also, `post-code.sh` applies the `ready-for-review` label on PR creation, so it’s common for the label to already exist when a fix run occurs.

### Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/post-fix.sh[351-359]

### Suggested fix
Keep the operation non-fatal, but distinguish expected vs unexpected failures:
- Capture stderr for the remove call, and if it fails with something other than "label not present" / 404, emit a `::warning::` noting that re-dispatch may not occur.
- Alternatively, check whether the label is currently present via `gh pr view --json labels` and only attempt removal when present; if removal fails, warn.

Do not make the script exit non-zero; just improve detection/observability for unexpected failures.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review

Findings

Low

  • [gha-workflow-command-injection] internal/scaffold/fullsend-repo/scripts/post-fix.shPR_NUMBER is interpolated unsanitized into ::notice:: and ::warning:: GHA workflow commands in the relabel step. PR_NUMBER is validated upstream in reusable-fix.yml with ^[1-9][0-9]*$ — strictly a positive integer and not attacker-controllable. The error message body (SANITIZED_ERR) is comprehensively sanitized against :: sequences, literal newlines/CRs, and percent-encoded %0A/%0D variants. Not a regression — follows existing conventions throughout the file.

  • [test integrity] internal/scaffold/fullsend-repo/scripts/post-fix-test.sh — The perform_relabel_retrigger test helper reimplements the production code rather than extracting it. If the production logic changes, the reimplementation can drift. The run_gh_token_execution_test partially mitigates this by running actual production code, but only validates GH_TOKEN propagation — not full error-handling semantics. This follows the accepted pattern used by other tests in this file.

  • [edge-case] internal/scaffold/fullsend-repo/scripts/post-fix.sh — The --add-label call discards stderr (2>/dev/null), so its failure warning provides no diagnostic detail — unlike the --remove-label path which captures and sanitizes stderr. Minor observability gap, not a correctness bug.

Previous run

Review

Findings

Low

  • [gha-workflow-command-injection] internal/scaffold/fullsend-repo/scripts/post-fix.shPR_NUMBER is interpolated unsanitized into ::notice:: and ::warning:: GHA workflow commands in the relabel step. PR_NUMBER is a GitHub-assigned integer set by the workflow caller and is not attacker-controllable in practice, so injection risk is negligible. The error message body (SANITIZED_ERR) is properly sanitized via tr '\n' ' ' | sed 's/::/: /g'. Not a regression — the new code follows the same conventions as the rest of the file.
Previous run (2)

Review

Findings

High

  • [api-contract] internal/scaffold/fullsend-repo/scripts/post-fix.sh:359 — The new step 5 (relabel re-trigger) calls gh pr edit before export GH_TOKEN="${PU..." (which only happens at the start of step 6, line ~367). The gh CLI will use whatever ambient GH_TOKEN the GitHub Actions runner inherits — in the per-org install model, this is github.token scoped to the config repository, not the target repository. The --remove-label and --add-label calls will fail with a permissions error. Because both failures are suppressed (|| true and || echo "::warning::..."), the feature silently does nothing — the review agent is never re-dispatched after a fix push, which is the entire purpose of this PR. In post-code.sh, export GH_TOKEN="${PU..." appears before the label application, so that script works correctly.
    Remediation: Move export GH_TOKEN="${PU..." from its current position (start of step 6) to before step 5, so the relabel gh calls authenticate with the app-minted token that has pull-requests:write on the target repo. This matches the pattern in post-code.sh.

Low

  • [gha-workflow-command-injection] internal/scaffold/fullsend-repo/scripts/post-fix.sh:362PR_NUMBER is interpolated into a ::warning:: GHA workflow command without sanitization for :: sequences or %0A/%0D encoded newlines. While PR_NUMBER is a GitHub-assigned integer and not attacker-controllable, this is inconsistent with defense-in-depth. Not a regression — matches pre-existing patterns elsewhere in the file.

Labels: PR fixes dispatch re-triggering for review agent after fix-agent push; modifies post-fix script in scaffold

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added component/dispatch Workflow dispatch and triggers bug labels Jul 23, 2026

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix-test.sh
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix-test.sh
@ggallen
ggallen force-pushed the fix/5188-relabel-review-on-fix-push branch from 6644a49 to de825b7 Compare July 24, 2026 01:21
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 24, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:23 AM UTC · Completed 1:37 AM UTC
Commit: de825b7 · View workflow run →

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review July 24, 2026 01:37

Superseded by updated review

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Jul 24, 2026
@rh-hemartin

Copy link
Copy Markdown
Member

Which is the relation with #5536?

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread internal/scaffold/fullsend-repo/scripts/post-fix-test.sh Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix.sh Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/post-fix-test.sh Outdated
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>
@ggallen
ggallen force-pushed the fix/5188-relabel-review-on-fix-push branch from de825b7 to b07a937 Compare July 24, 2026 16:59
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 24, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:01 PM UTC · Completed 5:18 PM UTC
Commit: b07a937 · View workflow run →

@ggallen

ggallen commented Jul 25, 2026

Copy link
Copy Markdown
Member Author

@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 ...[bot] suffix format) — but a separate "fix eligibility" check inside reusable-fix.yml re-fetches the author via gh pr view --json author (GraphQL), which returns a different format (app/fullsend-ai-coder, no [bot] suffix). That check's \[bot\]$ regex doesn't match the app/ format, so it misclassifies the PR as human-authored and blocks the fix agent from auto-running entirely, requiring a human to add fullsend-fix or run /fs-fix manually.

This PR only touches post-fix.sh, and post-fix.sh never even runs in #5536's failure mode — the eligibility check blocks the fix agent before it does anything, so there's nothing for this PR's label re-trigger to interact with. #5536 needs its own independent fix.

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.

@ggallen
ggallen requested a review from waynesun09 July 25, 2026 16:35

@ifireball ifireball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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 rh-hemartin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops, I agree this change does not belong here.

@ggallen

ggallen commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

@ifireball and @rh-hemartin,

@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.

Ah! Yes, this is exactly why #5588 is important.

I'll move this there. Thanks for catching it!

@ggallen

ggallen commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

Closing this — you're both right, and there's concrete confirmation: #5588 ("delete agent files from scaffold embed") removes post-fix.sh/post-fix-test.sh from this repo entirely, since "these are now served from fullsend-ai/agents at runtime via resolveAgentSource()." I checked fullsend-ai/agents' own copy of post-fix.sh — it's the actual currently-served production script, and it still has the original #5188 bug (no ready-for-review relabel logic at all). Fixing the copy here would have been fixing a file that's already effectively dead.

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.

@ggallen ggallen closed this Jul 27, 2026
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 27, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 2:56 PM UTC · Completed 3:15 PM UTC
Commit: b07a937 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #5551 — re-trigger review via label after fix-agent push

Timeline

  1. Jul 16: Retro agent files #5188 — review agent never re-dispatched after fix-agent pushes on bot-authored PRs.
  2. Jul 20–21: Code agent fails 3 times (workflow file too large, ShellCheck errors, then workflows permission blocked on push).
  3. Jul 21–23: ggallen manually creates PR #5415 (identity-based approach), which is closed because the approach was previously rejected in #2669.
  4. Jul 23: ggallen opens PR #5551 with a label-based approach — post-fix.sh removes then re-adds ready-for-review to force a fresh labeled webhook.
  5. Jul 23: Review agent Run 1 catches a real HIGH bugGH_TOKEN exported after the gh pr edit calls that need it. Author fixes it.
  6. Jul 24: Review agent Runs 2–3 both approve with only LOW findings remaining.
  7. Jul 24: Human reviewer waynesun09 posts 6 findings across 2 rounds (HIGH: silent failure mode, HIGH/CRITICAL: test reimplements production logic, MEDIUM: premature decision, MEDIUM: concurrency risk, MEDIUM: sanitization gaps).
  8. Jul 25: Review bot applies ready-for-merge.
  9. Jul 27: ifireball requests changes — the fix modifies internal/scaffold/fullsend-repo/scripts/post-fix.sh, which belongs in fullsend-ai/agents, not the platform repo. rh-hemartin reverses their earlier approval and agrees.
  10. Jul 27: ggallen closes the PR, noting PR #5588 already removes these scaffold files and the fix will be re-implemented in the agents repo.

What went well

  • Review agent Run 1 caught a real bug. The GH_TOKEN ordering issue (exported after calls that need it) meant the entire relabel feature would silently do nothing. The agent identified this on the first pass, the author fixed it, and Run 2 confirmed the fix. This is a genuine save.
  • Human reviewers provided exceptional depth. waynesun09's mutation-testing insight (grep test passes when export is commented out or in a subshell) and ifireball's architectural placement catch were both high-value contributions the agent couldn't match.

What the review agent missed

  1. Architectural placement (wrong repo) — The PR modified internal/scaffold/fullsend-repo/scripts/post-fix.sh, a file actively being deprecated/migrated to fullsend-ai/agents. The intent-coherence sub-agent (responsible for misplaced-abstraction detection) did not flag this. This is the finding that ultimately closed the PR.
  2. Test-integrity severity miscalibration — The agent found that tests reimplemented production logic (rated LOW). Human reviewer rated the same concern HIGH/CRITICAL because the reimplementation meant real bugs (like the GH_TOKEN ordering) couldn't be caught by the test suite.
  3. Silent failure analysis — The || true and 2>/dev/null patterns meant remove-label failures would silently prevent the review re-dispatch — the PR's entire purpose. Human reviewer rated this HIGH.

Existing issues with new evidence

  • #3476 / #3659: Review agent should detect deprecated scaffold paths and active file migrations. This PR is a concrete case where the gap caused 3 wasted review runs and 4 days of work on code that was merged to the wrong location.
  • #4415: Review agent should escalate to request_changes for architectural placement findings requiring PR closure. This PR was approved 2× by the review agent, then closed by humans.
  • #1393 / #5004: Review agent should detect silent failure paths. The || true suppression of remove-label failures was a HIGH finding caught only by human review.
  • #4063 / agents#447: Review agent should incorporate outstanding human review feedback on re-reviews. Run 3 approved despite waynesun09's 6 unresolved findings.
  • #3157 / #5215: AGENTS.md should document that agent scripts have migrated to fullsend-ai/agents. This documentation gap is a root cause — the review agent couldn't detect the migration because it wasn't documented.

Autonomy assessment

The 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 ready-for-merge label was applied prematurely. For this class of change — script modifications touching cross-repo boundaries — human review remains essential.

Proposals filed

@ggallen

ggallen commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

Follow-up: opened fullsend-ai/agents#469 with the fix re-implemented against the actual production script, as a shared library (retrigger_via_label) per @ifireball's suggestion.

ggallen added a commit to ggallen/agents that referenced this pull request Jul 27, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 27, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 27, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 28, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 28, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 28, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 28, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
ggallen added a commit to ggallen/agents that referenced this pull request Jul 29, 2026
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>
@github-actions
github-actions Bot deleted the fix/5188-relabel-review-on-fix-push branch August 30, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug component/dispatch Workflow dispatch and triggers ready-for-merge All reviewers approved — ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review agent skipped on bot-authored PRs due to collaborator permission check failing for GitHub App accounts

4 participants