@ranger1/dx 0.1.105 → 0.1.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/lib/codex-initial.js +79 -5
  2. package/package.json +1 -1
  3. package/skills/backend-audit-fixer/SKILL.md +98 -0
  4. package/skills/backend-audit-fixer/references/backend-layering.md +103 -0
  5. package/skills/backend-audit-fixer/references/e2e.md +60 -0
  6. package/skills/backend-audit-fixer/references/env-accessor.md +73 -0
  7. package/skills/backend-audit-fixer/references/error-handling.md +77 -0
  8. package/skills/{naming-audit-fixer/references/fix-guide.md → backend-audit-fixer/references/naming-fix-guide.md} +8 -3
  9. package/skills/backend-audit-fixer/references/naming.md +139 -0
  10. package/skills/backend-audit-fixer/references/pagination-dto.md +52 -0
  11. package/skills/create-issue/SKILL.md +90 -0
  12. package/skills/issues-batch-deliver/SKILL.md +193 -84
  13. package/skills/pr-train-ship/SKILL.md +202 -49
  14. package/skills/backend-layering-audit-fixer/SKILL.md +0 -180
  15. package/skills/e2e-audit-fixer/SKILL.md +0 -76
  16. package/skills/e2e-audit-fixer/agents/openai.yaml +0 -4
  17. package/skills/env-accessor-audit-fixer/SKILL.md +0 -149
  18. package/skills/env-accessor-audit-fixer/agents/openai.yaml +0 -7
  19. package/skills/error-handling-audit-fixer/SKILL.md +0 -187
  20. package/skills/error-handling-audit-fixer/agents/openai.yaml +0 -7
  21. package/skills/naming-audit-fixer/SKILL.md +0 -149
  22. package/skills/pagination-dto-audit-fixer/SKILL.md +0 -69
  23. package/skills/pagination-dto-audit-fixer/agents/openai.yaml +0 -7
  24. /package/skills/{env-accessor-audit-fixer → backend-audit-fixer}/references/bootstrap-env-foundation.md +0 -0
  25. /package/skills/{error-handling-audit-fixer/references/foundation-bootstrap.md → backend-audit-fixer/references/error-handling-foundation-bootstrap.md} +0 -0
  26. /package/skills/{error-handling-audit-fixer → backend-audit-fixer}/references/error-handling-standard.md +0 -0
  27. /package/skills/{pagination-dto-audit-fixer → backend-audit-fixer}/references/pagination-standard.md +0 -0
  28. /package/skills/{e2e-audit-fixer/scripts/e2e_e2e_audit.py → backend-audit-fixer/scripts/e2e_audit.py} +0 -0
  29. /package/skills/{env-accessor-audit-fixer → backend-audit-fixer}/scripts/env_accessor_audit.py +0 -0
  30. /package/skills/{error-handling-audit-fixer → backend-audit-fixer}/scripts/error_handling_audit.py +0 -0
  31. /package/skills/{naming-audit-fixer/scripts/audit_naming.py → backend-audit-fixer/scripts/naming_audit.py} +0 -0
  32. /package/skills/{pagination-dto-audit-fixer → backend-audit-fixer}/scripts/pagination_dto_audit.py +0 -0
@@ -21,7 +21,7 @@ issues-batch-deliver (本 skill — 编排器 / 主 agent)
21
21
  └─ 校验:mergedAt 真的非空?审查 comment 真的发了?
22
22
  ```
23
23
 
24
- 主 agent 只做:派发 → 校验 → 重试 → 推进。**不直接动代码、不直接改 issue/PR**。
24
+ 主 agent 只做:**依赖分析并行派发(独立 worktree)→ 校验 → 重试 → 推进**。不直接动代码、不直接改 issue/PR。**绝大多数决策主 agent 自行做,不在派 subagent 前找用户确认**——只有遇到不可恢复失败(escalation)才回报用户。
25
25
 
26
26
  ## Scope
27
27
 
@@ -32,7 +32,7 @@ issues-batch-deliver (本 skill — 编排器 / 主 agent)
32
32
  ```
33
33
  $issues-batch-deliver --issues 4774,4823,4901
34
34
  $issues-batch-deliver --issues 4774 # 单 issue 也走本流程
35
- $issues-batch-deliver # 从当前对话上下文提取(明确列出后再确认)
35
+ $issues-batch-deliver # 从当前对话上下文提取 issue 列表,主 agent 自行确认后直接执行
36
36
  ```
37
37
 
38
38
  **前提:**
@@ -50,12 +50,58 @@ $issues-batch-deliver # 从当前对话上下
50
50
  - 全程中文输出。
51
51
  - **事实校验优先**:subagent 说"完成了"不算数,必须 `gh` / `git` 实际查到才认。
52
52
  - **重试有上限**:同一 issue 的 plan-execute 重试 ≤ 2 次;同一 PR 的 ship 重试 ≤ 2 次;超限 escalate 给用户。
53
- - **Issue 之间默认串行**(避免一次开太多 WIP 干扰 dev DB / branch 切换);用户明确允许并行才并行。
54
- - **PR 之间按依赖串行**:依赖 PR `mergedAt` 非空才能开下游。
53
+ - **Issue 之间默认并行**:每个 issue 在**独立 worktree** subagent,互不干扰 branch / 文件。无需逐 issue 找用户确认——主 agent 自行决策派发。
54
+ - **有依赖的 issue 串行**:依赖关系(issue body / label 标注 `depends on #X` / `blocked by #X`,或输入显式给出)存在时,**先处理被依赖(上游)issue**,blocked issue 等上游完结后再派。无依赖的 issue 一律并行。
55
+ - **PR 之间按依赖串行**:依赖 PR `mergedAt` 非空才能开下游(同 issue 内 Track C train,不变)。
55
56
  - 不绕过下游 skill 的 Hard Gate:本 skill 是编排,不允许"为了赶进度跳 critic / 跳双 comment / `--admin` 合并"。
56
57
 
57
58
  ---
58
59
 
60
+ ## 脚本约定(先读这节,后面所有校验都依赖它)
61
+
62
+ ### 变量都是真 shell 变量,不是占位符
63
+
64
+ 后文脚本里 `$id`(当前 issue 号)、`$pr`(当前 PR 号)、`$result`(subagent 返回的 JSON)**全是真 shell 变量**。subagent 复制脚本前必须先赋值(`id=4774`),**严禁保留 `<id>` / `<n>` 字面量**——保留字面量会让 `grep` 永远匹配不到,触发假失败重试。
65
+
66
+ ### `$result` 的来源
67
+
68
+ 每次 subagent 返回后,主 agent 把它最后一段严格 JSON 存进变量,校验全部基于它:
69
+
70
+ ```bash
71
+ # 主 agent 从 subagent 返回文本里截取最后一段 JSON,赋给 result
72
+ result='<subagent 返回的 JSON>'
73
+ echo "$result" | jq . >/dev/null || { echo "subagent 未返回合法 JSON → 直接重新派发"; }
74
+ ```
75
+
76
+ JSON 不合法本身就是一种失败,按对应阶段的「失败重新派发」处理,无需落盘。
77
+
78
+ ### 校验聚合:所有 FAIL 必须汇总判定,不允许只 echo
79
+
80
+ 每段校验开头 `FAILS=()`,命中失败 `FAILS+=("...")`,末尾统一判定:
81
+
82
+ ```bash
83
+ if [ ${#FAILS[@]} -gt 0 ]; then
84
+ printf '校验失败:\n'; printf ' - %s\n' "${FAILS[@]}" # → 进入「失败重新派发」
85
+ else
86
+ echo "校验全通过"
87
+ fi
88
+ ```
89
+
90
+ ### 诊断采集(重试 prompt 的"当前仓库状态"从这里来)
91
+
92
+ Hard Gate 7 要求重试必附"当前真实状态"。重新派发前主 agent 跑这组命令,把输出填进重试 prompt:
93
+
94
+ ```bash
95
+ branch=$(gh pr view "$pr" --json headRefName --jq .headRefName 2>/dev/null)
96
+ head_sha=$(gh pr view "$pr" --json headRefOid --jq .headRefOid 2>/dev/null)
97
+ pr_state=$(gh pr view "$pr" --json state,mergedAt,mergeStateStatus --jq '[.state,.mergedAt,.mergeStateStatus]|@tsv' 2>/dev/null)
98
+ sent_comments=$(gh pr view "$pr" --json comments --jq '[.comments[].body | scan("审核报告(第|修复报告(第|✅ 验证总结")] | join(", ")' 2>/dev/null)
99
+ ```
100
+
101
+ > 不做 checkpoint / resume:subagent 失败就带诊断重新派发即可(重试有上限)。**只对关键点做事实校验**——PR 真存在、真合并、双 comment 真发、本地真全绿——其余轻信 subagent 自报。
102
+
103
+ ---
104
+
59
105
  ## 阶段一:输入解析与预检
60
106
 
61
107
  ### 1.1 解析 issue 列表
@@ -79,36 +125,73 @@ gh issue view $id --json number,title,state,body,labels --jq '{n:.number, t:.tit
79
125
  - body 含"验收标准"段(4 段齐全的简单代理判据)
80
126
  - 无以上 → 输出"Issue #X 缺验收标准 / 已关闭,跳过 / 终止",请用户确认或修复
81
127
 
82
- ### 1.3 输出执行计划
128
+ ### 1.3 依赖分析(主 agent 自行完成,不问用户)
129
+
130
+ 从每个 issue 的 body / labels 以及输入参数里提取依赖关系:
131
+
132
+ - 关键词:`depends on #X` / `blocked by #X` / `需先完成 #X` / `基于 #X` / label `blocked`
133
+ - 构建依赖图:被依赖的 issue(上游)排在前,blocked issue 排在后。
134
+ - 无依赖关系的 issue **互相独立**,归入同一并行批次。
135
+ - 有依赖的:上游先派;下游标记 `blocked_by=[...]`,上游全部完结后才进入可派发集合。
136
+
137
+ 判定规则(主 agent 直接决策,**不找用户确认**):
138
+
139
+ - 检测到环依赖(A→B→A)→ 这是唯一必须 escalate 的情况:输出环路给用户,请求拆解。
140
+ - 依赖指向的 issue 不在本批次且未合并 → 标记该下游为 blocked,输出告警,先并行跑可派发的,blocked 的在依赖满足后再派;始终无法满足则 escalate 该条。
141
+
142
+ ### 1.4 输出执行计划(直接执行,无 STOP 确认)
143
+
144
+ 输出计划后**直接进入阶段二派发**,不再 STOP 等用户确认(重操作的安全由下游 skill 的 Hard Gate + 本 skill 事实校验 + 独立 worktree 隔离共同保证):
83
145
 
84
146
  ```
85
147
  [Batch Plan]
86
- 3 issue 串行执行:
87
- 1. #4774 - <title>
88
- 2. #4823 - <title>
89
- 3. #4901 - <title>
148
+ 并行批次 1(无依赖,独立 worktree 同时派发):
149
+ - #4774 - <title>
150
+ - #4823 - <title>
151
+ 依赖链(串行,上游先):
152
+ - #4901 - <title> → blocked by #4774(等 #4774 完结后派)
90
153
  重试上限:plan-execute 2 次 / ship 2 次
154
+ escalate 策略:跳过该 issue 继续其余(环依赖 / 始终无法满足的依赖才回报用户)
91
155
  ```
92
156
 
93
157
  ---
94
158
 
95
- ## 阶段二:Issue 循环
159
+ ## 阶段二:Issue 并行调度
160
+
161
+ 按阶段 1.3 的依赖图调度。**无依赖的 issue 在独立 worktree 同时派发**(一次性派出整个可派发集合);blocked issue 等上游完结后再进入可派发集合。每个 issue 内部仍走**阶段三 + 阶段四**。
162
+
163
+ ### worktree 隔离(并行前提)
164
+
165
+ 每个并行 issue 必须独立工作树,避免 branch / 文件互踩。派 subagent 前主 agent 为该 issue 准备隔离工作区(`using-git-worktrees` 路径,或在 subagent prompt 内要求其自建 worktree);subagent prompt 必须注明其专属 worktree 路径与分支前缀,禁止跨 worktree 操作。
166
+
167
+ ### 调度循环(事件驱动,非逐个串行)
168
+
169
+ 1. 计算**可派发集合** = 所有 `blocked_by` 已全部完结的未派 issue。
170
+ 2. 一次性为可派发集合每个 issue 派 plan-execute subagent(独立 worktree、独立上下文)。
171
+ 3. 任一 issue 完结(全 PR merge 或 escalate)→ 重算可派发集合,新解锁的 blocked issue 立即派发。
172
+ 4. 全部 issue 完结 → 阶段六输出。
173
+
174
+ **escalate 后推进**(主 agent 自行决策,默认行为,不问用户):
96
175
 
97
- 对每个 issue 依序执行**阶段三 + 阶段四**。前一 issue 全部 PR 都 merge 到 main 后再开下一 issue
176
+ - 当前 issue 标记 escalated,记录原因,**不阻塞其余并行 issue**。
177
+ - 依赖被 escalated issue 的下游永远无法解锁 → 一并标记 escalated(原因:上游失败),最终在阶段六汇总回报。
178
+ - 仅环依赖 / 始终无法满足的依赖才在发现时即时回报用户(见阶段 1.3)。
98
179
 
99
180
  ```dot
100
- digraph issue_loop {
101
- "下一 issue" [shape=box];
102
- "阶段三:plan-execute" [shape=box];
103
- "阶段四:每个 PR ship" [shape=box];
104
- "全部 issue 完成?" [shape=diamond];
181
+ digraph issue_schedule {
182
+ "依赖分析" [shape=box];
183
+ "计算可派发集合" [shape=box];
184
+ "并行派发(独立 worktree)" [shape=box];
185
+ " issue 完结" [shape=box];
186
+ "还有未完结 issue?" [shape=diamond];
105
187
  "完成输出" [shape=doublecircle];
106
188
 
107
- "下一 issue" -> "阶段三:plan-execute";
108
- "阶段三:plan-execute" -> "阶段四:每个 PR ship";
109
- "阶段四:每个 PR ship" -> "全部 issue 完成?";
110
- "全部 issue 完成?" -> "下一 issue" [label="no"];
111
- "全部 issue 完成?" -> "完成输出" [label="yes"];
189
+ "依赖分析" -> "计算可派发集合";
190
+ "计算可派发集合" -> "并行派发(独立 worktree)";
191
+ "并行派发(独立 worktree)" -> " issue 完结";
192
+ " issue 完结" -> "还有未完结 issue?";
193
+ "还有未完结 issue?" -> "计算可派发集合" [label="yes(解锁下游)"];
194
+ "还有未完结 issue?" -> "完成输出" [label="no"];
112
195
  }
113
196
  ```
114
197
 
@@ -118,7 +201,7 @@ digraph issue_loop {
118
201
 
119
202
  ### 3.1 派发
120
203
 
121
- 为当前 `issue_id` 派一个 subagent,独立上下文、独立工作树(可选 worktree):
204
+ 为当前 `issue_id` 派一个 subagent,独立上下文、**独立 worktree(并行必需,非可选)**。prompt 内注明其专属 worktree 路径与分支前缀:
122
205
 
123
206
  Subagent prompt 模板:
124
207
 
@@ -155,32 +238,47 @@ Subagent prompt 模板:
155
238
 
156
239
  ### 3.2 事实校验(subagent 返回后立即跑)
157
240
 
158
- 不要相信 subagent 自报,直接查 GitHub / git:
241
+ 前置:已按「状态管理」把 subagent JSON 落到 `$result`,且 `id=<当前issue号>` 已赋值。不要相信 subagent 自报,直接查 GitHub / git:
159
242
 
160
243
  ```bash
244
+ FAILS=()
245
+
161
246
  # 校验 1:声称 push 的 PR 真存在且 OPEN
162
247
  for pr in $(echo "$result" | jq -r '.prs_pushed_this_session[].number'); do
163
- state=$(gh pr view $pr --json state --jq .state)
164
- [ "$state" = "OPEN" ] || echo "FAIL: PR #$pr state=$state"
248
+ state=$(gh pr view "$pr" --json state --jq .state)
249
+ [ "$state" = "OPEN" ] || FAILS+=("PR #$pr state=$state(非 OPEN)")
165
250
  done
166
251
 
167
- # 校验 2:PR body 含正确的 issue 关联
252
+ # 校验 2:PR body 含正确的 issue 关联(注意 $id 是真变量)
168
253
  for pr in $(echo "$result" | jq -r '.prs_pushed_this_session[].number'); do
169
- body=$(gh pr view $pr --json body --jq .body)
170
- echo "$body" | grep -qE "(Closes|Refs): #<id>" || echo "FAIL: PR #$pr 缺 issue 关联"
254
+ body=$(gh pr view "$pr" --json body --jq .body)
255
+ echo "$body" | grep -qE "(Closes|Refs): #$id\b" || FAILS+=("PR #$pr 缺 Closes/Refs: #$id 关联")
171
256
  done
172
257
 
173
258
  # 校验 3:消费侧 PR 必须有哨兵 SQL
174
259
  for pr in $(echo "$result" | jq -r '.prs_pushed_this_session[] | select(.is_consumer==true) | .number'); do
175
- body=$(gh pr view $pr --json body --jq .body)
176
- echo "$body" | grep -q "哨兵 SQL\|sentinel" || echo "FAIL: 消费侧 PR #$pr 缺哨兵证据"
260
+ body=$(gh pr view "$pr" --json body --jq .body)
261
+ echo "$body" | grep -qE "哨兵 SQL|sentinel" || FAILS+=("消费侧 PR #$pr 缺哨兵证据")
177
262
  done
178
263
 
179
- # 校验 4:PR 拓扑与 plan 一致(Track C
180
- # plan_path 文件,对比 prs_pushed + prs_pending 数量是否等于拓扑表总数
181
-
182
- # 校验 5:本地是否真的全绿——派一个轻量 subagent 跑一次 dx lint + 受影响 build
183
- # (可选,subagent 已声称跑过;抽查避免捏造)
264
+ # 校验 4:PR 拓扑与 plan 一致(仅 Track C;Track A/B 跳过)
265
+ track=$(echo "$result" | jq -r '.track')
266
+ if [ "$track" = "C" ]; then
267
+ planned=$(echo "$result" | jq -r '.total_prs_planned')
268
+ actual=$(echo "$result" | jq -r '(.prs_pushed_this_session|length) + (.prs_pending|length)')
269
+ [ "$planned" = "$actual" ] || FAILS+=("Track C 拓扑不一致:planned=$planned, pushed+pending=$actual")
270
+ fi
271
+
272
+ # 校验 5:本地全绿抽查(强制,不可跳——lint/build/test 是最易被捏造项)
273
+ # 派一个轻量 subagent 在 PR 分支跑 `dx lint` + 受影响 `dx build <target> --dev`,
274
+ # 返回每项 pass/fail。任一非 pass → FAILS+=("PR #$pr 本地复跑 <step> 未通过")
275
+ # (此步为主 agent 派发动作,非本脚本内联命令;结果回填 FAILS 后一起判定)
276
+
277
+ if [ ${#FAILS[@]} -gt 0 ]; then
278
+ printf '阶段三校验失败:\n'; printf ' - %s\n' "${FAILS[@]}" # → 3.3 失败重新派发
279
+ else
280
+ echo "阶段三校验全通过 → 进入阶段四"
281
+ fi
184
282
  ```
185
283
 
186
284
  ### 3.3 失败重新派发
@@ -245,26 +343,32 @@ done
245
343
  }
246
344
  ```
247
345
 
248
- **事实校验**(subagent 返回后):
346
+ **事实校验**(subagent 返回后;前置:`pr=<当前PR号>`、`$result` 已落地):
249
347
 
250
348
  ```bash
349
+ FAILS=()
350
+ comments=$(gh pr view "$pr" --json comments --jq '.comments[].body')
351
+
251
352
  # 校验 1:真合并
252
- merged=$(gh pr view $pr --json mergedAt --jq .mergedAt)
253
- [ "$merged" != "null" ] && [ -n "$merged" ] || echo "FAIL: PR #$pr 未真合并"
353
+ merged=$(gh pr view "$pr" --json mergedAt --jq .mergedAt)
354
+ { [ "$merged" != "null" ] && [ -n "$merged" ]; } || FAILS+=("PR #$pr 未真合并 mergedAt=$merged")
254
355
 
255
- # 校验 2:双 comment 都发了(每轮)
256
- comments=$(gh pr view $pr --json comments --jq '.comments[].body')
257
- echo "$comments" | grep -q "审核报告(第" || echo "FAIL: 缺审核报告"
258
- echo "$comments" | grep -q "修复报告(第" || echo "FAIL: 缺修复报告"
259
- echo "$comments" | grep -q "✅ 验证总结" || echo "FAIL: 缺验证总结"
356
+ # 校验 2:双 comment + 验证总结都发了
357
+ echo "$comments" | grep -q "审核报告(第" || FAILS+=("PR #$pr 缺审核报告")
358
+ echo "$comments" | grep -q "修复报告(第" || FAILS+=("PR #$pr 缺修复报告")
359
+ echo "$comments" | grep -q "✅ 验证总结" || FAILS+=("PR #$pr 缺验证总结")
260
360
 
261
361
  # 校验 3:审查轮数声明与 PR comments 实际轮数一致
262
362
  declared_rounds=$(echo "$result" | jq -r '.review_rounds')
263
363
  actual_rounds=$(echo "$comments" | grep -c "审核报告(第")
264
- [ "$declared_rounds" = "$actual_rounds" ] || echo "FAIL: 轮数不符 declared=$declared_rounds actual=$actual_rounds"
265
-
266
- # 校验 4:合并方式确认(squash + auto)
267
- # 注意:merge 后只能从 commit 历史推断;记录 PR mergedAt 即可作为通过判据
364
+ [ "$declared_rounds" = "$actual_rounds" ] || FAILS+=("PR #$pr 轮数不符 declared=$declared_rounds actual=$actual_rounds")
365
+
366
+ if [ ${#FAILS[@]} -gt 0 ]; then
367
+ printf '阶段四校验失败:\n'; printf ' - %s\n' "${FAILS[@]}" # 失败重新派发
368
+ else
369
+ echo "PR #$pr ship 校验全通过"
370
+ fi
371
+ # 合并方式(squash+auto)merge 后无法再查,以 mergedAt 非空为最终判据,不单列校验。
268
372
  ```
269
373
 
270
374
  **失败重新派发**:
@@ -286,14 +390,29 @@ actual_rounds=$(echo "$comments" | grep -c "审核报告(第")
286
390
 
287
391
  **Auto-merge 等待**:
288
392
 
289
- `gh pr merge --squash --auto` 已设但 `mergedAt` 仍为 null
393
+ `gh pr merge --squash --auto` 已设但 `mergedAt` 仍为 null。**卡死判定看 `mergeStateStatus` 状态,不靠纯墙钟时间**(大 CI 正常就可能跑很久):
290
394
 
291
395
  ```bash
292
- # 监控(建议用 Monitor 工具或 ScheduleWakeup 而不是同步轮询)
293
- gh pr view $pr --json state,mergedAt,mergeStateStatus,statusCheckRollup
294
- # Stuck > 30 min → 主 agent 介入:检查 mergeStateStatus(BLOCKED / DIRTY / UNSTABLE)
396
+ # 监控(建议用 Monitor 工具或 ScheduleWakeup,而不是同步轮询)
397
+ read -r state mss <<< "$(gh pr view "$pr" --json state,mergeStateStatus --jq '[.state,.mergeStateStatus]|@tsv')"
398
+ case "$mss" in
399
+ BLOCKED|DIRTY|BEHIND) echo "卡死:mergeStateStatus=$mss → 主 agent 立即介入 escalate";;
400
+ UNSTABLE) echo "CI 红/必需检查未过:$mss → 按 ship CI 红 重试";;
401
+ UNKNOWN|HAS_HOOKS) echo "GitHub 仍在计算 mergeability,正常等待,继续监控";;
402
+ CLEAN) echo "可合并,等待 auto-merge 触发,继续监控";;
403
+ esac
404
+ # 仅当 CLEAN/UNKNOWN 长时间不前进(如 > 30 min)才作为兜底超时 escalate。
295
405
  ```
296
406
 
407
+ | mergeStateStatus | 含义 | 动作 |
408
+ |------------------|------|------|
409
+ | `CLEAN` | 可合并,等 auto 触发 | 继续监控 |
410
+ | `UNKNOWN` / `HAS_HOOKS` | GitHub 计算中 | 继续监控 |
411
+ | `UNSTABLE` | 必需 CI 未过 | 按「ship CI 红」重试 |
412
+ | `BEHIND` | 落后 base 需更新分支 | 重试派 ship(rebase/update) |
413
+ | `DIRTY` | 有冲突 | 按「合并冲突」重试 |
414
+ | `BLOCKED` | 缺 review/签名等保护 | 立即 escalate(不可自动恢复) |
415
+
297
416
  ### 4.3 上游 merge 后回填下游
298
417
 
299
418
  若本 issue 的 `prs_pending` 中有依赖刚 merge PR 的项 → **回到阶段三**,再派一次 `feature-decide-plan-execute` subagent,prompt 注明:
@@ -313,12 +432,12 @@ plan 文档:docs/superpowers/plans/...md(已存在,按其中 PR-<k> Detail
313
432
  当前 issue 所有 PR(含 pending → pushed → merged)都 `mergedAt` 非空 → 当前 issue 完成。
314
433
 
315
434
  ```bash
316
- # 校验 issue 在 GitHub 上被自动关闭(末 PR 含 Closes: #<id>)
317
- gh issue view $id --json state --jq .state
318
- # 应为 CLOSED;若仍 OPEN → 末 PR 的 Closes: 关联可能写错,输出告警让用户检查
435
+ # 校验 issue 在 GitHub 上被自动关闭(末 PR 含 Closes: #$id);$id 是真变量
436
+ state=$(gh issue view "$id" --json state --jq .state)
437
+ [ "$state" = "CLOSED" ] || echo "告警:issue #$id 仍 $state → 末 PR 的 Closes: 关联可能写错,请用户检查"
319
438
  ```
320
439
 
321
- 进入下一 issue(回阶段二)。
440
+ issue 完结 → 通知阶段二调度器重算可派发集合(解锁依赖它的下游)。escalated issue 不做此校验,直接带 escalate 原因汇总,其下游标记为上游失败。
322
441
 
323
442
  ---
324
443
 
@@ -359,11 +478,13 @@ Batch Deliver 完成!
359
478
  1. **事实校验 gate** — subagent 自报完成不算,必须 `gh` / `git` 实际查到才推进。
360
479
  2. **重试上限 gate** — 同一 plan-execute / ship 最多 2 次重试,超限必须 escalate。
361
480
  3. **依赖串行 gate** — PR 间按 `depends_on` 拓扑串行;上游 `mergedAt` 非空才派下游。
362
- 4. **Issue 串行 gate**(默认)— 前一 issue PR 合并才开下一 issue。用户明确允许并行才并行。
481
+ 4. **Issue 并行 + 依赖串行 gate**(默认)— 无依赖 issue 在独立 worktree 并行派发;有依赖的上游先、blocked 后,上游完结才解锁下游。主 agent 自行依赖分析,不逐 issue 找用户确认。
363
482
  5. **不绕过下游 Hard Gate** — 本 skill 是编排,禁止"为赶进度跳 critic / 跳双 comment / `--admin` 合并"。失败必须重试或 escalate。
364
483
  6. **角色单一 gate** — 主 agent 只派发 + 校验 + 推进;禁止主 agent 直接 commit / push / 发 PR comment / merge。所有动作走 subagent + 下游 skill。
365
484
  7. **诊断附带 gate** — 重试派发时**必须**附带"上次失败原因 + 当前仓库状态",不允许裸重试。
366
- 8. **Auto-merge 真合并 gate** — `mergedAt` 非空才算 ship 完成;只设 `--auto` 不监控 = 未完成。
485
+ 8. **Auto-merge 真合并 gate** — `mergedAt` 非空才算 ship 完成;只设 `--auto` 不监控 = 未完成;卡死判定看 `mergeStateStatus` 而非纯墙钟时间。
486
+ 9. **自主派发 gate** — 主 agent 自行完成依赖分析与计划,**不在派 subagent 前找用户确认**;输出计划后直接派发。仅 escalation(环依赖 / 不可恢复失败 / 始终无法满足的依赖)才回报用户。
487
+ 10. **真变量 gate** — 校验脚本里 `$id` / `$pr` / `$result` 必须先赋真值,严禁保留 `<id>` / `<n>` 字面量裸跑(会产生假失败)。
367
488
 
368
489
  ---
369
490
 
@@ -389,7 +510,8 @@ Batch Deliver 完成!
389
510
  | 重试不附诊断信息让 subagent 裸跑 | Hard Gate 7:诊断 + 当前状态必备 |
390
511
  | 重试无上限死循环 | Hard Gate 2:最多 2 次 |
391
512
  | 上游 PR 未 merge 就派下游 ship | Hard Gate 3:依赖串行 |
392
- | 多 issue 并行干扰 dev DB | Hard Gate 4:默认串行 |
513
+ | 多 issue 并行互踩 branch / 文件 | Hard Gate 4:每个并行 issue 独立 worktree 隔离 |
514
+ | 无视依赖直接全并行,blocked issue 先跑 | Hard Gate 4:先依赖分析,上游先、blocked 等解锁 |
393
515
  | 主 agent 自己 `gh pr comment` 发审核 | Hard Gate 6:必须走 subagent + pr-train-ship |
394
516
  | 主 agent 自己 `gh pr merge` | 同上 |
395
517
  | 设了 `--auto` 没监控就声称完成 | Hard Gate 8:必须 mergedAt 非空 |
@@ -397,44 +519,31 @@ Batch Deliver 完成!
397
519
  | plan-execute subagent 自己直接调 pr-train-ship | subagent prompt 显式约束「禁止调用 pr-train-ship」 |
398
520
  | auto-merge stuck 仍重试 ship | 不可恢复类失败立即 escalate |
399
521
  | 末 PR 漏写 Closes: #<id> 导致 issue 不自动关 | 阶段五校验 issue.state,告警让用户检查 |
522
+ | 校验脚本保留 `<id>`/`<n>` 字面量裸跑 → 假失败 | Hard Gate 10:先赋真 shell 变量 |
523
+ | 派 subagent 前反复找用户确认拖慢批量 | Hard Gate 9:主 agent 自主决策,仅 escalation 才回报 |
524
+ | auto-merge 用 30min 墙钟判卡死,大 CI 误杀 | 看 mergeStateStatus(BLOCKED/DIRTY/UNSTABLE)|
400
525
 
401
526
  ## Tie-In With Other Skills
402
527
 
403
528
  - `feature-decide-plan-execute` — 阶段三派发的下游 skill(决策 + plan + 执行 + push + 建 PR)
404
529
  - `pr-train-ship` — 阶段四派发的下游 skill(审查 + 修复 + 合并)
405
- - `superpowers:dispatching-parallel-agents` — issue 间用户允许并行时的派发参考
530
+ - `superpowers:dispatching-parallel-agents` — issue 间默认并行派发的参考
531
+ - `using-git-worktrees` — 每个并行 issue 的独立工作树隔离
406
532
  - `Monitor` / `ScheduleWakeup` 工具 — auto-merge 等待场景用,避免同步轮询
407
533
 
408
- ## Subagent Prompt Library
409
-
410
- ### plan-execute prompt(阶段三)
411
-
412
- 完整模板见阶段 3.1。要点:
413
-
414
- - 显式声明走 `feature-decide-plan-execute` 全部 Hard Gate
415
- - 禁止调用 `pr-train-ship` / `gh pr comment` 发审核 / `gh pr merge`
416
- - 强制 JSON 返回格式(便于主 agent 解析校验)
417
-
418
- ### ship prompt(阶段四)
419
-
420
- 完整模板见阶段 4.2。要点:
421
-
422
- - 显式声明走 `pr-train-ship` 全部 Hard Gate
423
- - 作用域限定在指定 PR,禁止改其他 PR / 建新 PR / 调 `feature-decide-plan-execute`
424
- - 强制 JSON 返回格式
534
+ ## 重试 prompt 附加段(阶段 3.3 / 4.2 失败后通用)
425
535
 
426
- ### 重试 prompt 附加段(阶段 3.3 / 4.2 失败后)
536
+ 派发模板见阶段 3.1 / 4.2;重新派发时在原 prompt 后追加这段(变量用「诊断采集」的输出填实):
427
537
 
428
538
  ```
429
539
  【重试上下文】这是第 <N> 次尝试。
430
540
 
431
- 上次失败原因:
432
- - <具体 1>
433
- - <具体 2>
541
+ 上次失败原因(事实校验已确认):
542
+ - <FAILS 列表逐条>
434
543
 
435
- 当前仓库 / GitHub 真实状态(已校验):
436
- - 分支 <branch>:existed=<bool>,HEAD=<sha>
437
- - PR #<n>:state=<...>,merged=<...>,comments 已发:[...]
544
+ 当前仓库 / GitHub 真实状态:
545
+ - 分支 <branch>:HEAD=<head_sha>
546
+ - PR #<pr>:<pr_state>,comments 已发:<sent_comments>
438
547
 
439
- 请从未完成处续做,不要重启流程。不要重复已经做过的步骤。
548
+ 请从未完成处续做,不要重启流程,不要重复已经做过的步骤。
440
549
  ```