BOHICA-LABS / BOHICA-LABS/vsdd-factory

pr-manager: prefer `gh pr update-branch` over rebase+force-push when PR base advances during convergence

Open
#408 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2
Forks
1
Avg merge
6h 43m
Merged PRs (30d)
29

Description

## Summary

pr-manager's handling of "PR head branch is not up to date with base" during merge attempts reaches for \`git rebase origin/develop\` followed by \`git push --force-with-lease\`. This is unnecessarily destructive when GitHub provides a non-destructive alternative: \`gh pr update-branch \` performs a server-side merge of base into head with no history rewrite, no force-push, and preserves review approvals.

## Observed Sequence (switchboard-blue Wave-6 Tranche B, 2026-06-30)

1. Three feature branches (S-7.01, S-7.02, S-BL.ROUTER-ADDR) were dispatched in parallel worktrees, each branched from the same develop base.
2. Each completed independent BC-5.39.001 adversarial convergence (10 passes on some stories).
3. S-7.01 merged first (SHA 5c658e7). S-7.02 merged second (c54a8ad). Both advanced develop.
4. S-BL.ROUTER-ADDR PR #56 was rejected at merge time by branch-protection ("require branches to be up to date").
5. pr-manager response: local \`git rebase origin/develop\` (clean, no conflicts — disjoint modules), re-signed 10 commits, attempted \`git push --force-with-lease\`.
6. The force-push was correctly blocked by the auto-mode classifier for lacking explicit user authorization.
7. The user (correctly) asked "why are we force-pushing here at all?"

## The Defect

\`gh pr update-branch\` was the right tool and was not considered:

- It does a **server-side merge of base into head** — no rebase, no force-push, no history rewrite.
- Review approvals on the PR remain valid (they reference commits that still exist).
- Squash-merge at the final step flattens the transient merge commit anyway, so the visible history is identical to the rebase path.

## Impact

- **Audit trail:** force-push after review approvals invalidates the causal link "these reviewers approved these commits" — GitHub may dismiss stale reviews (repo-setting-dependent).
- **Data loss risk:** low in practice (\`--force-with-lease\` refuses if origin advanced), but nonzero — a race between fetch and push could clobber a colleague's push on the same feature branch.
- **User friction:** the auto-mode classifier correctly blocks unauthorized force-pushes, meaning pr-manager stalls waiting for a human authorization that would be unnecessary with \`update-branch\`.
- **Multiplier effect:** any Tranche with N parallel stories has N-1 stories that will hit this pattern.

## Recommended Fix

Update \`pr-manager\` (agents/pr-manager/AGENT.md and per-story-delivery skill/step 7):

1. When \`gh pr merge\` fails with "head branch is not up to date":
- **First**: attempt \`gh pr update-branch \` (server-side merge, no force-push).
- **Only if update-branch fails** (e.g., true merge conflict): fall back to local rebase + force-with-lease, and **explicitly document** why in the PR comment (with the specific conflicting files).
2. Never attempt a force-push without either (a) update-branch having failed first, or (b) an explicit user authorization in the current session.
3. Add a per-story-delivery.md note explaining Tranche/parallel-worktree serialization hazard.

## Cross-Ref

- switchboard-blue PR #56 (still open, rebased locally, awaiting decision to force-push vs. reset-and-update-branch)
- Related batch: `.vsdd-factory-issues-pending.md` batch 19 (POL-001 process-gap; separate concern)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.