diff --git a/.claude/agents/os-dev.md b/.claude/agents/os-dev.md index 9368edacb3..50bf720c14 100644 --- a/.claude/agents/os-dev.md +++ b/.claude/agents/os-dev.md @@ -102,7 +102,6 @@ model: opus - 排队约 20 分钟无进展 ⇒ 先看这次检查能否收窄到不必持锁(收窄要申报,见干净收尾)。 - 收窄不了就停下报 `blocked` 并点名持锁者:`os-verify-lock.sh --status` 打印持锁者与队列。 - 一动不动的持锁者本身就是真发现;沉默是唯一错误答案。 - - 等锁、门禁批或任何慢步骤一律在本轮内前台阻塞,锁脚本自己会等。 ## Toolchain traps @@ -126,8 +125,8 @@ model: opus ## 本地验证范围 —— 本地只跑定向门禁,全农场归 CI - ⛔ 不把 lint workflow 的 `check:*` 全枚举本地跑:CI 会把农场跑满。本地清单如下。 -- ① 先 build 依赖闭包:`pnpm --filter '^...' build` 是新 worktree 的第一条命令。 -- 跳过它产出的失败,读起来与你的改动弄坏了 import 一模一样。 +- ① diff 触到某包才有 ①:`pnpm --filter '^...' build` 建依赖闭包;不触任何包则报告无 ①。 +- 闭包为空(`packages/spec` 无 workspace 依赖)时 ① 空跑;读 `dist/` 的门禁前先 build 本包。 - ② 受影响包自己的 `pnpm test` / `pnpm typecheck`,用 `--filter` 圈定。 - 受影响包 = 本包;import 方只在公开面变化时欠测试:spec 契约、发布的 `exports`、线上形状。 - 公开面字节不变 ⇒ 只欠本包测试与派生门禁,⛔ 不给每个 import 方补测试。 @@ -188,11 +187,12 @@ model: opus - 消费者清扫的 filter 方向是前缀:`pnpm --filter '...@objectstack/'` = 下游消费者。 - 后缀形式是上游依赖,方向相反;契约收紧永远落在下游。 - 报告里写 N 个包全绿必须说方向,否则这句话无法复核。 +- 退役键的清扫默认走退役 playbook 的 tree-scoped 缺席 pin,不为一次缺席检查重建消费者闭包。 - 跨包类型改动需要一次反向验证:贴进一个新类型会拒绝的键,确认转红,再恢复。 - 这证明你读的是重建后的 `.d.ts`,不是缓存。 -- `packages/spec`:`gen:schema` 会重写 `authorable-surface.base.json`,这是预期产物。 +- `packages/spec`:`authorable-surface.base.json` 只由 `gen:authorable-surface-base` 写,普通构建从不写。 - ⛔ 永不回退它、永不为凑某个相等手改它;作数的断言是 `check:authorable-surface` 绿。 -- `baseRev` 允许滞后,一行信息不是错误。 +- `baseRev` 允许滞后,一行信息不是错误;普通构建下该文件动了是 finding,不是产物。 - ⛔ 永不在 MERGE 态跑 `gen:schema`:HEAD 还是 merge 前的 tip,锚点会静默回滚到旧分叉点。 - 那样门禁全绿而已落地的推进被吞掉;先 commit merge 再重生成:`bash scripts/pm/os-regen-merge.sh`。 - `git worktree` 只隔离工作树与 HEAD;`.git/` 下其余一切全 worktree 共享。 @@ -292,8 +292,9 @@ model: opus - 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行。 - ⛔ 不把不买内容的密度修复当筹行拒掉;删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬 ceiling。 - 例外:派发令点名测量优先的零余量受管账本 ⇒ 落行、不动上限行、红着报实测行数。 -- `skip-changeset` 标签按仓库分流,先认清目标仓有没有这个机制;判据:不从任何包发布东西。 -- 例:`docs/adr/**` · `.claude/**` · `scripts/pm/**` · 仓根工具配置 · 私有 workspace · 注释。 +- `skip-changeset` 唯一判据:没有已发布的东西移动;已发布 = 各包 `files[]` 实际发运的内容。 +- 快速通道:`docs/adr/**` · `.claude/**` · `scripts/pm/**` · 仓根配置 · 私有包 · 注释,不发布。 +- 其余实测:构建后 grep `files[]` 所列路径找符号,带正控;符号零命中、正控命中 ⇒ 不发布。 - 本仓库:标签是真实机制,打标签是你的步骤、不是 CI 的,PR 一开出就打。 - 写入首选加法端点(REST `POST .../issues//labels`,不碰已有标签);可达性按会话探,先探后用。 - 被拒 ⇒ 走回退:MCP 读现值→并集→整组写→必做对比式读回,并申报换道。 @@ -337,14 +338,13 @@ model: opus - 两条合法出路:在轮内同步等它(资源纪律的排队条款:限时获取 ⇒ 无锁工作 ⇒ 再取)。 - 或者收窄这次检查的范围并在报告里申报:已申报的收窄是被接受的偏差,CI 跑满农场。 - PM 复核的是 CI 收敛,不是你本地的覆盖面;未申报的收窄不在此列,那是漏跑。 - - 反轮询与不停轮由同一个形状同时满足,而且只有这一个:一次前台阻塞等待。 - - 形状是 Monitor 带 until 条件,或干脆在前台把那套件跑完。 + - 唯一同时反轮询又不停轮的形状是一次前台阻塞等待:前台跑完,或 `tail --pid` 等它退出。 + - 比回合长的门禁在写报告那一刻读日志(重定向目标);未完成的记 NOT MEASURED 并写原因。 - ⛔ 不以结束一轮当反轮询解法:停轮不是合规替代,它恰是本条禁止的终点。 - 自检是机械的,不看你怎么形容这次等待:终消息只能是报告 JSON 或 `blocked` 报告。 - - 其它任何收尾文本按定义即停摆;⛔ 不指望后台 monitor 唤醒你,完成通知本身就是停轮。 + - ⛔ 永不结束回合去等 Monitor / 后台通知:结束回合即停摆,通知只送达在跑的回合。 - 结束一轮之前自检:最后一条消息是否在描述你不拥有的进程给你的唤醒? - 排队的锁、别的 agent 的 build、脱管的 watcher 都不会来;保持这一轮活着,自己收退出码。 - - 报告不违反此条:它以结果结束一轮,不是等别的东西来恢复的承诺。 ## 何时停手不写码