diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index fe06169573..76e9a0ab64 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -75,7 +75,7 @@ references);② 创建后手动 fire 一轮烟测,判据取**GitHub 上的产出 | `pm:dispatched` | 已派发(派发评论记轮次);与摘 `pm:queue` **同一次标签写入**成对落地 | | `needs-user-decision` | 决定**待做** —— 永不派发、除已裁代裁通道外永不代答;维护者的收件箱 | | `pm:on-hold` | 决定**已做**且答案是「不是现在」—— 不派发也不催;**仅当正文带机器可读行 `Restart-when: closed #N`(由 `Blocked-by:` 的同一遍解锁扫描点火、同一正文单通道)或 `Restart-when: <一行可执行判据>` 时才合法**;hold 评论带日期、理由、出处(维护者裁或座位定级,⛔ 不设第二个标签区分);**放行双查(两查皆机械、零判断)**:① 只对**最近一次** `pm:on-hold`/`pm:blocked` 转换评论所载条件放行,⛔ 永不对线程里更早的 blocker —— 已放行过的条件是花掉的,再点火就把过期前提立成现行;② 该转换评论之后卡上有**更新的 merged PR** ⇒ 拒绝放行 —— 那是条件写下后卡已前进的信号(引用的事实可以为真而不再是现行条件) | -| `pm:blocked` + 正文行 `Blocked-by: #N` | 等上游 —— 选择期跳过,#N 关闭时由解锁扫描放回 | +| `pm:blocked` + 正文行 `Blocked-by: #N` | 等上游 —— 选择期跳过,#N 关闭时由解锁扫描放回。**工已完、PR 被外部门禁缺陷卡住的卡同用本态,⛔ 不设新标签**:`Blocked-by:` 指向门禁缺陷卡,正文另加机器可读行 `Unlock-action: re-check PR #M` —— 解锁扫描读到它就把解锁动作从「回队重派」换成「重查该 PR 的落地」(回队前提检查见到已完工的 open PR 即按落地工作处理,⛔ 永不给完工卡重派 dev);停放的 PR 正文必须点名门禁卡,让链路从任一端可读、不依赖会被整篇改写的座位贴 | | `pm:blocking` | 有 open 下游依赖者(分诊 sweep 自 `Blocked-by:` 索引推导的缓存,⛔ 不手工挂);进选择优先级全序 | | `finding` | 观察类记录,恒 = **待首次定级**(定级即离标:晋级换 `pm:queue` / 关闭 / hold 换 `pm:on-hold`;裸标签数即健康读数)—— 不占队列不进收件箱 | | `target:` | 发版阻塞 —— 每个 backlog 恰好一个生产者,见「发版板」 | @@ -112,8 +112,8 @@ references);② 创建后手动 fire 一轮烟测,判据取**GitHub 上的产出 ## 平台读数纪律 统一原则:**判据取命令的输出,不取 API 字段的字面值、不取本地工作树现状、不取「看起来相邻」的 -日志。** GitHub API / 工具行为的实测事实表(队列成员资格与 auto-merge、API 配额、读数陷阱、截 -断双读取、容器重启三态)在`references/platform-readings.md`,做对应操作的那一刻查阅。常驻原则: +日志。** GitHub API / 工具行为的实测事实表在 `references/platform-readings.md`(条目清单即其文内 +标题),做对应操作的那一刻查阅。常驻原则: - **核验 main 用 `origin/main`**(先 fetch,再 `git grep origin/main -- ` / `git show origin/main:`),⛔ 不用共享检出的工作树 —— 它的 HEAD由别的 agent 摆布。 @@ -135,8 +135,6 @@ references);② 创建后手动 fire 一轮烟测,判据取**GitHub 上的产出 证据的零实现停手是好产出,不当返工计)。**裁决明令的动作实施中测出对向事实** ⇒ 照裁决字面执 行、被打断行为的 pin 反转为拒绝 pin(不是删除)、⛔ 同 PR 不做任何 promote/回退、冲突立 成 `needs-user-decision` 卡、该 PR 不挂 auto-merge 留异议窗口。 -- **spec 改动的 fixture triage 必须跑消费包测试**(A 包的改动可让 B 包的 fixture 反着断言 - ,spec 范围内任何 sweep 都看不见)—— 动契约面的派发令点名消费包测试清单,报告要有各消费包真实读数。 ## 多仓协调(五条规则) @@ -173,8 +171,13 @@ changeset 流、无 `packages/`;合并队列 + required `build` + `merge_group` 5. **一块板,不设第二跟踪器(one board, no second tracker)。** pm 标签就是状态机;org Project 只是维护者的聚合视图,权威层坚持 issue 正文 + REST。 **跨座位转移**:工作跨座位线,PM 永不跨(唯一豁免:简单阻塞项直接接手,见「候选与批次」)—— 落到 -对方队列(目标仓立单带 `pm:queue` +出处行),依赖走 `Blocked-by:`;后续杂事由消费侧座位立;凡触 -`packages/spec` 一律转`domain:spec` 座位(唯一所有者),不论谁需要它。 +对方队列(目标仓立单带 `pm:queue` + 出处行 + 一行可执行判据),依赖走 `Blocked-by:`;后续杂事由消 +费侧座位立;凡触 `packages/spec` 一律转 `domain:spec` 座位(唯一所有者),不论谁需要它。**任何跨座 +位请求都是工作,同判**(要一次读数、要对方开卡的义务、要访问/授权):一律立卡进目标车道队列,⛔ 座 +位贴敲门或裁决评论永不作唯一载体(评论是加速器不是记录 —— 散文对候选查询、sweep、老化告警全不可 +见);等待方**同一笔**把自卡翻 `pm:blocked` + `Blocked-by:` 指向请求卡(队列标签对卡住的卡说「可派 +发」就是撒谎;落进词表的等待自动享有既有解锁扫描与老化机械,⛔ 不设新标签新 sweep);目标仓不可达 +时按缝卡规则落 objectstack 带 `repo:*` + 具名读者(顺带解掉请求方无目标仓写权限的失败)。 ## 域车道(Domain lanes,同仓多 PM 并发) @@ -185,29 +188,17 @@ changeset 流、无 `packages/`;合并队列 + required `build` + `merge_group` | 标签 | 包家族 | |:--|:--| -| `domain:engine-core` | `packages/objectql`、`packages/core`、`packages/formula`(CEL / `matches-filter` / RLS 谓词求值)、`plugin-pinyin-search`(落点在编译/查询核心) | -| `domain:metadata` | `packages/metadata*`(加载、注册、持久化、缓存、目录)、`packages/platform-objects` | -| `domain:drivers` | `packages/drivers/driver-*`(维护者 2026-08-05 对 `driver-memory` / `driver-mongodb` 族有投入冻结指令;`formula` / `driver-sql` 不受影响) | -| `domain:services` | `packages/services/*`、`packages/connectors/*`、`packages/triggers/*`、`plugin-approvals`、`plugin-webhooks`、`plugin-email`、`plugin-reports`、`embedder-openai`、`knowledge-*` | -| `domain:identity` | `plugin-auth`、`plugin-security`、`plugin-sharing`、`plugin-audit` | +| `domain:engine` | `packages/objectql`、`packages/core`、`packages/formula`(CEL / `matches-filter` / RLS 谓词求值)、`plugin-pinyin-search`(落点在编译/查询核心);`packages/metadata*`(加载、注册、持久化、缓存、目录)、`packages/platform-objects`;`packages/drivers/driver-*`(维护者 2026-08-05 对 `driver-memory` / `driver-mongodb` 族有投入冻结指令;`formula` / `driver-sql` 不受影响)—— 车道合并(维护者 2026-08-19:「engine-core + metadata + drivers -> engine, identity + services → services 怎么样?」),原 `domain:engine-core` / `domain:metadata` / `domain:drivers` 三标签**退役**(只退出流通;GitHub 标签对象保留 —— 删标签会剥光已关卡、毁掉存档,止住流通的是本表) | +| `domain:services` | `packages/services/*`、`packages/connectors/*`、`packages/triggers/*`、`plugin-approvals`、`plugin-webhooks`、`plugin-email`、`plugin-reports`、`embedder-openai`、`knowledge-*`;`plugin-auth`、`plugin-security`、`plugin-sharing`、`plugin-audit`(2026-08-19 并入,原 `domain:identity` 标签**退役**,同上只退流通不删对象) | | `domain:devx` | `packages/lint`、`packages/sdui-parser`、`content/docs/**`、`apps/docs`、`scripts/`(门禁类;与 `domain:skills` 的分界按门禁的 SUBJECT:治理 agent 指令面/governed 面的归 skills,治理代码/文档质量的归本域)—— 与 `domain:spec` 相交的三面按「是否围着 spec 契约转」切分 | | `domain:skills` | 两个技能根:`.claude/skills/**`(含本文件)+ `skills/**`(维护者 2026-08-11 裁定单设座位,与维护者走专题讨论;skills 更新 ADR-class,见 Guardrails);指令架构文件:根 `AGENTS.md` + 根 `CLAUDE.md`(所有面向 agent 的宪法文本);governed 面(统一定义见 ACCEPT 路径分叉)的治理执行文件:`.github/CODEOWNERS`(治理路由半边)+ SUBJECT 是 governed 面本身的门禁/审计(现为 `scripts/pm/check-governed-merges.mjs`,一句话见守卫索引;未来同类同判)—— 维护者 2026-08-18 裁决:「skills 相关的应该都归你管,为什么派给了 devx」 | -| `domain:spec` | `packages/spec` 整包唯一契约,语义/文本/机器三面同席:schema 形状、`contracts/**`、退役行为半边、strictness 台账;describe/JSDoc/墓碑散文/错误 guidance 与 alias 表;`packages/spec/scripts/**`、`packages/spec/docs/**` 及围着 spec 契约转的工具链(门禁/生成器/lint 规则/报错散文/references 管线)—— 一般开发工具面留 `devx`(维护者 2026-08-09 裁决);席内分派判据见下文「spec 席内分派参考」 | +| `domain:spec` | `packages/spec` 整包唯一契约,语义/文本/机器三面同席:schema 形状、`contracts/**`、退役行为半边、strictness 台账;describe/JSDoc/墓碑散文/错误 guidance 与 alias 表;`packages/spec/scripts/**`、`packages/spec/docs/**` 及围着 spec 契约转的工具链(门禁/生成器/lint 规则/报错散文/references 管线)—— 一般开发工具面留 `devx`(维护者 2026-08-09 裁决);席内分派判据见 `references/lanes/spec.md` | | `domain:cli` | `packages/cli`、`runtime`、`verify`、`qa`、`types`、`packages/rest`、`packages/mcp`、`packages/observability`、`packages/client*`、`cloud-connection`、`create-objectstack`、`packages/adapters/*`、`plugin-hono-server`、`plugin-dev` | | (无固定归属,按落点分诊) | `packages/apps/*`、`packages/console`(dist 由脚本生成 ⛔ 手改;UI 缺陷走 `repo:objectui`,pin/刷新脚本归 `scripts/` 行)、`examples/*`(归它演练的子系统) | 表未覆盖的包在首次分诊时归类并**走 PR 更新本表**;**新增或退役一个 `domain:*` 必须同批改本表**(在流 通而不在表 = 无主车道)。座位在编情况以 `label:pm:seat` 索引为准,每个 `domain:*` 与 `repo:*` 恰一张座位贴。 -**spec 席内分派参考**(维护者 2026-08-16 裁定合并车道:原 `domain:spec-surface` / `domain:spec-tooling` 标签已退役, -三面同归 `domain:spec` 一席,锚定规则双射恢复;以下判据降为席内分派与定价依据):语义/文本按 -「合法元数据集合变没变」分 —— 改动前能过校验的输入,改动后逐字节同判 ⇒ 文本面(changeset 恒 patch, -默认 sweep-first),否则语义面;**任何改变接受/拒绝行为的卡,不论多小,按语义面处理**。机器面改 -「围着契约转的机器」,与文本面无交集,⛔ 不碰 `packages/spec/src/**/*.zod.ts` 与 strictness 台账。 -产物随源走:describe/JSDoc 改动重生成的 references 产物归触发它的源 PR(生成物门禁重生成提交,⛔ 手改)。 -`metadata` 自 `engine-core` 的二次切分按包边界(无例外);改元数据**格式/接受面**的照旧归 `domain:spec`, -`/meta` 路由本体在 `packages/rest` 归 `domain:cli`;拿不准 FLAG 回分诊。 - **单一生产者。** `domain:*` 只由分诊座位产出;打标签 ≠ 认领;**未打标签的 issue 任何人不得认领 ** —— 那意味着分诊还没走到,不是「可以自己判一下」。 @@ -222,17 +213,20 @@ changeset 流、无 `packages/`;合并队列 + required `build` + `merge_group` ## 座位贴协议(一座位一贴,单写手) 多写手共编一个 body 机制上防不住互吞(维护者 2026-08-06 拍板):**贴 = 座位**(标签 `pm:seat`), -正文固定六段现值、**只由在任座位 PM 编辑**、正文为权威,标题与 assignee 是派生视图、三者同笔更 -新;接管/移交 = 改正文 + 审计评论(**评论只作审计不承载状态**),接管压缩是标准步骤。**写侧刷新 -点 = 轮次边界**(派发、收班、暂停/交接前),中途状态由卡上 claim/ACCEPT 评论承载(本就是 state -of record)。**读侧闭环(维护者 2026-08-12 批准):接管与巡检只读贴正文 + 晚于正文最后编辑的评 -论** —— 更早的已被吸收,是存档不是现状。**热文件串行队是正文具名段**(区域写不清就只能整文件串 -行)。无心跳,活性惰性判定;竞态三招 —— 动手前重 fetch 正文、审计评论时间戳先到先得、写后回读。**换班报告默 +正文固定**四段**现值(当前 PM / 继承台账 / 热文件串行队 / 说明)、**只由在任座位 PM 编辑**、正文为 +权威,标题与 assignee 是派生视图、三者同笔更新;接管/移交 = 改正文 + 审计评论(**评论只作审计不承 +载状态**),接管压缩是标准步骤。**范围与常设承诺是岗位说明不是状态,版本化在 +`references/lanes/.md`**(维护者 2026-08-19 裁定:「所以我认为每一种项目经理的岗位说明应该进 +skills,类似分诊」)—— 贴内指针指向其车道文件,升级走技能 PR,⛔ 手抄接力(逐任手抄正是本条要退役 +的失效模式;存量贴的四段收缩细则在 seat-post-protocol)。**写侧刷新点 = 轮次边界**,读侧只读贴 +正文 + 晚于正文最后编辑的评论(维护者 2026-08-12 批准;更早的已被吸收,是存档不是现状),中途状态 +由卡上 claim/ACCEPT 评论承载。**热文件串行队是正文具名段**(区域写不清就只能整文件串行)。无心跳, +活性惰性判定;竞态三招 —— 动手前重 fetch 正文、审计评论时间戳先到先得、写后回读。**换班报告默 认零建议**(维护者 2026-08-12 裁定,原话:「还有各车道下班时会提交 skills 建议有必要吗?就是那些 搞得后来skills越来越乱。」):强制建议清单已退役,离任报告只收三类 —— 原则错/缺(→ skills 席专题) 、可机械化项(→ 门禁/脚本卡,⛔ 不是散文)、平台事实变化(→ references 事实表改一行)—— 以 `finding` 入 skills 车道由该席分诊,三类之外默认关 not planned;「经验教训」散文不再入技能文本 -(防错归门禁,判断归档位)。六段模板、状态词表、接管/退场收尾清单等细则见 +(防错归门禁,判断归档位)。四段模板、状态词表、接管/退场收尾清单等细则见 `references/seat-post-protocol.md`;epic 委托不入座位贴体系;`packages/spec` 恒归 spec 座位。 ## Epic 子树车道 @@ -340,7 +334,15 @@ issue,逐个读当前 open/closed/assignee,引用读到的现状 ⛔ 不引用 张卡还开着吗」;过时动作断言 dev 动手即自纠,过时卡引用不变红)。花几分钟,不查则赔一次 agent 运行。 **批次独立性。** 一批内任两单不得可能碰同一个包/registry/barrel/spec schema;拿不准就串行。**同 -文件单跨轮硬串行;延后不是搁置**(被延后那一刻就把已知的坑记到该 issue 上)。**维护者明示豁免同 +文件单跨轮硬串行;延后不是搁置**(被延后那一刻就把已知的坑记到该 issue 上)。**家族派发(family dispatch)是本条的范围澄清,不是豁免**:独立性防的是两个 agent 相撞同一区域, +一个 dev **有意**覆盖 N 张同区域已裁卡是平凡满足不变量,可折叠为一次派发(折叠认领约定见「认 +领」节)。准入五门全过才可折:① 同缺陷形态同修法(⛔ 不是同关键词/同子系统);② 同包/区域(一 +worktree、一 changeset、一队列位);③ **每张成员都已裁/已定级,⛔ 决策箱内一张不许**(承重门:防 +借折叠把未裁卡洗进已裁 PR);④ 每成员独立可核(每成员一个具名判据,批次不能静默少交);⑤ 派发令 +点名**排除清单** —— 长得像家族而不是的成员及理由(承重门:盲扫「同类」正是要防的错编辑)。 +**fold-or-serial 是必答题**(维护者 2026-08-19 原话:「你自己定的工作方式你也会忘。」):凡 ≥2 张 +排队卡共享热文件,串行队条目和/或链首认领必须以五门为判据显式答折叠还是串行 —— 不答而默认串行是 +漏答不是安全选项(零余量棘轮文件上的串行还翻倍付账搜刮与人工合并次数)。**维护者明示豁免同 文件串行时,替代纪律四条**(豁免的是排队,不是防撞):① 文件面申报到**区域**级(函数/段落);② 开 PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队列仲裁,⛔ PM 不手动排序;豁免不外溢。** 阻塞解除后给延后单重新定价**:派发前一单时带必答项「你的改动让 #X 变简单/变难/变得不必要还是无 @@ -382,7 +384,7 @@ PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队 不相交挡不住**读耦合**:本卡 pin 断言兄弟卡在改的行为 ⇒ 各自全绿、先合者令后者 CI 无因变红;派 发令点名跨车道兄弟时**应**注明本卡 pin 是否断言其面,是则在用例内预登记翻转触发词(兄弟行为落地 即变红:删除或反转,⛔ 不修绿)。文件面对跨域例外单**必填**、普通单建议(定向在飞检查与 epic 领 -地判断的唯一输入);分支名必须带 issue 号。**限流不拆原子对**:发不出评论就撤 assign 或不开始;配额尽则整对排队,永不留半个。 +地判断的唯一输入);分支名必须带 issue 号。**家族派发(见批次独立性)的折叠认领约定**:共享分支按链首卡命名,**每张成员卡各留认领评论并点名该分支**(成员卡无自有分支是设计不是半状态);一 PR 正文多行 `Fixes #` 每成员一行、逐卡 commit(= 每成员的独立可核件);完整串行约束检查落链首认领,成员认领指向之。**限流不拆原子对**:发不出评论就撤 assign 或不开始;配额尽则整对排队,永不留半个。 3. **竞态复读**:自己的认领评论上墙后重读全线程 —— assignment 幂等,两个 agent 都会「成功」,** 认领评论时间戳是唯一仲裁**;更早的评论带不同 session ID/分支 ⇒ 你输了,回「already claimed — yielding」另选。**让行是交接不是退场**:连同让行评论交出已诊断的一切与 PM 侧已取的板面读 @@ -402,7 +404,7 @@ dev 侧推分支要早 —— 远程分支是在飞工作最硬的证据。**死 拿不准就升一档 —— 错派低档的返工贵过省下的额度);上限 `fable`(最重协议/流程/编排卡,按卡取用非新 默认)。**⛔ 强制条款两条**:① 凡改 `.claude/skills/pm-dispatch/**` 的卡一律 `model: "claude-fable-5"`;② 凡**改变契约接受/拒绝行为或扩大公开面**的卡(`domain:spec` 语义面; -判据即分诊代裁的机械边界测试与 spec 席内分派判据,⛔ 不另抄第二份)一律 `claude-fable-5`(维护者 +判据即分诊代裁的机械边界测试与 spec 席内分派判据 —— `references/lanes/spec.md`,⛔ 不另抄第二份)一律 `claude-fable-5`(维护者 2026-08-12 裁定,原话:「同意,就按语义面收窄,立卡并通知 spec 席」)—— 契约错毒化一切下游,全仓最贵(条款②闸门见「入队与落地」)。两条唯一降档出口:**额度耗尽豁免**(维护者 2026-08-13 原话:「fable 如果用完了,可以用 opus」):仅当 fable 实测不可用(限流/墙杀中途,重派同样可降) 才落 `opus`,⛔ 不再往下,档位与理由记入认领评论「Container & model」行。明确不变(合并后按席内 @@ -556,9 +558,8 @@ issue 上(不能合 ≠ 不复核;技能面 PR 的复核席须跑在契约复审 出处:维护者 2026-08-11 提问(「首先项目经理能不能查到相关的数据,其次是到达时间窗口工作就会停, 是否应该设置一个1小时的定时以监测时间窗口已经解锁」)。检测读数、盲区与恢复 playbook 细则见 `references/platform-readings.md`;常驻原则: -- **检测**:`ccusage blocks` 给窗口边界与燃烧率,但只有单容器视野、估成本不估套餐余量(没有任何 - 面向 agent 的接口暴露账号级剩余额度);**权威的墙信号是失败本身**——撞墙报文里的重置时刻在那 - 一刻可得、事前查不到,把它记下来。 +- **检测**:`ccusage blocks` 只有单容器视野、估成本不估套餐余量(账号级剩余额度无接口可查); + **权威的墙信号是失败本身**——撞墙报文里的重置时刻在那一刻可得、事前查不到,把它记下来(工具读数与盲区在事实表)。 - **跨墙定时器**:拿到重置时刻 ⇒ 一发定点(reset + 缓冲)优先;没有 ⇒ 挂每小时 cron Routine,⛔ **不用 send_later 链** —— send_later 是 run-once、fire 后自禁用,投进死窗口那一发是否被重试未实 测且文档未承诺,一次性链条可能断在它存在的意义上;第一枪成功的 fire 跑恢复后**删除 cron**(幸存 cron 是孤儿定时器)。fired 文本照定时器写法纪律。 diff --git a/.claude/skills/pm-dispatch/references/lanes/cli.md b/.claude/skills/pm-dispatch/references/lanes/cli.md new file mode 100644 index 0000000000..0b2eb09af8 --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/cli.md @@ -0,0 +1,37 @@ +# 车道岗位说明:domain:cli(references/lanes —— 座位贴指针指向本文件) + +岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件。 + +## 范围 + +- `packages/cli`、`runtime`、`verify`、`qa`、`types`、`packages/rest`、 + `packages/mcp`、`packages/observability`、`packages/client*`、 + `cloud-connection`、`create-objectstack`、`packages/adapters/*`、 + `plugin-hono-server`、`plugin-dev`。 +- 红线:按落点判归属 —— 标题挂 cli 而落点在别包的卡只上报误标不改签; + `packages/spec` 恒归 spec 座位;`/meta` 路由**本体**归本席,元数据格式/接受面归 + `domain:spec`。 + +## 常设承诺 + +- **Required checks 六个**:`TypeScript Type Check` · `Lint & Repo Gates` · + `Test Core` · `Dogfood Regression Gate` · `Build Core` · + `Temporal Conformance (live PG + MySQL)` —— 逐 job 读各自 `conclusion`,⛔ 不认 + 聚合,`in_progress` 不是过;advisory 门禁红进 main 是共享损伤,照样止血立单。 +- **PR 侧绿 ≠ 队列侧绿**;队列成员资格直接可读: + `git ls-remote origin 'refs/heads/gh-readonly-queue/*'`(条目名 + `main/pr-{number}-{parent sha}`,parent sha 可重建队序;⚠️ ref 在出队后滞留、入 + 队瞬间滞后)。 +- `dispatch-gates.mjs` 只报**路径推导**的地板 —— 条款②从卡**内容**判且优先于它; + 已知盲区:它不点名 `pnpm lint` 族 ⇒ 本车道派发令恒补一句「跑 `pnpm lint`」。 +- ⛔ 永不削弱门禁 —— 棘轮上跳是门禁在报你的改动有缺陷;规则文案里自带的逃生舱只用 + 于它描述的那种情形。 + +## 席内判断 + +- **探针的 baseline 也是测量**,而且是没人复查的那个 —— 判据恒读命中行本身,⛔ 不 + 读命中数;断言「文本被删」的探针要锚在消失的那段上(被删串的前缀在删除后仍然幸 + 存是构造使然)。 +- 静默时长是**发探针**的门槛,永不是判死的(本车道实测基线:派发 → draft PR ≈ + 35–50 分钟);分支无提交 + SendMessage 探针便宜,且实测能复活假死的 dev —— ⛔ 永 + 不往可能活着的 worktree 派第二个 agent。 diff --git a/.claude/skills/pm-dispatch/references/lanes/devx.md b/.claude/skills/pm-dispatch/references/lanes/devx.md new file mode 100644 index 0000000000..0e28d427e8 --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/devx.md @@ -0,0 +1,38 @@ +# 车道岗位说明:domain:devx(references/lanes —— 座位贴指针指向本文件) + +岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件。 + +## 范围 + +- `packages/lint`、`packages/sdui-parser`、`content/docs/**`、`apps/docs`、 + `scripts/`(门禁类)、`.github/workflows/`(门禁接线)、`.githooks/`、 + `examples/**` 测试基建面、`docker/README.md`。 +- 边界:守护 skills 的门禁脚本在 `scripts/` 下时归本席 —— 判据是**被改文件的路 + 径**,SUBJECT 是 governed 面本身的门禁/审计除外(归 skills,见 SKILL.md 域车道 + 表);`.claude/workflows/` ≠ `.claude/skills/`;与 spec 相交的三面按「是否围着 + spec 契约转」切分;**范围内的文件 ≠ 范围内的卡**,归属按卡的 `domain:*` 判,反 + 向亦然(本席卡的落点溢进他席文件面时,由此产生的人工合并等后果照单接受)。 + +## 常设承诺 + +- `content/docs/releases/**` 是 release-owned,恰两条通道:完整性缺口逐卡批准 + (⛔ 不构成先例);事实错误走专用 docs-only PR。发布页作用域只管 v16 及以后。 +- ⛔ 不做任何发布动作,含改根 `version` 脚本链;**能点绿的门禁不等于该点绿**。 +- governed 面 PR 照 SKILL.md「ACCEPT 之后的路径分叉」:恒 draft、留维护者、看得见 + 地悬着;设计如此的红门禁必须在 PR 上说明红因并声明不修。 +- changeset 按 publish 面判:根 `scripts/` / docs / test-only ⇒ `skip-changeset`; + 落进已发布包的源 ⇒ 真 changeset;**收窄接受集**须 lint+spec 双侧语义登记,尤须 + 慎重。 + +## 席内判断 + +- **卡片正文冻结在立卡那一刻**,而本仓刻意把裁定/更正/`Blocked-by:` 放在评论里 —— + 超过一天的卡,正文是页面上最不当前的东西;先读晚于正文的评论再判可派性。 +- **量具在共享 checkout 上会静默说谎**:读内容用 `git show origin/main:` 带路径, + 跑脚本必须在自己的 worktree,复核 diff 用具名 ref,⛔ 不用 `FETCH_HEAD`(它是共 + 享的,会被别的 agent 的 fetch 在两条命令之间冲掉)。 +- **门禁的自述必须为真** —— 理由为假的门禁比没有门禁更坏(下一个读者会相信某风险 + 已被覆盖);新门禁靠**故意复现伤害**自证,语料已被修干净时加反空转肢(某个面读 + 不出具名 pin 即判失败),⛔ 让枚举静默退化成 no-op。 +- 派发词给出的实测值必须同时给「自己重测」的指令(PM 清单会错,dev 重推导是兜 + 底);先例给的是「怎么想」,不是「怎么改」。 diff --git a/.claude/skills/pm-dispatch/references/lanes/engine.md b/.claude/skills/pm-dispatch/references/lanes/engine.md new file mode 100644 index 0000000000..2c397d3cc1 --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/engine.md @@ -0,0 +1,41 @@ +# 车道岗位说明:domain:engine(references/lanes —— 座位贴指针指向本文件) + +岗位说明(范围 / 常设承诺 / 席内判断)版本化于此,升级走技能 PR;现值状态(当前 +PM、继承台账、热文件串行队)恒在座位贴,⛔ 不迁入本文件。本车道 2026-08-19 由 +engine-core + metadata + drivers 三车道合并而成(裁决引文在 SKILL.md 域车道表)。 + +## 范围 + +- `packages/objectql`(含 SchemaRegistry)、`packages/core`、`packages/formula` + (CEL / `matches-filter` / RLS 谓词求值)、`plugin-pinyin-search`(落点在编译/查 + 询核心)。⚠️ `objectql/src/metadata-facade.ts` 名字带 metadata,归本车道。 +- `packages/metadata*`(加载、注册、持久化、缓存、目录)、`packages/platform-objects`。 +- `packages/drivers/driver-*`(driver-memory / driver-mongodb / driver-sql / + driver-sqlite-wasm / driver-turso)。 +- 红线:改元数据**格式/接受面**(判据是「**改变**接受面」,不是「碰到 spec」)⇒ + `domain:spec`;`/meta` 路由本体在 `packages/rest` ⇒ `domain:cli`; + `packages/services/**` ⇒ `domain:services`;`content/docs/**`、`packages/lint` + ⇒ `domain:devx`。 + +## 常设承诺 + +- **投入冻结随包不随车道**:维护者 2026-08-05 对 `driver-memory` / + `driver-mongodb` 族的投入冻结继续有效;能穿过冻结的形状是「消除静默失败模式」与 + 清账/对齐既有能力,形如**能力投资**的卡派发前须取裁决;`formula` / `driver-sql` + 不受影响。 +- **driver conformance 台账只降不升**:任何 driver 卡的派发令要求 dev 前后各读一 + 次 covered/DEBT 读数,写进报告。 +- 改变契约接受/拒绝行为的卡按条款②处理(判据与档位在 SKILL.md,⛔ 不另抄)。 + +## 席内判断 + +- **区域 ≠ 文件**:区域放行只能来自对方卡**真实改动行程**(有 PR 读 diff,没有就 + 申报 UNKNOWN);**做删除的卡,其行程没人能从「它加了什么」的名字推出**。行号数 + 小时内即腐烂,恒按符号定位。 +- **五个 driver 列只有约三个独立实现**:`driver-sqlite-wasm` 与 `driver-turso` + local 都继承 `SqlDriver` 的 filter 编译器 —— 把一致性表当五方佐证会高估证据;同 + 理,单点修 SQL 家族共享 seam 即可覆盖三个 driver。 +- **元数据合并语义按键类各不相同**(fields 展开 / validations+indexes 连接 / 标量 + last-writer-wins)—— 评审 pin 时先问它**没有**覆盖什么;标量的 last-writer-wins + 是跨机制重复立卡的老源头,同 seam 的第三张分歧卡优先裁**类**,不裁实例。 +- 元数据接受面形状的卡先问「生产者在哪」—— 答案常改变卡的范围与域标签,回分诊。 diff --git a/.claude/skills/pm-dispatch/references/lanes/services.md b/.claude/skills/pm-dispatch/references/lanes/services.md new file mode 100644 index 0000000000..727c8b716d --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/services.md @@ -0,0 +1,31 @@ +# 车道岗位说明:domain:services(references/lanes —— 座位贴指针指向本文件) + +岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件。本车道 +2026-08-19 并入原 identity 车道的四个插件(裁决引文在 SKILL.md 域车道表)。 + +## 范围 + +- `packages/services/*`、`packages/connectors/*`、`packages/triggers/*`、 + `plugin-approvals`、`plugin-webhooks`、`plugin-email`、`plugin-reports`、 + `embedder-openai`、`knowledge-*`。 +- 身份侧(2026-08-19 并入):`plugin-auth`、`plugin-security`、`plugin-sharing`、 + `plugin-audit`。 +- 红线:零持有 `packages/spec` —— 触 spec 的卡一律转 spec 座位;**安全/权限边界的 + 放宽**(访问控制、认证流、RLS/共享语义、审计留痕)是人工地板,恒升级不代裁。 + +## 常设承诺 + +- **每条否定性 pin 都要消融验证**(被禁行为放回 → 测试转红 → 报失败输出 → 恢复) + —— 单独的绿不是证据。 +- **安全族卡的披露纪律**:复现配方不落任何公开面(卡、PR、评论);证据以抽象描述 + 或私有通道承载。 +- 门禁读数不轻信聚合:`check:type-check-debt` 可以在包级 typecheck 绿时红; + `check:i18n` 以「PREREQUISITE NOT MET — workspace CLI 未 build」退 1 不是漂移。 + +## 席内判断 + +- **认证栈版本族升级把 `pnpm-workspace.yaml` overrides 与 `plugin-auth/**` 当同一 + 个热文件面**串行;在旧版本族上测得的前提(兼容性、行为断言)在新版本族落地后 + **逐卡重读**再派发,⛔ 不沿用旧读数。 +- 多服务共享同一条自动化引擎/数据源 seam 时同文件卡跨轮硬串行,后一单派发前先用前 + 一单的报告重新定价(SKILL.md 候选与批次的重定价条款)。 diff --git a/.claude/skills/pm-dispatch/references/lanes/skills.md b/.claude/skills/pm-dispatch/references/lanes/skills.md new file mode 100644 index 0000000000..769b461cd4 --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/skills.md @@ -0,0 +1,36 @@ +# 车道岗位说明:domain:skills(references/lanes —— 座位贴指针指向本文件) + +岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件。 + +## 范围 + +- 两个技能根:`.claude/skills/**`(含 pm-dispatch 本体)+ `skills/**`(发布目录, + 恒英文);`scripts/pm/**` PM 循环工具;指令架构文件:根 `AGENTS.md` + 根 + `CLAUDE.md`;governed 面的治理执行文件(`.github/CODEOWNERS` 治理路由半边 + + SUBJECT 是 governed 面本身的门禁/审计)。全量判据与裁决引文在 SKILL.md 域车道 + 表;governed 面统一定义见 SKILL.md「ACCEPT 之后的路径分叉」,判定命令 + `node scripts/pm/check-governed-merges.mjs --test` 带路径。 +- QA 管理循环执行归本席;qa-run 记录是协议载体不是工作;契约复审(条款②复审链)归 + 分诊席,本席仅过渡期代行。 + +## 常设承诺 + +- 四维分析先于派发与复核。 +- governed PR 恒 draft 等人合;flip/arm 前跑 `check-governed-merges --test`;轮报 + 的 governed 合并审计清单带 `--since` 四仓实跑,⛔ 不凭记忆汇总。 +- 档位从 `--tier` 推导引用;pm-dispatch 根 fable 强制;条款②闸门照现行;限额豁免 + floor opus。 +- 棘轮逐行付账,⛔ re-wrap;付账砍点逐条核幸存 —— 被砍内容若在别处无家,砍掉就是 + 丢规则。 +- 首触定级每轮;决策形状 ⇒ 决策箱带四棱块,⛔ 永不自裁(唯一例外:本车道 finding + 自分诊,全仓轮跳过)。 +- 内部指令面中文,机器判据恒英文;认领前重读全线程;标签写 read-modify-write + + 回读。 +- QA 波次由维护者手动触发,⛔ 不自启。 + +## 席内判断 + +- 技能文本改动的复核先问「谁在读这一行」—— 无具名读者的新增是 token 税;每条经验 + 自含失效模式与边界,⛔ 操作文本不引 issue 编号(id-lint 机械强制)。 +- fold-or-serial 必答与家族派发五门在 SKILL.md 批次独立性段 —— 本车道的 SKILL.md + 热文件链是它最常命中的现场,链首认领就是答题处。 diff --git a/.claude/skills/pm-dispatch/references/lanes/spec.md b/.claude/skills/pm-dispatch/references/lanes/spec.md new file mode 100644 index 0000000000..21a48b645e --- /dev/null +++ b/.claude/skills/pm-dispatch/references/lanes/spec.md @@ -0,0 +1,44 @@ +# 车道岗位说明:domain:spec(references/lanes —— 座位贴指针指向本文件) + +岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件。 + +## 范围 + +- `packages/spec` 整包唯一契约,语义/文本/机器三面同席:schema 形状、 + `contracts/**`、退役行为半边、strictness 台账;describe/JSDoc/墓碑散文/错误 + guidance 与 alias 表;`packages/spec/scripts/**`、`packages/spec/docs/**` 及围着 + spec 契约转的工具链(门禁/生成器/lint 规则/报错散文/references 管线)。 +- 一般开发工具面留 devx(维护者 2026-08-09 裁决);`packages/spec` 恒归本席,不论 + 谁需要它。 + +## 席内分派参考 + +(维护者 2026-08-16 裁定合并车道:原 spec-surface / spec-tooling 标签已退役,三面 +同归 `domain:spec` 一席,锚定规则双射恢复;以下判据降为席内分派与定价依据。) + +- 语义/文本按「合法元数据集合变没变」分 —— 改动前能过校验的输入,改动后逐字节同 + 判 ⇒ 文本面(changeset 恒 patch,默认 sweep-first),否则语义面;**任何改变接 + 受/拒绝行为的卡,不论多小,按语义面处理**(条款②)。 +- 机器面改「围着契约转的机器」,与文本面无交集,⛔ 不碰 + `packages/spec/src/**/*.zod.ts` 与 strictness 台账。 +- 产物随源走:describe/JSDoc 改动重生成的 references 产物归触发它的源 PR(生成物 + 门禁重生成提交,⛔ 手改)。 +- 改元数据**格式/接受面**的照旧归 `domain:spec`,`/meta` 路由本体在 + `packages/rest` 归 `domain:cli`;拿不准 FLAG 回分诊,⛔ 不自设第二套判据。 +- 档位随面走的现行表在 SKILL.md 模型分档(单源,⛔ 不另抄)。 + +## 常设承诺 + +- findings 首触定级归分诊席,本席只供证据。 +- **待命巡逻每次做整车道全交集读**(delta 扫描有尾隙:扫描后、波次边界前入队的卡 + 谁都看不见;全交集读是安全网)。 +- **契约面卡的 fixture triage 必须跑消费包测试**(A 包的改动可让 B 包的 fixture + 反着断言,spec 范围内任何 sweep 都看不见)—— 派发令点名消费包测试清单,报告要有 + 各消费包真实读数。 +- 派发前触发文件必查段照座位贴现值执行(那是状态,不是岗位说明);跨仓 pin 滞后的 + 读法在 SKILL.md 多仓协调。 + +## 席内判断 + +- 候选卡的评论是读取的一部分,即使正文看起来已是决策形状 —— 裁决与撤销住在评论 + 里,跳过评论就是跳过裁决。 diff --git a/.claude/skills/pm-dispatch/references/seat-post-protocol.md b/.claude/skills/pm-dispatch/references/seat-post-protocol.md index 6d6df93ced..2cbe5636c9 100644 --- a/.claude/skills/pm-dispatch/references/seat-post-protocol.md +++ b/.claude/skills/pm-dispatch/references/seat-post-protocol.md @@ -1,11 +1,12 @@ # 座位贴协议细则(references —— 按需加载) -出处:主文件「座位贴协议」。原则(一座位一贴、单写手、正文为权威)与 2026-08-06 -拍板出处住在主文件;本表是接管/移交/回收那一刻要查的**协议细则**。 +出处与原则(一座位一贴、单写手、正文为权威)住主文件「座位贴协议」;本表是接管/ +移交/回收那一刻要查的**协议细则**。 -- **贴 = 座位**,标签 `pm:seat`,正文固定六段:**范围 | 当前 PM | 继承台账 | 热文 - 件串行队 | 常设承诺 | 说明** —— 仅此六段,段段皆**现值**,没有一段随时间增长 - (维护者 2026-08-11 接受)。 +- **贴 = 座位**,标签 `pm:seat`,正文固定四段:**当前 PM | 继承台账 | 热文件串行 + 队 | 说明** —— 段段皆**现值**,没有一段随时间增长;范围与常设承诺是岗位说明,版 + 本化在 `lanes/.md`,「说明」段放一行指针(两裁决出处均在主文件);存量贴 + 由在任座位在下次写侧刷新时按四段收缩(⛔ 岗位说明 PR 不代改贴正文)。 - **标题即状态板**:固定格式 `[PM seat] <座位名> — <状态>`,状态词表 `🟢 `(在任)/ `🟢 Routine` / `⏳ vacant` / `⏸️ paused`。标题只放慢 状态(换班级频率);轮次、在飞、队列快照等快状态 ⛔ 不进标题,留在「说明」段。 @@ -16,15 +17,14 @@ + 上任时刻。审计/认领评论的**作者字段**是平台盖章、不可自述错的硬读数 —— 接管仲 裁与活性判定优先用它对账正文。 - **读侧边界(接管与巡检)**:只读晚于正文最后编辑时间的评论 —— 评论无界增长而正 - 文有界,读全评论是纯 token 税;正文编辑时刻与评论时间戳都是平台盖章的硬读数,比 - 对即得(维护者 2026-08-12 批准)。 + 文有界,读全评论是纯 token 税;两个时刻都是平台盖章的硬读数,比对即得(批准出处在主文件)。 - **班次叙事不进贴正文**:逐卡状态在卡与 PR 上本就必填,轮次合计走轮次报告;贴正 文按写侧刷新点(下方)编辑,⛔ 不逐事件追加(无界贴会超出单次读取上限)。 -- **接管压缩细则**:接任 PM 把交接的有效内容按六段模板重述为新正文,**编辑历史即 +- **接管压缩细则**:接任 PM 把交接的有效内容按四段模板重述为新正文,**编辑历史即 存档** —— 旧账留在上一版 body revision,审计评论带版本指针(哪一版、何时)。超 大贴由半状态巡查的 report-only 项浮出,不等读取失败。 -- **热文件串行队是正文具名段**(跨轮、跨班次的常设事实):文件 → 有序卡片清单 → - 每张卡认领的**区域**;区域列写清楚才敢并行,写不清楚就只能整文件串行。 +- **热文件串行队**(跨轮、跨班次的常设事实):文件 → 有序卡片清单 → 每张卡认领 + 的**区域**(并行判据在主文件:区域写不清就只能整文件串行)。 - **残余竞态补遗**(三招在主文件):贴正文是多席可写面(接管即换写手)⇒ 写后读回 **恒不降级**;新增座位贴(拆域)同样先查 `pm:seat` 索引再立贴。 - **无心跳,活性判定两条路**:惰性半边在**接管冲突**时评估一次 —— Routine 座位查 diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index 89282f7158..a79dc0337a 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -56,6 +56,15 @@ export const CEILINGS = new Map([ ['.claude/skills/pm-dispatch/references/review-checklist.md', 82], ['.claude/skills/pm-dispatch/references/landing-operations.md', 82], ['.claude/skills/pm-dispatch/references/seat-post-protocol.md', 101], + // Lane job descriptions (maintainer ruling 2026-08-19: per-lane PM job + // descriptions move from seat-post prose into versioned skill references). + // Set at landed line counts (headroom 0, same convention as above). + ['.claude/skills/pm-dispatch/references/lanes/engine.md', 41], + ['.claude/skills/pm-dispatch/references/lanes/services.md', 31], + ['.claude/skills/pm-dispatch/references/lanes/cli.md', 37], + ['.claude/skills/pm-dispatch/references/lanes/devx.md', 38], + ['.claude/skills/pm-dispatch/references/lanes/skills.md', 36], + ['.claude/skills/pm-dispatch/references/lanes/spec.md', 44], ['.claude/agents/os-dev.md', 399], // #9473: the other four `.claude/skills/` are read in full by the sessions // that use them too — the erosion mechanism the ratchet exists to stop @@ -130,6 +139,7 @@ function selfTest() { ['SKILL.md is covered', CEILINGS.has('.claude/skills/pm-dispatch/SKILL.md'), true], ['the dev-agent definition is covered', CEILINGS.has('.claude/agents/os-dev.md'), true], ['all five compressed references are covered', ['dispatch-runbook', 'platform-readings', 'review-checklist', 'landing-operations', 'seat-post-protocol'].every((n) => CEILINGS.has(`.claude/skills/pm-dispatch/references/${n}.md`)), true], + ['all six lane job descriptions are covered', ['engine', 'services', 'cli', 'devx', 'skills', 'spec'].every((n) => CEILINGS.has(`.claude/skills/pm-dispatch/references/lanes/${n}.md`)), true], ['the other four skills are covered (#9473)', ['checklist-test', 'checklist-author', 'dogfood-verification', 'spec-property-retirement'].every((n) => CEILINGS.has(`.claude/skills/${n}/SKILL.md`)), true], ['root AGENTS.md is covered (#9792)', CEILINGS.has('AGENTS.md'), true], ]; diff --git a/scripts/pm/ensure-pm-labels.sh b/scripts/pm/ensure-pm-labels.sh index 7978c77424..ec12c4cb61 100644 --- a/scripts/pm/ensure-pm-labels.sh +++ b/scripts/pm/ensure-pm-labels.sh @@ -8,13 +8,17 @@ # # The label set IS the PM state machine (.claude/skills/pm-dispatch/SKILL.md, # "State model"): every label here is consumed by a named query or gate. -# ⛔ The retired lanes (domain:engine, domain:ui; domain:spec-surface and -# domain:spec-tooling, retired 2026-08-16 — maintainer ruling 「A」 merged both -# into the single domain:spec lane; the sub-lane criteria survive as the spec -# seat's internal dispatch reference in SKILL.md) are deliberately ABSENT — -# recreating a retired label puts an ownerless lane back into GitHub's -# autocomplete. Their leftover label OBJECTS may still exist in the repos; -# deleting those objects is a separate, deliberate PM action. +# ⛔ The retired lanes (domain:ui; domain:spec-surface and domain:spec-tooling, +# retired 2026-08-16 — maintainer ruling 「A」 merged both into the single +# domain:spec lane, the sub-lane criteria surviving as the spec seat's dispatch +# reference; domain:engine-core / domain:metadata / domain:drivers / +# domain:identity, retired 2026-08-19 — maintainer ruling 「engine-core + +# metadata + drivers -> engine, identity + services → services 怎么样?」 folded +# the engine-side three into domain:engine, which thereby RE-ENTERS circulation +# after its own earlier retirement, and identity into domain:services) are +# deliberately ABSENT — recreating a retired label puts an ownerless lane back +# into GitHub's autocomplete. Their leftover label OBJECTS may still exist in +# the repos; deleting those objects is a separate, deliberate PM action. # # Requires the `gh` CLI. Where only the GitHub MCP tools are available, mirror # these creations through them — the protocol is identical. @@ -72,7 +76,7 @@ gh label create repo:cloud -R objectstack-ai/objectstack -c c5def5 -d "Seam c # Domain lanes — the roster lives in SKILL.md's domain table; keep both in sync # BY PR whenever a lane is added or retired. -for D in engine-core metadata drivers services identity devx spec cli skills; do +for D in engine services devx spec cli skills; do gh label create "domain:$D" -R objectstack-ai/objectstack -c bfd4f2 -d "Domain lane — seat card indexed by label:pm:seat" 2>/dev/null || true done