| name | issues |
| description | 激活 forge 的 issue/work-item tracker + 看板项目管理单源技能(GitHub Issues+Project v2 / Azure Boards / GitLab issues,经 forge.sh 适配)。Part A:epic 拆解 + wave 实施顺序评论(找子任务 → blocked-by DAG → wave 1-4 容量装箱排序:每 wave ≤4、pri 优先、wave 内切并行组/串行链、OPEN 重排、已完成不动、装箱溢出顺延下一 wave、仅超窗(Wave 4 后仍未分配)单列 → 只追加 epic 评论;不写 Project 字段、不改 epic body)。Part B:issue/PR 原子操作(建/改 backlog issue、area/type/pri label、PR 双轴状态 label 流转、统一 PR 评论格式 + 冲突预检/CI watch 跟进,ship/fix 共用)。非 epic issue 号 → 查代码判状态(只判不修,建议 /ship 或 close)。当用户要整理 epic 排 wave、建/改 backlog issue、贴 label、切 PR 状态、给 PR 留评论、核一个 issue 是否还成立时使用。 |
| argument-hint | <epic #N | #issue(非epic→状态核查)| create-issue | edit-labels | pr-status | comment> [...] |
| allowed-tools | ["Read","Grep","Bash","Agent","AskUserQuestion"] |
issues — 项目管理单源(Epic/Wave + Issue/PR/Label/评论)
真源 = 激活 forge 的 issue 系统(GitHub Issues / Azure Boards / GitLab Issues)+ 激活 forge 的看板(Azure Boards / GitHub Project / GitLab)。内容/结构 + 治理全在 .github/project-template/:issue body → backlog.md/epic.md,PR body → pull_request_template.md,PR 评论 → pr-comment.md,label/字段/评级/流程 → PROJECT.md(索引见 README.md)。本技能只负责编排,不复制模版内容。
输入分派:epic #N / 带 epic label 的 issue → Part A(拆解 + wave 调度);普通 issue 号(无 epic label) → 下方「非 epic issue 状态核查」;动词(create / edit / pr-status / comment)→ Part B 原子操作。
create issue 前先 search 查重(幂等)。
repo 标识经 bash hack/automation/forge.sh repo-slug 取得;看板经激活 forge 的看板机制管理,不写死平台路径。
非 epic issue 状态核查(查代码判状态,只判不修)
输入普通 issue 号(无 epic label)时,不排 wave,而是查代码判断该 issue 是否仍成立:
bash hack/automation/forge.sh issue-view <N> 读问题描述 + body 的 Files。
- 按 Files / 关键字 Read/Grep 定位代码;跨 3+ 文件时并行派
Agent(Explore) 核查。
- 判状态(只判不修):存在 / 已修复(给证据:哪行 / 哪 PR)/ 已变更(形态变化)/ 无法确认。
- 输出状态 + 证据 + 建议:需修 → 建议
/ship #<N>(或定位到 file:line 后 /fix);已修复 / 过期 → 建议 Part B 关闭(forge.sh issue-close)。
Part A — Epic 拆解 + Wave 实施顺序评论
负责 epic 级「找子任务 → 排 wave → 追加 epic 评论」。不写 Project 字段,不改 epic body;issue/label/评论原子操作见 Part B。
A1. 读 epic → 关键字查找相关 issues → 关联 → 汇总子 issues
- 读 epic:
bash hack/automation/forge.sh issue-view <epic#>(确认 epic label;从 title + 目标/范围提取关键字)。
- 关键字查找相关 issues:
bash hack/automation/forge.sh issue-list "<关键字>" open,挑出属于本 epic 的候选;用 AskUserQuestion 确认候选集(不擅自全关联)。
- 关联到 epic(建父子关系,已关联的跳过):
bash hack/automation/forge.sh subissue-link <epic#> <child#>
- 汇总子 issues:经 forge 列出 epic 子任务(
bash hack/automation/forge.sh issue-list "" open 结合父子关系过滤,或激活 forge 的父子关系 API);对每个 OPEN 子任务读 label(area/type/pri)+ body 的 Blocked-by: #NNN(多行/逗号分隔,无声明=无前置)。
子任务跨 3+ 包或描述模糊时,用 Agent(Explore) 核实归属 / 状态 / Blocked-by 再汇总(wave 内冲突分区 + 实施顺序的分析在 A2 第 6 步,见下)。
A2. 建 blocked-by DAG + wave 容量装箱排序(每 wave ≤4,Wave 1-4 有界)
滚动 + 有界 + 容量装箱算法(每次更新 epic 都重跑;作用域 = epic 的 OPEN 子任务)。wave 不再纯=依赖深度,而是「依赖约束 + 每 wave ≤4 容量」的贪心 list-scheduling——pri 决定容量受限时谁进早 wave:
- 节点 = OPEN 子任务;CLOSED(已完成)子任务排除——不参与排序,仅在评论中单列为已完成。
- 有向边
blocker → dependent(来自 Blocked-by),仅当 blocker 也 OPEN;blocker 已 close = 依赖已满足 → 删该边。这是「滚动」的来源:前置完成后 dependent 自动前移到更早 wave。
- 检测环:若有环,AskUserQuestion 让用户裁定断哪条边(不静默)。
- 逐 wave w=1..4 贪心装箱(每 wave 至多 4 个 issue):
ready 集 = 全部 blocker 都已分到更早 wave 的未分配 OPEN 节点(无 blocker 的节点天然 ready)。
- ready 集按
pri(p0>p1>p2>p3) → 基础性产出先 → Cx(小先,由 cx-X label 提供) → issue# 排序,取前 ≤4 入 wave w。
- 其余(含同深度溢出、blocker 刚入本 wave 而本轮未 ready 的)留待下一 wave(溢出顺延)。
- 有界 cap = Wave 4:装箱到 Wave 4 仍未分配的节点标记 超窗,在评论中单列,不写任何 Project 字段。
- wave 内冲突分区(确认「真并行」vs「须串行」):对每个 wave(成员 ≥2)并行派
Agent(Explore) 分析其中每个任务的 scope / 触碰文件 / 产出↔消费 / 风险,主 agent 汇总后切:
- 并行组:两两无文件重叠 + 无隐式产出↔消费 + 无资源冲突 → 可同时跑(≤4 并行 agent)。「可并行」= 经冲突分析确认无冲突,非仅「无
Blocked-by」。
- 串行链:有上述任一冲突 → 须串行,链内按
pri → 基础性产出先 → Cx → issue# 定序,并注明冲突原因(如「同改 foo.rs」)。
- 单任务 wave 跳过分析。
- 输出每个 OPEN 子任务的
(wave, 并行组/串行链, 链内序) 或「超窗」。
呈现给用户的 dry-run 表(只列 OPEN;超窗与已完成单列):
Wave 1(依赖深度1,取 pri 前4):
并行组 A(零冲突,可同时): #a(p0·Cx1) #b(p0·Cx2)
串行链 B(#c→#d 同改 foo.rs,按 pri): [1] #c(p1·Cx2) [2] #d(p2·Cx1)
Wave 2(深度1溢出 + 依赖 Wave 1):
并行组 A: #e(p3·Cx1 深度1溢出) #g(p1·Cx2 ←blocked-by #a)
超窗(Wave 4 之后,评论单列): #z(依赖链/装箱越 W4)
已完成(不动): #y
A3. 追加 epic 实施顺序评论
cat > /tmp/epic-wave-comment.md <<'C'
`pm:epic-wave`
🌊 Epic 实施顺序更新:每 wave ≤4 容量装箱,OPEN 按 pri 排 Wave 1-4;wave 内标明并行组 / 串行链;已完成与超窗(Wave 4 之后)单列。排序结果只写在本评论中,不写 Project 字段,不改 epic body。
粘贴 A2 dry-run 表(不带尖括号占位符)
C
bash hack/automation/forge.sh issue-comment <epic#> /tmp/epic-wave-comment.md
A4. 沟通规则
- 环检测命中:停下 AskUserQuestion。
- DAG 排序结果先 dry-run 呈现,确认后只追加 epic 评论。
- 不改子任务代码 / 不关 issue / 不改 area-type-pri label(那是 Part B /
fix 职责)。
Part B — Issue / PR / Label / 评论
issue/PR 的 forge 编排,是 issue/PR/label/评论固定命令形态的单源——ship/fix/pr-review 引用本部分,不重印命令。body 骨架见 .github/project-template/ 的 backlog.md / epic.md / pull_request_template.md;PR 评论格式见 pr-comment.md;label / 字段 / 评级 rubric 见 PROJECT.md。本部分不复制模版内容。
B1. 新建 backlog issue(PBI 叶子)
B1 建的是 PBI 叶子(Work Item Type = Product Backlog Item,≈ 一个 PR),validate 默认 --tier pbi 守四轴。容器层 Epic / Feature 走 §1.1 三层映射(Azure UI 手工建、不贴 cx / type);脚本化建容器时校验用 issue-labels.sh validate --tier feature|epic(要求 area+pri、禁止 type/cx)。
四轴 label 齐全(area + type + pri + cx)+ backlog,全部 CLI 显式贴(pri/cx 必填,cx 无 unknown sentinel):
bash hack/automation/issue-labels.sh validate --labels "backlog,pri-p2,area-review,type-bug,cx-2"
bash hack/automation/forge.sh issue-create \
"[<ID>] <简短标题>" <填好的 backlog.md> \
"backlog,pri-p2,area-review,type-bug,cx-2"
由 review/fix finding(OUT_OF_SCOPE / 派生)成文时:body 按 backlog.md 顶部的字段映射无损填充,不得一句话带过——否则后续无法据此修复;并从 finding 的 […Cx…] tag 取 cx-X label 一并贴。
- area-XX(1 个,8 选):见
.github/project-template/PROJECT.md §2.1。
- type-XX(1 个,8 选):见 §2.2。
- pri-pX:评级 rubric 见
.github/project-template/PROJECT.md §3。/fix 派生默认 pri-p2;pri-p0 仅 incident-driven,停下 AskUserQuestion 确认。
- cx-X(必填):复杂度 rubric 见
.github/project-template/PROJECT.md §3.2 / §2.6。建单前必须定级并显式指定 cx-X label(与 pri 对称,无 unknown sentinel——定不到级也要就近取一档);finding 派生从 […Cx…] tag 取。epic / feature 容器例外(不贴 cx / type,§1.1)。
- flag-cond(可选):条件延后型加此 label + body 写
## Trigger。
P0 红线不得默认贴。area/type/cx 漏贴时用 bash hack/automation/forge.sh issue-edit-labels <N> --add "area-X" --remove "" 补;建单前 issue-labels.sh validate 强制门正常会先拦截,此为绕过门(raw web UI)后的补救。
B2. 编辑 label / 关闭 issue
bash hack/automation/forge.sh issue-edit-labels <N> --add "area-data" --remove "area-review"
bash hack/automation/forge.sh issue-edit-labels <N> --add "type-debt" --remove ""
bash hack/automation/forge.sh issue-close <N> "completed" "Fixed in PR <NNN>"
bash hack/automation/forge.sh issue-close <N> "not planned" "<理由>"
容器层 Epic / Feature(§1.1 三层映射)= 原生 Work Item Type + forge.sh subissue-link 写原生父子(不手写 body task list);Epic 另贴 epic label。父子链 Epic→Feature→PBI:bash hack/automation/forge.sh subissue-link <epic#> <feature#> / subissue-link <feature#> <pbi#>。wave 排序见 Part A。
B3. PR 状态 label 流转(编排)
两正交轴(pr-status 流转 / pr-review 结论)的取值与「何时切」语义见 .github/project-template/PROJECT.md §2.5 + §5(单源,不在此复制表)。两轴各自互斥:pr-status 恰好一个;pr-review approved XOR changes-requested——切一侧必 --remove 同轴对侧。本节只给切换命令。
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-status/needs-review-again" --remove "pr-status/in-progress"
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-review/changes-requested,pr-status/needs-fix" --remove "pr-review/approved,pr-status/needs-review-again"
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-review/approved,pr-status/ready" --remove "pr-review/changes-requested,pr-status/needs-review-again"
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-status/needs-check-fix" --remove "pr-status/needs-fix"
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-status/ready,pr-review/approved" --remove "pr-status/needs-check-fix,pr-review/changes-requested"
bash hack/automation/forge.sh pr-set-labels <N> --add "pr-review/changes-requested,pr-status/needs-fix" --remove "pr-status/needs-check-fix,pr-review/approved"
B4. PR 评论(编排)
留痕约定 / 标记规则见 .github/project-template/PROJECT.md §5;评论格式(pm:ship / pm:fix / pm:pr-review 三模板 + footer)见 .github/project-template/pr-comment.md。本节是贴评论命令 + 回显 comment URL 的单源(ship/fix/pr-review 引用本节,不重印):
URL=$(bash hack/automation/forge.sh pr-comment <N> <填好的 pr-comment.md 模板>)
echo "已贴评论:$URL"
- stdout 即评论 URL(含锚点)——贴完必须捕获并回显,便于用户跳转 / 引用该评论。
- 命令非 0 退出 → 报错退出,不静默跳过。
- footer 格式见
.github/project-template/pr-comment.md(PR#/工具/分支/worktree/session,AI 自填)。
B5. PR 冲突预检 + CI 跟进(ship/fix 共用)
push 后流程分两阶段:① 冲突预检(阻塞,贴评论前必过)→ 立即收尾(贴评论 + 切 label,不等 CI)→ ② CI 异步收敛(收尾后再跑,结果贴独立 pm:ci 评论)。
① 冲突预检(阻塞,必须先于收尾):bash hack/automation/forge.sh pr-mergeable <N>。mergeable 由 forge 异步计算,刚 push 常返回 UNKNOWN——轮询几次(~5-10s 间隔)直到落定 MERGEABLE / CONFLICTING,单查 UNKNOWN 无效。CONFLICTING → 先解冲突:REMOTE=$(bash hack/automation/forge.sh remote); git -C <wt> fetch "$REMOTE" && git -C <wt> merge "$REMOTE/develop" --no-edit(解冲突 → commit → push)→ 回本步重检。MERGEABLE → 立即进行收尾(贴评论 + 切 label),不等 CI。
② CI 异步收敛(收尾评论 + label 切换之后再跑):激活 forge(azure)无 CI 时,ci-* 命令返回 no-ci 哨兵,此阶段降级为本地 pnpm build && pnpm test + cargo build/test/fmt/clippy,不贴 pm:ci 评论;以下 watch 逻辑作为有 CI forge(如 GitHub Actions)的路径保留。
bash hack/automation/forge.sh ci-watch <N>
bash hack/automation/forge.sh ci-failed <N>
bash hack/automation/forge.sh ci-logs <run-id> <job-id>
- 等待上限 ~12-15 min(~2.5× 典型,吸收 runner 排队)。超 Bash 10min 上限用后台轮询兜底(
run_in_background 跑 ci-watch,或循环 bash hack/automation/forge.sh pr-state <N> 间隔 30-60s 判 CI 完成);超上限仍 pending → 停下报告,不无限等。
- 失败 → 回
fix 修复循环(定位 → 修 → commit → push → 重新预检),最多 3 轮;3 轮仍红 → 停下交人工,不 AskUserQuestion。
- CI 收敛后(全绿或 3 轮红)贴独立
pm:ci 评论(verdict=ci-green 或 verdict=ci-failed),不合并进主 pm:ship / pm:fix 评论。
B6. 沟通规则
- label 编辑 / PR 状态切换 / 评论:按流程自动执行,不逐条问。
- CI watch / 取失败日志:自动执行;CI 修复 3 轮仍红 → 贴 PR 评论留痕 + 停下交人工(不 AskUserQuestion)。