[Feature] 已交付 PR 保鲜:检测目标分支前进导致的冲突/落后,自动在原分支合入最新基线并交 Agent 解决冲突

Ouverte
#479 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
5/5
Temps estimé
Plus d'une semaine
Accessibilité débutants
25/100
Type d'issue
Fonctionnalité
Clarté
Plutôt claire
Activité
Active
Stack technique
git, github, go

Piste de recherche

Start with internal/tracker/mr_delivery_sync.go, internal/tracker/github.go, and internal/domain/mr_delivery.go to trace how delivery state is refreshed and stored; then read internal/engine/align.go for the existing baseline-alignment flow. Run the relevant tracker and engine tests first. Done means open delivery PRs expose mergeability and the configured refresh behavior meets the listed acceptance criteria, including safeguards for human commits and refresh limits.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

背景与借鉴来源

Agent 交付的 PR/MR 往往要排队等人评审,这段时间里默认分支还在不断合入别的需求(包括其他 Agent 的交付)。一旦目标分支前进,之前的 PR 就会冲突或落后,评审人打开时已经合不了,只能手动拉分支解决或重新派发。专门批量产出自动化 PR 的系统都把「已开 PR 的保鲜」当作核心能力:

  • renovatebot/renovate(https://github.com/renovatebot/renovate ,约 2.3 万 star,2026-11-13 发布 44.237.3,几乎每天发版):文档 docs/usage/updating-rebasing.md
    • 目标分支前进导致 PR 冲突时自动在最新基线上重建分支,用户「永远不需要手动解冲突」;
    • rebaseWhen:auto / conflicted / behind-base-branch / never,按仓库需要决定只处理冲突还是落后也更新;
    • 人推过提交的分支不再自动改写(避免覆盖人工修改),PR 描述里提供「勾选即重新 rebase」复选框做手动触发。
  • dependabot/dependabot-core(https://github.com/dependabot/dependabot-core ,约 5.8k star,2026-11-13 仍有提交):PR 冲突时自动 rebase,支持在 PR 评论 @dependabot rebase / recreate 手动触发,人工推过提交则停止自动 rebase。
  • 对照:LoopForge 已有的 #231(合入前等 CI)、#219(webhook 与评审意见回流)都不覆盖「PR 打开期间因目标分支前进而冲突/落后」这一情况。

借鉴点:定期检测已交付 PR 的可合并性 → 冲突/落后时自动在原分支合入最新目标分支(冲突交给 Agent 解决)→ 人工改过的分支不自动动、只提醒 → 有手动触发入口和次数上限。

LoopForge 现状与不足

(代码引用固定到 main 223bd41)

  1. 交付状态同步只看开/合/关,不看可合并性。 tracker/mr_delivery_sync.go#L83-L148 每 5 分钟刷新未合入的 MR;GitHub 分支走 tracker/github.go#L240-L251 refreshGitHubDelivery,githubPull(github.go#L84-L97)只解析 state/merged/merged_at/head/base,丢弃了 mergeable / mergeable_state(dirty/behind/clean);工蜂分支 mr_state_lookup.go 同样只取状态和目标分支。domain.MRDeliveryState(domain/mr_delivery.go#L8-L20)没有可合并性字段,需求列表/详情看不出「这个 PR 已经冲突了」。
  2. 已有读取能力只给聊天 Bot 用。 httpapi/agent_tool_github.go#L606 已经读取 mergeable_state 返回给 Bot 工具,但交付同步路径没用上。
  3. 冲突修复回路只在「合入集成分支的那一刻」触发。 engine/integrate.go#L241-L285 requeueIntegrationConflict 已经能「找修复节点 → 写冲突反馈 → 重置下游 → 上限 maxIntegrationReworks=3」,domain/conflict_blocks.go#L21 ExtractConflictBlocks 能抽取冲突块给 Agent;基线对齐也有专门的 engine/align.go(集成分支 ↔ 默认分支)。但对于已经结束 run、PR 仍在等人评审的需求(非集成模式下 Agent 创建的 MR 直接指向默认分支,见 httpapi/dispatch.go#L150-L153),后续目标分支前进造成的冲突没有任何检测或处理入口。
  4. 手动补救成本高。 现在只能人工拉分支解冲突,或者重新派发需求让 Agent 「继续已有工作分支」(dispatch 的 existing work branch 模式)——但这会跑完整 SOP,而且发起人要自己发现冲突、自己写清楚要做什么。

建议方案

1. 同步可合并性(tracker + DeliveryRepo)

  • githubPull 增加 mergeable(*bool)、mergeable_state;GitHub 计算是异步的,返回 null/unknown 时保持上次值、下一轮再查,不得当作冲突。工蜂用 MR 详情中的合并状态字段(如 merge_status 的 can_be_merged / cannot_be_merged)实现同一语义。
  • MRDeliveryState 增加 Mergeability(clean / behind / conflicted / unknown)、HeadSHA、MergeabilityCheckedAt;新列走 gorm AutoMigrate 增量补列,不在启动路径做数据迁移。只对 opened 状态的交付 MR 计算,已合入/关闭的不查。
  • 需求列表/详情的交付 MR 标签显示「有冲突」「落后基线」,需求列表支持按此筛选。

2. 仓库级保鲜策略 DeliveryRefresh(Repository 新字段)

  • mode:notify(默认:只标记并通知需求负责人,行为不改分支)/ conflicted(冲突时自动处理)/ behind(落后也自动合入最新目标分支)/ off。
  • maxRefreshes(默认 3)、cooldownMin(默认 30,避免目标分支频繁合入时反复刷新)。

3. 自动刷新执行(复用现有回路,不新造流程)

  • 判定需刷新时,先检查分支上是否有非平台身份的新提交(对比 PR 提交作者与平台 Git 身份 / 上次记录的 HeadSHA);有人工提交则只通知、不自动改写(对齐 Renovate/Dependabot)。
  • behind 且无冲突:在受控工作区直接 git merge origin/<target> 并推送原工作分支(只用 merge,不 force-push 改写历史),无需启动 Agent。
  • conflicted:发起一个轻量「冲突刷新」运行——复用基线对齐 SOP 的形式(类似 scheduled-baseline-align),在原工作分支上 merge 目标分支,把 ExtractConflictBlocks 的冲突块 + 原需求标题/描述作为反馈交给解决冲突的 Agent,完成后推送原分支、PR 自动更新;不重跑需求的完整 SOP。
  • 每次刷新在需求 Operations 和 PR 上留一条记录(「目标分支前进至 xxx,已自动合入并解决 N 个文件冲突」);超过 maxRefreshes 或 Agent 无法解决时停止,PR 保持原样并通知负责人。

4. 手动触发

  • 需求详情的交付 MR 旁增加「同步最新基线」按钮(有项目写权限的人可用),以及对应 API / 平台 MCP 工具,走同一套逻辑(即使 mode=notify 也可手动触发);有人工提交时二次确认后才执行。

验收标准

  • GitHub 交付 PR 的 mergeable_state 为 dirty/behind/clean 时,MRDeliveryState.Mergeability 分别记为 conflicted/behind/clean;GitHub 返回 null 时保持原值(fake GitHub server 单测覆盖)。工蜂 MR 有同等单测。
  • 需求列表/详情能看到交付 MR 的「有冲突/落后基线」标记,并能按此筛选。
  • mode=notify(默认)时只标记与通知,不修改任何分支;现有交付同步相关测试全部通过。
  • mode=behind:PR 落后但无冲突时,工作分支上新增一个 merge 提交并推送,PR 变为 clean,全程不启动 Agent、不 force-push。
  • mode=conflicted:PR 冲突时自动启动冲突刷新运行,Agent 收到冲突块与需求上下文,推送原分支后 PR 变为可合并;不重跑需求的完整 SOP。
  • 分支上存在人工提交时不自动刷新,只通知;手动触发需二次确认。
  • 同一 PR 自动刷新次数达到 maxRefreshes 后停止并通知;冷却期内不重复触发。
  • 每次刷新在需求操作记录中可追溯(时间、目标分支 SHA、处理结果)。
  • 改动遵守 AGENTS.md:新字段归 DeliveryRepo / CatalogRepo,handler 分层不越界,基线 schema 需要时附 migrations/NNN_*.sql。
Langage dominant
Go
Étoiles
141
Forks
28
Merge moyen
1 j 15 h
PR mergées (30 j)
113

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de Tencent/LoopForge

Toutes les issues de Tencent/LoopForge

Issues similaires

Plus d'issues Go

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.