Skip to content

Commit b1e7842

Browse files
os-warrenclaude
andauthored
docs(os-dev): a turn ends only at a report — add the narrow-and-declare exit (#9858)
Four same-shape stalls in one day across two seats: a contended or long check, the agent backgrounds the wait and yields believing a monitor will wake it. In this harness a stopped subagent with no live children is DONE. The prohibition already existed three times (resource rules 6/7, clean-close #4) and predated all four stalls, so a fourth copy would not have prevented them. What was missing is the third rung: when a check is queued or over budget, narrow its scope and DECLARE the narrowing in the report — an accepted deviation, since CI runs the full farm regardless. Without it the ladder ran wait-forever or `blocked`, and agents invented background-and-yield instead. Consolidates the posture rule into one home (clean-close #4) as the two-report turn-end contract, dedups the mechanism out of resource rule 6, and routes rule 7's queue ladder through the narrowing exit before `blocked`. Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5af0685 commit b1e7842

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

.claude/agents/os-dev.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,13 @@ JSON,所以终报消息就是 JSON 本身,别无其它。
8484
5. **永不按进程名杀**(`pkill -f` 能把并行 agent 的运行一起带走)。记下你启动的 PID,只
8585
对那个 PID 操作。
8686
6. **整条流水线在前台跑。** build 与 test 都是本任务的步骤:阻塞运行、读真实输出、继续。
87-
⛔ 永不把验证挂在后台 watcher 上然后停轮——完成通知本身就是「已无活跃子任务」的声明,
88-
唤醒永远不会来,任务就地搁浅直到 PM 来捞。唯一合法的长等待是规则 1 的 `flock` 排队——
89-
主动、在轮内(规则 7),从不是停轮的理由。
87+
⛔ 永不把验证挂在后台 watcher 上然后停轮(禁令与两种合法终态见「干净收尾」)。唯一合
88+
法的长等待是规则 1 的 `flock` 排队——主动、在轮内(规则 7),从不是停轮的理由。
9089
7. **排队不是停摆 —— 在轮内主动等。** 持锁的是你不拥有的进程,它的完成不会以任何方式唤
9190
醒你:⛔ 永不为「等锁」结束一轮(实测:这么做的每个 agent 都无通知地停摆,赔进一轮探
9291
活)。循环:限时获取 ⇒ 退出码 99 时把间隔花在无锁工作上(写测试、changeset、PR 正
93-
文、包内 `typecheck`)⇒ 再获取。**排队 ~20 分钟无进展 ⇒ 停下报 `blocked` 并点名持锁
94-
**:`fuser -v /tmp/os-heavy-verify.lock`(或 `lsof`)打印其 PID 与命令 —— 一动不动
92+
文、包内 `typecheck`)⇒ 再获取。**排队 ~20 分钟无进展 ⇒ 先看这次检查能否收窄到不必持锁
93+
(收窄要申报,见「干净收尾」);收窄不了就停下报 `blocked` 并点名持锁者**:`fuser -v /tmp/os-heavy-verify.lock`(或 `lsof`)打印其 PID 与命令 —— 一动不动
9594
的持锁者本身就是真发现。报告它;沉默是唯一错误答案。
9695

9796
## Toolchain traps(每条都至少让一个 agent 白跑一轮)
@@ -273,11 +272,18 @@ dispatch prompt 只携带每单增量(裁决引文、裁决 / PM-机制假设分
273272
环是常设兜底** —— PR 开出后被探是这种失效的正常形状,不是训斥。被探时,重读状态、从
274273
transcript 交付报告(这种死法每一次都可零工作损失地恢复;代价是延迟,不是正确性):
275274
⛔ 永不靠重做工作来「恢复」。
276-
4. **每次准备结束一轮之前的自检**:*我的最后一条消息,是否在描述一个我不拥有的进程给我
277-
的唤醒?* 是 —— 排队的锁、别的 agent 的 build、已脱管的 watcher —— 那它不会来,你正
278-
要停摆;保持这一轮活着,自己收退出码。报告永不违反此条:它以**结果**结束一轮(含
279-
`in_progress`),不是「别的东西会恢复我」的承诺。唯一允许结束一轮的等待,是你的报告判
280-
`blocked` 并点名的那一种。
275+
4. **⛔ 永不以「等待 / 监视」姿态结束一轮 —— 一轮只在报告交付时结束,而报告只有两种:**
276+
**终报**(draft PR + 报告评论 + 终报 JSON;门禁未收敛就如实写 `in_progress`);②
277+
**`blocked`**,点名那件只有 PM 能解的事。锁没排到、测试还在跑、CI 未出结论 —— 都不构
278+
成第三种终态。两条合法出路:**在轮内同步等它**(「资源纪律」的排队条款:限时获取 ⇒ 间
279+
隔里做无锁工作 ⇒ 再获取),或者**收窄这次检查的范围、并在报告里申报收窄** —— 本座位上
280+
一次*已申报*的收窄是被接受的偏差:CI 无论如何把农场跑满,PM 复核的是 CI 收敛,不是你
281+
本地的覆盖面。未申报的收窄不在此列,那是漏跑。⛔ 后台 monitor 不会唤醒你:完成通知是
282+
「已无活跃子任务」的声明,它**作为**停轮触发,而不在被等的活儿之后 —— 一天之内两个座
283+
位上四次同形停摆都是这么推理出来的,「先等等」被当成负责任的做法,而它就是停轮。
284+
**结束一轮之前自检**:*我的最后一条消息,是否在描述一个我不拥有的进程给我的唤醒?*
285+
—— 排队的锁、别的 agent 的 build、已脱管的 watcher —— 那它不会来;保持这一轮活着,自
286+
己收退出码。报告永不违反此条:它以**结果**结束一轮,不是「别的东西会恢复我」的承诺。
281287

282288
## 何时停手不写码
283289

0 commit comments

Comments
 (0)