Pull Requests Always — Never Merge Locally into Main — HARD BLOCK
Principle: All work targeting main (or production-equivalent branch) must go through Pull Request on GitHub/GitLab/Gitea/etc. — never git merge locally followed by git push origin main. No exceptions across any Git-based project using collaborative workflows.
Why
Permanent paper trail. PRs remain indexed and shareable forever — a link for documentation, retrospectives, and future debugging ("when did this change land? what was the context?").
git logalone cannot answer "what was tried, rejected, or decided?"Squash-merge consolidates. PR allows squashing 5–10 local commits into 1 clean commit per feature. Main remains auditable (1 line per logical change, not 50 noisy commits).
Revert is trivial. GitHub's "Revert" button creates a reverse PR; manual
git revert <sha>is error-prone in squashed histories and causes merge conflicts.CI/CD gates. Pipelines configured to run on PR catch regressions that local pre-commit hooks miss (E2E tests, security scans, integration tests, etc.).
Branch protection enforcement. Production branches should be protected; direct push is blocked anyway. PR is the only path.
Discoverability. PR list shows what's in flight to other team members and future sessions —
git loglocal context does not.
Mandatory Workflow
1. Work on feature/fix/* branch (never directly on main)
2. Make local commits with clear messages (Conventional Commits preferred)
3. git push -u origin <branch>
4. gh pr create --title "..." --body "..." (or web UI if preferred)
5. Wait for CI to pass (if configured)
6. Merge via UI (squash-merge for features, merge-commit for complex hotfixes)
7. Branch auto-deleted post-merge
AI responsibility: Execute gh pr create programmatically — do not ask the human to open UI. Return the PR URL for visibility.
Prohibited Anti-patterns — HARD BLOCK
git checkout main && git merge feature/x && git push→ forbidden, even as solo maintainer- "It's just a typo, merging straight to main" → forbidden — open branch + PR (squash-merge resolves in 30 seconds)
- "Branch protection is not enabled on this repo" → irrelevant — this is a process rule, not an enforcement-dependent rule
- Push the branch and "open PR later" → there is no later — PR is opened in the same session
- AI merging locally "to save the human time" → humans explicitly prefer the +30-second PR cost for permanent audit trail. Do not optimize against their stated trade-off.
Rare Exceptions (Explicit Only)
- Human explicitly requests "merge locally and push directly" (with clear reason: production outage, GitHub downtime blocking PR merge, etc.)
- Repos with no remote (purely local — rule does not apply; if
originexists, it applies) - Commits to personal feature branches (not main) — these can be pushed directly to the branch; PR required only to integrate into main
Coordinator Session Pattern — Any Session Can Batch-Merge Open PRs
Humans don't memorize which session created which PR. Do not wait to "return to the original author session" to merge — that is an anti-pattern.
Rule: A PR must be self-contained. Title, description, diff, commits, and CI status are sufficient context for any future session to merge safely.
When an AI session ends with open PRs:
- Do not promise "I'll come back to merge it later" — there is no guaranteed "later" (sessions compact, close, or are archived)
- Document in
session-handoff.md(or equivalent) that PR is open, include URL, and note CI status - Report to human in clear terms: "PR #123 is open and ready to merge when you decide; any future session can finalize it"
Coordinator session pattern — Human opens any session and says:
List my open PRs via: gh pr list --author @me --state open
For each PR:
1. Check CI status, conflicts, and age
2. If CI is passing, no conflicts, clear description → squash-merge
3. If conflicts exist → resolve, show what goes to main, ask for approval
4. If CI failing or description is unclear → report blocker and skip
Report summary: X merged, Y need input, Z blocked.
Implication: invest in complete PR descriptions — future sessions and the human weeks later need to reconstruct context from the PR alone.
Pre-work PR Scan — Check Open PRs Before Starting Development — HARD BLOCK
Before touching code in a Git project (bug fix, new feature, refactor, etc.), run:
gh pr list --author @me --state open
For each open PR that touches the relevant area (same file, same module, same feature, same symptom), read the description and diff summary (gh pr diff <N> --stat) before deciding if new work is necessary.
Why: Different sessions, different times, no visibility into each other. A new session starts, receives a task ("fix this bug"), and jumps to implementation — unaware that a prior session already opened a PR fixing the exact same bug with the same approach. Result: wasted work, artificial merge conflicts, code churn.
Burned example (2026-05): Fixed a data-formatting bug in a chart-sync component without first checking open PRs. A PR from a prior session (opened 2 days earlier) already addressed the same bug with the identical fix. ~10 minutes of redundant work + risk of divergence if the prior PR had evolved. The lesson: check the PR list first.
How to apply: Run gh pr list at the start of every dev session in a repo with active collaboration (≥1 recent open PR). Especially important when:
- Human requests a specific bug fix
- The code area has high activity (recent CHANGELOG entries, frequent work)
- Human mentions a prior session or says "I think we already have a PR for this"
When you find a relevant open PR: read description + diff stat before starting new work.
Prohibited anti-patterns:
- Begin a fix without running
gh pr listin a repo with active PRs - See an open PR and ignore it because "I can do it faster from scratch" — merging the existing PR is higher-value than redundant work
- Work on a new branch without checking if the feature already exists in another branch ahead of main
Does not apply to: individual customer support tasks, operational-only work, solo projects with no active PRs, or human requests that explicitly say "ignore open PRs, do this from scratch"
Applies to: all collaborative Git projects. Valid for all AI agents and session types in both local and cloud execution contexts.