@@ -1820,9 +1820,10 @@ attached.
18201820静默杀掉 —— 2026-08-05 实测,五个「在飞」dev 里三个(#5050 /#5515 /#5483 )
18211821已死数小时,批次视图仍显示 5/5,实际吞吐 2/5,零信号。规程五条:
18221822
1823- - 每次巡检(定时器唤醒、轮间隙)对** 每个已派发且尚无远程分支/PR ** 的
1823+ - 每次巡检(定时器唤醒、轮间隙)对** 每个已派发且报告未达 ** 的
18241824 dev 发一次状态询问(SendMessage,措辞「回一段简报后继续干活」,不改变
1825- 任务);派发后 ~ 45 分钟无任何远程产出即到探活门槛。
1825+ 任务);派发后 ~ 45 分钟无任何远程产出即到探活门槛。⛔ 已有远程分支/PR
1826+ 不豁免 —— 触发面为什么这么宽,见下面「探活是常设兜底」。
18261827- 两种回包都有价值:活着 → 拿到进度与阻塞点;** 「no active task; resumed
18271828 from transcript」→ agent 生前已死,这次询问本身就是复活** —— 从其
18281829 transcript 带全部上下文恢复,比 worktree 接手协议(step 5)便宜得多,
@@ -1845,6 +1846,29 @@ attached.
18451846 而非门槛值。在飞清零的待命期可放宽到 60-70 分钟;有任何 dev 在飞即收紧
18461847 回 ≤45,灭批频发期(如宿主重启风暴)进一步压到 20-30 分钟。
18471848
1849+ ** 探活是常设兜底,不是异常通道 —— 而「PR 已经开出来了」不是豁免,那恰恰是失败
1850+ 发生的那一格。** 上面第一条的触发面曾挂在「已派发且** 尚无** 远程分支/PR」上;
1851+ 2026-08-08 的实测把那个口径证伪了:当天 ** 7 / 7** 个派发都是** 在开出正确的 PR
1852+ 之后** 没能干净交回(#6586 / #6747 )。失败的那一批** 全都有远程分支、有 PR、有提交**
1853+ —— 按旧口径,它们一个也不会被探到。所以触发判据是现在这个写法:** 探的是「报告
1854+ 未达」,不是「分支未出现」** ;远程产出只把一个 dev 从「可能还没开始」挪到「可能死在
1855+ 收尾上」,它从来不是活着的证据(这就是上面第三条「判据永远取正向证据」里,PR 的存在
1856+ 算哪一种正向证据的答案:它证明工作发生过,不证明 agent 还在)。
1857+
1858+ - ** 生产侧的条款不能替代它。** 那批里有 4 个的派发词逐字带着终止条款,其中 ** 3 个
1859+ 照样死了** (3/4)。成因在文档够不着的地方,所以兜底必须常设在消费侧,⛔ 不能写成
1860+ 「派发词写全了就可以不探」。
1861+ - ** 代价是延迟,不是正确性 —— 这既是它便宜的原因,也是回应只能是探针的原因。**
1862+ 至今每一例都能从 transcript 完整复活,** 零工作丢失** : PR 在、分支在、提交在,缺的
1863+ 只有那段 JSON。所以 ⛔ 永远不要拿「重新派发」回应它 —— 往一个** 可能还活着** 的
1864+ worktree 里塞第二个 agent,是用一个只花时间的问题去换一个会毁东西的问题
1865+ (step 5「Handing off an interrupted dev」的碰撞面)。先探,拿到「no active task;
1866+ resumed from transcript」这类回包再谈恢复。
1867+ - 与判死门槛的关系一字不变:本条只把** 探针** 的适用面铺满,⛔ 不降低判死的三类正当
1868+ 依据(见下一段)。已有 PR 的那一格尤其要守住这个分界 —— PR 全绿会让人很想直接跳到
1869+ 「报告丢失 ≠ 验收停摆」那条兜底验收,而那条的三个条件里第二条正是** 探活确认已死或
1870+ ≥2h 无推送** ,不是「PR 看着能收了」。
1871+
18481872** 45 分钟是发探针的门槛,⛔ 不是判死的门槛 —— 两者必须分开。** 上面五条回答
18491873「什么时候去问」;这一条回答 PM 真正面对的另一个问题:「多久之后我才可以下
18501874『它死了』的结论」。分开的理由是** 后果不同** —— 探针的代价是一次 SendMessage,
@@ -1903,6 +1927,30 @@ resource discipline — fixing it at the producer beats patching it at the PM
19031927(Prime Directive #12 's instinct, applied to agent protocol); these three are the
19041928backstop, not the primary fix.
19051929
1930+ ** 通知到达 ≠ 有新东西发生 —— 第一眼读它是谁,不是读它带的 JSON。** 上一条处理
1931+ 「通知带着任务中状态」;这一条处理另一半:通知** 形态完全正常** 、报告** 完整且正确** ,
1932+ 而它只是同一份东西的第 N 次重放。#5330 一张卡发出 ** 6** 条通知,其中 ** 5 条是同一份
1933+ 完整 JSON 报告的重放** (PR #6703 ;有一条来自一个盯着 agent 自己早已 ` TaskStop ` 掉的
1934+ 运行的 monitor)。它们在到达那一刻与真完成** 完全同形** —— 同结构、同载荷 —— 于是每
1935+ 一条都被从头验收了一遍才发现是重复。** 这个成本按到达次数计,由读的人付** : N 条通知
1936+ = N 次全套复核,除非第一眼读的是身份而不是内容。PM 侧的处置:
1937+
1938+ - ** 先算身份,再决定读不读内容。** 去重三元组:` (issue, 分支, PR head sha) ` + 通知
1939+ ** 自报** 的守护对象。与本轮已验收过的那份逐项相同 ⇒ 在轮次台账上记一行「重放,
1940+ 首达时间 T」就结束,⛔ 不重新验收、⛔ 不重读 diff、⛔ 不重复留 ACCEPT 评论(重复的
1941+ ACCEPT 评论会把审计线变成两条互相印证的假象)。
1942+ - ⛔ ** 不把它的到达读成「还活着」。** 重放来自一个按** 自己的 deadline** 触发的
1943+ monitor,与它的主体是否还在跑无关 —— #5330 那条守的正是一个已被取消的运行。活着
1944+ 的判据只有一个:探针回包。
1945+ - ⛔ ** 也不把它的不到达读成「已经死了」。** 这是同一枚硬币的另一面,与上面「绝不把
1946+ 『还没收到失败通知』读作『还在跑』」同源:重放一多,「最近有动静」这种读数就彻底
1947+ 失效,两个方向都不能再从通知节奏里读出状态。判死照旧只认那三类正当依据。
1948+ - ** 生产侧的自报是「变便宜」,不是前提。** dev 侧的对账写在
1949+ ` .claude/agents/os-dev.md ` 的终止契约里(#6586 ): monitor 若仍触发,首行先自报它守
1950+ 的是什么、那东西还活不活着,再给 JSON。⛔ 但不要把去重建立在「对面会自报」上 ——
1951+ 同一批实测里,逐字携带终止条款的 4 个派发死了 3 个,携带率打不穿的成因同样打不穿
1952+ 这条。对面自报了就省一步,没自报就用上面那个三元组自己算。
1953+
19061954** Cloud mode:** there is no direct return channel — collect through GitHub.
19071955Arm a ` send_later ` check-in (~ 15 min); on each wake, sweep the dispatched
19081956issues for ` <!-- os-dev-report --> ` comments and linked PRs, then re-arm
@@ -2042,8 +2090,9 @@ Verdict per issue:
20422090
20432091- ** ACCEPT** — comment on the issue (English) linking the PR and summarizing
20442092 what shipped. Then drive it to landing (maintainer policy: review passed +
2045- CI green ⇒ merge): once every check on the PR is green, mark it ready for
2046- review and ** add it to the merge queue** — the queue rebuilds the PR
2093+ CI green ⇒ merge): once every check on the PR is green, ** 先按下面那段读一次
2094+ PR 的路径面** (⛔ 碰 ADR 的 PR 在这里就到头了,不走这条路);路径面干净,才
2095+ mark it ready for review and ** add it to the merge queue** — the queue rebuilds the PR
20472096 against current ` main ` and lands it only if that result is green, which is
20482097 the repo's sanctioned path. Never ` --auto ` -merge outside the queue; where
20492098 no queue exists, merge serially per AGENTS.md §7 only after remote CI is
@@ -2052,6 +2101,30 @@ Verdict per issue:
20522101 Guardrails:维护者明示授权的 ` .claude/ ` 工具 PR,授权引用于 PR 正文 +
20532102 walkthrough 复核,不得自审自合)。
20542103
2104+ ** ⛔ ACCEPT 在动手之前先按路径分叉 —— 碰 ADR 的 PR,终局动作不是入队。**
2105+ 上一段那条一般规则** 没有错,而正是它正确执行的结果触发了被禁止的动作** ——
2106+ #6732 不是谁「决定要合 ADR」,是 ACCEPT 照章办事,把一份已复核、全绿的 dev PR
2107+ 推进了合并队列。所以这个判据必须落在** 手动之前** ,而不是只写在 Guardrails 里
2108+ 等人事后对照:一个先读 Guardrails、再读 ACCEPT 的 PM,做的是 ACCEPT 说的事,
2109+ 因为手在这里。维护者裁决原文见 Guardrails 那条(引用、未翻译)。
2110+
2111+ 翻 ready / 挂 auto-merge / 入队之前,先取一次 PR 的路径面
2112+ (` pull_request_read ` 的 ` get_files ` ,⛔ 不看报告的自述)。** 只要路径面里有一条
2113+ 命中** ` docs/adr/** ` ,ACCEPT 换一套终局状态,三件缺一不可:
2114+
2115+ 1 . ** 复核结论照常写在 issue 上** —— 不能合不等于不复核,ACCEPT 的复核部分一字
2116+ 不减;
2117+ 2 . ** PR 留给维护者** —— ⛔ 不合并、⛔ 不入队、⛔ 不挂 auto-merge。ready 或 draft
2118+ 都行,判据是** 它必须看得见地悬着** ,不是被悄悄停在一边;
2119+ 3 . ** 轮次报告里单列一行「awaiting a human merge」** —— 这是它不会烂成静默积压
2120+ 的唯一读数:在 GitHub 上,「等着人来合」与「被忘了」长得一模一样,区别只存在
2121+ 于有没有人每轮把它念一遍。
2122+
2123+ 混合 diff(既动 ` docs/adr/** ` 也动别的)走同一分叉 —— ** 一条命中就够** ,⛔ 不按
2124+ 比例判、⛔ 不用「主要改的是别的」放行;要拆就让 dev 把 ADR 那部分单独开一个 PR。
2125+ 已经入队之后才读到这一条?撤回动作见 Guardrails 那条的 ⚠️:** 只有转 draft 才真
2126+ 的踢出队列** ,` disable_pr_auto_merge ` 单独调用不解除成员资格。
2127+
20552128 ** ` Fixes ` 还是 ` Part of ` 是 PM 的判断,而且必须在入队之前核。** dev 的默认模板
20562129 写的是 ` Fixes ` ;当这一单只落地了** 可实施的那一半** (另一半 ` needs_decision ` 还在
20572130 维护者决策箱里,或按范围被有意排除),PR 首行必须是 ** ` Part of #N ` ** —— 否则合并
@@ -2466,6 +2539,29 @@ Stop the loop and report when any of these hits:
24662539 rc.4 —— release.yml 的 on-push 自动通道在无人指令下完整发出了 rc.4
24672540 (#6169 /#6170 );机械通道的存在不构成授权 —— 读到这条的座位遇到那类通道,
24682541 当缺陷上报,不当工具使用。
2542+ - ** ADR 由维护者确认、由维护者人工合并(维护者 2026-08-08 拍板,#6741 )。**
2543+ 原文引用、未翻译:
2544+
2545+ > ** adr 只能由维护者自己确认,人工合并,ai 不得擅自合并。**
2546+
2547+ 任何 AI 座位(PM / dev / Routine / 队列管家)对一个** 改动了** ` docs/adr/** `
2548+ ** 的 PR** ,⛔ 不得执行以下任一动作:合并、加入合并队列、调
2549+ ` enable_pr_auto_merge ` 。起草
2550+ ADR、推分支、开 PR 都可以;** 确认它、让它落地,是维护者亲手的动作** 。
2551+ ** 「已复核 + 已批准 + 全绿」不构成例外** —— 本条与上面那条版本发布同形:一类
2552+ 改动的落地是人的行为,绿灯只说明机器没意见。为什么偏偏是 ADR:按 AGENTS.md
2553+ PD #13 ,accepted ADR ** 就是** 那个决定本身,合并它等于采纳一个治理立场 ——
2554+ 正好是「CI 绿」零信息量的那一类。worked example ** #6668 ** :一份彻底、全绿、
2555+ 测量无误的 ADR 草案,维护者以** 没人要这个能力** 为由关掉,那是任何门禁都评不
2556+ 出来的判据;反方向的代价见 #6191 / #6483 (一次没有 ADR 的 ADR 级反转,至今
2557+ 还在拆)。PM 侧的终局动作见 step 7 ACCEPT 里的路径分叉 —— 那一段才是手真正
2558+ 会动的地方。本条的仓级权威落点按 #6741 要求 1 是 AGENTS.md(PD #13 旁;截至
2559+ 本条写入时那一半尚未落地,落地后照本节末行的既有优先序以 AGENTS.md 为准,
2560+ 这里是 PM 循环侧的执行拷贝)。
2561+ ⚠️ ** 撤回机制,反着记会以为自己合规了:已入队的 PR 只有转回 draft 才真的被
2562+ 踢出队列** ,` disable_pr_auto_merge ` 单独调用** 不解除队列成员资格** ,PR 照样
2563+ 落地。实测 #6732 :13:47Z 挂上 auto-merge 并入队,读到本条后当场反转 ——
2564+ disable ** 加转 draft** ,再以远程读数确认它已离队且不在 ` origin/main ` 上。
24692565- Never force-push, never push ` main ` , never reassign an issue claimed by
24702566 someone else, never dispatch a ` needs-user-decision ` issue.
24712567- Every dev agent works in its ** own worktree per repo** (enforced by
0 commit comments