Skip to content

Base-branch config-folder restore silently reverts changes that race the agent run (trusted triggers) #55318

Description

@benjaminawd-flowdesk

Summary

The base-branch config-folder snapshot/restore (#26380) silently reverts legitimate changes to .github / .claude / etc. in the PR it produces, whenever the base branch advances during the agent run. The snapshot is taken at activation time but the PR is committed against a later base tip, so the force-restore writes stale config back over changes that landed in between — and these deletions are attributed to the agent PR.

This is noted as intentional ("protects against concurrent base branch mutations during execution"), but for trusted, non-fork triggers (workflow_dispatch, command, scheduled) it produces incorrect, confusing diffs rather than protecting anything, and it silently defeats the create_pull_request allowed_files scoping (the restore runs outside that filter).

Repro (observed in production)

  1. A command-triggered workflow with safe-outputs.create_pull_request.allowed_files scoped to a single file, and protect_top_level_dot_folders: true.
  2. Activation job checks out base (master) at SHA A and snapshots GH_AW_AGENT_FOLDERS (incl. .github) into /tmp/gh-aw/base.
  3. During the ~2-minute agent run, an unrelated human PR merges to master (SHA B), adding a step to .github/workflows/publish.yml.
  4. create_pull_request commits the agent's change on top of B; restore_base_github_folders.sh overwrites .github with the SHA-A snapshot.
  5. Resulting PR diff: the intended one-line change plus a spurious deletion of the step added in B — even though the agent never touched .github and it isn't in allowed_files.

Confirmed at the git level: the workflow blob in the agent's commit is byte-identical to <base-add-commit>^ (pre-change base), while the commit's parent already contains the change.

Impact

  • Silent reverts of workflow/config changes that raced the run — a correctness and, for .github/.mcp.json, a supply-chain-adjacent concern.
  • allowed_files gives false confidence: it does not bound what the PR actually changes.
  • Noisy PRs that reviewers must manually clean up (or worse, merge).

Suggested fixes (either)

  1. Re-snapshot against the base tip at PR-creation time (re-fetch base right before restore_base_github_folders.sh) so the restore reflects the actual PR base, not the activation-time base.
  2. Scope the force-restore to untrusted contexts only (fork PRs / pull_request_target / issue_comment), where the threat model applies. Trusted workflow_dispatch/command/schedule runs don't need it.
  3. At minimum, extend the allowed_files guard to the restore step so config-folder writes outside the declared scope are dropped rather than committed.

Environment

  • setup action v0.77.5, firewall/agent images 0.25.58.
  • Scripts actions/setup/sh/{save,restore}_base_github_folders.sh unchanged on main at time of filing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions