Purpose
PR-only endpoint for feature branches.
This skill does not stage or commit. It validates branch/remotes state, prepares the feature branch against the correct main source remote, runs full-project tests as part of preflight, and should execute push/PR commands directly when possible. If command execution fails, it outputs exact fallback commands for the user.
Inputs expected
- Work is already committed on a feature branch.
originexists and points to the working repository.upstreammay or may not exist.- Workflow may be either:
- fork model:
originis fork andupstreamis canonical, or - single-remote model:
originis canonical and PR is opened from branch on the same repo.
- fork model:
Repository And Auth Model Detection
Default modes:
pr_model=autoauth_scope=command(default)auth_scope=subshell-session(optional)
Model resolution in pr_model=auto:
- Read URLs for
originand optionalupstream. - Parse
<owner>/<repo>for each remote URL. - If both remotes exist, repo names match, and owners differ: use
fork-two-remote. - If only
originexists, or both remotes resolve to same owner/repo: usesingle-remote. - If remotes point to different repository names: fail and ask user to resolve target repository.
Derived values after model resolution:
target_remote:upstreamforfork-two-remote, otherwiseorigin.target_repo:<target_owner>/<repo_name>fromtarget_remote.head_ref:<origin_owner>:<branch>forfork-two-remote,<branch>forsingle-remote.sync_main_ref:<target_remote>/main.
Auth scope behavior:
command: prefix each auth-sensitive git command with a scoped override, e.g.GIT_SSH_COMMAND='ssh -i <key> -o IdentitiesOnly=yes -o BatchMode=yes' git fetch ....subshell-session: run a short grouped block with exportedGIT_SSH_COMMANDfor contiguous network commands only. Do not assume cross-chat or global persistence.ghauth is separate fromgitSSH auth. Treatghcredentials explicitly and report failures separately.
Establish Branch Context
Before proceeding with PR preparation, use the branch-context skill to understand:
- What has been implemented so far across all commits
- Branch intent and motivation
- Current state of the work
This context is essential for:
- Test failure analysis and fixes
- Comprehensive PR body generation
- Understanding the full scope of changes
Minimum history coverage requirements:
- Review the complete branch commit history relative to
main(not only recent session actions), including:
git log --reverse --oneline main..HEADgit log --reverse --name-status --format=fuller main..HEAD
- Identify branch intent from early commits and sustained themes across the full range.
- Distinguish substantive feature work from sync mechanics (for example merge/rebase conflict resolution commits).
- Build PR text as: "what this branch adds to main," not "what the agent did recently."
Guardrails
Before producing the PR command, verify:
- Current branch is not
main. - Branch name follows feature flow (prefer
feature/*, allowfix/*,refactor/*,enhance/*,experiment/*). originexists.- Repository model resolves successfully (
fork-two-remoteorsingle-remote). - If
upstreamexists, repository names betweenoriginandupstreammatch. - Branch tracks
origin/<branch>, or can be established viagit push -u origin <branch>before PR creation. - Working tree is clean.
- Branch contains commits not on
main.
If any check fails:
- Stop immediately.
- Do not output a
gh pr createcommand. - Report which checks failed.
- Suggest corrective actions for the user to perform.
PR Prerequisites
Complete these prerequisite steps before running preflight checks:
- Fetch latest
mainfrom the resolved sync remote (sync_main_ref). - Merge the resolved sync branch into the current feature branch.
- If merge conflicts occur:
- Stop before resolving.
- Inspect each conflicted file and summarize what each side changed.
- Provide a suggested resolution for each conflict.
- Get explicit user agreement for each suggested resolution.
- Apply the agreed resolutions, then continue.
Use model-aware sync targets:
fork-two-remote: fetch/merge fromupstream/main.single-remote: fetch/merge fromorigin/main.
If sync or conflict resolution is incomplete:
- Stop immediately.
- Do not output a
gh pr createcommand. - Report what is blocking prerequisite completion.
Documentation Review
After establishing branch context and completing prerequisites, review whether the branch changes warrant updates to project documentation before proceeding to preflight checks.
Common triggers:
- New modules, files, or directories added — the project overview or file tree in
AGENTS.mdmay need updating. - Material changes to tests — test commands or instructions in project documentation may be outdated.
- New or renamed public APIs, CLI commands, or configuration options — usage documentation may need corresponding updates.
- Changes to build, deploy, or development workflows — relevant guides or READMEs may need revision.
If any documentation appears stale relative to the branch changes:
- Present the specific updates needed to the user with clear rationale.
- Wait for the user to confirm the updates are complete (or explicitly decline them) before proceeding to preflight checks.
Do not block on purely cosmetic or trivial gaps — focus on changes that would leave a reader of the documentation with an incorrect understanding of the project.
Preflight Checks
Run PR preflight checks only after prerequisites and documentation review are complete.
Preflight checks are intended to be rerunnable.
- Run the full-project test suite (see Test section below).
Post-Test Revalidation
After tests pass, rerun preflight checks that can drift during preflight work, at minimum:
- working tree clean state
- branch still contains commits not on
main - current branch is still not
main
If revalidation fails:
- Stop immediately.
- Report failed checks and corrective actions.
- Do not output or run
gh pr create.
Test (Part of Preflight)
Run a full-project test suite as the final preflight step.
Sandbox-safe uv execution
If the canonical test/lint command uses uv run, do not run bare uv.
First resolve the project virtual environment directory name (for example .venv-linux) in this order:
- Project instructions/docs (for example
AGENTS.md, task docs, README). - Repository config/tooling files (for example
pyproject.toml,uv.toml,Makefile, CI config) that setUV_PROJECT_ENVIRONMENTor document the venv path. - If still unknown, ask the user before running
uvcommands.
Then prefix each uv command with:
UV_PROJECT_ENVIRONMENT=<venv-dir> UV_CACHE_DIR=/tmp/uv-cache
This avoids permission prompts from uv cache writes to ~/.cache/uv in sandboxed/worktree sessions.
Examples:
UV_PROJECT_ENVIRONMENT=<venv-dir> UV_CACHE_DIR=/tmp/uv-cache uv run pytest -q ...UV_PROJECT_ENVIRONMENT=<venv-dir> UV_CACHE_DIR=/tmp/uv-cache uv run ruff check ...UV_PROJECT_ENVIRONMENT=<venv-dir> UV_CACHE_DIR=/tmp/uv-cache uv run ruff format --check ...
Requirements:
- Always identify and run the canonical run all tests command for the current project before producing a PR command.
- If that command is
uv-based, run it with the resolvedUV_PROJECT_ENVIRONMENTandUV_CACHE_DIR=/tmp/uv-cacheprefix. - Cache successful test runs so they are not rerun unnecessarily.
- Cache key must include at least:
HEADcommit SHA- Test command string
- Reuse cached success when key matches and no tracked files changed since the cached run.
- Invalidate cache when:
HEADchanges- test command changes
- tracked working tree content changes
- Failed test runs must never be cached as pass.
Recommended cache implementation:
- Store cache in
.gitmetadata (for example,.git/pr_preflight_test_cache.json) so it remains local to the repository. - Record timestamp, commit SHA, command, and result.
If tests fail:
- Use branch-context skill (run for this PR flow) to understand branch work and intent.
- Analyze test failures in the context of branch changes.
- Create an implementation plan to resolve test issues.
- Execute fixes.
- Re-run tests.
- Only proceed when tests pass.
- Do not output a
gh pr createcommand until tests pass.
Final Gate (Required Immediately Before PR Creation)
Run this gate immediately before any push or PR creation command.
- Run:
git status --porcelain --untracked-files=all
- If output is non-empty:
- Fail preflight immediately.
- Inspect and summarize the pending changes for the user:
- changed file list
- high-level intent of those changes
- likely impact on PR scope
- Present a recommended next action with commands:
- Include in PR: create a commit for these changes, then rerun final gate.
- Exclude from PR: stash or discard, then rerun final gate.
- Ask for user confirmation on which path to execute.
- Do not output or run
git pushorgh pr createuntil final gate passes.
- If output is empty:
- Continue to PR creation flow.
PR Body Context Requirements
When preparing the PR title/body, leverage the branch context established earlier in this PR workflow.
Additional requirements:
- Ensure full commit history was reviewed during the branch-context review performed for this PR flow.
- Reflect the entire branch scope in the PR body, including all meaningful changes.
- Include intent/motivation for the feature branch, not just implementation details.
- Reference task document context if it was found (for example
.agent/tasks/.../TASK.md). - Explicitly prioritize net-new behavior/value relative to
main. - Do not lead summary bullets with upstream sync mechanics (for example "merged upstream main") unless the PR's primary intent is branch synchronization.
- If sync/merge conflict resolution was required, include it only as brief supporting context after substantive branch outcomes.
Output contract
Hard rule:
- Do not output or run
gh pr createunless the Final Gate has passed with a clean working tree.
When all preflight checks pass, output:
- A short preflight status summary.
- Attempt to push the branch (
git push -u origin <branch>when needed), using configured auth scope for auth-sensitive git network commands. - Attempt to run
gh pr createdirectly using a PR body file (--body-file). - Report command results and output the PR link as a standalone line in this exact format:
PR URL: <https://...>. - If push or
ghcommand fails, provide a ready-to-run fallback command for the user.
When preflight checks fail, output:
- A short preflight status summary.
- Which checks failed.
- Suggested corrective actions (do not proceed to PR command).
Command templates
Body transport strategy:
- Agent-run PR creation path (default): use
--body-fileto preserve real newlines and avoid escaped\nartifacts. - User-run fallback path: use inline
--bodyfor a single ready-to-run command.
Execution order:
- Resolve
pr_model(autoby default) and derivetarget_remote,target_repo, andhead_ref. - Resolve auth strategy (
auth_scope=commandby default). - Ensure branch is pushed/up to date on
origin. - Create a temporary PR body file with the generated body content.
- Run
gh pr createdirectly with--body-file. - Fetch the created PR URL and print
PR URL: <https://...>. - Clean up the temporary file.
- Only fall back to user-run commands when direct execution fails.
Command-scoped auth template (default):
GIT_SSH_COMMAND='ssh -i <bot_key> -o IdentitiesOnly=yes -o BatchMode=yes' git fetch "${TARGET_REMOTE}" main
GIT_SSH_COMMAND='ssh -i <bot_key> -o IdentitiesOnly=yes -o BatchMode=yes' git merge "${TARGET_REMOTE}/main"
GIT_SSH_COMMAND='ssh -i <bot_key> -o IdentitiesOnly=yes -o BatchMode=yes' git push -u origin "$(git branch --show-current)"
Subshell-session auth template (optional):
(
export GIT_SSH_COMMAND='ssh -i <bot_key> -o IdentitiesOnly=yes -o BatchMode=yes'
git fetch "${TARGET_REMOTE}" main
git merge "${TARGET_REMOTE}/main"
git push -u origin "$(git branch --show-current)"
)
Agent-run PR creation (preferred):
BODY_FILE="$(mktemp)"
BRANCH="$(git branch --show-current)"
TARGET_REPO="<target_owner>/<repo_name>"
# fork-two-remote:
HEAD_REF="<origin_owner>:${BRANCH}"
# single-remote:
# HEAD_REF="${BRANCH}"
cat > "${BODY_FILE}" <<'EOF'
<summary of full branch context, motivation, and validation>
EOF
gh pr create \
--repo "${TARGET_REPO}" \
--base main \
--head "${HEAD_REF}" \
--title "<type>: <short summary>" \
--body-file "${BODY_FILE}"
PR_URL="$(gh pr view --repo "${TARGET_REPO}" --json url --jq '.url')"
echo "PR URL: <${PR_URL}>"
rm -f "${BODY_FILE}"
User-run fallback PR creation command (only when agent-run fails):
gh pr create \
--repo "<target_owner>/<repo_name>" \
--base main \
--head "<resolved head_ref>" \
--title "<type>: <short summary>" \
--body "<summary of full branch context, motivation, and validation>"
Push command (when upstream tracking is missing or branch not yet pushed):
git push -u origin "$(git branch --show-current)"
In command-scoped mode with bot SSH override:
GIT_SSH_COMMAND='ssh -i <bot_key> -o IdentitiesOnly=yes -o BatchMode=yes' git push -u origin "$(git branch --show-current)"
Shell-safety directive for fallback inline --body
When generating inline --body text, avoid characters that commonly break pasted shell commands.
- Do not use markdown backticks.
- Do not use double quotes.
- Do not use command-substitution markers like
$(or backticks. - Prefer plain text headings and hyphen bullets.
- If code identifiers are needed, write them as plain words without quoting.
Post-merge behavior
After the user explicitly states the PR has been merged, include and run these sync commands:
git checkout main
git fetch <target_remote>
git rebase <target_remote>/main
git push origin main
Post-merge workspace cleanup (worktree/clone-worktree sessions)
If the PR session is running from a sibling worktree or a sibling clone workaround directory, cleanup is required after the sync commands above.
Detection rules:
- Real git worktree checkout:
git rev-parse --git-dirdiffers fromgit rev-parse --git-common-dir. - Clone workaround checkout: checkout path follows sibling pattern
w-<repo-root>--<branch-slug>but is not a real git worktree checkout.
Safety rule:
- Do not try to delete the current working directory while still inside it.
- Capture the path first,
cdout, then remove.
Real worktree cleanup:
WORKTREE_DIR="$(git rev-parse --show-toplevel)"
PRIMARY_REPO_DIR="$(cd "$(git rev-parse --git-common-dir)/.." && pwd)"
cd "${PRIMARY_REPO_DIR}"
git worktree remove "${WORKTREE_DIR}"
git worktree prune
Clone-workaround cleanup:
CLONE_DIR="$(git rev-parse --show-toplevel)"
cd "$(dirname "${CLONE_DIR}")"
rm -rf "${CLONE_DIR}"
Notes:
- For clone-workaround cleanup, request explicit user confirmation before
rm -rf. - If cleanup fails, report the exact error and provide the corrected command for the user.
PR text quality bar
- Title matches change intent and commit style.
- Body states:
- Context/problem and motivation
- What changed across the full branch
- Validation performed (or explicitly not run)
Relationship to other skills
feature-start: branch setup policy.fcommit: progress commits during implementation.PR: preflight + direct PR creation flow, with fallback command handoff only on execution failure.