From 660e0b84b2959c905006bbc8970108b10adb91b8 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 05:30:10 +0000 Subject: [PATCH] =?UTF-8?q?docs(os-dev):=20a=20turn=20ends=20only=20at=20a?= =?UTF-8?q?=20report=20=E2=80=94=20add=20the=20narrow-and-declare=20exit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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`. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd --- .claude/agents/os-dev.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.claude/agents/os-dev.md b/.claude/agents/os-dev.md index e9e4ffe980..0fe8f69fbc 100644 --- a/.claude/agents/os-dev.md +++ b/.claude/agents/os-dev.md @@ -84,14 +84,13 @@ JSON,所以终报消息就是 JSON 本身,别无其它。 5. **永不按进程名杀**(`pkill -f` 能把并行 agent 的运行一起带走)。记下你启动的 PID,只 对那个 PID 操作。 6. **整条流水线在前台跑。** build 与 test 都是本任务的步骤:阻塞运行、读真实输出、继续。 - ⛔ 永不把验证挂在后台 watcher 上然后停轮——完成通知本身就是「已无活跃子任务」的声明, - 唤醒永远不会来,任务就地搁浅直到 PM 来捞。唯一合法的长等待是规则 1 的 `flock` 排队—— - 主动、在轮内(规则 7),从不是停轮的理由。 + ⛔ 永不把验证挂在后台 watcher 上然后停轮(禁令与两种合法终态见「干净收尾」)。唯一合 + 法的长等待是规则 1 的 `flock` 排队——主动、在轮内(规则 7),从不是停轮的理由。 7. **排队不是停摆 —— 在轮内主动等。** 持锁的是你不拥有的进程,它的完成不会以任何方式唤 醒你:⛔ 永不为「等锁」结束一轮(实测:这么做的每个 agent 都无通知地停摆,赔进一轮探 活)。循环:限时获取 ⇒ 退出码 99 时把间隔花在无锁工作上(写测试、changeset、PR 正 - 文、包内 `typecheck`)⇒ 再获取。**排队 ~20 分钟无进展 ⇒ 停下报 `blocked` 并点名持锁 - 者**:`fuser -v /tmp/os-heavy-verify.lock`(或 `lsof`)打印其 PID 与命令 —— 一动不动 + 文、包内 `typecheck`)⇒ 再获取。**排队 ~20 分钟无进展 ⇒ 先看这次检查能否收窄到不必持锁 + (收窄要申报,见「干净收尾」);收窄不了就停下报 `blocked` 并点名持锁者**:`fuser -v /tmp/os-heavy-verify.lock`(或 `lsof`)打印其 PID 与命令 —— 一动不动 的持锁者本身就是真发现。报告它;沉默是唯一错误答案。 ## Toolchain traps(每条都至少让一个 agent 白跑一轮) @@ -273,11 +272,18 @@ dispatch prompt 只携带每单增量(裁决引文、裁决 / PM-机制假设分 环是常设兜底** —— PR 开出后被探是这种失效的正常形状,不是训斥。被探时,重读状态、从 transcript 交付报告(这种死法每一次都可零工作损失地恢复;代价是延迟,不是正确性): ⛔ 永不靠重做工作来「恢复」。 -4. **每次准备结束一轮之前的自检**:*我的最后一条消息,是否在描述一个我不拥有的进程给我 - 的唤醒?* 是 —— 排队的锁、别的 agent 的 build、已脱管的 watcher —— 那它不会来,你正 - 要停摆;保持这一轮活着,自己收退出码。报告永不违反此条:它以**结果**结束一轮(含 - `in_progress`),不是「别的东西会恢复我」的承诺。唯一允许结束一轮的等待,是你的报告判 - 为 `blocked` 并点名的那一种。 +4. **⛔ 永不以「等待 / 监视」姿态结束一轮 —— 一轮只在报告交付时结束,而报告只有两种:** + ① **终报**(draft PR + 报告评论 + 终报 JSON;门禁未收敛就如实写 `in_progress`);② + **`blocked`**,点名那件只有 PM 能解的事。锁没排到、测试还在跑、CI 未出结论 —— 都不构 + 成第三种终态。两条合法出路:**在轮内同步等它**(「资源纪律」的排队条款:限时获取 ⇒ 间 + 隔里做无锁工作 ⇒ 再获取),或者**收窄这次检查的范围、并在报告里申报收窄** —— 本座位上 + 一次*已申报*的收窄是被接受的偏差:CI 无论如何把农场跑满,PM 复核的是 CI 收敛,不是你 + 本地的覆盖面。未申报的收窄不在此列,那是漏跑。⛔ 后台 monitor 不会唤醒你:完成通知是 + 「已无活跃子任务」的声明,它**作为**停轮触发,而不在被等的活儿之后 —— 一天之内两个座 + 位上四次同形停摆都是这么推理出来的,「先等等」被当成负责任的做法,而它就是停轮。 + **结束一轮之前自检**:*我的最后一条消息,是否在描述一个我不拥有的进程给我的唤醒?* 是 + —— 排队的锁、别的 agent 的 build、已脱管的 watcher —— 那它不会来;保持这一轮活着,自 + 己收退出码。报告永不违反此条:它以**结果**结束一轮,不是「别的东西会恢复我」的承诺。 ## 何时停手不写码