[Feature] 需求间阻塞依赖:定时派发只认领依赖已完成的需求,按优先级排序,上游完成自动放行

Ouverte
#393 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
22/100
Type d'issue
Fonctionnalité
Clarté
Plutôt claire
Activité
Active
Stack technique
github, go
Domaine
api, backend, databases

Piste de recherche

Start with the scheduler path: execute() and matchingIssues() in internal/schedule/service.go, the candidate ordering from Issues() in internal/repo/issues.go, and the Issue type in internal/domain/issue.go. Also read internal/httpapi/dispatch.go and internal/tracker/github.go. Done means the acceptance checklist in the issue passes, including readiness and cycle-detection unit tests and a migration under migrations/.

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

Description

背景与借鉴来源

需求一多,AI 自动认领就会遇到顺序问题:B 需求必须等 A 合入才能做,但调度器不知道,照样把 B 派给 Agent,结果要么在旧代码上实现、要么和 A 冲突,最后只能人工撤回。主流「给 Agent 用的任务系统」都把需求间的阻塞依赖 + 只派发就绪项当作核心能力:

项目 规模/活跃度(2026-11-13) 相关能力
steveyegge/beads ~28.7k stars,当天有提交,v1.3.4(2026-11-04) 依赖图驱动的 Agent 任务记忆:bd dep add B A(A 阻塞 B),bd ready 只列出没有未关闭阻塞项的任务,bd ready --claim 原子认领;A 关闭后 B 自动解除阻塞。依赖分阻塞型(blocks/parent-child/waits-for)和非阻塞型(related/discovered-from),见 Dependencies 文档
MrLesk/Backlog.md ~7.4k stars,11-11 有提交,v1.55.3 面向 AI 助手的任务看板,任务支持 dependencies,详情页同时显示「我在等谁」和「谁在等我」
eyaltoledano/claude-task-master ~28.4k stars 任务带 dependencies,next 命令只返回依赖已完成、按优先级排序的下一项
GitHub Issues — 原生已支持 issue 的 blocked by / blocking 关系和 sub-issues(REST /issues/{n}/dependencies/blocked_by,GraphQL issueDependenciesSummary)

共同做法:依赖关系存在任务上;调度/认领只看「就绪」集合;上游完成自动放行下游;界面能看见卡在谁身上。

LoopForge 现状与不足

  1. 需求之间没有依赖字段。 internal/domain/issue.go 的 Issue 只有 SOPBindings[].DependsOn(internal/domain/issue_sop.go),那是同一个需求内多条 SOP 泳道之间的先后,不能表达「需求 #12 要等需求 #9 完成」。
  2. 定时派发不看依赖和优先级。 internal/schedule/service.go 的 execute() → matchingIssues() 只按项目、状态、来源筛选;可派发判断只有 IssueHasTask/DeliveryLocked/已关闭/AutomationState=ignored,以及集成分支阻塞(guard,按仓库)。候选顺序来自 IssuesRepo.Issues()(internal/repo/issues.go)按 Number 倒序,即最新的需求最先派,Issue.Priority 不参与;MaxDispatch 名额可能被新的、低优先级、或依赖没完成的需求占掉。
  3. blocked 状态只是手工/失败标记。 internal/httpapi/dispatch.go 里 run 启动失败会把需求置为 blocked,但没有「被谁阻塞」的数据,上游完成后也不会自动恢复。
  4. 外部来源的依赖关系丢失。 internal/tracker/github.go 同步 GitHub issue 时只取标题/正文/状态,GitHub 原生的 blocked-by、sub-issue 关系没有带进来(TAPD、工蜂同理)。

建议方案

  1. 数据模型:Issue 增加 BlockedBy []string(同项目内需求 ID);读取时反查生成 Blocks(谁在等我),不重复存。基线变更按 AGENTS.md 规范写 migrations/NNN_issue_dependencies.sql,如需单独关系表放在 IssuesRepo。
  2. 就绪判定(domain 层纯函数,便于测试):IssueReady(issue, lookup):所有 BlockedBy 都已完成(Completed(),或 DeliveryMRState 为 merged/integrated,可配置哪个算完成)才算就绪;阻塞项被取消/删除时视为解除并记一条 IssueOperation。新增/修改依赖时检测环,有环直接拒绝。
  3. 定时派发:schedule.Service.execute 在筛 eligible 时跳过未就绪需求,并把原因写进 job.Blockers(如「#12 等待 #9 完成」),与现有集成阻塞一起在任务结果里展示;候选排序改为「优先级 → 创建时间早的先派」,可在 ScheduleJob 上保留按编号倒序的旧行为开关。
  4. 手动派发:dispatchIssue 对未就绪需求返回 409 并列出阻塞项;提供 force 参数让有权限的人显式越过,记操作日志。
  5. 自动放行:上游需求完成或 MR 合入时,下游需求在下一次调度扫描中自然进入就绪集合;可选:此时给下游负责人发一条通知(复用 internal/notification)。
  6. 外部同步(可分期):GitHub 同步时读取 issue 的 blocked-by 关系,映射为 BlockedBy(两端都已同步进 LoopForge 才建立);TAPD/工蜂后续按各自 API 补。
  7. 界面与 API/MCP:需求详情显示「等待中 / 阻塞了」两个列表,可增删依赖;需求列表支持「仅就绪」筛选;平台 MCP 增加查询就绪需求和维护依赖的工具,方便澄清/拆分类 SOP 拆出子需求时直接写上先后关系。

验收标准

  • 可以在需求上添加/删除「被阻塞于」关系,接口和 UI 都能用;自依赖和成环被拒绝并给出明确提示。
  • 定时任务扫描时,依赖未完成的需求不会被派发,任务结果里能看到「#X 等待 #Y」的原因;上游完成后,下一轮扫描能自动派发下游。
  • 定时任务候选按优先级从高到低派发,同优先级先建先派;MaxDispatch 名额不被未就绪需求占用。
  • 手动派发未就绪需求默认被拒绝(409 + 阻塞清单),带 force 可越过并在需求操作记录里留痕。
  • 上游需求被取消/删除时,下游不会永久卡住(自动解除并记录)。
  • 需求详情能同时看到「等待中」和「阻塞了」;需求列表可筛选「仅就绪」。
  • domain 就绪判定、环检测、schedule 跳过与排序逻辑有单元测试;新增表/列有对应 migrations/ 脚本,不在启动路径里做迁移。
  • (可选,分期)GitHub 同步能带入原生 blocked-by 关系。
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.