[controller][workflow] Prevent approved PRs from stalling on outdated or conflicting branches #727

Closed
opened 2026-07-17 09:47:10 -05:00 by jcwalker3 · 1 comment
Owner

Problem

Approved PRs can stall when the base branch advances, the PR head becomes outdated, or merge conflicts appear. Controllers and LLM sessions currently lack a single native PR-synchronization assessment path that routes each open PR to a sanctioned next action without rebasing, force-pushing, or falling back to direct API / CLI / Web UI mutations.

Goal

Add a native PR synchronization lifecycle that assesses live PR vs base state and routes each open PR to exactly one of:

Action Meaning
merge_now Approval at current head, mergeable, checks ok, base current enough for policy
update_branch_by_merge Behind live base; author-only merge of base into PR branch (no rebase)
author_conflict_remediation Conflicts or non-mergeable conflict signal; author remediates in the existing worktree
fresh_review_required Head moved after approval / prepared verdict; prior approval and verdicts are invalid
blocked Incomplete pins, unsafe state, or no safe sanctioned action

Required behavior

Native PR synchronization assessment

  • Provide a pure (network-free) assessment helper and a native MCP assess tool that returns the recommended action with structured reasons.
  • Decision order must fail closed: incomplete identity/open state/head SHAs → conflicts → head-changed-after-approval → behind-base update → merge_now → otherwise blocked.

Dual PR-head / base-head pinning

  • All update and merge routing must pin both the live PR head SHA and the live base (master) head SHA.
  • Stale pins fail closed; no mutation proceeds on mismatched heads.

Author-only branch updates

  • update_branch_by_merge is author-only. Reviewer, merger, reconciler, mixed, and limited roles must be denied.
  • Update style is merge only — never rebase, rebase-merge, squash-as-update, or force-push.

Conflict remediation in the existing worktree

  • When conflicts are detected, route to author_conflict_remediation.
  • Author resolves conflicts in the existing issue/PR worktree (do not invent a parallel branch or abandon the lock).

Approval, lease, and prepared-verdict invalidation after head changes

  • After any successful branch head change (update-by-merge or conflict remediation), invalidate:
    • approvals recorded for the previous head
    • reviewer/merger leases scoped to the previous head
    • prepared review verdicts / drafts pinned to the previous head
  • Route to fresh_review_required until a new independent review lands on the new head.

Sequential PR processing after every master update

  • After master advances (including after a merge), re-assess remaining open PRs sequentially with fresh dual head pins.
  • Do not batch-apply stale assessments across PRs after a master change.

Hard non-goals / safety rails

  • No rebase of PR branches.
  • No force-push.
  • No direct API, CLI, or Web UI fallback for synchronization mutations when native MCP is available.
  • No self-review / self-merge from the author profile.

Acceptance criteria

  1. Assessment returns one of: merge_now, update_branch_by_merge, author_conflict_remediation, fresh_review_required, blocked.
  2. Dual full-SHA pins (PR head + base head) are required for update preflight; incomplete pins block.
  3. Author-only gate on branch update; non-author roles blocked with structured reasons.
  4. Update style is merge-only; rebase/force styles rejected.
  5. Conflict path remediates in the existing worktree under the existing lock.
  6. Post-update head transition invalidates prior approval, leases, and prepared verdicts for the old head and requires fresh_review_required.
  7. Sequential queue step re-assesses PRs after each master update with fresh pins.
  8. No rebase, force-push, or non-native fallback paths are introduced.
  9. Focused regression suite covers all routing states and safety gates (target ≥28 tests in tests/test_pr_sync_status.py).
  10. Implementation remains compatible with post-#679 master.

Implementation notes (pre-built, to adopt)

Existing implementation on branch feat/pr-sync-status @ 98fbfb3de735069dd05670a3d8755e7c14349af1:

  • pr_sync_status.py — assessment + update preflight + post-update transition + sequential queue helpers
  • gitea_mcp_server.py — native MCP wiring
  • task_capability_map.py — capability entries
  • workflow template updates under skills/llm-project-workflow/
  • tests/test_pr_sync_status.py — focused regression tests

Do not recreate or duplicate this work; adopt it under the issue-backed branch naming policy after lock.

Duplicate search (pre-create)

  • Exact title: no open/closed match
  • Keywords: pr-sync, outdated, stalling, merge_now, update_branch_by_merge, author_conflict_remediation, fresh_review_required, synchronization lifecycle — no full-coverage open or closed issue found in paginated inventories
  • Related but non-duplicate: #522 (conflict-fix live re-pin), #609 (prepared verdict resume), #604 (anti-stomp preflight) — partial adjacent concerns only
## Problem Approved PRs can stall when the base branch advances, the PR head becomes outdated, or merge conflicts appear. Controllers and LLM sessions currently lack a single native PR-synchronization assessment path that routes each open PR to a sanctioned next action without rebasing, force-pushing, or falling back to direct API / CLI / Web UI mutations. ## Goal Add a native PR synchronization lifecycle that assesses live PR vs base state and routes each open PR to exactly one of: | Action | Meaning | |--------|---------| | `merge_now` | Approval at current head, mergeable, checks ok, base current enough for policy | | `update_branch_by_merge` | Behind live base; author-only merge of base into PR branch (no rebase) | | `author_conflict_remediation` | Conflicts or non-mergeable conflict signal; author remediates in the existing worktree | | `fresh_review_required` | Head moved after approval / prepared verdict; prior approval and verdicts are invalid | | `blocked` | Incomplete pins, unsafe state, or no safe sanctioned action | ## Required behavior ### Native PR synchronization assessment - Provide a pure (network-free) assessment helper and a native MCP assess tool that returns the recommended action with structured reasons. - Decision order must fail closed: incomplete identity/open state/head SHAs → conflicts → head-changed-after-approval → behind-base update → merge_now → otherwise blocked. ### Dual PR-head / base-head pinning - All update and merge routing must pin **both** the live PR head SHA and the live base (master) head SHA. - Stale pins fail closed; no mutation proceeds on mismatched heads. ### Author-only branch updates - `update_branch_by_merge` is **author-only**. Reviewer, merger, reconciler, mixed, and limited roles must be denied. - Update style is **merge only** — never rebase, rebase-merge, squash-as-update, or force-push. ### Conflict remediation in the existing worktree - When conflicts are detected, route to `author_conflict_remediation`. - Author resolves conflicts in the **existing** issue/PR worktree (do not invent a parallel branch or abandon the lock). ### Approval, lease, and prepared-verdict invalidation after head changes - After any successful branch head change (update-by-merge or conflict remediation), invalidate: - approvals recorded for the previous head - reviewer/merger leases scoped to the previous head - prepared review verdicts / drafts pinned to the previous head - Route to `fresh_review_required` until a new independent review lands on the new head. ### Sequential PR processing after every master update - After master advances (including after a merge), re-assess remaining open PRs **sequentially** with fresh dual head pins. - Do not batch-apply stale assessments across PRs after a master change. ### Hard non-goals / safety rails - **No rebase** of PR branches. - **No force-push**. - **No direct API, CLI, or Web UI fallback** for synchronization mutations when native MCP is available. - No self-review / self-merge from the author profile. ## Acceptance criteria 1. Assessment returns one of: `merge_now`, `update_branch_by_merge`, `author_conflict_remediation`, `fresh_review_required`, `blocked`. 2. Dual full-SHA pins (PR head + base head) are required for update preflight; incomplete pins block. 3. Author-only gate on branch update; non-author roles blocked with structured reasons. 4. Update style is merge-only; rebase/force styles rejected. 5. Conflict path remediates in the existing worktree under the existing lock. 6. Post-update head transition invalidates prior approval, leases, and prepared verdicts for the old head and requires `fresh_review_required`. 7. Sequential queue step re-assesses PRs after each master update with fresh pins. 8. No rebase, force-push, or non-native fallback paths are introduced. 9. Focused regression suite covers all routing states and safety gates (target ≥28 tests in `tests/test_pr_sync_status.py`). 10. Implementation remains compatible with post-#679 master. ## Implementation notes (pre-built, to adopt) Existing implementation on branch `feat/pr-sync-status` @ `98fbfb3de735069dd05670a3d8755e7c14349af1`: - `pr_sync_status.py` — assessment + update preflight + post-update transition + sequential queue helpers - `gitea_mcp_server.py` — native MCP wiring - `task_capability_map.py` — capability entries - workflow template updates under `skills/llm-project-workflow/` - `tests/test_pr_sync_status.py` — focused regression tests Do not recreate or duplicate this work; adopt it under the issue-backed branch naming policy after lock. ## Duplicate search (pre-create) - Exact title: no open/closed match - Keywords: pr-sync, outdated, stalling, merge_now, update_branch_by_merge, author_conflict_remediation, fresh_review_required, synchronization lifecycle — no full-coverage open or closed issue found in paginated inventories - Related but non-duplicate: #522 (conflict-fix live re-pin), #609 (prepared verdict resume), #604 (anti-stomp preflight) — partial adjacent concerns only
jcwalker3 added the type:featurestatus:ready labels 2026-07-17 09:47:10 -05:00
jcwalker3 added status:in-progress and removed status:ready labels 2026-07-17 09:50:57 -05:00
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: claim - issue: #727 - branch: feat/issue-727-pr-sync-status - phase: claimed - profile: prgs-author - pr: none - blocker: none - next_action: create worktree and begin implementation
jcwalker3 added status:pr-open and removed status:in-progress labels 2026-07-17 09:51:17 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#727