Skip to content

Commit c9bafab

Browse files
os-zhuangclaude
andauthored
Teach the shared-refs family rule at recipe level in os-dev.md and platform-readings (#11137)
git worktree isolates the working tree and HEAD, and nothing else under .git/ — refs (including refs/remotes/*), the stash stack, config and hooks are common to every worktree. os-dev.md now states the family rule once (folding the stash clause into it), records BASE=$(git rev-parse HEAD) at branch time in the worktree recipe, and anchors "where I started" reset/diff/log/rebase to the recorded "$BASE", never to origin/main — a shared pointer another agent's fetch advances, whose soft reset stages their merged files as yours while reporting success. platform-readings gains the measured fact row. Ceilinged files pay by in-file deletion of genuine duplicates and land exactly at their ceilings (399, 134). Claude-Session: https://claude.ai/code/session_01MsbKEG4LtERSLaDrbehM3e Co-authored-by: Claude <noreply@anthropic.com>
1 parent 208bd22 commit c9bafab

2 files changed

Lines changed: 17 additions & 13 deletions

File tree

.claude/agents/os-dev.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ JSON,所以终报消息就是 JSON 本身,别无其它。
2929

3030
1. **Worktree-first。** 任何编辑之前:
3131
`git worktree add ../<repo>-issue-<n> -b claude/issue-<n>-<slug> origin/main`,然后
32-
`cd` 进去 `pnpm install`。永不编辑共享检出(PreToolUse 钩子会拦);修复横跨姊妹仓时
32+
`cd` 进去 `pnpm install`,并在动笔前记下基点 `BASE=$(git rev-parse HEAD)`(「标准条
33+
款」家族规则的锚)。永不编辑共享检出(PreToolUse 钩子会拦);修复横跨姊妹仓时
3334
**一仓一 worktree****建好分支后的第一个动作:先把空分支
3435
推上去**(任何编辑之前 `git push -u origin <branch>`)——它既是认领评论所指分支的落地
3536
标记,又是第一分钟的写路由探针:容器凭据是不对称的,等门禁全绿才发现推不上去就太晚了。
@@ -84,14 +85,12 @@ JSON,所以终报消息就是 JSON 本身,别无其它。
8485
5. **永不按进程名杀**(`pkill -f` 能把并行 agent 的运行一起带走)。记下你启动的 PID,只
8586
对那个 PID 操作。
8687
6. **整条流水线在前台跑。** build 与 test 都是本任务的步骤:阻塞运行、读真实输出、继续。
87-
⛔ 永不把验证挂在后台 watcher 上然后停轮(禁令与两种合法终态见「干净收尾」)。唯一合
88-
法的长等待是规则 1 的锁排队——主动、在轮内(规则 7),从不是停轮的理由。
88+
⛔ 永不把验证挂在后台 watcher 上然后停轮(禁令与两种合法终态见「干净收尾」)。
8989
**平台事实(2026-08-20 实测):容器把前台命令钉在 ~10 分钟上限,超时 SIGTERM 杀掉
9090
(`exit 143`,日志常常连一个发现都没写出)。** 这不改前台纪律,它划定前台里放什么:
9191
重活走规则 1 的锁 —— 串行化之后不再与并行 build 抢 CPU,争用下顶到上限的命令轻载只要
9292
~2 分钟;仓级扫描归 CI(见「本地验证范围」);消融/变异脚本自带还原 trap(硬线在「标
93-
准条款」的 ablation 条)。一次 SIGTERM 实测正落在消融中途,把变异树留给了之后的每一
94-
次测量。
93+
准条款」的 ablation 条)。
9594
7. **排队不是停摆 —— 在轮内主动等。** 持锁的是你不拥有的进程,它的完成不会以任何方式唤
9695
醒你:⛔ 永不为「等锁」结束一轮(实测:这么做的每个 agent 都无通知地停摆,赔进一轮探
9796
活)。循环:拿到 99 就把间隔花在无锁工作上(写测试、changeset、PR 正文、包内
@@ -186,11 +185,16 @@ dispatch prompt 只携带每单增量(裁决引文、裁决 / PM-机制假设分
186185
械化:`bash scripts/pm/os-regen-merge.sh`)。姊妹陷阱:`gen:schema` 的清理会抹掉
187186
`gen:openapi` 的产物(rest 里冒出假 5xx 失败);用
188187
`pnpm --filter @objectstack/spec gen:openapi` 恢复。
189-
- **⛔ 取出修复用临时 commit 或 patch 文件——永不 `git stash`** worktree 隔离文件与
190-
HEAD,不隔离 `refs/stash`:所有 worktree 共享一个 LIFO 栈,两个 agent 同时 stash 会互换
191-
条目而 `pop` 照样报成功(机制与 hook 见 AGENTS.md)。安全替代,都在自己 worktree 内:
192-
`git commit -am wip``git reset --soft HEAD~1`;
193-
`git diff > /tmp/wip.patch && git checkout -- <paths>``git apply /tmp/wip.patch`
188+
- **家族规则:`git worktree` 只隔离工作树与 HEAD;`.git/` 下其余一切 —— refs(含
189+
`refs/remotes/*`)、stash 栈、config、hooks —— 全 worktree 共享;配方只有不点名共享态
190+
才 worktree-safe。家族同签名:操作看着本地、报成功,唯一症状是 `git status` 里出现他
191+
人文件。** ⛔ 永不 `git stash`(共享一个 LIFO 栈,两个 agent 同时 stash 互换条目;机
192+
制与 hook 见 AGENTS.md);取出修复用临时 commit 或 patch 文件,都在自己 worktree 内:
193+
`git commit -am wip``git reset --soft HEAD~1`;`git diff > /tmp/wip.patch &&
194+
git checkout -- <paths>``git apply /tmp/wip.patch`。⛔ `origin/main` 是共享指针,
195+
别的 agent 一次 fetch 就推进它:`git reset --soft origin/main` 把你分支点之后**他人
196+
已合并的文件**整批 stage 成你的(实测一次四个 agent 的合并文件,commit 前才逮住)。
197+
「我从哪开始」的 reset/diff/log/rebase 一律锚基本规则 1 记录的 `"$BASE"`
194198
- **要做反向验证(「回退修复,看诊断变化」)?先 commit 修复。** 已 commit,恢复只是
195199
`git checkout <your-branch> -- <path>`;对着未提交的编辑,
196200
`git checkout origin/main -- <path>` 不留任何恢复点 —— 工作树曾是唯一副本,而丢弃它是

.claude/skills/pm-dispatch/references/platform-readings.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
405 `Changes must be made through the merge queue`)或 rulesets API;姊妹仓不一致(objectos 2026-08-18 起有队列,hotcrm 只有 ruleset)⇒ 新仓落地约定靠实测确立,⛔ 不由缺席推断(2026-08-20 实测)。
1212
- 判「在不在合并队列」看 timeline 事件 `added_to_merge_queue`(REST
1313
`GET /repos/{owner}/{repo}/issues/{pr}/timeline`),⛔ 不看 `auto_merge` 字段 ——
14-
入队后它回落为 off,零信息量(维护者 2026-08-11 裁定)。队列分支读法
15-
(`git ls-remote --heads origin 'refs/heads/gh-readonly-queue/*'`)正命中是「已
16-
入队」的充分证据,反向推断作废 —— 队列满载时 PR 已入队而分支尚未建出。
14+
入队后它回落为 off,零信息量(维护者 2026-08-11 裁定)。队列分支(ls-remote 拼写见
15+
「零成本等价物」)正命中即已入队,缺席不作反证 —— 队列满载时分支尚未建出。
1716
- **成功序列读间隔不读事件名**:`removed_from_merge_queue`~1 秒内跟 `merged`
1817
是落地不是被踢;真被踢是其后无 `merged`、几分钟后 PR 仍 open。
1918
- 「不在 `origin/main` 上」是二义读数(在队列里等 / 没入队,处置相反)—— 落地检查
@@ -93,6 +92,7 @@
9392
更硬判据是查声明式(`^(export )?(const|type|interface) <Name>\b`)而非查提及;浅检出上的历史读数不可信
9493
(`merge-base --is-ancestor` 假「非祖先」、`rev-list --count` 截断、`branch -r --contains` 零输出)—— 先 `--deepen` 再判,或走 REST `compare`;
9594
**容器里没有 `gh`**(实测:`command -v gh` 退出 1、`/usr/bin/gh``/usr/local/bin/gh` 都不存在),于是 `gh … || echo "none"` 是个**不可证伪的否定** —— 127「命令不存在」与「grep 没命中」在输出上同值,实测五张 PR 上跑五次「无重叠文件」全部打印安心结论、一次都没检查,险些作为已核验声明进 PR 正文(与隔管道读退出码同类:仪器对两种结局回同一个值,重跑多少次都不自相矛盾)。安全拼写:先 `command -v <cmd>` 确认存在,或在 `||` 之前捕获状态;⛔ 一般规则:**任何可能不存在的命令上挂 `|| 回退` 都是不可证伪的否定**,PR / 查重类核验改走 MCP GitHub 工具或 git。
95+
- **`refs/remotes/origin/main` 全 worktree 共享,别的 agent 一次 fetch 就推进它**(worktree 只隔离工作树与 HEAD,`.git/` 下 refs、stash 栈、config、hooks 皆共享):`git reset --soft origin/main` 把你分支点之后**他人已合并的文件**整批 stage 成你的改动 —— 报成功、唯一症状是 `git status` 里的他人文件(实测一次 stage 进四个 agent 的合并文件,commit 前才逮住);「我从哪开始」的 reset/diff/log/rebase 一律锚建分支时记录的 base sha(`BASE=$(git rev-parse HEAD)`),⛔ 永不锚 `origin/main`
9696
- `rerun_failed_jobs` 复用原 run 的提交与合并 ref,不拿新 main 重算 —— 红因是基上
9797
缺一个已合修复时重跑无效,只能推提交(`git merge origin/main`);判别:修复的合并时间晚于 run 创建时间即是。
9898
- **同一 head 上轻量兄弟 workflow `success` + 重量级载体 `cancelled` 是普通取代的

0 commit comments

Comments
 (0)