Skip to content

Publish branches atomically in create_pull_request#166

Merged
alvarosanchez merged 3 commits into
mainfrom
feat/atomic-create-pull-request
Jun 30, 2026
Merged

Publish branches atomically in create_pull_request#166
alvarosanchez merged 3 commits into
mainfrom
feat/atomic-create-pull-request

Conversation

@alvarosanchez

@alvarosanchez alvarosanchez commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • make create_pull_request the single agent-facing call for exact branch publication, PR creation, durable linking, and KPI attribution
  • scope publication to the issue's checked-out execution worktree rather than the shared project primary workspace
  • keep the GitHub credential inside the trusted plugin worker and pass it to native Git over an anonymous file descriptor rather than an agent environment variable, command argument, URL, config value, or file
  • make retries reconcile an already-open PR only when repository, head, base, and head SHA all match

Tool contract

create_pull_request now requires:

  • paperclipIssueId
  • head (plain local branch name)
  • headCommitSha (full exact local branch-tip SHA)
  • base
  • title

The plugin resolves the mapped repository, issue execution workspace, checkout ownership, and company-scoped GitHub secret internally. There is no separate agent-facing push tool.

Safety properties

  • requires host checkout ownership for the calling agent and run
  • rejects cross-company/project/workspace/repository mismatches
  • verifies the requested branch is the execution worktree's checked-out branch
  • verifies both worktree HEAD and the shared local branch ref equal headCommitSha
  • rejects owner-qualified heads, arbitrary refspecs, base-branch publication, non-full SHAs, and non-fast-forward updates
  • fetches the remote base in a sanitized temporary bare repository and requires the commit to descend from it
  • uses an empty Git template, disables hooks, system/global config, prompts, and inherited credential helpers, and applies bounded output plus a five-minute command timeout
  • sends the credential to Git over inherited fd 3; it is absent from Git arguments, environment variables, and temporary files
  • verifies the remote branch SHA before calling GitHub's PR API
  • does not call the PR API when publication fails
  • on a retryable create conflict, reuses only an open exact repository/head/base/SHA match before repairing the link and metric
  • never deletes a branch or closes a PR as automatic compensation

Transaction boundary

This is one ordered, retry-safe agent tool call, not a literal transaction across Git, GitHub, and Paperclip. A branch may remain if PR creation fails, and a PR may remain if link persistence fails. A retry safely re-verifies publication and reconciles an exact existing PR.

Validation

  • pnpm test — 261 plugin tests, 6 branch-publisher tests, and 5 build-script tests passed
  • pnpm typecheck — passed
  • pnpm build — passed
  • git diff --check — passed
  • real transport smoke — this PR branch was published with the new publisher from its actual execution worktree; remote SHA readback matched f57156baf45c4a07fcdc598444db4100974379a5

Rollout

After release and staging verification, agent GITHUB_TOKEN and Git credential-helper environment bindings can be removed again. Agent Company guidance should then call only create_pull_request with the local branch and exact commit SHA.

Copilot AI review requested due to automatic review settings June 30, 2026 15:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@alvarosanchez alvarosanchez merged commit 579a274 into main Jun 30, 2026
1 check passed
@alvarosanchez alvarosanchez deleted the feat/atomic-create-pull-request branch June 30, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants