@@ -107,7 +107,7 @@ protocol is identical.)
107107
108108## Operational notes(实测坑位)
109109
110- 队列与平台层的九条实测结论 。共同点:** 判据取命令的输出,不取 API 字段的字面值,
110+ 队列与平台层的十二条实测结论 。共同点:** 判据取命令的输出,不取 API 字段的字面值,
111111也不取本地工作树的现状,更不取「看起来相邻」的两行日志** —— 每一条都是在这一步上
112112咬过人之后写下来的。
113113
@@ -242,6 +242,69 @@ draft、解绑 `Fixes`,免得一个错结论继续被当作已立案的事实引
2422428 条讲过它的覆盖面)—— 两条 ** issue** 描述同一个问题,没有任何门禁能看见,
243243查重只能发生在立单前、你自己手里。
244244
245+ ** 10. 合并前认门禁 job 的结论,不认聚合读数 —— advisory 门禁红着合并会毒化全仓。**
246+ PR #5584 的新测试文件触发 ` check:engine-double-contract ` (这一族门禁挂在 ** ESLint
247+ job** 里),该 job 19:53Z 结论 ` failure ` ,而 PR 在红了 ** 19 分钟后照常过队合并** 。
248+ 合并后,` main ` 上这条红被 merge ref 带进** 每一个后续 PR 的 ESLint job** ,#5601 等
249+ 直接中招;热修 #5615 才解除,治理侧另立 #5617 。两句纪律:
250+
251+ - 合并前必须确认** 承载门禁族的 job** (本仓即 ESLint、TypeScript Type Check ——
252+ ` check:engine-double-contract ` / ` check:error-code-casing ` /
253+ ` check:route-envelope ` 等都跑在 ESLint job 内)已达 ** ` completed: success ` ** ,
254+ 而不是「暂时还没出现 failure」。step 7 的 ACCEPT 那句 * once every check on the PR
255+ is green* 要读成「每个门禁 job 的** 结论** 已出且为 success」,` in_progress `
256+ 不算数。
257+ - 「队列会把关」只对 ** required** 检查成立。一条不在 required 集里的 advisory
258+ 门禁,merge queue 的 merge_group 检查集同样看不见它 —— 它红着合并进 main 就是
259+ ** 共享损伤** ,** 任何车道发现都要立即止血 + 立单** (#5615 止血 / #5617 治理即
260+ 此形)。#5617 是本条的治理半边(required 集怎么配),与本条互补:配置面归它,
261+ 流程面归这里,两边都到位才关掉这个失效面。
262+
263+ ** 11. dev 子代理自己死了 ≠ 维护者中止 —— 不得据推断立一道谁也不敢退的门。** #5085 的
264+ dev 子代理零推送、零分支就没了(子代理正常的 ` /compact ` /中断死法,step 6 的探活与
265+ step 5「Handing off an interrupted dev」讲的就是它)。前任 PM 把它** 推断** 成
266+ 「维护者手动中止」,设了「是否重派等维护者示意」的门:该门从 08-05 07:00Z 立到
267+ 08-06 02:42Z 解除,** 近 20 小时** 压着一个 p0-邻近的真 bug,直到维护者本人确认
268+ 「没有中止」才发现是误判。两句纪律:
269+
270+ - 子代理消失(零推送 / 零分支 / 无报告)是** 子代理的正常死法** ,按 step 4 的
271+ ** stale-claim reclaim** 处理(先探活 / SendMessage 复活,复活不成再回收重派),
272+ ⛔ 不得推断为维护者意图。
273+ - 「维护者中止」只在有** 显式信号** 的记录时才成立 —— 维护者原话,或宿主明确回报
274+ 的 * stopped by the user* 。同一条 #5085 上两种都出过:08-05 07:00Z 那次是推断
275+ (误判,门压近 20 小时),08-06 04:12Z 那次是宿主信号(真中止,维护者两分钟后
276+ 示意重派、门即解除)。** 判据是信号,不是症状** :两次的症状(零推送、无分支)
277+ 完全一样。没有显式信号就当死认领回收,⛔ 不要立一道没有重启条件的门 —— 那次
278+ 的门只写在「认领解除」评论里、标签退回了 ` pm:queue ` ,于是队列视图显示可派发而
279+ 谁也不敢派,比 ` pm:on-hold ` 更隐蔽(状态机根本读不到它)。真需要 hold 就照
280+ 状态模型办:` pm:on-hold ` + 带** 重启条件** 的评论成对落地(「A hold without a
281+ restart condition is a state nobody can ever legally exit」)。
282+
283+ ** 12. 判「正文被 sanitizer 截断」必须双读取 —— 单一读法的尾部缺失先算读取端截断。**
284+ #5148 / #5149 (2026-08-05,分诊座位)与 #5164 (cli 车道 PM)被判为「正文已被 GitHub
285+ sanitizer 截断,不可分诊/派发」,据此挂起并要求原作者重贴。事后以两种读法复核 ——
286+ REST 取 ` body ` (原文 4321 / 5183 / 4181 字符)+ 取 ` body_html ` (渲染版)—— ** 三条
287+ 正文都完整** ,` <object> ` / ` <id> ` 一类占位符全部落在行内代码或围栏内、未被吞。
288+ 三条判读均不成立,真因是** 读取端(工具输出)截断** 被误读成 issue 端截断;代价是
289+ 三条 issue 各白停摆 1–2 天(#5148 是有脚本化复现的可入队缺陷,#5149 / #5164 是
290+ 应当尽早进维护者决策箱的裁决卡),外加三张打给作者的假工单。两句纪律:
291+
292+ - 判截断前必须** 双读取** ,` body_html ` 要带 full 媒体类型才拿得到:
293+
294+ ``` bash
295+ curl -s " https://api.github.com/repos/<owner>/<repo>/issues/<n>" \
296+ -H ' Accept: application/vnd.github.full+json' # .body 原文 + .body_html 渲染版
297+ ```
298+
299+ ** 两者在同一处断掉** 才算 issue 端截断;任何单一读法的尾部缺失都先假定是读取端
300+ 截断(工具输出上限、分页、` [:N] ` 切片)。这与 notes 6「零命中必须用一个确定存在
301+ 的邻近词反查」是同一条纪律的另一半 —— ** 缺失类读数在下结论前都要先证伪「扫描器
302+ 坏了」这个解释** 。
303+ - step 0 的 ** Repair first** 是** 停摆指令** ,成本由作者承担,所以它的判据必须比
304+ 其它分类更硬:误判一次的代价是一条可入队缺陷躺一天,外加一条打给作者的假工单。
305+ 已发出的重贴指令若事后证伪,** 要在同一处公开作废** (同 notes 7:诊断结论一旦
306+ 公开发出又被推翻,更正要发在同样公开的位置)。
307+
245308## Multi-repo coordination (backend / frontend / cloud)
246309
247310The product spans three repos with a fixed dependency direction:
@@ -1129,7 +1192,7 @@ attached.
11291192下面的停摆纠偏处理「带任务中状态的通知到了」;这一条处理更隐蔽的另一半:
11301193** 通知根本不来** 。宿主进程重启会把运行中的 subagent 连同其完成通知一起
11311194静默杀掉 —— 2026-08-05 实测,五个「在飞」dev 里三个(#5050 /#5515 /#5483 )
1132- 已死数小时,批次视图仍显示 5/5,实际吞吐 2/5,零信号。规程三条 :
1195+ 已死数小时,批次视图仍显示 5/5,实际吞吐 2/5,零信号。规程五条 :
11331196
11341197- 每次巡检(定时器唤醒、轮间隙)对** 每个已派发且尚无远程分支/PR** 的
11351198 dev 发一次状态询问(SendMessage,措辞「回一段简报后继续干活」,不改变
@@ -1140,6 +1203,17 @@ attached.
11401203 优先用它;resume 不可用时才走接手协议。
11411204- 判据永远取正向证据(远程分支、PR、报告、探活回包),⛔ 绝不把「还没
11421205 收到失败通知」读作「还在跑」。
1206+ - ** 定时器重挂是每次巡检的第一动作,不是最后一个** (维护者 2026-08-06
1207+ 授权)。巡检执行到一半被打断(穿插提问、事件风暴、会话中断)时,排在
1208+ 末尾的重挂会整个丢失,守夜链就此断裂 —— 2026-08-06 实测:一次漏挂让
1209+ 四连灭批静默了 ~ 100 分钟而不是探活门槛设计的 ≤45 分钟。先挂后查,链条
1210+ 对中断免疫;挂错了间隔可以在本轮末尾用 delete_trigger + 重挂修正,但
1211+ 「没挂」无法被本轮以外的任何机制补救。
1212+ - ** 批量在飞期间,主巡检间隔不得长于 45 分钟** (同一授权)。探活门槛是
1213+ 45 分钟,巡检间隔一旦超过它,门槛就成了写在纸上的数字 —— 最坏情形下
1214+ 一个派发后即死的 agent 要等到下一轮巡检才被发现,静默窗口 = 巡检间隔,
1215+ 而非门槛值。在飞清零的待命期可放宽到 60-70 分钟;有任何 dev 在飞即收紧
1216+ 回 ≤45,灭批频发期(如宿主重启风暴)进一步压到 20-30 分钟。
11431217
11441218** A stalled subagent is this half's most common failure, and it never
11451219self-heals.** When a dev stops mid-task reasoning that "a background watcher will
@@ -1206,6 +1280,12 @@ against the report's own claims:
12061280 plainly unrelated to the issue.
12071281- Test evidence in the report shows the actual commands and passing output,
12081282 not a bare "tests pass".
1283+ - ** 报告到达 ≠ CI 收敛。** arm auto-merge / 入队前** 亲核门禁 job 的结论** —— 不止
1284+ ` pull_request_read get_status ` 那个聚合读数,要看 ESLint 与 TypeScript Type Check
1285+ 这两个具体 job 的 ` conclusion ` 已为 ` success ` (门禁族都跑在它们里面,Operational
1286+ notes 10)。dev 可能在自己的 ESLint 还没出结论时就交了「本地绿」的报告 ——
1287+ #5584 的 advisory 红就是这样漏过复核、红着合并进 main 的;os-dev 定义侧已要求
1288+ 「PR 开出后等 CI 收敛再交报告」,本条是它在复核侧的对账。
12091289- The diff plausibly satisfies the issue's acceptance criteria.
12101290- ** 收益穿过它必经的那道边界之后还在吗?** 判据(不是每单都做):这批工作的价值主张
12111291 是否** 依赖某个下游组件如实转发** —— HTTP 错误信封、序列化、日志汇聚、跨进程传输。
0 commit comments