Skip to content

Commit ab19075

Browse files
os-zhuangclaude
andauthored
docs(pm-dispatch): principles-only SKILL.md rewrite — lessons distilled in place, no issue-ID citations (#7936)
The PM operating protocol is rewritten to principles + state machine + lookup tables per the maintainer rulings of 2026-08-12 (「大幅简化,只需要说原则」; 「保留 issue id没有意义」). At-that-moment operational detail moves to references/ fact tables loaded on demand; references/incidents.md is deleted (git history is the archive). The outage-detection readings and cross-wall recovery timer discipline land as principles; the lost Guardrails bullet's meaning is restored (decisions belong to the maintainer / never dispatch an assigned or needs-user-decision issue); the ruled triage auto-adjudication protocol lands in the triage duty section. Gates: the line ratchet drops to 686; a new issue-ID lint (check:pm-skill-id-lint) keeps operative text citation-free, with one self-expiring legacy waiver for the os-dev definition until its own rewrite lands; the os-regen merge four-step and the pm-label vocabulary are mechanized into scripts/pm/. The frame-sync self-test fixture is adapted to the ID-free frame section. Claude-Session: https://claude.ai/code/session_01W3v2G9dvcfxkC4NsZ4JCE9 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2daafe1 commit ab19075

15 files changed

Lines changed: 1416 additions & 4119 deletions

.claude/skills/pm-dispatch/SKILL.md

Lines changed: 628 additions & 2510 deletions
Large diffs are not rendered by default.

.claude/skills/pm-dispatch/references/compile-surfaces.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# 过滤 / 谓词语义的编译面清单(references —— 按需加载)
22

3-
出处:主文件 step 5「过滤 / 谓词语义裁决」标准条款 —— 命中该条款的派发令把本清单
4-
**逐面抄进去**,PR 逐面申报。清单正文自 SKILL.md 纯搬移(#5925 item 7),维护纪律
5-
与派发前复核串在正文内,一并适用:**这张表由 PR 维护、派发前先跑复核串重验,⛔ 不凭
6-
记忆抄**
3+
出处:主文件「派发」的过滤/谓词语义标准条款 —— 命中该条款的派发令把本清单**逐面抄
4+
进去**,PR 逐面申报。维护纪律与派发前复核串在正文内,一并适用:**这张表由 PR 维护、
5+
派发前先跑复核串重验,⛔ 不凭记忆抄**
76

87
编译面清单(逐面实测 @ `main` `48f98b0`,2026-08-07):
98

@@ -15,7 +14,7 @@
1514
| 4 | service-analytics filter-normalizer | `packages/services/service-analytics/src/strategies/filter-normalizer.ts:1235`(`lowerAnalyticsWhere`) | analytics / cube 侧 |
1615
| 5 | `formula` | `packages/formula/src/matches-filter.ts:73`(`matchesFilterCondition`) | RLS 写侧 `check` 与公式求值;JS 两值语义的基准面 |
1716
| 半面 | objectql `having-filter` | `packages/objectql/src/having-filter.ts:92` / `:98`(`applyHaving` / `matchesHaving`) | 聚合****过滤。算半面是因为词表是子集,**但申报义务不打折** —— 它是**唯一没有 conformance 表覆盖的面**(`FILTER_LOGIC_CASES` 不驱动 HAVING 路径),所以漏了它连门禁都不会红 |
18-
| 冻结 | `driver-memory` / `driver-mongodb` || #5499 冻结投入:**pin-annotate,不翻转**。冻结面仍要申报,结论是「不在范围 + #5499」。现场注释见 `read-scope-sql.ts:176``having-filter.ts:41` |
17+
| 冻结 | `driver-memory` / `driver-mongodb` || 维护者 2026-08-05 投入冻结:**pin-annotate,不翻转**。冻结面仍要申报,结论是「不在范围 + 冻结指令」。现场注释见 `read-scope-sql.ts:176``having-filter.ts:41` |
1918

2019
**这张表本身由 PR 维护 —— 与域表同一纪律。** 增删一面(新驱动、新求值器、某面被合并
2120
或退役、冻结状态变化)的那个 PR 顺手改这里,不留给下一次裁决重新数。清单****过期是
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# 派发与收集运行细则(references —— 按需加载)
2+
3+
出处:主文件「派发」「收集」。原则住在主文件;本表是派发云卡、接手死 dev、处置停
4+
摆/重放/失报那一刻查阅的操作细则。⛔ 不引用 issue 编号。
5+
6+
## 云卡(`mode:cloud`)四课
7+
8+
一次性云卡用 `create_session`,⛔ 不用 create_trigger+fire(维护者 2026-08-07 拍
9+
板;trigger 流只留给定时/重复型)。
10+
11+
1. **授权面随 source,不随环境**:trigger 拉起的会话没有仓库授权(只能只读勘察);
12+
`create_session``source_url` 的会话出生即持推送授权。同时带
13+
`outcome_branch`(= 认领分支)、显式 `model`(trigger 流不可指模型)、`title`
14+
(以车道名开头,⛔ 不叫 os-dev;形如 `⚡ <车道> #<单号> <短语>`)。
15+
2. **派发词必带自驱条款**(云会话回合一结束就停摆等 poke,不写这条 dev 会停在中期
16+
汇报或提问处):⛔ 不为提问/中期汇报结束回合;开放选择按裁决与评估轴自裁记入终报
17+
open_questions;合法回合终点只有 (a) 推送完成 + 终报,或 (b) 硬阻塞详报。
18+
3. **交付通道**:dev 自开 draft PR(`Fixes #<n>`,正文含验证记录)+ 终报以 issue 评
19+
论(os-dev-report 标记)交付;未 attach 的姊妹仓够不着,跨仓跟进卡由 PM 代立。
20+
trigger 拉起的定时会话维持降级通道:推送 outcome branch + 终报走最后一条会话消
21+
息,PM 代开 draft PR。
22+
4. **云卡 draft PR 一存在,立即 `subscribe_pr_activity` —— 硬步骤**:未订阅的云卡
23+
PR 是轮询负债,订阅把感知从巡检周期缩到秒级。
24+
25+
监控与转向:`get_session` 读实时状态(IDLE + 分支未推送 = 停摆待 poke);投递消息
26+
用绑定会话的 poke 触发器(`create_trigger``persistent_session_id` +
27+
`fire_trigger` + 用后即 `delete_trigger`);巡检退为兜底心跳,每轮先核订阅已覆盖哪
28+
些面、只补盲区(会话停摆、未开 PR 的分支、姊妹仓动静)。CCR 云会话不注册跨会话消息
29+
roster —— `ListAgents` 列不到、`SendMessage` 直投 not-reachable 是设计而非故障(维
30+
护者 2026-08-11 裁定:事件驱动架构即长期方案),⛔ 不复测 roster 路径。
31+
32+
## 接手中断的 dev(worktree 接手协议)
33+
34+
先试 SendMessage 复活(从 transcript 带全部上下文恢复),resume 不可用才接手。⛔
35+
不重跑原派发词 —— 新 agent 带四条增量:
36+
37+
- worktree 已存在,⛔ 不要新建,`cd` 进去接着做(第二个 worktree 会劈开工作);
38+
- 先读全部既有提交与未提交改动,逐 hunk 决定保留或修正 —— 既不推倒重来也不盲信(死
39+
agent 从未回报,它的一切都未经验证);
40+
- 把死 agent 没跑完的验证**完整重跑**并报真实输出(中断的运行没有留下任何测试证
41+
据);
42+
- assignee、认领评论、分支**全部不动** —— 这是既有认领的延续,不是新认领;认领评论
43+
记录接手,不被替换。
44+
45+
## 停摆复位梯度
46+
47+
停摆的 subagent 永不自愈 —— 携带**任务中途状态**的完成通知本身就是停摆信号,立刻
48+
SendMessage 附执行姿态句(「前台(阻塞)同步执行全部步骤,中途不停止、不把构建/测
49+
试挂到后台等唤醒」),⛔ 不等任何静默阈值 —— 阈值是给「没有回答」的,不是给「回答说
50+
我停了」的。**每次复位比上一次更具体**(原样重发同一句话不算一次复位):① 复述执行
51+
姿态 → ② 点名下一个工具调用 + 明令禁止后台等待 → ③ 第三次停摆判 unreliable,按接手
52+
协议重派到该分支。自己挂的定时器不会唤醒自己。长验证管线的派发/接力词写明前台姿
53+
态。生产侧条款在 os-dev 定义 —— 这里是消费侧兜底,⛔ 不能写成「派发词写全了就可以不
54+
探」。
55+
56+
## 通知重放去重
57+
58+
通知可以形态完全正常、报告完整正确,而只是同一份东西的第 N 次重放(monitor 按自己
59+
的 deadline 触发)。**先算身份,再决定读不读内容**:去重三元组
60+
`(issue, 分支, PR head sha)` + 通知自报的守护对象;与已验收那份逐项相同 ⇒ 台账记
61+
「重放,首达时间 T」即结束,⛔ 不重新验收、不重读 diff、不重复 ACCEPT。⛔ 到达不读
62+
作「还活着」(活着的判据只有探针回包),不到达也不读作「已死」(判死只认三类正当依
63+
据)。对面自报守护对象是「变便宜」,不是去重的前提 —— 没自报就用三元组自己算。
64+
65+
## 直接验收兜底(报告丢失 ≠ 验收停摆)
66+
67+
同时满足 (a) draft PR 已存在且 CI 全绿、(b) 探活确认已死或 ≥2h 无任何推送、(c) 报
68+
告未达 ⇒ PM 直接按 PR 验收:逐文件核对 diff 与认领申报的文件面,对照 `origin/main`
69+
复核 PR 正文的前提声明与验证叙述,复核清单其余判据不减。顺序保护:agent 可能还活着
70+
**先探活、后翻 ready**(抢先翻会与它的收尾推送竞态)。死因可以是舰队级的(全账号
71+
断粮同杀所有在飞 dev,探活半边同时不可用)—— 此时取 (a)+(c) 照常收口,PR body 就是
72+
报告。「推分支 → 开 draft PR → 立即交报告」是保险不是效率优化,它住在 os-dev 定义
73+
的 Definition of done,派发令只带增量。
74+
75+
## 派发词构造细则
76+
77+
⛔ 默认不整段粘贴 issue 正文 —— 让 dev 自己读 GitHub 全文与全部评论(premise-first
78+
本来就要求),并**必须**要求 dev 自查正文完整性:长正文经工具读取可能被静默截断,
79+
截断风险随「自己读」转移给 dev,这条自查是风险转移的对价,不是客套。派发词只带增
80+
量:
81+
82+
- **三分区,措辞决定 dev 敢不敢证伪**:「裁决(不可重裁)」= 维护者/PM 已拍板的方
83+
向与语义 —— dev 执行,不重开;「PM 机制假设(须实测,鼓励证伪)」= PM 对代码机制
84+
的判断 —— dev 动手前验证,证伪了照实报告并按裁决意图换实现路径,⛔ 不许为了顺从假
85+
设硬做;「PM 建议的路线(可选,实测优先)」= PM 顺手给的实现选项/断言写法/排除面
86+
—— dev 有更好的就换,⛔ 不得因为「派发令写了」而照做。凡「我觉得可以这样」的一律降
87+
到第三块 —— 不分区的派发令里,机制假设穿着裁决的衣服,两个方向都是返工。
88+
- **标准非协商条款 ⛔ 不抄进派发词** —— 已一次性下沉进 `.claude/agents/os-dev.md`
89+
角色文件优先级是实测事实:派发词与角色文件冲突时角色文件胜,所以对每张卡都成立的
90+
无条件条款只能住在角色文件、错了就修那里;逐卡变量走模板占位符与三分区,⛔ 不靠派
91+
发词临时覆盖角色文件默认值。
92+
- **清单、路径、行号在派发那一刻从树上取**,⛔ 不从卡片/上次派发/记忆抄(门禁清单单
93+
班之内就会过期)。取数:`node scripts/pm/dispatch-gates.mjs <改动路径>…` 产出本卡
94+
该跑的门禁族,填进派发令;取数的是 PM 不是 dev —— dev 只跑被点名的几族,全 farm
95+
归 CI 跑一次,点名的准确性从此是 PM 独担的。卡片或分诊评论里的行级断言,转述进派
96+
发令前必须自己重验一遍。
97+
- **文件面写两句**:「预期落点是 X;若实测表明真正的生产者在别包,报备后按生产者侧
98+
修(落点与理由写进报告和 PR 正文),⛔ 不在消费者侧打补丁」—— 只写一个路径名的派
99+
发令,是要求 dev 在守约与修对之间二选一。跨包常常等于跨车道,PM 侧的对价是事后补
100+
跨座位声明。
101+
- **Same-day churn 进派发词**:派发时 `git log origin/main --oneline -20 --
102+
<paths>` 见到当天合并 ⇒ 加一行「基于合并后的代码工作,issue 引用的片段可能已变,
103+
先核对当前 main」(dev 的 worktree 从 origin/main 切出后不会自己更新)。**在飞重
104+
叠也要拦截**(churn 行只覆盖派发瞬间):每轮读 main 新落 PR 与每个在飞派发的申报
105+
文件面求交,相交立即警告四句 —— 合 main 重跑测试矩阵、读对方 diff 重划边界、只补
106+
它没覆盖的部分、被完全覆盖就停下回报 ⛔ 不硬造 diff。晚一轮 = 一次返工。
107+
- **翻转公开语义的裁决随卡带全仓 pin 清扫**,两句缺一不可:① grep 错误码/错误消息
108+
**全仓扫描**同语义 pin,一轮翻完,不要只改本包(旧立场的 pin 住在被改包之外的消费
109+
层);② 翻转后的 pin 必须继续承重 —— 断言新语义的**实质**(行数、译文、状态码),
110+
不是「旧断言已删」;真正非法形状的拒收断言**逐字保留**,被守护的面永不缩水。丢第
111+
二句,「全仓翻完」退化成「全仓删光」,绿而无值。
112+
- **条件性标准条款,命中判据才抄,不命中就省掉别硬套**:
113+
- 多实现面组件(同一契约 ≥2 个实现面)⇒ 「测试放在**未来的分叉会被抓住的地方**,
114+
进共享一致性覆盖,不是独立测试文件」;不变量形:与 `find()` 给出相同行集,或以
115+
`INVALID_FILTER` 拒收 —— 不允许有第三种、更安静的答案。
116+
- 新增/改写拒收类用例 ⇒ 「最低断言错误的 `code``status`(ADR-0112 信封);
117+
`toThrow()` / `rejects.toThrow()` 单独使用不构成拒收测试;措辞本身是契约时首句
118+
断言**加在** `code`+`status` 之上;只约束新写/改写的用例,不回填存量」。
119+
- 改过滤/谓词语义 ⇒ 把 `references/compile-surfaces.md` 的编译面清单**按其复核串
120+
重验后逐面抄进派发令**(⛔ 不凭记忆),并带:「每一面都必须在 PR 正文有一个结
121+
论:已改 / 本就合规(证据)/ 明确不在范围(理由);⛔ 静默略过 —— 评审把没提到
122+
的面读作漏掉的面」。防的不是做错,是做对了一部分然后以为做完了。
123+
- **Premise-first 写明**:issue 正文是线索不是规格,先对 origin/main 验前提;
124+
`premise_still_valid: false` + 无 PR 是合法且常常有价值的交付 —— 派发词预设
125+
issue 为真,就把好运行变成表面抗命。

0 commit comments

Comments
 (0)