Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -41,12 +41,12 @@ model: opus
按 issue 隔离**:在 scratchpad 目录下建 `issue-<n>/` 子目录,所有临时文件写进去——同批
agents 共用一个 scratchpad 目录,自然命名(`pr-body.md`)会被彼此的成功回执静默覆盖;靠结构隔
离,不靠记性。
2. **issue 已由 PM 认领**(大家共享同一 GitHub 身份)。不要动 assignee;若发现与他人在途
工作重复,停下报 `blocked`。**PR 上不是你设置的状态属于另一个 actor——去问,永不去
「纠正」**:共享身份让所有人的写入都像你写的;被改写的 body 只是关于 body 的证据,不证
明别的;回退他人的操作——尤其是 ready 翻转——永远轮不到你(转回 draft 实测两向:
掉 auto-merge 与队列成员资格,或踢不掉、照样合入 —— 没有一向是好的)。把意外写进
`summary`,交给 PM 裁决
2. **assignee 归 PM**:派发原子对已把它设好(共享身份下该字段答不了「谁」,你的身份位是认
领评论里的分支);仓 CLAUDE.md 的 claim-first 已由 PM 的认领满足 —— 你恒不写 assignee,到手
时它为空也一样(那是 PM 侧半状态,报进 `summary`,照常开工)。发现与他人在途工作重复,停
下报 `blocked`。**PR 上不是你设置的状态属于另一个 actor——去问,永不去「纠正」**:共享
身份让所有人的写入都像你写的;被改写的 body 只是关于 body 的证据,不证明别的;回退他人
的操作——尤其 ready 翻转(转 draft 两向实测都坏)——永不轮到你。把意外写进 `summary`。
3. **范围 = 这张 issue,别无其它。** 顺路撞见的无关缺陷立成新的**无 assignee** issue,列进
`out_of_scope_findings` —— 永不在本 PR 里修。立单纪律:**先搜再立**(关键词 + 文件路径扫
open issues;并行 dev 看不见彼此同一小时立的卡,这一搜只能靠你)—— 通道**先探后选**:
Expand DownExpand Up@@ -332,10 +332,10 @@ dispatch prompt 只携带每单增量(裁决引文、裁决 / PM-机制假设分
签是真实机制,打标签是你的步骤、不是 CI 的,PR 一建立就打。写入首选**加法端点**(REST
`POST .../issues/<n>/labels`——不碰已有标签、无读写窗口),⚠️ 但它只在会话门开着的席位可
达(2026-08-25 实测:容器 dev 席整类 repo-scoped REST 全 403);被拒 ⇒ 走实测过的回退:MCP 读
现值→并集→整组写→**必做读回**,并申报换道——整组写会剥并发席位刚挂的标签,读回
是回退安全的全部理由。加法写同样必要不充分:实测 size-labeler 的整组 PUT 曾在 ~1 秒内抹
掉一次正确的加法写——收尾一律读回、把清单引进报告;标签消失读作被抹,**重新加
**,不是你的错。关此步骤的是读回,不是写入;⚠️ 读回验的是「写落了」,验不出「有门
现值→并集→整组写→**必做对比式读回**(diff 现集对 union(读集, 目标) —— union 有而回读
缺 = 被你的整组写剥掉的并发标签,重挂并写进报告),并申报换道。加法写同样必要不充分:
实测 size-labeler 的整组 PUT 曾在 ~1 秒内抹掉一次正确的加法写——收尾一律读回、把清单
引进报告;标签消失读作被抹,**重新加上**,不是你的错。关此步骤的是读回,不是写入;⚠️ 读回验的是「写落了」,验不出「有门
在读」——幻影门标签读回同样成功。**objectui:同名标签对象在(历史误挂铸出的),但零
workflow/脚本读它、豁免不了任何东西,pin 测试钉着这条**——那边的声明方式是空 frontmatter
的 changeset,门禁自己的判定行是权威;⛔ 永不在那边施加该标签(挂上去只是给 PR 挂一个假
Expand DownExpand Up@@ -457,14 +457,14 @@ skill 文件)。原始 NUL 让 grep 把整文件当二进制;其它控制字节
字符,就在门禁之外自扫(`grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' <files>`)。

GitHub 正文 sanitizer 是同一纪律的另一半 —— 形状、触发条件与作者纪律都归 AGENTS.md 的
「GitHub mutates body BYTES」条款(一条规则一个家;此处不再复制窄版)。署名页脚必须用
**session-URL** 形式:
「GitHub mutates body BYTES」条款(一条规则一个家;此处不再复制窄版)。署名页脚两形:

```text
_Generated by [Claude Code](https://claude.ai/code)_ ← stripped on every edit
_Generated by [Claude Code](https://claude.ai/code/session_<id>)_ ← survives both paths
_Generated by [Claude Code](https://claude.ai/code)_ ← bare:评论用;PR 正文编辑后的落形
_Generated by [Claude Code](https://claude.ai/code/session_<id>)_ ← session-URL:创建 PR 正文用
```

以裸形式收尾的正文,之后每次编辑都丢掉整个页脚;创建时的写入可能把裸形式静默改写成
session 形式 —— 那是平台行为,不是别的 agent 在编辑你的 PR,也不构成任何其它证据(基本
规则 2)。评论是另一条通路:裸形式在那里原样存活。
实测(2026-08-26,三写逐写回读):create 保 session 形,并把裸形静默改写成它(平台行为,基本
规则 2);**每次 PATCH 编辑把 session 形降回裸形,裸形其后原样存活** ⇒ session 页脚只按
create-only 对待:归属要跨正文编辑存活,把 session URL 写进正文散文或评论作耐久副本,⛔ 不
循环重贴页脚。评论是另一条通路:裸形在那里原样存活。
30 changes: 15 additions & 15 deletions .claude/skills/pm-dispatch/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,12 +136,12 @@ fire 一轮烟测,判据取**GitHub 上的产出**;③ 每 fire 一轮:读座位
闭/作废,评论带出处三件(谁的指令、原话、在哪说的)** —— 无出处的关闭与误操作在证
据上不可区分,会被兄弟席当误扫重开;同理适用于摘标签、回收认领等不可反推理由的动
作。
- **写后回读按风险定向;标签写恒为硬步骤 read-modify-write + 回读**(维护者 2026-08-18 裁定):①
先取现集 → ② 只增删目标标签 → ③ 写合并集 → ④ 写后回读核验 —— 整组 PUT 写的是
本席快照,并发席落在你读与写之间的标签被静默剥掉,受害者常是你没打算碰的那枚;**承
载闸门语义的标签**(如 `needs:contract-review`)挂与清两向同此四步,闸门被剥不是红灯是放
行,与「从未挂过」在证据上不可区分,回读是唯一察觉手段;多席可写面恒读回(防竞态覆
,不只防 sanitizer);「API 返回 200」≠「落地内容正确」。
- **写后回读按风险定向;标签写恒为硬步骤 read-modify-write + 对比式回读**(维护者 2026-08-18
裁定):① 取现集 → ② 只增删目标标签 → ③ 写合并集 → ④ 回读并 diff 对 union(现集,
目标增删) —— 读与写之间落地的并发标签被你的整组 PUT 静默剥掉,常剥你没打算碰的那
枚;union 有而回读缺 = 被剥,重挂并报告(对比只察觉、不预防);**承载闸门语义的标签**(如
`needs:contract-review`)挂与清两向同此四步,闸门被剥不是红灯是放行,与「从未挂过」在证据
上不可区分;多席可写面恒读回(防竞态覆盖,不只防 sanitizer);「API 200」≠「落地正确」。
- **PM 写进 GitHub 的文本 ⛔ 不用尖括号路径占位符**,改写成「后跟显式路径」的说法 ——
被 sanitizer 吃掉后剩下的裸命令读起来完整而其实不是(实测:一条派发令就
在「永不用裸形式」之前展示了它要禁的那条裸形式);backtick、围栏块与标题同吃,都不是
Expand DownExpand Up@@ -543,8 +543,8 @@ PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队
### 认领(先认领后动工)

同账号内的多会话共享 GitHub 身份,assignee 只回答「有 agent 认领了」,回答不了「哪个」——
认领评论承载身份(`mode:subagent` 派发下其身份位是分支,见规则 2);跨账号只需一条:assignee
不是你 ⇒ 永不碰。选中的单,派发前按序执行**一个原子对**:
认领评论承载身份;**assignee 字段归 PM**:原子对 step 1 设,dev 席恒不写它(os-dev 规则 2 同
句);跨账号只需一条:assignee 不是你 ⇒ 永不碰。选中的单,派发前按序执行**一个原子对**:

1. **Assign @me + 状态标签对调**(`pm:dispatched` 与摘 `pm:queue` 同一次标签写入 ——只摘不换留
下的在飞卡会被分诊析取每轮重付全评论读);step 1 之后获得 assignee 的直接弃出本批。
Expand DownExpand Up@@ -583,10 +583,11 @@ epic 领
数(复现命令、依赖路径、已确认的坑、在飞同文件PR、区域申报、串行约束),赢家不必重
扫。

dev 侧推分支要早 —— 远程分支是在飞工作最硬的证据。**死认领回收(stale-claim reclaim)**:认
领 >~24h、承诺分支
不存在、无 PR ⇒ 死认领 —— 评论询问,静默一窗后摘 assignee(注明原因)回队;有带提交活分
支的认领永不回收。
dev 侧早推分支 —— 远程分支是在飞工作最硬的证据。**死认领回收(stale-claim reclaim)**:认领
>~24h、承诺分支不存在、无 PR ⇒ 死认领 —— **回收前先救工作树**:派发 worktree 的未提交改
动先 WIP commit 到派发分支并 push,sha 记进回收评论、标 INCOMPLETE AND UNREVIEWED(续派者 diff
它,⛔ 不无审续建;死在编辑中途的 dev 没来得及自己 WIP 推,这一步是最后防线)—— 再评论
询问,静默一窗后摘 assignee(注明原因)回队;有带提交活分支的认领永不回收。

### 派发

Expand DownExpand Up@@ -984,9 +985,8 @@ grep <branch>`),复升级时逐条**跑**一遍,零命中/变形的就地改写

`premise_still_valid: false` + `pr: null` 是合法终报 —— 当再分诊输入复核,永不当失败派发。
`status: needs_decision` 时 `open_questions` 必须非空。`out_of_scope_findings` 应已由 dev 立成无 assignee
的卡
(查重先行、归挂判据、`finding` 标注,立在修复落地仓并带回链);PM 核验它们存在,**并把同轮
并行报告互相
的卡(查重先行、归挂判据、标签按种分 —— 观察类打 `finding`、具体缺陷不打标留分诊,与
os-dev 规则 3 同句;立在修复落地仓并带回链);PM 核验它们存在,**并把同轮并行报告互相
对读** —— 两个 dev 同一小时审相邻代码会立出孪生卡,只有 PM 同时看得见两份报告。

## 机械守卫索引(原则在此,细节以脚本头为权威)
Expand Down
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -476,11 +476,11 @@ _Generated by [Claude Code](https://claude.ai/code)_ ← bare: u
_Generated by [Claude Code](https://claude.ai/code/session_<id>)_ ← session-URL: use in PR BODIES
```

**PR body:** bare loses the **whole** footer, `---` included, on every `update_pull_request` edit;
session-URL survives both write paths, and `create_pull_request` *rewrites* bare into it — how a body
comes back in a shape nobody typed. An edit also **APPENDS a fresh platform bare footer** under yours,
and the next edit strips that one and appends another — the floor is your session-URL footer plus one
platform bare, so ⛔ don't loop trying to normalize it. **Issue comment:** the platform APPENDS a bare
**PR body:** `create_pull_request` keeps the session-URL form and *rewrites* bare into it — how a body
comes back in a shape nobody typed. On EDIT the promise inverts (measured 2026-08-26, three REST
writes, per-write read-back): every `update_pull_request`/PATCH edit normalises the session-URL footer
DOWN to bare, and that bare survives later edits verbatim. Treat the session id as create-only (⛔ no
re-append loop); durable attribution lives in body prose or a comment. **Issue comment:** the platform APPENDS a bare
footer to every one (measured 2026-08-20 — MCP `add_issue_comment` and direct REST agree: per-surface,
not per-tool). It is idempotent if yours is already bare; if yours is the session-URL form *it survives
verbatim* and a bare one lands under it, leaving two. ⛔ A tail bare footer on a comment is the
Expand Down
Loading