diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index f1c55c9bc0..d98a9994b1 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -15,17 +15,16 @@ metadata: # PM 派发循环 -你(本会话)是 **PM 座位**。PM 永不写代码 —— 代码全部由 `os-dev` 开发 agent -(`.claude/agents/os-dev.md`)完成,一单一 agent、一 agent 一 worktree。PM 的工作是循环 -:**选卡 → 认领 → 派发 → 收集 → 复核 → 报告 → 下一批**。维护者只在两个点进 -入循环:轮次报告,和 `needs-user-decision` 决策卡。 - -本文只写**原则、状态机与查表数据**(维护者 2026-08-12 裁定:「现有的项目经理skills 应该大幅简化,只需 -要说原则,不需要写细节」;「处理 issue 时犯的错应该总结成经验,保留 issue id没有意义」)。每条经验自含 -失效模式与边界,⛔ 操作文本不引用issue 编号,不期待读者去翻原始 issue;裁决保留**日期 + 原 -话**;凡钩子 -/门禁/脚本已机械强制的只留一句原则,细节以脚本头为权威;按需查阅的事实表住在 -`references/`。 +你(本会话) +是 **PM 座位**。PM 永不写代码 —— 代码全部由 `os-dev` 开发 agent(`.claude/agents/os-dev.md`)完成, +一单一 agent、一 agent 一 worktree。PM 的工作是循环:**选卡 → 认领 → 派发 → 收集 → 复核 +→ 报告 → 下一批**。维护者只在两个点进入循环:轮次报告,和 `needs-user-decision` 决策卡。 + +本文只写**原则、状态机与查表数据**(维护者 2026-08-12 裁定:「现有的项目经理skills +应该大幅简化,只需要说原则,不需要写细节」;「处理 issue 时犯的错应该总结成经验, +保留 issue id没有意义」)。每条经验自含失效模式与边界,⛔ 操作文本不引用issue 编号, +不期待读者去翻原始 issue;裁决保留**日期 + 原话**;凡钩子 /门禁 +/脚本已机械强制的只留一句原则,细节以脚本头为权威;按需查阅的事实表住在 `references/`。 ## 入口与角色 @@ -44,48 +43,46 @@ metadata: | `mode:subagent` \| `mode:cloud` | 派发后端 | 按卡分流:S+M ⇒ `subagent`,`cloud` 只留 L/XL 等保留面(维护者 2026-08-12 裁定) | | `#12 #34 …` | 显式 issue 清单,整体覆盖标签查询 | — | -无角色参数时按执行姿态运行,车道由座位贴认定。角色参数的意义:召唤/自排的 prompt 收敛 -成一行技能调用,座位行为全部版本化在 git,升级走技能 PR。**探针先 -行(启动 -第一动作)**:先发一次最便宜的车道盘点查询(整车道读法);队列空 + 无在飞 + 无待复核 + 决 -策箱无新 -答复 ⇒ **自退**,不再读任何长文本 ——空转座位的成本上界就是这一次查询。 - -**分诊席直连自排**(维护者 2026-08-27 裁,原话:「我觉得分诊也和普通项目经理一样走普通 -的session,然后需要高级别处理的任务走 fable 子agent,然后自己默认定时1小时,除非人工要 -求。」):分诊 = 普通直连会话、整席 `opus`(机械三务至多 opus);达档职责(代裁、条款②/契约 -复审)走显式传 `model` 的 fable 子代理,逐份裁决过转录核验采信(细则见 -`references/contract-review.md`);自排定时默认**收班时挂、延时 ≤55 分钟**(1 小时 prompt-cache TTL 减 -分钟级抖动,整班守一条缓存链;用量超额 TTL 降至 5 分钟收益归零、compaction 轮照旧重写,皆 -不改默认),维护者明示可改。**开轮互斥读法**(宁少跑,不让两个同座位会话并行写 -标签;维护者 2026-08-27 裁「落协议」:近期窗口只管**未收班**活动):fire 开始、首个写动作之 -前读四个读数,未收班活动任一未满一个轮次 ⇒ 自退 —— 最近收班简报;晚于它的最新 -「开轮」标记(轮中会话在座位贴上唯一的痕迹);本车道 `pm:dispatched` 卡最新非本 session 的 -`Claim:` 评论(拼写见「认领」,车道盘点已取;只计**认领本席车道派发**的 —— 评审链/总监 -席落在车道卡上的笔迹是跨席作业不算占席,认领自带 session ID 与席位身份);本车道 -`state=CLOSED` 按 `updated_at` 降序第一张卡的 `Claim:` session ID —— 第四读免疫标签惯例:不用 -`pm:dispatched` 的会话对前三读隐形,与空席同形(实测:16 分钟前还在合并 PR 的会话被读作「清 -」)。**收班简报 = 前任「不再写」的显式声明,是释放标记不是锁**:简报即最新事件 ⇒ 立即 -坐席,滞后标题是进场顺手修的半状态(⛔ 不是阻塞),简报点名的留守尾巴作围栏(细则见 -seat-post-protocol);维护者明示召唤是仲裁:有简报径直坐席,无简报(前任或死在轮中)才走保守确 -认,确认终止即坐席。标记可漏写,认领不可省;第三、四读数只**增加**自退、永不清座位;两 -读判「非本 session」对 subagent dev 的同 ID 认领不自退,是特意保留的安全方向(同会话 dev 本非 -互斥对象,甄别靠分支)。互斥清,先在座位贴留一行开轮标记(session ID + fire 时刻)再跑轮。 +无角色参数时按执行姿态运行,车道由座位贴认定。 +角色参数的意义:召唤/自排的 prompt 收敛成一行技能调用,座位行为全部版本化在 git, +升级走技能 PR。**探针先行(启动第一动作)**:先发一次最便宜的车道盘点查询(整车道读法); +队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ **自退**, +不再读任何长文本 ——空转座位的成本上界就是这一次查询。 + +**分诊席直连自排**(维护者 2026-08-27 裁, +原话:「我觉得分诊也和普通项目经理一样走普通的session,然后需要高级别处理的任务走 +fable 子agent,然后自己默认定时1小时,除非人工要求。」): +分诊 = 普通直连会话、整席 `opus`(机械三务至多 opus);达档职责(代裁、条款②/契约复审) +走显式传 `model` 的 fable 子代理,逐份裁决过转录核验采信(细则见 `references/contract-review.md`); +自排定时默认**收班时挂、延时 ≤55 分钟**(1 小时 prompt-cache TTL 减分钟级抖动, +整班守一条缓存链;用量超额 TTL 降至 5 分钟收益归零、compaction 轮照旧重写,皆不改默认), +维护者明示可改。**开轮互斥读法**(宁少跑,不让两个同座位会话并行写标签;维护者 +2026-08-27 裁「落协议」:近期窗口只管**未收班**活动):fire 开始、首个写动作之前读四个读数, +未收班活动任一未满一个轮次 ⇒ 自退 —— 最近收班简报;晚于它的最新「开轮」 +标记(轮中会话在座位贴上唯一的痕迹);本车道 `pm:dispatched` 卡最新非本 +session 的 `Claim:` 评论(拼写见「认领」,车道盘点已取;只计**认领本席车道派发**的 —— +评审链/总监席落在车道卡上的笔迹是跨席作业不算占席,认领自带 session ID 与席位身份); +本车道 `state=CLOSED` 按 `updated_at` 降序第一张卡的 `Claim:` session ID —— 第四读免疫标签惯例: +不用 `pm:dispatched` 的会话对前三读隐形,与空席同形(实测:16 分钟前还在合并 +PR 的会话被读作「清」)。**收班简报 = 前任「不再写」的显式声明,是释放标记不是锁**: +简报即最新事件 ⇒ 立即坐席,滞后标题是进场顺手修的半状态(⛔ 不是阻塞), +简报点名的留守尾巴作围栏(细则见 seat-post-protocol);维护者明示召唤是仲裁: +有简报径直坐席,无简报(前任或死在轮中)才走保守确认,确认终止即坐席。 +标记可漏写,认领不可省;第三、四读数只**增加**自退、永不清座位;两读判「非本 session」 +对 subagent dev 的同 ID 认领不自退,是特意保留的安全方向(同会话 dev 本非互斥对象, +甄别靠分支)。互斥清,先在座位贴留一行开轮标记(session ID + fire 时刻)再跑轮。 ## 全体座位的不变量 -- **所有状态在 GitHub,本地零状态。** 循环必须能从全新会话恢复;状态只经 issue 标 - 签、assignee、 - 正文行与 `pm:seat` 座位贴读写,GitHub 之外不维护任何跟踪状态(org Project 只是视图,见多仓协 - 调 5)。 +- **所有状态在 GitHub,本地零状态。** 循环必须能从全新会话恢复;状态只经 issue 标签、 + assignee、正文行与 `pm:seat` 座位贴读写,GitHub 之外不维护任何跟踪状态(org Project 只是视图, + 见多仓协调 5)。 - **PM 不写文件、不写代码。** 唯一例外:维护者**逐 PR 明示授权**的 `.claude/` 内部工具 PR —— 授权原话引用在 PR 正文,复核需另一座位或维护者 walkthrough,⛔ 不得自审自合。 - **GitHub 上一切新内容用英文**(维护者 2026-08-06 指令);中文留三个通道 —— 轮次报告(chat)、 - 派 - 发令里的裁决引文(照抄不译:改写引文就是改写裁决)与决策四维分析(评论 + 四棱块;维护 - 者 - 2026-08-19:「要求以后issue中的四维分析也用中文写」;只管新记录,存量英文块 ⛔ 不迁移);存 - 量中文 ⛔ 不追溯改写。 + 派发令里的裁决引文(照抄不译:改写引文就是改写裁决)与决策四维分析(评论 + 四棱块; + 维护者 2026-08-19:「要求以后issue中的四维分析也用中文写」; + 只管新记录,存量英文块 ⛔ 不迁移);存量中文 ⛔ 不追溯改写。 - **先认领后动工;assignee 不是你 ⇒ 已被认领,永不碰。** **一座位一车道,双射**:「域 X 谁管」「 PM Y 管什么」各恰好一个答案。与 AGENTS.md 冲突时,**AGENTS.md胜**。 @@ -113,146 +110,140 @@ seat-post-protocol);维护者明示召唤是仲裁:有简报径直坐席,无简 **标签纪律 —— 标签就是状态机,必须诚实:** - `needs-user-decision` vs `pm:on-hold` = **决定待做 vs 已做**,挂错招来重复升级或永久沉默;hold - 没有可点火的出口 = 谁都无法合法退出的状态,`manual — <理由>` ⛔ 不是合法出口 —— 没 - 有机制能唤醒的卡不 - hold,按「暂时不准备开发 ⇒ 直接关闭」(维护者 2026-08-16 原话:「我建议有些暂时不准备开发的应该直接 - 关闭。」)关 not planned,理由与出处写进关单评论:卡即记录、重开免费、维护者可否决。**关闭 - 默认不适用 `type:Bug` 的 hold**,三分支:可复现且用户可达 ⇒ 回 `pm:queue`(被 hold 的 Bug 就是 - 被藏起的缺陷);declared≠enforced 观察类 ⇒ 转 enforce-or-remove 通道(不 hold 不裸关);真 - won't-fix 候选 ⇒ 逐卡进决策箱 —— 座位永不自行关闭真实缺陷。**机会主义重启条件必须 - 点名触发文件**(维护者 2026-08-11 接受):派发/折叠检查时读半状态巡查锚(`half-state-patrol.yml` - 的 `ANCHOR_ISSUE` 置顶 issue)的 H17 on-hold 触发文件索引、与本次派发文件面相交,命中 ⇒ - 按该 hold 评论的 rider/restart 条款处置(点名该单、顺手活列为申报过的增项)。 + 没有可点火的出口 = 谁都无法合法退出的状态,`manual — <理由>` ⛔ 不是合法出口 —— + 没有机制能唤醒的卡不 hold,按「暂时不准备开发 ⇒ 直接关闭」(维护者 2026-08-16 原话: + 「我建议有些暂时不准备开发的应该直接关闭。」)关 not planned,理由与出处写进关单评论: + 卡即记录、重开免费、维护者可否决。**关闭默认不适用 `type:Bug` 的 hold**, + 三分支:可复现且用户可达 ⇒ 回 `pm:queue`(被 hold 的 Bug 就是被藏起的缺陷);declared≠enforced + 观察类 ⇒ 转 enforce-or-remove 通道(不 hold 不裸关);真 won't-fix 候选 ⇒ 逐卡进决策箱 —— + 座位永不自行关闭真实缺陷。**机会主义重启条件必须点名触发文件**(维护者 2026-08-11 + 接受):派发/折叠检查时读半状态巡查锚(`half-state-patrol.yml` 的 `ANCHOR_ISSUE` 置顶 issue) + 的 H17 on-hold 触发文件索引、与本次派发文件面相交, + 命中 ⇒ 按该 hold 评论的 rider/restart 条款处置(点名该单、顺手活列为申报过的增项)。 - **关闭即摘 `pm:*` 状态标**(与关单同一笔;`domain:*`/类型标签留下 —— 归属不是状态)。 - **`Blocked-by:` 行是机器可 grep 的反向索引**,一遍读喂三个职责:上游关单时放回被解锁的、 - 按解锁扇出排序选择、**在合并后的 ref 上重验每张回队卡的文件面**(⛔ 只做第一件;关掉 - 上游的那个合并最可能顺手把你这张卡也修掉)。**一个标签存在,当且仅当有具名读 - 者**;`pm:blocking` 即其推导缓存(语义见状态模型行,读者以词表脚本注为权威;裁决原话见 - runbook 全序节)。 -- **跨仓解锁的判据是「消费方可安装」,不是「上游已合并」**:消费仓以**发布包**消费该上 - 游(而非 git SHA pin)时,解锁扫描放回前先验证修复已进入消费方可安装的发行版(安装面探 - 针:装上的包是否接受新键/新行为);未发版 ⇒ 转 `pm:on-hold` + `Restart-when:` 加消费方安装面 - 判据,⛔ 不回 `pm:queue` —— 回队烧掉的派发注定以 premise-false 收场;发行与依赖升级是人工 - 动作,hold 评论预写唤醒后的派发形状。pin 消费的仓不适用本条 —— pin 移动即可安装,照 - 旧走 pin 滞后读数(多仓协调 2)。 -- **状态变更不过夜**:标签挂了评论没跟上、assignee 设了没认领评论、结论只在 chat —— 都 - 是半状态,结束会话(含限流悬挂)前补齐成对或回滚半边(report-only 巡查见机械守卫索 - 引)。**等待他座位也是状态,写在卡上才存在**(等谁、自何时,⛔ 不留在会话记忆);P0 嫌疑 - 的等待 ⇒ 紧急直接分诊通道是义务不是选项(维护者 2026-08-19)。**代执行他人指令的关 - 闭/作废,评论带出处三件(谁的指令、原话、在哪说的)** —— 无出处的关闭与误操作在证 - 据上不可区分,会被兄弟席当误扫重开;同理适用于摘标签、回收认领等不可反推理由的动 - 作。 + 按解锁扇出排序选择、**在合并后的 ref 上重验每张回队卡的文件面**(⛔ 只做第一件; + 关掉上游的那个合并最可能顺手把你这张卡也修掉)。 + **一个标签存在,当且仅当有具名读者**;`pm:blocking` 即其推导缓存(语义见状态模型行, + 读者以词表脚本注为权威;裁决原话见 runbook 全序节)。 +- **跨仓解锁的判据是「消费方可安装」, + 不是「上游已合并」**:消费仓以**发布包**消费该上游(而非 git SHA pin) + 时,解锁扫描放回前先验证修复已进入消费方可安装的发行版(安装面探针: + 装上的包是否接受新键/新行为);未发版 ⇒ 转 `pm:on-hold` + `Restart-when:` + 加消费方安装面判据,⛔ 不回 `pm:queue` —— 回队烧掉的派发注定以 premise-false 收场; + 发行与依赖升级是人工动作,hold 评论预写唤醒后的派发形状。 + pin 消费的仓不适用本条 —— pin 移动即可安装,照旧走 pin 滞后读数(多仓协调 2)。 +- **状态变更不过夜**:标签挂了评论没跟上、assignee 设了没认领评论、 + 结论只在 chat —— 都是半状态,结束会话(含限流悬挂)前补齐成对或回滚半边 + (report-only 巡查见机械守卫索引)。**等待他座位也是状态,写在卡上才存在**(等谁、 + 自何时,⛔ 不留在会话记忆);P0 嫌疑的等待 ⇒ 紧急直接分诊通道是义务不是选项 + (维护者 2026-08-19)。**代执行他人指令的关闭/作废,评论带出处三件(谁的指令、 + 原话、在哪说的)** —— 无出处的关闭与误操作在证据上不可区分, + 会被兄弟席当误扫重开;同理适用于摘标签、回收认领等不可反推理由的动作。 - **写后回读按风险定向;标签写恒为硬步骤 read-modify-write + 对比式回读**(维护者 2026-08-18 裁定):① 取现集 → ② 只增删目标标签 → ③ 写合并集 → ④ 回读并 diff 对 union(现集, - 目标增删) —— 读与写之间落地的并发标签被你的整组 PUT 静默剥掉,常剥你没打算碰的那 - 枚;union 有而回读缺 = 被剥,重挂并报告(对比只察觉、不预防);**承载闸门语义的标签**(如 - `needs:contract-review`)挂与清两向同此四步,闸门被剥不是红灯是放行,与「从未挂过」在证据 - 上不可区分;多席可写面恒读回(防竞态覆盖,不只防 sanitizer);「API 200」≠「落地正确」。 -- **PM 写进 GitHub 的文本 ⛔ 不用尖括号路径占位符**,改写成「后跟显式路径」的说法(被吃 - 后剩下的裸命令读来完整而其实不是;backtick、围栏与标题同吃都不是护身符,写侧形状见事 - 实表)。不产生这个构造才是修法,回读只是兜底:携带易损片段的评论(派发令与裁决,例行 - 标记除外)post 后读回。 + 目标增删) —— 读与写之间落地的并发标签被你的整组 PUT 静默剥掉, + 常剥你没打算碰的那枚;union 有而回读缺 = 被剥, + 重挂并报告(对比只察觉、不预防);**承载闸门语义的标签**(如 `needs:contract-review`) + 挂与清两向同此四步,闸门被剥不是红灯是放行,与「从未挂过」在证据上不可区分; + 多席可写面恒读回(防竞态覆盖,不只防 sanitizer);「API 200」≠「落地正确」。 +- **PM 写进 GitHub 的文本 ⛔ 不用尖括号路径占位符**, + 改写成「后跟显式路径」的说法(被吃后剩下的裸命令读来完整而其实不是;backtick、 + 围栏与标题同吃都不是护身符,写侧形状见事实表)。不产生这个构造才是修法, + 回读只是兜底:携带易损片段的评论(派发令与裁决,例行标记除外)post 后读回。 ## 平台读数纪律 -统一原则:**判据取命令的输出,不取 API 字段的字面值、不取本地工作树现状、不取「看起来相 -邻」的日志。** GitHub API / 工具行为的实测事实表在 `references/platform-readings.md`,做对应操作 -的那一刻查阅。常驻原则: +统一原则:**判据取命令的输出, +不取 API 字段的字面值、不取本地工作树现状、不取「看起来相邻」的日志。** GitHub API +/ 工具行为的实测事实表在 `references/platform-readings.md`,做对应操作的那一刻查阅。常驻原则: - **核验 main 用 `origin/main`**(先 fetch,再 `git grep origin/main -- ` / `git show origin/main:`),⛔ 不用共享检出的工作树 —— 它的 HEAD由别的 agent 摆布。 -- **零命中必须用确定存在的邻近词反查**,否则零命中不成立;仓不可达同理,⛔ 不因「查不了」当「查 - 过了干净」—— 在 issue 上贴出给对应座位的现成命令,等读数回贴再派。 -- **定时器文本纪律(一切自设定时器适用)**:已删除的定时器仍会投递,投递时文本可能落后 - 现实数 - 轮 —— 每一枪**以「幂等 —— 动手前先重读状态」开头**,只写关键判 - 据(「若 X 则 Y」),其余指针化 - (座位贴为唯一状态源);⛔ 不写结论、不含未经重读即可执行的祈使句。 +- **零命中必须用确定存在的邻近词反查**, + 否则零命中不成立;仓不可达同理,⛔ 不因「查不了」 + 当「查过了干净」—— 在 issue 上贴出给对应座位的现成命令,等读数回贴再派。 +- **定时器文本纪律(一切自设定时器适用)**:已删除的定时器仍会投递, + 投递时文本可能落后现实数轮 —— 每一枪**以「幂等 —— 动手前先重读状态」 + 开头**,只写关键判据(「若 X 则 Y」), + 其余指针化(座位贴为唯一状态源);⛔ 不写结论、不含未经重读即可执行的祈使句。 - **放行认门禁 job 的结论,不认聚合读数**(判据 `completed: success`,定向读法见事实表);advisory - 门禁红着合并进 main 是共享损伤,任何车道发现都立即止血 + 立单(main-red 跳队与锚卡两约 - 定见 landing-operations B);落地两个读数与踢出重投的签名纪律见事实表。 -- **dev 自己死了 ≠ 维护者中止**:子代理消失(零推送/零分支/无报告)是正常死法,走死认领回 - 收;「维护者中止」只在有显式信号(原话,或宿主回报 stopped by the user)时成立 —— 判据是 - 信号不是症状,⛔ 不得据推断立一道没有重启条件的门。 -- **立单前查重**(关键词、CVE/公告号、包名、报错串各搜一遍 —— 两条 issue 描述同一个问 - 题,没有 - 门禁能看见);**共享基础设施修复,入队前按「症状」复查 main,不按issue 号**(重复修复守卫 - 只拦同 - 仓同号,后合者可能是静默回退;真撞上先比数值与作用域再决定关哪个)。 -- **sweep 晋级与立卡的前提要对「此刻的 main」**(同族 ADR 的 phase 提交能整体吸收成员;dev 带 - 证据的零实现停手是好产出,不当返工计)。**裁决明令的动作实施中测出对向事实** ⇒ 照 - 裁决字面执 - 行、被打断行为的 pin 反转为拒绝 pin(不是删除)、⛔ 同 PR 不做任何 promote/回退、冲突立 - 成 `needs-user-decision` 卡、该 PR 不挂 auto-merge 留异议窗口。 + 门禁红着合并进 main 是共享损伤,任何车道发现都立即止血 + 立单(main-red + 跳队与锚卡两约定见 landing-operations B);落地两个读数与踢出重投的签名纪律见事实表。 +- **dev 自己死了 ≠ 维护者中止**:子代理消失(零推送/零分支/无报告)是正常死法, + 走死认领回收;「维护者中止」只在有显式信号(原话,或宿主回报 stopped by the user) + 时成立 —— 判据是信号不是症状,⛔ 不得据推断立一道没有重启条件的门。 +- **立单前查重**(关键词、 + CVE/公告号、包名、报错串各搜一遍 —— 两条 issue 描述同一个问题,没有门禁能看见); + **共享基础设施修复,入队前按「症状」复查 main,不按issue 号**(重复修复守卫只拦同仓同号, + 后合者可能是静默回退;真撞上先比数值与作用域再决定关哪个)。 +- **sweep 晋级与立卡的前提要对「此刻的 main」**(同族 ADR 的 phase 提交能整体吸收成员;dev + 带证据的零实现停手是好产出,不当返工计)。**裁决明令的动作实施中测出对向事实** + ⇒ 照裁决字面执行、被打断行为的 pin 反转为拒绝 pin(不是删除)、⛔ 同 + PR 不做任何 promote/回退、冲突立成 `needs-user-decision` 卡、该 PR 不挂 auto-merge 留异议窗口。 ## 多仓协调(五条规则) -产品依赖方向固定:`objectstack`(后端;`packages/spec` 是唯一契约)→ `objectui`(前端,构建产物经 -`pnpm objectui:refresh` 回流)与 `cloud`。**仓分两类**(维护者 2026-08-26 裁定;原话与决裁归席交 -接见「升级与决策」):**多车道仓** `objectstack`、`objectui` —— 中央分诊是 `domain:*`/type/定级 -的唯一生产者;**单车道仓** `cloud`、`objectos`、`hotcrm`、`www.objectos.ai`(未来新仓默认此类)—— -其 `repo:*` 席自理无冲突的机械三务(自扫 sweep、自打 `type`、自做 `finding` 首触定级),⛔ 不产 -`domain:*`,决策卡默认入 objectstack 收件箱;跨仓查重/shadow 检查恒归中央(全仓视图不可下放)。 -**新仓登记是一张清单**:座位贴、标签、类别归属、门禁盘点;准入判据一句 —— 这个仓 -真的需要常设席位吗。逐仓事实照实设(objectos 无 changeset 流、无 `packages/`,合并队列已上线; -hotcrm 收卡判据与宪章见 `references/lanes/hotcrm.md`)。 -**objectui 卡按修复落点分流三流**(维护者 2026-08-21 裁定,`domain:ui` 唯一新增标签,命名定稿原 -话:「按 domain:ui 定稿」):`domain:devx`(工程面)/`domain:spec`(契约面)跨仓归各自车道,其余 —— 发 -布库与 apps —— `domain:ui` 归 objectui 执行席;症状位置不改流向,docs 随所记录的面走,落点不 -明留分诊首触 ⛔ 不猜。 -**车道可按仓分席(域×仓)**:忙时一个 domain 车道开多个按仓席位(如 devx@objectstack / -devx@objectui;触发即规则 4 预登记的拆分条件),各席独立座位贴与 claim 互斥,闲时收归一席 -—— 名册状态,不改协议文本;seam 卡单一归属:归修复落地仓的席,双仓皆动 objectstack 侧主 -导;`scripts/pm/**` 等住 objectstack 的全板工具链单写手恒为 objectstack 侧席,他侧上游立卡回 -链(hotcrm 宪章同款纪律)。 - -1. **Issue 住在修复落地的仓,分诊时按判据严格执行**(维护者 2026-08-10 裁决;2026-08-16 重申收 - 紧)。判 - 据:正文抽掉 objectstack 还成立 ⇒ file-at-destination,分诊当场转仓 —— console/UI 缺陷即转 - objectui - (transfer 不可用时重建:出处头 + 裸 `#N` 改全名 + 关源单为 moved);不成立才是缝卡。**缝卡收 - 窄到真 - 协调卡**,留在 objectstack 带 `repo:objectui` / `repo:cloud`,且**正文必须具名读者**(哪个座位、哪 - 一 - 步读它 —— 只有标签没有具名读者的队列没人扫);维护者收件箱恒为 objectstack。在飞卡 - ⛔ 不中途转仓。 -2. **Contract-first 拆分。** 跨仓 feature 永不是一次派发:父单 + 每仓一 sub-issue, spec/后端先行,下 - 游带 `Blocked-by: #`;凡 `Blocked-by` 未关闭/未合并的不派发(对 GitHub 现验);被链接 - 或同父的两单永不同批。**Pin 滞后是它的盲区**:本仓 pin 是否已覆盖那个 commit 是第二个 - 读数,派发前 - 用 REST `compare` 核祖先关系(本地 `merge-base` 在浅检出上给假「非祖先」);未覆盖 ⇒ 派发令 - 要求 PR - 正文留档分叉窗口,且 ⛔ pin bump 不做 rider(走专用 bump 脚本连带 override 与 lockfile)。 -3. **联动杂事立单,不靠记忆。** 已验收 PR 的产物流向另一仓时,由**接受那个 PR 的执行座 - 位**立即 - 在消费仓立后续单(带 `Blocked-by:`);`domain:*` 仍由分诊补。 -4. **纵向拆分:一个分诊 PM + N 个执行 PM,一人一车道双射**(维护者 2026-08-05 拍板;2026-08-16 裁定 - 分诊统一收归一座)。分诊座位**唯一**:多车道仓 backlog 的分诊/定级/路由/type 由它一座生 - 产,只扫/分类/打标签/拆分/查重/转仓,⛔ 永不认领、永不派发、永不写代码。执行座位信 - 任标签、只在本车道认领,误标**不自行改**、挂 `pm:retriage` + 异议评论同笔;单车道仓 - `repo:*` 席 = 执行座位 + 机械三务自理(类别与三务见首段;skills 车道 finding 自分诊例外照 - 旧)。**拆分触发条件预登记**:单轮时长逼近 fire 周期,或某仓在优先级全序下持续断粮 ⇒ - 按仓拆回多席 —— 扩容是记录在案的出口,不是重设计。⛔ 借调已删除:突发积压调频率 - 或 `batch`,持续积压拆域走 PR。**维护者直派通道**(2026-08-10 常设授权):维护者当面指挥的 PM - 会话直接路由,审计评论逐字引用授权指令,只对明示指挥的卡成立。多车道仓分诊空缺时 - 会话型执行 PM 可**代扫**(只做分诊动作,不跨车道认领,座位贴注明),座位有主立即停止 - —— 双生产者并存即失守。 -5. **一块板,不设第二跟踪器(one board, no second tracker)。** pm 标签就是状态机;org Project 只是维 - 护者的聚合视图,权威层坚持 issue 正文 + REST。 - -**跨座位转移**:工作跨座位线,PM 永不跨(唯一豁免:简单阻塞项直接接 -手,见「候选与批次」)—— 落到 -对方队列(目标仓立单带 `pm:queue` + 出处行 + 一行可执行判据),依赖走 `Blocked-by:`;后续杂事由 -消 -费侧座位立;凡触 `packages/spec` 一律转 `domain:spec` 座位(唯一所有者),不论谁需要它。**任何跨 -座 -位请求都是工作,同判**(要一次读数、要对方开卡的义务、要访问/授权):一律立卡进目标车 -道队列,⛔ 座 -位贴敲门或裁决评论永不作唯一载体(评论是加速器不是记录 —— 散文对候选查询、sweep、 -老化告警全不可 -见);等待方**同一笔**把自卡翻 `pm:blocked` + `Blocked-by:` 指向请求卡(队列标签对卡住的卡说「可派 -发」就是撒谎;落进词表的等待自动享有既有解锁扫描与老化机械,⛔ 不设新标签新 sweep);目标仓不可达 -时按缝卡规则落 objectstack 带 `repo:*` + 具名读者(顺带解掉请求方无目标仓写权限的失败)。 +产品依赖方向固定:`objectstack`(后端; +`packages/spec` 是唯一契约)→ `objectui`(前端,构建产物经 `pnpm objectui:refresh` 回流) +与 `cloud`。**仓分两类**(维护者 2026-08-26 裁定;原话与决裁归席交接见「升级与决策」): +**多车道仓** `objectstack`、`objectui` —— 中央分诊是 `domain:*`/type/定级的唯一生产者; +**单车道仓** `cloud`、`objectos`、`hotcrm`、`www.objectos.ai`(未来新仓默认此类)—— 其 `repo:*` +席自理无冲突的机械三务(自扫 sweep、自打 `type`、自做 `finding` 首触定级),⛔ 不产 `domain:*`, +决策卡默认入 objectstack 收件箱;跨仓查重/shadow 检查恒归中央(全仓视图不可下放)。 +**新仓登记是一张清单**:座位贴、标签、类别归属、门禁盘点; +准入判据一句 —— 这个仓真的需要常设席位吗。逐仓事实照实设(objectos 无 changeset 流、 +无 `packages/`,合并队列已上线;hotcrm 收卡判据与宪章见 `references/lanes/hotcrm.md`)。 +**objectui 卡按修复落点分流三流**(维护者 2026-08-21 裁定,`domain:ui` 唯一新增标签, +命名定稿原话:「按 domain:ui 定稿」):`domain:devx`(工程面)/`domain:spec`(契约面)跨仓归各自车道, +其余 —— 发布库与 apps —— `domain:ui` 归 objectui 执行席;症状位置不改流向,docs +随所记录的面走,落点不明留分诊首触 ⛔ 不猜。**车道可按仓分席(域×仓)**:忙时一个 +domain 车道开多个按仓席位(如 devx@objectstack / devx@objectui;触发即规则 4 预登记的拆分条件), +各席独立座位贴与 claim 互斥,闲时收归一席 —— 名册状态,不改协议文本;seam 卡单一归属: +归修复落地仓的席,双仓皆动 objectstack 侧主导;`scripts/pm/**` 等住 +objectstack 的全板工具链单写手恒为 objectstack 侧席,他侧上游立卡回链(hotcrm 宪章同款纪律)。 + +1. **Issue 住在修复落地的仓,分诊时按判据严格执行**(维护者 + 2026-08-10 裁决;2026-08-16 重申收紧)。判据:正文抽掉 objectstack 还成立 ⇒ file-at-destination, + 分诊当场转仓 —— console/UI 缺陷即转 objectui(transfer 不可用时重建: + 出处头 + 裸 `#N` 改全名 + 关源单为 moved);不成立才是缝卡。**缝卡收窄到真协调卡**, + 留在 objectstack 带 `repo:objectui` / `repo:cloud`,且**正文必须具名读者**(哪个座位、 + 哪一步读它 —— 只有标签没有具名读者的队列没人扫); + 维护者收件箱恒为 objectstack。在飞卡 ⛔ 不中途转仓。 +2. **Contract-first 拆分。** 跨仓 feature 永不是一次派发:父单 + 每仓一 sub-issue, spec/后端先行, + 下游带 `Blocked-by: #`;凡 `Blocked-by` 未关闭/未合并的不派发(对 GitHub 现验); + 被链接或同父的两单永不同批。**Pin 滞后是它的盲区**: + 本仓 pin 是否已覆盖那个 commit 是第二个读数,派发前用 REST `compare` 核祖先关系 + (本地 `merge-base` 在浅检出上给假「非祖先」);未覆盖 ⇒ 派发令要求 PR 正文留档分叉窗口, + 且 ⛔ pin bump 不做 rider(走专用 bump 脚本连带 override 与 lockfile)。 +3. **联动杂事立单,不靠记忆。** 已验收 PR 的产物流向另一仓时, + 由**接受那个 PR 的执行座位**立即在消费仓立后续单(带 `Blocked-by:`);`domain:*` 仍由分诊补。 +4. **纵向拆分:一个分诊 PM + N 个执行 PM,一人一车道双射** + (维护者 2026-08-05 拍板;2026-08-16 裁定分诊统一收归一座)。分诊座位**唯一**: + 多车道仓 backlog 的分诊/定级/路由/type 由它一座生产,只扫/分类/打标签/拆分/查重/转仓, + ⛔ 永不认领、永不派发、永不写代码。执行座位信任标签、 + 只在本车道认领,误标**不自行改**、挂 `pm:retriage` + 异议评论同笔;单车道仓 `repo:*` + 席 = 执行座位 + 机械三务自理(类别与三务见首段;skills 车道 finding 自分诊例外照旧)。 + **拆分触发条件预登记**:单轮时长逼近 fire 周期,或某仓在优先级全序下持续断粮 + ⇒ 按仓拆回多席 —— 扩容是记录在案的出口,不是重设计。⛔ 借调已删除: + 突发积压调频率或 `batch`,持续积压拆域走 PR。**维护者直派通道**(2026-08-10 常设授权): + 维护者当面指挥的 PM 会话直接路由,审计评论逐字引用授权指令, + 只对明示指挥的卡成立。多车道仓分诊空缺时会话型执行 PM 可**代扫**(只做分诊动作, + 不跨车道认领,座位贴注明),座位有主立即停止 —— 双生产者并存即失守。 +5. **一块板,不设第二跟踪器(one board, no second tracker)。 + ** pm 标签就是状态机;org Project 只是维护者的聚合视图,权威层坚持 issue 正文 + REST。 + +**跨座位转移**:工作跨座位线,PM 永不跨(唯一豁免:简单阻塞项直接接手, +见「候选与批次」)—— 落到对方队列(目标仓立单带 `pm:queue` + 出处行 + 一行可执行判据), +依赖走 `Blocked-by:`; +后续杂事由消费侧座位立;凡触 `packages/spec` 一律转 `domain:spec` 座位(唯一所有者), +不论谁需要它。**任何跨座位请求都是工作,同判**(要一次读数、要对方开卡的义务、 +要访问/授权):一律立卡进目标车道队列,⛔ 座位贴敲门或裁决评论永不作唯一载体 +(评论是加速器不是记录 —— 散文对候选查询、sweep、老化告警全不可见); +等待方**同一笔**把自卡翻 `pm:blocked` + `Blocked-by:` 指向请求卡(队列标签对卡住的卡说 +「可派发」就是撒谎;落进词表的等待自动享有既有解锁扫描与老化机械, +⛔ 不设新标签新 sweep);目标仓不可达时按缝卡规则落 +objectstack 带 `repo:*` + 具名读者(顺带解掉请求方无目标仓写权限的失败)。 ## 域车道(Domain lanes,同仓多 PM 并发) @@ -271,289 +262,267 @@ devx@objectui;触发即规则 4 预登记的拆分条件),各席独立座位贴 | `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:*` 恰 -一张座位贴。 +表未覆盖的包在首次分诊时归类并**走 PR 更新本表**; +**新增或退役一个 `domain:*` 必须同批改本表**(在流通而不在表 = 无主车道)。 +座位在编情况以 `label:pm:seat` 索引为准,每个 `domain:*` 与 `repo:*` 恰一张座位贴。 -**单一生产者。** `domain:*` 只由分诊座位产出;打标签 ≠ 认领;**未打标签的 issue 任何人不得 -认领 -** —— 那意味着分诊还没走到,不是「可以自己判一下」。 +**单一生产者。** `domain:*` 只由分诊座位产出;打标签 ≠ 认领;**未打标签的 +issue 任何人不得认领** —— 那意味着分诊还没走到,不是「可以自己判一下」。 -**跨域例外路径(越界通道之一;另一条:简单阻塞项直接接手,见「候选与批次」)。** 真拆不 -动的跨域 -单 PR 由**分诊座位指定**一个车道PM 认领;认领评论**申报完整文件面**;只在这条路径上 -跑**定向在飞 -检查**(范围 = 该单文件面触及的那几个域的在飞单,读各自认领评论的文件面申报,要求不相 -交,相交即 -让行)。日常同域批次选择不跑全局在飞检查 —— 同域独立性由本域批次选择保证,跨域相 -交只从这两条越界通道进来。 +**跨域例外路径(越界通道之一;另一条:简单阻塞项直接接手,见「候选与批次」)。 +** 真拆不动的跨域单 PR 由**分诊座位指定**一个车道PM 认领;认领评论**申报完整文件面**; +只在这条路径上跑**定向在飞检查**(范围 = 该单文件面触及的那几个域的在飞单, +读各自认领评论的文件面申报,要求不相交, +相交即让行)。日常同域批次选择不跑全局在飞检查 —— 同域独立性由本域批次选择保证, +跨域相交只从这两条越界通道进来。 -**合并队列仍是一条共享串行资源。** 车道买到的是并行编写,不是并行落地;flaky 税随PM 数 -线性放大 -,红队列同时挡住所有车道 —— 谁发现 flake 谁修或立单,不绕行。 +**合并队列仍是一条共享串行资源。** 车道买到的是并行编写,不是并行落地;flaky +税随PM 数线性放大,红队列同时挡住所有车道 —— 谁发现 flake 谁修或立单,不绕行。 ## 座位贴协议(一座位一贴,单写手) 多写手共编一个 body 机制上防不住互吞(维护者 2026-08-06 拍板):**贴 = 座位**(标签 `pm:seat`), -正文固定**四段**现值(当前 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;「经验教训」散文不再入技能文 -本 +正文固定**四段**现值(当前 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 子树车道 -大开发(父单 + sub-issue 树)整体委托一个专职 PM 会话:`/pm-dispatch epic:#`。队列 = 子 -树 open 未认领 sub-issue,**每轮重读不缓存**(新挂的自动入队)。委托信号成对落地:父单 -打 `pm:epic` + 正文写会话 ID 与声明的文件领地;其它 PM 的候选获取跳过整棵子树;域座位批次 -选择 -时读一次 `label:pm:epic` 索引避开领地相交。epic PM 不同时持有`domain:*` 座位;认领纪律全套照 -做;触 `packages/spec` 的 sub-issue 照旧转 spec 座位。**衍生问题三分法**(判据:不修它,epic 验 -收过不过得去?):in-scope ⇒ 挂父单sub-issue 下轮自动入队;顺带发现 ⇒ 独立立单进修复落地 -仓 backlog(查重先行,⛔ 不借sub-issue 通道把未分诊的塞进池子);触 spec/公共契约 ⇒ 转 spec 座 -位 -队列 + epic 侧写`Blocked-by:`;每次分流留一行审计评论。进度视图:父单维护 checklist 汇总评 -论,决策仍锚在具体 sub-issue。收尾四步、僵尸回收与领地防撞(声明式,越窄越诚实)细则见 -`references/seat-post-protocol.md`。 +大开发(父单 + sub-issue 树)整体委托一个专职 PM 会话:`/pm-dispatch epic:#`。 +队列 = 子树 open 未认领 sub-issue,**每轮重读不缓存**(新挂的自动入队)。委托信号成对落地: +父单打 `pm:epic` + 正文写会话 ID 与声明的文件领地;其它 PM 的候选获取跳过整棵子树; +域座位批次选择时读一次 `label:pm:epic` 索引避开领地相交。epic PM 不同时持有`domain:*` 座位; +认领纪律全套照做;触 `packages/spec` 的 sub-issue 照旧转 spec 座位。**衍生问题三分法**(判据: +不修它,epic 验收过不过得去?):in-scope ⇒ 挂父单sub-issue 下轮自动入队; +顺带发现 ⇒ 独立立单进修复落地仓 backlog(查重先行,⛔ 不借sub-issue +通道把未分诊的塞进池子);触 spec/公共契约 ⇒ 转 spec 座位队列 + epic 侧写`Blocked-by:`; +每次分流留一行审计评论。进度视图:父单维护 checklist 汇总评论,决策仍锚在具体 sub-issue。 +收尾四步、僵尸回收与领地防撞(声明式,越窄越诚实)细则见 `references/seat-post-protocol.md`。 ## 分诊座位职责 -(执行座位 ⛔ 跳过本节动作 —— 读到标签当既成事实。)职责按仓类执行(类别 -见「多仓协调」首段):sweep 与首触定级只对多车道仓(单车道仓机械三务自理);发版板(无板仓 -跳过)、查重/shadow 检查与代裁通道全仓照跑。**代裁通道保留、档位硬门**(维护者 2026-08-26 -裁定,原话:「代裁通道如果是 fable 可以代裁,其他接受你的建议」):裁决只由**达档者**产出 +(执行座位 ⛔ 跳过本节动作 —— 读到标签当既成事实。) +职责按仓类执行(类别见「多仓协调」 +首段):sweep 与首触定级只对多车道仓(单车道仓机械三务自理);发版板(无板仓跳过)、 +查重/shadow 检查与代裁通道全仓照跑。**代裁通道保留、档位硬门**(维护者 2026-08-26 裁定, +原话:「代裁通道如果是 fable 可以代裁,其他接受你的建议」):裁决只由**达档者**产出 (⛔ 永不凭自述)—— 分诊席显式传 `model` 的 fable 子代理(逐份过转录核验,2026-08-27 裁;见 `references/contract-review.md`)或达档总监席;其余座位 ⛔ 不代裁;2026-08-12 置信门其余条件照旧。 -**工具加载纪律(fire 开局)**:互斥检查/自退判断只按名加载所需工具 —— `ToolSearch` 用 -`select:mcp__github__list_issues,mcp__github__issue_read` 形式,判定「本轮有活」之后才加载其余;⛔ 开 -局不做泛关键词 ToolSearch(一次注入全家桶 schema —— 分诊席 2026-08-20 自测:空转轮 ~12 万 -token,~8 万是这张门票);可验判据:空转轮 ~4 万以内。只约束分诊 fresh session 的开局,执行座 -位与 dev(需全工具面)不受此约束。 - -**两级盘点(two-tier inventory;维护者 -2026-08-20:「每次都需要 四仓全量 open issue 盘点 … 吗?建议分诊多久执行一次」→「立卡」)**:小 -时轮以 `since` 窗口读增量 —— 锚 = 座位贴上一份收班简报的时间戳(互斥守卫同一读数,零 -新状态;标签写入刷新 `updated_at`,窗口锚在简报而非上次 fire,漏 fire 积压自动入窗);每日一 -fire 跑全仓全量对账并归集日频职责;选层按 fire 时刻 ⛔ 不用计数器(fresh session 无计数 -器);简报写明本轮跑的层(下轮读者靠它知道窗口盖了什么)。从不更新的卡不入窗是设计:它 -上次变更时已被扫过,老化欠账归半状态巡查不归小时轮(`since` 读法与成本对价见 runbook)。 - -**Backlog sweep(常设职责,不等请求)。** 每轮扫任一析取命中的卡:① 全裸(无`pm:*`、无 -`needs-user-decision`、无 `domain:*`);② 有 `pm:queue` 无 `domain:*`(仅多车道仓 —— 三流拆分见多仓 -协调;单车道仓无 `domain:*` 是队列卡常态,自扫归其席);③ 有 `domain:*` 无 pm-state。②③ 只取 -`updated_at` 早于 ~2 分钟的卡且不是可选项 —— 半标注卡是协议自己按设计生产的(一次标签 -写入即把老卡打成半标注),只带路由或状态机其一的卡对两个视图同时不可见。排 -除:`tracking`、`status:parked`(其正常形状恰是「带域标签无 pm-state」)、全部 `pm:seat` 贴、`qa-run` -记录(协议载体非工作);存量大时每轮限量 —— 新入卡①优先最新,半状态治愈积压②③**最 -老优先、P0 嫌疑先行**,⛔ 优先最新不适用(细则见 runbook)。**紧急卡直接分诊** (维护者 -2026-08-13):维护者点名或 p0 嫌疑 ⇒ 立即起 `claude-fable-5` 分诊子代理,不等定时轮次;授权面 = -分诊本身(定级/路由/标签/既有评论格式),⛔ 不写码不认领;产出落卡,与定时轮分诊同格式同 -效力(细则见 `references/dispatch-runbook.md`)。 **跨仓 pin 链的窗口级兜底也在本 sweep**(联动单第 -一产者仍是接受座位;⛔ 只立单不执行 bump): objectui pin 落后且其队列已空 ⇒ 在本仓立/刷新 -console bump 单;见新 tag 族发布 ⇒ 在 cloud 立 `.objectstack-sha` bump 单;单张封顶(先查同题 open -单,已有就追评刷新),工具链新形态只提请不扩面。 +**工具加载纪律(fire 开局)**:互斥检查/自退判断只按名加载所需工具 —— `ToolSearch` +用 `select:mcp__github__list_issues,mcp__github__issue_read` 形式,判定「本轮有活」之后才加载其余; +⛔ 开局不做泛关键词 ToolSearch(一次注入全家桶 schema —— 分诊席 2026-08-20 自测: +空转轮 ~12 万 token,~8 万是这张门票);可验判据: +空转轮 ~4 万以内。只约束分诊 fresh session 的开局,执行座位与 dev(需全工具面)不受此约束。 + +**两级盘点(two-tier inventory;维护者 2026-08-20: +「每次都需要 四仓全量 open issue 盘点 … 吗?建议分诊多久执行一次」→「立卡」)**: +小时轮以 `since` 窗口读增量 —— 锚 = 座位贴上一份收班简报的时间戳(互斥守卫同一读数, +零新状态;标签写入刷新 `updated_at`,窗口锚在简报而非上次 fire, +漏 fire 积压自动入窗);每日一 fire 跑全仓全量对账并归集日频职责; +选层按 fire 时刻 ⛔ 不用计数器(fresh session 无计数器);简报写明本轮跑的层 +(下轮读者靠它知道窗口盖了什么)。从不更新的卡不入窗是设计:它上次变更时已被扫过, +老化欠账归半状态巡查不归小时轮(`since` 读法与成本对价见 runbook)。 + +**Backlog sweep(常设职责, +不等请求)。** 每轮扫任一析取命中的卡:① 全裸(无`pm:*`、无 `needs-user-decision`、 +无 `domain:*`);② 有 `pm:queue` 无 `domain:*`(仅多车道仓 —— 三流拆分见多仓协调; +单车道仓无 `domain:*` 是队列卡常态,自扫归其席);③ 有 `domain:*` 无 pm-state。 +②③ 只取 `updated_at` 早于 ~2 分钟的卡且不是可选项 —— 半标注卡是协议自己按设计生产的 +(一次标签写入即把老卡打成半标注),只带路由或状态机其一的卡对两个视图同时不可见。 +排除:`tracking`、`status:parked`(其正常形状恰是「带域标签无 pm-state」)、 +全部 `pm:seat` 贴、`qa-run` 记录(协议载体非工作);存量大时每轮限量 —— 新入卡①优先最新, +半状态治愈积压②③**最老优先、P0 嫌疑先行**,⛔ 优先最新不适用(细则见 runbook)。 +**紧急卡直接分诊** (维护者 2026-08-13):维护者点名或 p0 嫌疑 ⇒ 立即起 +`claude-fable-5` 分诊子代理,不等定时轮次;授权面 = 分诊本身(定级/路由/标签/既有评论格式), +⛔ 不写码不认领;产出落卡,与定时轮分诊同格式同效力(细则见 `references/dispatch-runbook.md`)。 +**跨仓 pin 链的窗口级兜底也在本 sweep**(联动单第一产者仍是接受座位; +⛔ 只立单不执行 bump): objectui pin 落后且其队列已空 ⇒ 在本仓立/刷新 console bump 单; +见新 tag 族发布 ⇒ 在 cloud 立 `.objectstack-sha` bump 单; +单张封顶(先查同题 open 单,已有就追评刷新),工具链新形态只提请不扩面。 **分类动作**(每张三选一 + 一个修复通道):**`pm:queue`** —— 有具名落点或复现的具体缺陷、 -范围明确 -的工具/门禁修复、恢复不变量的 finding、test-only pin,无可问之事;**`needs-user-decision`** —— 设 -计卡、feature/契约形状提案、需要 appetite 的多周程序、碰存量数据迁移形状或删除已发布能 -力的,落卡时 -**必带四棱卡面块**(见「升级与决策」),⛔ 不留待有人接手再补;**`finding`** —— 观察类(死 -代码、未演 -练漂移、抛光;真实但今天没有用户撞上),待首次定级;**先修复(repair first)** —— 正文被 -sanitizer 截断的卡不 -可派发,评论修复指令后跳过;停摆指令判据必须比其它分类更硬(双读取),事后证伪同处公开 -作废。 -**决策箱勤务(常设)**:落卡入箱时校验/补全标准四棱卡面块(块形状见「升级与决策」);存量 -卡低频子轮回填,语言按不变量。 - -**原生 issue 类型 Bug/Feature/Task 是分诊的固定产出**(维护者 2026-08-12 裁定「同意」):分诊 -座位是 `type` 字段的唯一权威生产者(立单者可预填,分诊校正 —— 与 `domain:*` 同一纪律);判 -据即 -代裁的机械边界测试(⛔ 不另抄):违背已声明契约 ⇒ `Bug`,扩大接受集/公开面 ⇒ `Feature`,其 -余 -⇒ `Task`。`Bug` 无具名落点或复现路径不入 `pm:queue`(标记补复现);⛔ 不回填存量 backlog(全库 -重 -扫必烂),新卡即时打、存量卡下次碰到补。读者三个:代裁路由(`Feature` 机械落人工地板,`Bug`/ -`Task` 才是代裁候选)、发版板缺陷扫描(`type:Bug is:open`)、普通队列 Bug 优先平手判据。 - -**路由即分诊的技术判断,永不升级「哪个仓?」。** 读全仓代码定落点;跨仓的按contract-first -拆分;父单已有子结构的,父单队列标签即可(sub-issue 自动成为候选),分诊逐个展开路由、补 -`Blocked-by:` -排序,父单是协调节点**永不派发**。每张留一条英文审计评 -论(「Triage: lands in …; rationale: …」) -,可选带 `Size/model suggestion:` 行供执行席参考。跨仓查重(shadow 检查):跟跨仓引用 + 关键词搜 -各姊妹仓 —— 在飞 ⇒ `Blocked-by:` 不派;open 未认领 ⇒ 先收敛成一个派发入口;已完成 ⇒ 卡 -可能过期 -。**「生产者在哪?」是常设分诊问题**:declared ≠ enforced 形状的卡先问谁在写这个字段 —— -答案通 -常就是根因,并在派发前改变卡的范围与域标签。 - -**发现分诊轮(队列的出水口)。** `finding` 恒 = 待首次定级、定级即离标(维护者 2026-08-13 意 -见;换标与 hold 评论纪律见状态模型,hold 重验只在 `Restart-when:` 命中时发生 —— closed 形态随 -每轮解锁扫描,可执行判据由分诊席每日一个低频子轮批量执行(十几条一行判据逐小时 -跑是浪费,每日即消化节奏),命中同 closed 命中一个待遇:回队前 ref 重验再回队;⛔ 不设逐卡 -豁免评论)。**每 fire 跑到清空**:⛔ 无每轮总量预算,当轮定完全部未定级 finding、优先于旧 -卡重验;质量靠**每批 ≤5 张同族卡逐张读**,不靠封顶总量(维护者 2026-08-25,原话不译): -「单轮跑数小时没关系啊。不读卡的批量盖章 可以通过每批5张这种约定来解决」 -—— 单轮数小时是可接受形态;窗口耗尽未跑完的,下一 fire 从断点续跑(定级即离标,⛔ 不重 -读,标签纪律即断点)。每批先过时前提检查再三选一 —— 晋级 / 关闭 not planned(维护者可否 -决重开,PM 不等批准)/ hold;**判级发生在这里,不在立单时**。车道座位可附证据/前提重验,⛔ -不定级不改标(唯一例外:skills 车道 finding 由该席自分诊,全仓轮跳过)。域分批与 sweep 打包晋 -级五条照用(常设授权,维护者 2026-08-13);原话、每批约定与积压告警见 -`references/dispatch-runbook.md`。 -**`pm:retriage` 重判每 fire 高优先处理**:按异议评论的证据与建议定级重裁,维持或改判皆由本 -座位同笔摘标(挂标归异议席,见状态模型)。 - -**发版板(`target:`;鲜度节奏、清板三选一、pin 前置等运维细则见 -`references/seat-post-protocol.md`)。** 判据二元(⛔ 不做优先级渐变 —— 渐变没人维护):「不修它, -当前 RC 能不能发?」判阻塞四类:① 用户今天就撞的已发布面缺陷;② 公开契约 declared≠enforced;③ 存 -量数据/迁移形状(发布后修不回);④ 发布说明里要为它道歉的。拆分/分票时 `target:*` 随工作 -走,对每 -一半重跑二元判据,默认继承,不继承按四类写明理由。**每张板同归本座位生产**(每板恰好 -一个生产者)。 - -**高置信决策卡的分诊代裁(维护者 2026-08-12 裁定)。** 出处原话:「让他帮我从实际业务需求出发, -从平台长远合理性出发,从避免ai写代码犯错的角度出发,从创业阶段不扩散需求的角度出发综合分析……很 -多时候ai会有明确的建议,大部分建议我都会接受,这个是不是可以让分诊就处理掉。他没把握的才找我」 -;「我同意你的意见,并补充功能新增类的,adr类别的,协议变化类别的,还是需要人工决裁,如果是代码整 -理或者bug修改,具体的代码细节其实ai看的比我清楚,让我判断我也判断不了」。 - -- **人工地板(不论四棱是否同向,恒交维护者)**:功能新增类;ADR 类;协议/公开契约变化类;破坏 - 性或难回滚动作(存量数据迁移形状、删除已发布能力、force 操作);**安全/权限边界**(放宽 - 访问控制、认证流、RLS/共享语义、审计留痕的「修复」是伪装的产品决定);**门禁削 - 弱**(降阈值、删必查项、抬 ratchet 上限、跳过/隔离测试 —— AI 有把CI 弄绿的结构性动 - 机,削弱农场必须是人的动作);**花费/配额/舰队形态/默认模型档位** (动的是维护者的预 - 算);**新增运行时第三方依赖**(供应链/许可/维护义务)。 -- **代裁车道(分诊座位裁)**:代码整理(行为不变的重构)与 bug 修复。**机械边界测试**:改动是 - 否** 扩大接受集或公开面**?扩大 ⇒ 功能新增/协议变化 ⇒ 人工;接受集不变、拉回已声明 - 契约(declared = enforced 的恢复)⇒ bug/整理 ⇒ 代裁车道。 -- **置信门(全部成立才可代裁)**:① 四棱同向(全指向同一选项,任何分裂即升级);② 不在人工 - 地板上;③ 不收窄、不推翻任何既有维护者裁决;④ 执行是**否决窗口不是许可门**—— - 裁定 → 一次标签写入换 `needs-user-decision` 为工作态 → 卡上贴四棱块 + 结论 + - `auto-adjudicated` 标记 → 轮次报告设**代裁清单**专节(聚合漂移的刹车);⑤ 本节首段的档位 - 硬门达标(未达 ⇒ 本 fire 代裁整体跳过、卡原样留在决策箱走维护者路径,恒安全)。 +范围明确的工具/门禁修复、恢复不变量的 finding、test-only pin,无可问之事; +**`needs-user-decision`** —— 设计卡、feature/契约形状提案、需要 appetite 的多周程序、 +碰存量数据迁移形状或删除已发布能力的,落卡时**必带四棱卡面块**(见「升级与决策」), +⛔ 不留待有人接手再补;**`finding`** —— 观察类(死代码、 +未演练漂移、抛光;真实但今天没有用户撞上),待首次定级;**先修复(repair first)** —— 正文被 +sanitizer 截断的卡不可派发,评论修复指令后跳过;停摆指令判据必须比其它分类更硬(双读取), +事后证伪同处公开作废。**决策箱勤务(常设)**:落卡入箱时校验/补全标准四棱卡面块 +(块形状见「升级与决策」);存量卡低频子轮回填,语言按不变量。 + +**原生 issue 类型 Bug/Feature/Task 是分诊的固定产出**(维护者 2026-08-12 裁定「同意」): +分诊座位是 `type` 字段的唯一权威生产者(立单者可预填, +分诊校正 —— 与 `domain:*` 同一纪律);判据即代裁的机械边界测试(⛔ 不另抄): +违背已声明契约 ⇒ `Bug`,扩大接受集/公开面 ⇒ `Feature`,其余 ⇒ `Task`。 +`Bug` 无具名落点或复现路径不入 `pm:queue`(标记补复现);⛔ 不回填存量 backlog(全库重扫必烂), +新卡即时打、存量卡下次碰到补。读者三个:代裁路由(`Feature` 机械落人工地板, +`Bug`/ `Task` 才是代裁候选)、发版板缺陷扫描(`type:Bug is:open`)、普通队列 Bug 优先平手判据。 + +**路由即分诊的技术判断, +永不升级「哪个仓?」。** 读全仓代码定落点;跨仓的按contract-first 拆分;父单已有子结构的, +父单队列标签即可(sub-issue 自动成为候选),分诊逐个展开路由、补 `Blocked-by:` 排序, +父单是协调节点**永不派发**。每张留一条英文审计评论(「Triage: lands in …; rationale: …」), +可选带 `Size/model suggestion:` 行供执行席参考。跨仓查重(shadow 检查):跟跨仓引用 + +关键词搜各姊妹仓 —— 在飞 ⇒ `Blocked-by:` 不派;open 未认领 ⇒ 先收敛成一个派发入口; +已完成 ⇒ 卡可能过期。**「生产者在哪?」是常设分诊问题**:declared ≠ enforced +形状的卡先问谁在写这个字段 —— 答案通常就是根因,并在派发前改变卡的范围与域标签。 + +**发现分诊轮(队列的出水口)。** `finding` 恒 = 待首次定级、定级即离标(维护者 +2026-08-13 意见;换标与 hold 评论纪律见状态模型,hold 重验只在 `Restart-when:` 命中时发生 +—— closed 形态随每轮解锁扫描,可执行判据由分诊席每日一个低频子轮批量执行 +(十几条一行判据逐小时跑是浪费,每日即消化节奏),命中同 closed 命中一个待遇: +回队前 ref 重验再回队;⛔ 不设逐卡豁免评论)。**每 fire 跑到清空**:⛔ 无每轮总量预算, +当轮定完全部未定级 finding、优先于旧卡重验;质量靠**每批 ≤5 张同族卡逐张读**, +不靠封顶总量(维护者 2026-08-25,原话不译):「单轮跑数小时没关系啊。 +不读卡的批量盖章 可以通过每批5张这种约定来解决」 —— 单轮数小时是可接受形态; +窗口耗尽未跑完的,下一 fire 从断点续跑(定级即离标,⛔ 不重读,标签纪律即断点)。 +每批先过时前提检查再三选一 —— 晋级 / 关闭 not planned(维护者可否决重开,PM 不等批准)/ +hold;**判级发生在这里,不在立单时**。车道座位可附证据/前提重验,⛔ 不定级不改标 +(唯一例外:skills 车道 finding 由该席自分诊,全仓轮跳过)。域分批与 sweep 打包晋级五条照用 +(常设授权,维护者 2026-08-13);原话、每批约定与积压告警见 `references/dispatch-runbook.md`。 +**`pm:retriage` 重判每 fire 高优先处理**:按异议评论的证据与建议定级重裁, +维持或改判皆由本座位同笔摘标(挂标归异议席,见状态模型)。 + +**发版板(`target:`;鲜度节奏、清板三选一、 +pin 前置等运维细则见 `references/seat-post-protocol.md`)。** 判据二元(⛔ 不做优先级渐变 —— +渐变没人维护):「不修它,当前 RC 能不能发?」判阻塞四类:① 用户今天就撞的已发布面缺陷; +② 公开契约 declared≠enforced;③ 存量数据/迁移形状(发布后修不回); +④ 发布说明里要为它道歉的。拆分/分票时 `target:*` 随工作走,对每一半重跑二元判据, +默认继承,不继承按四类写明理由。**每张板同归本座位生产**(每板恰好一个生产者)。 + +**高置信决策卡的分诊代裁(维护者 2026-08-12 裁定)。 +** 出处原话:「让他帮我从实际业务需求出发,从平台长远合理性出发, +从避免ai写代码犯错的角度出发,从创业阶段不扩散需求的角度出发综合分析…… +很多时候ai会有明确的建议,大部分建议我都会接受,这个是不是可以让分诊就处理掉。 +他没把握的才找我」;「我同意你的意见,并补充功能新增类的,adr类别的, +协议变化类别的,还是需要人工决裁,如果是代码整理或者bug修改, +具体的代码细节其实ai看的比我清楚,让我判断我也判断不了」。 + +- **人工地板(不论四棱是否同向,恒交维护者)**:功能新增类;ADR 类;协议/公开契约变化类; + 破坏性或难回滚动作(存量数据迁移形状、删除已发布能力、force 操作);**安全/权限边界** + (放宽访问控制、认证流、RLS/共享语义、审计留痕的「修复」是伪装的产品决定); + **门禁削弱**(降阈值、删必查项、抬 ratchet 上限、跳过/隔离测试 —— AI + 有把CI 弄绿的结构性动机,削弱农场必须是人的动作);**花费/配额/舰队形态/默认模型档位** + (动的是维护者的预算);**新增运行时第三方依赖**(供应链/许可/维护义务)。 +- **代裁车道(分诊座位裁)**:代码整理(行为不变的重构)与 bug 修复。 + **机械边界测试**:改动是否** 扩大接受集或公开面**?扩大 ⇒ 功能新增/协议变化 ⇒ 人工; + 接受集不变、拉回已声明契约(declared = enforced 的恢复)⇒ bug/整理 ⇒ 代裁车道。 +- **置信门(全部成立才可代裁)**:① 四棱同向(全指向同一选项, + 任何分裂即升级);② 不在人工地板上;③ 不收窄、不推翻任何既有维护者裁决; + ④ 执行是**否决窗口不是许可门**—— 裁定 → 一次标签写入换 `needs-user-decision` + 为工作态 → 卡上贴四棱块 + 结论 + `auto-adjudicated` 标记 → 轮次报告设**代裁清单**专节 + (聚合漂移的刹车);⑤ 本节首段的档位硬门达标(未达 ⇒ 本 fire 代裁整体跳过、 + 卡原样留在决策箱走维护者路径,恒安全)。 - **一类自裁门(维护者 2026-08-29 裁:「把「一类」判据写进代裁通道(skills 席立卡固化)」)**: - 召唤中总监席可免呈自裁一张决策卡,当且仅当三判据全立:① 既有维护者裁定/在案类规 - 则/成文纪律**机械决定方向**(席位只应用不发明;裁决评论必须点名所用权威 —— 在案裁 - 定的日期/引文、类规则或纪律的家);② 失败方向响亮(拒绝/诊断/红门禁,永不无声行为漂 - 移)且一次 revert 可回;③ 四类人工地板零移动 —— 安全/权限边界 · 已发布契约语义(含 - wire 形与产品面方向)· 产品能力取舍 · 门禁强度,任一触碰 ⇒ 照常现场呈报,不论①②;降 - 档保险丝照管(不达 `CONTRACT_REVIEW_TIER` ⇒ 通道整体跳过、卡停放),地板是排除项不是权重。 - 逐卡记录:裁决评论引本通道 + ①的权威,随后状态转移与现场裁过的卡同型(录裁 + 转 - `pm:queue`,⛔ 裁不派);每场召唤收尾呈一张**摘要表(卡 · 权威 · 方向)**供维护者追认,被推 - 翻的行以该卡新裁决评论 + 状态转移执行。二类(边界:带一个可报点)与三类(地板)照旧现 - 场呈报,走每批 ≤5 与详细写法纪律。 -- **回翻条款**:代裁卡实施中发现契约终究要动 ⇒ dev 停手,卡回`needs-user-decision` —— 报告 - 分叉,⛔ 永不静默重裁。 -- **请示纪律(维护者 2026-08-25:「不要不停的弹出来让我确认,很浪费时间」)**:①方向性授权( - 如「接受你的建议」「帮我合并」)覆盖整条执行链一并做完,⛔ 不逐项回问;②需裁事项** - 攒批**(≤5 项/批,每项一行带推荐),一句同意即全链执行;③中间状态与限流/重试类运维细 - 节只进座位贴和触发器,⛔ 不弹给维护者——汇报只在里程碑、真阻塞、被问到时;④可逆 - 且有推荐默认的事项按否决窗口:声明即执行,异议再回滚;人工地板项(发版、天花板、契约 - 扩大)仍需明确字句,但攒批不逐项弹。 + 召唤中总监席可免呈自裁一张决策卡,当且仅当三判据全立: + ① 既有维护者裁定/在案类规则/成文纪律**机械决定方向**(席位只应用不发明; + 裁决评论必须点名所用权威 —— 在案裁定的日期/引文、类规则或纪律的家); + ② 失败方向响亮(拒绝/诊断/红门禁,永不无声行为漂移)且一次 revert 可回; + ③ 四类人工地板零移动 —— 安全/权限边界 · 已发布契约语义(含 wire 形与产品面方向) + · 产品能力取舍 · 门禁强度,任一触碰 ⇒ 照常现场呈报,不论①②;降档保险丝照管 + (不达 `CONTRACT_REVIEW_TIER` ⇒ 通道整体跳过、卡停放),地板是排除项不是权重。逐卡记录: + 裁决评论引本通道 + ①的权威,随后状态转移与现场裁过的卡同型(录裁 + 转 `pm:queue`, + ⛔ 裁不派);每场召唤收尾呈一张**摘要表(卡 · 权威 · 方向)**供维护者追认, + 被推翻的行以该卡新裁决评论 + 状态转移执行。 + 二类(边界:带一个可报点)与三类(地板)照旧现场呈报,走每批 ≤5 与详细写法纪律。 +- **回翻条款**:代裁卡实施中发现契约终究要动 ⇒ dev 停手, + 卡回`needs-user-decision` —— 报告分叉,⛔ 永不静默重裁。 +- **请示纪律(维护者 2026-08-25:「不要不停的弹出来让我确认,很浪费时间」)**:①方向性授权 + (如「接受你的建议」「帮我合并」)覆盖整条执行链一并做完,⛔ 不逐项回问; + ②需裁事项**攒批**(≤5 项/批,每项一行带推荐),一句同意即全链执行;③中间状态与限流 + /重试类运维细节只进座位贴和触发器,⛔ 不弹给维护者——汇报只在里程碑、 + 真阻塞、被问到时;④可逆且有推荐默认的事项按否决窗口:声明即执行, + 异议再回滚;人工地板项(发版、天花板、契约扩大)仍需明确字句,但攒批不逐项弹。 ## 执行座位职责 -**每轮巡检第一判据**:先读半状态巡查锚(`half-state-patrol.yml` 置顶 issue)点名本道卡/PR/座位贴 -的 H 行,逐行认领或处置,再做其余判据;锚行未处置 ⛔ 不开新派发。 +**每轮巡检第一判据**:先读半状态巡查锚(`half-state-patrol.yml` 置顶 issue) +点名本道卡/PR/座位贴的 H 行,逐行认领或处置,再做其余判据;锚行未处置 ⛔ 不开新派发。 ### 候选与批次 -**整车道一次读全,本地求交**(维护者 2026-08-11 接受):`list_issues` 带 `labels: [domain:X]` + -最小字段一次拿回全车道 open 集,各状态本地求交 —— 按单一 pm 状态切片的查询看不见其 -它状态,是结 -构性盲区。候选 = open、未 assign、无`needs-user-decision`、无 `pm:retriage`;已排队父单的 open -sub-issue 自动是 -候选(`pm:epic` 父单的子树除外)。**每张候选读全文 + 全部评论,写派发词前补一次决策复 -读(decision re-read),与认领的竞态复读对称**:评论读到最后一页,凡维护者裁决**逐字引入派发 -词裁决分区**作约束,无则写明「无裁决」—— 竞态复读只答「被谁认领」答不 -了「已被裁过」(裁决评论不带 session ID,裁后回队的标签状态与从未裁过的卡同形,队列列表 -分不出),漏读的派发词把已闭分叉当开放问题重开、并丢掉裁决自带的实施约束;评论还可能 -记着一半工作已交付。**派发前做前提过时检查(stale-premise check)—— 裁决同罪**(裁决描述的 -也是当时的仓,写得权威、日期又近,恰恰更容易被当成现成事实),三面都查:**动作面** —— -`git log --oneline -20 -- ` 之外,裁决实施卡再核被点名的动作在 `origin/main` 上还没被做 -掉;**卡引用面** —— 裁决/卡片点名为阻塞、认领面、协调对象或「落地即启用」依赖的每 -张 issue,逐个读当前 open/closed/assignee,引用读到的现状 ⛔ 不引用裁决写作时的描述(过时动作 -断言 dev 动手即自纠,过时卡引用不变红);**工作项面** —— 卡片与分诊评论列的每条工作 -项,逐条**对树**核验它是否仍未完成(grep 具名字符串、读那个常量),⛔ 不对卡核验:评论复读 -只找得到被推翻的裁决,找不到在别的卡号下已被做掉的工作(实测:一张三项卡有两项早已落 -地、点名的验证语料也已退役,烧掉一整轮才测出来)。每条工作项写进派发令时都是**dev 首 -先证伪的前提**(卡的中心断言已经这么写,任务清单照办),派发令即自带过时探测器。不查则 -赔一次 agent 运行。 - -**批次独立性。** 一批内任两单不得可能碰同一个包/registry/barrel/spec schema;拿不准就串 -行。**同 -文件单跨轮硬串行;延后不是搁置**(被延后那一刻就把已知的坑记到该 issue 上)。**家族派 -发(family dispatch)是本条的范围澄清,不是豁免**:独立性防的是两个 agent 相撞同一区域,一个 dev -**有意**覆盖 N 张同区域已裁卡是平凡满足不变量,可折叠为一次派发(折叠认领约定见「认 -领」节)。准入五门全过才可折:① 同缺陷形态同修法(⛔ 不是同关键词/同子系统);② 同包/区域(一 -worktree、一 changeset、一队列位);③ **每张成员都已裁/已定级,⛔ 决策箱内一张不许**(承重 -门:防 -借折叠把未裁卡洗进已裁 PR);④ 每成员独立可核(每成员一个具名判据,批次不能静默少 -交);⑤ 派发令 -点名**排除清单** —— 长得像家族而不是的成员及理由(承重门:盲扫「同类」正是要防的错 -编辑)。 -**fold-or-serial 是必答题**(维护者 2026-08-19 原话:「你自己定的工作方式你也会忘。」):凡 ≥2 -张 -排队卡共享热文件,串行队条目和/或链首认领必须以五门为判据显式答折叠还是串行 —— -不答而默认串行是 -漏答不是安全选项(零余量棘轮文件上的串行还翻倍付账搜刮与人工合并次数)。**维护者明 -示豁免同 -文件串行时,替代纪律四条**(豁免的是排队,不是防撞):① 文件面申报到**区域**级(函数/段 -落);② 开 -PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队列仲裁,⛔ PM 不手动排序;豁免不 -外溢。** -阻塞解除后给延后单重新定价**:派发前一单时带必答项「你的改动让 #X 变简单/变难/变得不必要还是无 -影响?」,派发后一单前用这个回答重读它的选项与成本,⛔ 不沿用立单时那份(前后单共用同一契约或数 -据表示时适用)。**跨车道简单阻塞项直接接手**(维护者 2026-08-13):本车道卡被他车道卡挡住 -且阻塞项 -**机械、规格清楚、S 级** ⇒ 被挡座位直接接手做掉,⛔ 不持续等待;他车道卡上走完整认 -领、尊重其热文 -件串行队、完工留收单注记;带设计判断/语义权衡的仍归属地车道(细则见 -`references/dispatch-runbook.md`)。 - -**选择优先级 —— 车道取卡全序**(维护者 2026-08-13,并入 2026-08-11/2026-08-12 的 Bug 平手裁定) -:`priority:p0` 插队 > `pm:blocking` > `target:` 板上项 > type `Bug` > 其余;同级按卡龄 -,`pm:blocking` 级内先按解锁扇出(照旧从 `Blocked-by:` 反向索引现算,⛔ 扇出数不落标签)。全序 -每级 -取既有信号现读/现算,零逐卡维护 —— 与 P1–P5 已拒不矛盾(拒的是手工维护的渐变档:没人 -维护必烂);**优先是排序,不是豁免**。**解锁那一刻 PM 自己的判断最不可 -信**:「这条裁决收窄/关掉了那张卡」是假设不是前提,必须以机制假设身份进派发令,被证伪 -就在同一张卡公开更正再重新分诊(卡内文件面重验已是 `Blocked-by:` 解锁扫描的第三职责,⛔ -此处不另抄)。 +**整车道一次读全,本地求交**(维护者 2026-08-11 接受): +`list_issues` 带 `labels: [domain:X]` + 最小字段一次拿回全车道 open 集, +各状态本地求交 —— 按单一 pm 状态切片的查询看不见其它状态, +是结构性盲区。候选 = open、未 assign、无`needs-user-decision`、无 `pm:retriage`; +已排队父单的 open sub-issue 自动是候选(`pm:epic` 父单的子树除外)。**每张候选读全文 + +全部评论,写派发词前补一次决策复读(decision re-read),与认领的竞态复读对称**: +评论读到最后一页,凡维护者裁决**逐字引入派发词裁决分区**作约束, +无则写明「无裁决」—— 竞态复读只答「被谁认领」 +答不了「已被裁过」(裁决评论不带 session ID,裁后回队的标签状态与从未裁过的卡同形, +队列列表分不出),漏读的派发词把已闭分叉当开放问题重开、并丢掉裁决自带的实施约束; +评论还可能记着一半工作已交付。**派发前做前提过时检查(stale-premise check)—— +裁决同罪**(裁决描述的也是当时的仓,写得权威、日期又近,恰恰更容易被当成现成事实), +三面都查:**动作面** —— `git log --oneline -20 -- ` 之外,裁决实施卡再核被点名的动作在 +`origin/main` 上还没被做掉;**卡引用面** —— 裁决/卡片点名为阻塞、 +认领面、协调对象或「落地即启用」依赖的每张 issue,逐个读当前 open/closed/assignee, +引用读到的现状 ⛔ 不引用裁决写作时的描述(过时动作断言 dev 动手即自纠, +过时卡引用不变红);**工作项面** —— 卡片与分诊评论列的每条工作项, +逐条**对树**核验它是否仍未完成(grep 具名字符串、读那个常量), +⛔ 不对卡核验:评论复读只找得到被推翻的裁决,找不到在别的卡号下已被做掉的工作(实测: +一张三项卡有两项早已落地、点名的验证语料也已退役,烧掉一整轮才测出来)。 +每条工作项写进派发令时都是**dev 首先证伪的前提**(卡的中心断言已经这么写, +任务清单照办),派发令即自带过时探测器。不查则赔一次 agent 运行。 + +**批次独立性。** 一批内任两单不得可能碰同一个包/registry/barrel/spec schema;拿不准就串行。 +**同文件单跨轮硬串行;延后不是搁置**(被延后那一刻就把已知的坑记到该 issue 上)。 +**家族派发(family dispatch)是本条的范围澄清,不是豁免**:独立性防的是两个 agent +相撞同一区域,一个 dev **有意**覆盖 N 张同区域已裁卡是平凡满足不变量,可折叠为一次派发 +(折叠认领约定见「认领」节)。准入五门全过才可折:① 同缺陷形态同修法 +(⛔ 不是同关键词/同子系统);② 同包/区域(一 worktree、一 changeset、一队列位); +③ **每张成员都已裁/已定级,⛔ 决策箱内一张不许**(承重门:防借折叠把未裁卡洗进已裁 PR); +④ 每成员独立可核(每成员一个具名判据,批次不能静默少交);⑤ 派发令点名**排除清单** +—— 长得像家族而不是的成员及理由(承重门:盲扫「同类」正是要防的错编辑)。 +**fold-or-serial 是必答题**(维护者 2026-08-19 原话:「你自己定的工作方式你也会忘。」):凡 +≥2 张排队卡共享热文件,串行队条目和/或链首认领必须以五门为判据显式答折叠还是串行 +—— 不答而默认串行是漏答不是安全选项 +(零余量棘轮文件上的串行还翻倍付账搜刮与人工合并次数)。 +**维护者明示豁免同文件串行时,替代纪律四条**(豁免的是排队,不是防撞): +① 文件面申报到**区域**级(函数/段落);② 开 PR 前合一次 main;③ 兄弟卡落地后再合一次; +④ 冲突交合并队列仲裁,⛔ PM 不手动排序;豁免不外溢。**阻塞解除后给延后单重新定价**: +派发前一单时带必答项「你的改动让 #X 变简单/变难/变得不必要还是无影响?」, +派发后一单前用这个回答重读它的选项与成本,⛔ 不沿用立单时那份 +(前后单共用同一契约或数据表示时适用)。**跨车道简单阻塞项直接接手**(维护者 2026-08-13): +本车道卡被他车道卡挡住且阻塞项**机械、规格清楚、S 级** ⇒ 被挡座位直接接手做掉, +⛔ 不持续等待;他车道卡上走完整认领、尊重其热文件串行队、 +完工留收单注记;带设计判断/语义权衡的仍归属地车道(细则见 `references/dispatch-runbook.md`)。 + +**选择优先级 —— 车道取卡全序**(维护者 2026-08-13,并入 2026-08-11/2026-08-12 的 Bug 平手裁定): +`priority:p0` 插队 > `pm:blocking` > `target:` 板上项 > type `Bug` > 其余; +同级按卡龄,`pm:blocking` 级内先按解锁扇出(照旧从 `Blocked-by:` 反向索引现算, +⛔ 扇出数不落标签)。全序每级取既有信号现读/现算,零逐卡维护 +—— 与 P1–P5 已拒不矛盾(拒的是手工维护的渐变档:没人维护必烂);**优先是排序, +不是豁免**。**解锁那一刻 PM 自己的判断最不可信**:「这条裁决收窄/关掉了那张卡」 +是假设不是前提,必须以机制假设身份进派发令,被证伪就在同一张卡公开更正再重新分诊 +(卡内文件面重验已是 `Blocked-by:` 解锁扫描的第三职责,⛔ 此处不另抄)。 ### 认领(先认领后动工) 同账号内的多会话共享 GitHub 身份,assignee 只回答「有 agent 认领了」,回答不了「哪个」—— -认领评论承载身份;**assignee 字段归 PM**:原子对 step 1 设,dev 席恒不写它(os-dev 规则 2 同 -句);跨账号只需一条:assignee 不是你 ⇒ 永不碰。选中的单,派发前按序执行**一个原子对**: +认领评论承载身份;**assignee 字段归 PM**:原子对 step 1 设,dev 席恒不写它(os-dev 规则 2 同句); +跨账号只需一条:assignee 不是你 ⇒ 永不碰。选中的单,派发前按序执行**一个原子对**: -1. **Assign @me + 状态标签对调**(`pm:dispatched` 与摘 `pm:queue` 同一次标签写入 ——只摘不换留 - 下的在飞卡会被分诊析取每轮重付全评论读);step 1 之后获得 assignee 的直接弃出本批。 -2. **认领评论**(英文),固定形状;session ID 不可省,但 `mode:subagent` 的 dev 与 PM 同会话、同 - ID(实测),甄别身份是**分支** —— 评论对买到「dev 跑过、在哪条分支」,`mode:cloud` 才额外 - 买到「哪个会话」;**首行以字面 `Claim:` 开头是机器判据**(维护者 2026-08-11 裁定;巡查谓词 - 只认这一个拼写且保持严格,修法是全舰队向文档拼写收敛,⛔ 不放宽谓词): +1. **Assign @me + 状态标签对调**(`pm:dispatched` 与摘 + `pm:queue` 同一次标签写入 ——只摘不换留下的在飞卡会被分诊析取每轮重付全评论读);step + 1 之后获得 assignee 的直接弃出本批。 +2. **认领评论**(英文),固定形状;session ID 不可省,但 `mode:subagent` 的 dev 与 PM 同会话、 + 同 ID(实测),甄别身份是**分支** —— 评论对买到「dev 跑过、在哪条分支」,`mode:cloud` + 才额外买到「哪个会话」;**首行以字面 `Claim:` 开头是机器判据**(维护者 2026-08-11 裁定; + 巡查谓词只认这一个拼写且保持严格,修法是全舰队向文档拼写收敛,⛔ 不放宽谓词): > Claim: PM loop round N > Session: `session_` @@ -565,115 +534,110 @@ PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队 > Clause-②: yes | no —— 条款②内容肢的强制申报,恒英文机器判据,恰这两种拼写:`Clause-②: yes` / `Clause-②: no`;判据:本卡改变契约接受/拒绝行为或扩大公开面吗?`yes` 绑定入队闸门(见「入队与落地」) > Serial constraints cleared: `<点名同文件/同包的前驱 PR 与在飞认领,及分诊点名的任意车道在飞兄弟卡中本卡 pin 断言其行为者;无则 "none">` -末行把「查过串行约束」变成落在评论里的读数(同包在飞单不点名等于没查);兄弟卡必 -读,因为文件面 -不相交挡不住**读耦合**:本卡 pin 断言兄弟卡在改的行为 ⇒ 各自全绿、先合者令后者 CI 无 -因变红;派 -发令点名跨车道兄弟时**应**注明本卡 pin 是否断言其面,是则在用例内预登记翻转触发词(兄 -弟行为落地 -即变红:删除或反转,⛔ 不修绿)。文件面对跨域例外单**必填**、普通单建议(定向在飞检查与 -epic 领 -地判断的唯一输入);分支名必须带 issue 号。**家族派发(见批次独立性)的折叠认领约定**:共 -享分支按链首卡命名,**每张成员卡各留认领评论并点名该分支**(成员卡无自有分支是设计不 -是半状态);一 PR 正文多行 `Fixes #` 每成员一行、逐卡 commit(= 每成员的独立可核件);完整串 -行约束检查落链首认领,成员认领指向之。**限流不拆原子对**:发不出评论就撤 assign 或不开 -始;配额尽则整对排队,永不留半个。 -3. **竞态复读**:自己的认领评论上墙后重读全线程 —— assignment 幂等,两个 agent 都 - 会「成功」,** - 认领评论时间戳是唯一仲裁**;更早的评论带不同 session ID/分支 ⇒ 你输了,回「already claimed - — yielding」另选。**让行是交接不是退场**:连同让行评论交出已诊断的一切与 PM 侧已取的板面读 - 数(复现命令、依赖路径、已确认的坑、在飞同文件PR、区域申报、串行约束),赢家不必重 - 扫。 - -dev 侧早推分支 —— 远程分支是在飞工作最硬的证据。**死认领回收(stale-claim reclaim)**:认领 ->~24h、承诺分支不存在、无 PR ⇒ 死认领 —— **回收前先救工作树**:派发 worktree 的未提交改 -动先 WIP commit 到派发分支并 push,sha 记进回收评论、标 INCOMPLETE AND UNREVIEWED(续派者 diff -它,⛔ 不无审续建;死在编辑中途的 dev 没来得及自己 WIP 推,这一步是最后防线)—— 再评论 -询问,静默一窗后摘 assignee(注明原因)回队;有带提交活分支的认领永不回收。 +末行把「查过串行约束」变成落在评论里的读数(同包在飞单不点名等于没查);兄弟卡必读, +因为文件面不相交挡不住**读耦合**:本卡 pin 断言兄弟卡在改的行为 ⇒ 各自全绿、 +先合者令后者 CI 无因变红;派发令点名跨车道兄弟时**应**注明本卡 pin 是否断言其面, +是则在用例内预登记翻转触发词(兄弟行为落地即变红:删除或反转,⛔ 不修绿)。 +文件面对跨域例外单**必填**、普通单建议(定向在飞检查与 epic 领地判断的唯一输入); +分支名必须带 issue 号。**家族派发(见批次独立性)的折叠认领约定**:共享分支按链首卡命名, +**每张成员卡各留认领评论并点名该分支**(成员卡无自有分支是设计不是半状态); +一 PR 正文多行 `Fixes #` 每成员一行、 +逐卡 commit(= 每成员的独立可核件);完整串行约束检查落链首认领,成员认领指向之。 +**限流不拆原子对**:发不出评论就撤 assign 或不开始;配额尽则整对排队,永不留半个。 +3. **竞态复读**:自己的认领评论上墙后重读全线程 —— assignment 幂等, + 两个 agent 都会「成功」,**认领评论时间戳是唯一仲裁**;更早的评论带不同 + session ID/分支 ⇒ 你输了,回「already claimed — yielding」另选。**让行是交接不是退场**: + 连同让行评论交出已诊断的一切与 PM 侧已取的板面读数(复现命令、 + 依赖路径、已确认的坑、在飞同文件PR、区域申报、串行约束),赢家不必重扫。 + +dev 侧早推分支 —— 远程分支是在飞工作最硬的证据。**死认领回收(stale-claim reclaim)**: +认领 >~24h、承诺分支不存在、无 PR ⇒ 死认领 —— **回收前先救工作树**: +派发 worktree 的未提交改动先 WIP commit 到派发分支并 push,sha 记进回收评论、 +标 INCOMPLETE AND UNREVIEWED(续派者 diff 它,⛔ 不无审续建; +死在编辑中途的 dev 没来得及自己 WIP 推,这一步是最后防线)—— 再评论询问, +静默一窗后摘 assignee(注明原因)回队;有带提交活分支的认领永不回收。 ### 派发 一单一次 `Agent` 调用,`subagent_type: "os-dev"`,后台并行。 -**模型分档(model tiering;维护者 2026-08-10 三档裁定,本节覆盖一切更旧档制)。** 授权原话:「项目经理技能还需 -要考虑的是派任务时使用什么模型,也应该项目经理决定,最低下限sonnet,最高可以 fable」;「比如 更新 项 -目经理技能 必须要使用 Fable 5」。**派发模型是 PM 的逐卡显式决定** —— 下限 `sonnet`(机械 -卡:正确性由门禁农场机械判定,失败在漏跑门不在判断);默认判断档 `opus`(M/L、裁决实施、任 -何带设计判断的卡;拿不准就升一档 —— 错派低档的返工贵过省下的额度);上限 `fable`(最重 -协议/流程/编排卡,按卡取用非新默认)。**⛔ 强制条款两条**:① 凡改**协议语义面**的卡一律 -`model: "claude-fable-5"` —— 面 = -本 `SKILL.md` 主文件、决策框架拷贝所在文件(以 `check:skill-frame-sync` 强制处为准)与 -`.claude/agents/os-dev.md`(2026-08-20 收窄,维护者原话:「接受你的建议」—— fable 当审计师用,不当 -施工队用);仅 `references/**` 面、或任一 pm-dispatch 治理面上一行级机械文本改动的卡降为 **opus -施工**(纯机械一行 PM 酌定可至 sonnet 地板),**补偿控制即既有技能面复核档要求**(ACCEPT 路径 -分叉 ①:复核席跑契约复审档位)—— opus 施工的治理面改动只经 fable 档复核到达维护者,⛔ -不新增标签不新增链;② 凡**改变契约接受/拒绝行为或扩大公开面**的卡(`domain:spec` 语义 -面;判据即分诊代裁的机械边界测试与 spec 席内分派判据 —— `references/lanes/spec.md`,⛔ 不另 -抄第二份)一律 `claude-fable-5`(维护者 2026-08-12 裁定,原 -话:「同意,就按语义面收窄,立卡并通知 spec 席」)—— 契约错毒化一切下游,全仓最贵(条 -款②闸门见「入队与落地」)。**负边界(维护者 2026-08-28 裁定)**:运行时权限/安全**行为**变 -更不是条款② —— 归人工地板「安全/权限边界」类(控制是裁决本身,不走复审链);条 -款②只指**已发布契约面**(两独立席位曾同错读,故明写)。**卡面对条款②的复述仍是条 -款②**(座位复述会丢掉原文旁的例外,而被读的正是复述):额度耗尽豁免及其 -`needs:contract-review` 补偿一并及于它;豁免够不到的地板只有维护者裁决能设。**席位档策 -略(同 2026-08-20 裁决)**:skills 车道外执行 PM 席与分诊席默认 `opus` 会话,fable 保留给裁决/复审 -子代理、skills 席与条款②工作 —— 各自档位归既有条款(本行只记策略)。降档出口两 -条:**额度耗尽豁免**(维护者 2026-08-13 原话:「fable 如果用完了,可以用 opus」):仅当 fable 实测 -不可用(限流/墙杀中途,重派同样可降) 才落 `opus`,⛔ 不再往下;与**主动预降**(余量吃紧可预 -先降档),两者档位与理由皆记入认领评论「Container & model」行。明确不变:spec 文本面照旧 -sonnet/opus;机器面与下游适配默认 opus, 门禁语义设计升 fable,拿不准升档照旧。**档位逐次派 -发显式传参,永不省略**(解析顺序、pin 语义与允许名单回退陷阱以 os-dev 定义 frontmatter 注释 -为权威),连同尺寸写进同一行;分诊 suggestion 行是输入不是决定,不采纳给理由。 - -**派发词原则(构造细则与条款原文见 `references/dispatch-runbook.md`)。** ⛔ 默认不整段粘 -贴 issue 正文 —— 让 dev 自己读 GitHub 全文与全部评论,并**必须**要求 dev 自查正文完整性(截 -断 -风险随「自己读」转移给 dev,自查是对价不是客套)。派发词只带增量: - -- **三分区,措辞决定 dev 敢不敢证伪**:「裁决(不可重裁)」/「PM 机制假设(须实测,鼓励证伪)」/「PM - 建议的路线(可选,实测优先)」;凡「我觉得可以这样」的一律降到第三块 —— 机制假设穿着裁决 - 的衣服,两个方向都是返工(细则见 runbook)。 -- **标准非协商条款 ⛔ 不抄进派发词,分层砍**:hook 已机械强制段(worktree-first / never-stash)与 - os-dev.md 已载通用段(push 重试、语言、releases 禁令)砍掉;⛔ 不砍卡类特有约束(ADR 类 - draft-only、tier 推导引用、棘轮实况、释义纪律)。无条件条款只住角色文件(冲突时它胜、 - 错了修那里,⛔ 不靠派发词临时覆盖)。**终报要求随派发词带一句**:只收机器可核字段 - (gates/line_budget/deviations/files_changed),⛔ 复述 PR body 叙事。**清单、路径、行号在派发那 - 一刻从树上取**,⛔ 不从卡片/上次派发/记忆抄(`node scripts/pm/dispatch-gates.mjs`,取数的是 - PM;点名单是线索不是规格,dev 对实际改动重取补跑);行级断言转述前必须自己重验。 -- **派发令里关于代码的危害断言必须有读数**(点名 call site / 路径 / 迁移),与零命中同一 - register —— 「这会毁数据」「这会弄坏 X」是关于安全的缺席断言,同样要控制项。PM 座位 - 测不了 ⇒ 写成给 dev 的问题,⛔ 不写成栅栏:未测量的栅栏把 dev 挡在正确修法之外,拒绝它 - 要赔一次往返、且指望 dev 敢跟派发者争(实测:一句「会截断数据」的栅栏,那条路径上每 - 一列其实都是空的)。**人工地板栅栏**(挡在维护者该做的决定之外)关于流程不关于代 - 码,免测量。 -- **派发令必须要求 dev 留自己的认领评论**(其**本身**的 session ID + 分支,在 PM 那条**之外**; - 身份语义见「认领」规则 2)。「已认领、别动 assignee」⛔ 收窄到 assignee 字段本身:「认领协议 - 已满足」是另一句话且可能是假的(实测:被这么告知的卡 assignee、认领评论、分支三者皆无)。 -- **触 `skills/**`(对外发布的技能包)的卡,派发词必带 PM 定的净增行数预算**(按 feature 大小 - 定,小功能给小数);dev 装不下 ⇒ 停手回报,⛔ 不自行扩写、不自行抬预算(抬预算是维护者 - 裁决)。 - **原则:对外发布的技能包是平台最大的对外价值,评估恒整包整体**(维护者 - 2026-08-21:「对外发布的 skills 是整个平台的最大价值,尤其要整体考虑和评估。」)。 -- **文件面写两句**(预期落点 + 生产者在别包时报备后按生产者侧修,⛔ 不在消费者侧打补丁 - );**same-day churn 行**(当天合并 ⇒ 先核对当前 main);**在飞重叠拦截**(每轮求交,相交即发四句 - 警告,被完全覆盖就停下回报 ⛔ 不硬造 diff)。 -- **翻转公开语义的裁决随卡带全仓 pin 清扫**,两句缺一不可(两句原文见 runbook)。**条件性标 - 准条款 - 命中判据才抄**:多实现面 ⇒ 共享一致性覆盖;拒收用例 ⇒ `code`+`status` 最低断言;过滤/谓 - 词语 - 义 ⇒ 编译面清单逐面申报(⛔ 静默略过)。 -- **前提先行(premise-first)写明**:issue 正文是线索不是规格;`premise_still_valid: false` +无 PR 是合法 - 且常常有价值的交付 —— 派发词预设 issue 为真,就把好运行变成表面抗命。 - -**资源与后端(维护者 2026-08-12 裁定:中级卡改子 agent、模型由 PM 按难度逐卡指定;覆盖 -2026-08-10 的 -「M 及以上默认云卡」)。** S 级机械 + M ⇒ `mode:subagent`(PM 容器内并行,档位按模型分档显式 -传 -参);S 级但不机械(判断面在设计不在门禁)按 M 待遇。`mode:cloud` 只保留给:L/XL、必须活过 PM -会话的工 -作、浏览器/dogfood 验证、逐卡判断的 build 重 M 卡(论证见 `references/dispatch-runbook.md`)。**归档 -义 -务只落在云卡**;OOM 死的单独重派;判定连同档位写进认领评论。 +**模型分档(model tiering;维护者 2026-08-10 三档裁定,本节覆盖一切更旧档制)。 +** 授权原话:「项目经理技能还需要考虑的是派任务时使用什么模型,也应该项目经理决定, +最低下限sonnet,最高可以 fable」;「比如 更新 项目经理技能 必须要使用 Fable 5」。 +**派发模型是 PM 的逐卡显式决定** —— 下限 `sonnet`(机械卡: +正确性由门禁农场机械判定,失败在漏跑门不在判断);默认判断档 `opus`(M/L、 +裁决实施、任何带设计判断的卡;拿不准就升一档 —— 错派低档的返工贵过省下的额度); +上限 `fable`(最重协议/流程/编排卡,按卡取用非新默认)。**⛔ 强制条款两条**: +① 凡改**协议语义面**的卡一律 `model: "claude-fable-5"` —— 面 = 本 `SKILL.md` 主文件、 +决策框架拷贝所在文件(以 `check:skill-frame-sync` 强制处为准)与 `.claude/agents/os-dev.md`(2026-08-20 +收窄,维护者原话:「接受你的建议」—— fable 当审计师用,不当施工队用); +仅 `references/**` 面、或任一 pm-dispatch 治理面上一行级机械文本改动的卡降为 **opus 施工** +(纯机械一行 PM 酌定可至 sonnet 地板),**补偿控制即既有技能面复核档要求**(ACCEPT 路径分叉 +①:复核席跑契约复审档位)—— opus 施工的治理面改动只经 fable 档复核到达维护者, +⛔ 不新增标签不新增链;② 凡**改变契约接受/拒绝行为或扩大公开面**的卡(`domain:spec` +语义面;判据即分诊代裁的机械边界测试与 spec 席内分派判据 —— `references/lanes/spec.md`, +⛔ 不另抄第二份)一律 `claude-fable-5`(维护者 2026-08-12 裁定, +原话:「同意,就按语义面收窄,立卡并通知 spec 席」)—— 契约错毒化一切下游, +全仓最贵(条款②闸门见「入队与落地」)。**负边界(维护者 2026-08-28 裁定)**: +运行时权限/安全**行为**变更不是条款② —— 归人工地板「安全/权限边界」 +类(控制是裁决本身,不走复审链);条款②只指**已发布契约面**(两独立席位曾同错读, +故明写)。**卡面对条款②的复述仍是条款②**(座位复述会丢掉原文旁的例外, +而被读的正是复述):额度耗尽豁免及其 `needs:contract-review` 补偿一并及于它; +豁免够不到的地板只有维护者裁决能设。**席位档策略(同 2026-08-20 裁决)**:skills 车道外执行 +PM 席与分诊席默认 `opus` 会话,fable 保留给裁决/复审子代理、skills 席与条款②工作 —— +各自档位归既有条款(本行只记策略)。降档出口两条:**额度耗尽豁免**(维护者 2026-08-13 原话: +「fable 如果用完了,可以用 opus」):仅当 fable 实测不可用(限流/墙杀中途,重派同样可降) 才落 +`opus`,⛔ 不再往下;与**主动预降**(余量吃紧可预先降档),两者档位与理由皆记入认领评论 +「Container & model」行。明确不变:spec 文本面照旧 sonnet/opus;机器面与下游适配默认 +opus, 门禁语义设计升 fable,拿不准升档照旧。**档位逐次派发显式传参, +永不省略**(解析顺序、pin 语义与允许名单回退陷阱以 os-dev 定义 frontmatter 注释为权威), +连同尺寸写进同一行;分诊 suggestion 行是输入不是决定,不采纳给理由。 + +**派发词原则(构造细则与条款原文见 `references/dispatch-runbook.md`)。 +** ⛔ 默认不整段粘贴 issue 正文 —— 让 dev 自己读 GitHub 全文与全部评论,并**必须**要求 dev +自查正文完整性(截断风险随「自己读」转移给 dev,自查是对价不是客套)。派发词只带增量: + +- **三分区,措辞决定 dev 敢不敢证伪**:「裁决(不可重裁)」/「PM 机制假设(须实测, + 鼓励证伪)」/「PM 建议的路线(可选,实测优先)」;凡「我觉得可以这样」 + 的一律降到第三块 —— 机制假设穿着裁决的衣服,两个方向都是返工(细则见 runbook)。 +- **标准非协商条款 ⛔ 不抄进派发词,分层砍**:hook 已机械强制段(worktree-first / never-stash) + 与 os-dev.md 已载通用段(push 重试、语言、releases 禁令) + 砍掉;⛔ 不砍卡类特有约束(ADR 类 draft-only、tier 推导引用、棘轮实况、释义纪律)。 + 无条件条款只住角色文件(冲突时它胜、错了修那里,⛔ 不靠派发词临时覆盖)。 + **终报要求随派发词带一句**:只收机器可核字段(gates/line_budget/deviations/files_changed), + ⛔ 复述 PR body 叙事。**清单、路径、行号在派发那一刻从树上取**, + ⛔ 不从卡片/上次派发/记忆抄(`node scripts/pm/dispatch-gates.mjs`,取数的是 PM; + 点名单是线索不是规格,dev 对实际改动重取补跑);行级断言转述前必须自己重验。 +- **派发令里关于代码的危害断言必须有读数**(点名 call site / 路径 / 迁移), + 与零命中同一 register —— 「这会毁数据」「这会弄坏 X」 + 是关于安全的缺席断言,同样要控制项。PM 座位测不了 ⇒ 写成给 dev 的问题, + ⛔ 不写成栅栏:未测量的栅栏把 dev 挡在正确修法之外,拒绝它要赔一次往返、且指望 + dev 敢跟派发者争(实测:一句「会截断数据」的栅栏,那条路径上每一列其实都是空的)。 + **人工地板栅栏**(挡在维护者该做的决定之外)关于流程不关于代码,免测量。 +- **派发令必须要求 dev 留自己的认领评论**(其**本身**的 session ID + 分支, + 在 PM 那条**之外**;身份语义见「认领」 + 规则 2)。「已认领、别动 assignee」⛔ 收窄到 assignee 字段本身:「认领协议已满足」 + 是另一句话且可能是假的(实测:被这么告知的卡 assignee、认领评论、分支三者皆无)。 +- **触 `skills/**`(对外发布的技能包)的卡,派发词必带 PM 定的净增行数预算**(按 feature 大小定, + 小功能给小数);dev 装不下 ⇒ 停手回报, + ⛔ 不自行扩写、不自行抬预算(抬预算是维护者裁决)。 + **原则:对外发布的技能包是平台最大的对外价值,评估恒整包整体**(维护者 2026-08-21: + 「对外发布的 skills 是整个平台的最大价值,尤其要整体考虑和评估。」)。 +- **文件面写两句**(预期落点 + 生产者在别包时报备后按生产者侧修, + ⛔ 不在消费者侧打补丁);**same-day churn 行**(当天合并 ⇒ 先核对当前 main); + **在飞重叠拦截**(每轮求交,相交即发四句警告,被完全覆盖就停下回报 ⛔ 不硬造 diff)。 +- **翻转公开语义的裁决随卡带全仓 pin 清扫**,两句缺一不可(两句原文见 runbook)。 + **条件性标准条款命中判据才抄**:多实现面 ⇒ 共享一致性覆盖; + 拒收用例 ⇒ `code`+`status` 最低断言;过滤/谓词语义 ⇒ 编译面清单逐面申报(⛔ 静默略过)。 +- **前提先行(premise-first)写明**:issue 正文是线索不是规格;`premise_still_valid: false` + +无 PR 是合法且常常有价值的交付 —— 派发词预设 issue 为真,就把好运行变成表面抗命。 + +**资源与后端(维护者 2026-08-12 裁定:中级卡改子 agent、模型由 PM 按难度逐卡指定; +覆盖 2026-08-10 的「M 及以上默认云卡」)。** S 级机械 + M ⇒ `mode:subagent`(PM 容器内并行, +档位按模型分档显式传参);S 级但不机械(判断面在设计不在门禁) +按 M 待遇。`mode:cloud` 只保留给:L/XL、必须活过 PM 会话的工作、 +浏览器/dogfood 验证、逐卡判断的 build 重 M 卡(论证见 `references/dispatch-runbook.md`)。 +**归档义务只落在云卡**;OOM 死的单独重派;判定连同档位写进认领评论。 **云卡四课全文见 runbook**;一次性云卡用 `create_session`,⛔ 不用 create_trigger+fire(维护者 2026-08-07 拍板,trigger 流只留给定时/重复型)。 @@ -682,318 +646,292 @@ dev**:先试 SendMessage 复活,不可用才走接手协议(四条增量见 runb ### 收集 -**报告通道统一:GitHub 是两种模式共用的真相源。** dev 终报先落 issue 评论、再作返回消息 -—— 评论是记录(会话中途死掉时它是唯一幸存副本),消息是加速器;收集先扫 GitHub,标记 -评论在 = 报告完整,两处皆无才进探活/判死。**标记两种拼写等效**:HTML 注释 -`` 与首行纯文本 `os-dev-report`;⛔ 仅凭 HTML 注释形式缺失永不读 -作「报告未达」—— 被 sanitizer 清洗的报告与从未送达的在证据上不可区分,误读即把一份 -完整终报送进探活/判死流程。⛔ 永不把「没收到失败通知」读作「还在跑」、报告缺席读 -作成功,永不虚构未回报 agent 的结果。 - -**探活是每轮巡检的固定动作 —— 完成通知不可靠,缺席什么都不证明。** ① 定时器重挂是 -每次巡检的**第一动作**(先挂后查,链条对中断免疫);② 在飞期间主巡检间隔 ≤45 分钟,待命 -期 60–70;③ 已派发未回报的 dev 逐个发状态询问(「回一段简报后继续干活」),派发后 ~45 分 -钟无远程产出即到门槛,**已有远程分支/PR 不豁免** —— 远程产出证明工作发生过,不证明 -agent 还在(常见死格恰在开出正确 PR 之后);④ 两种回包都有价值:活着 ⇒ 进度与阻塞点;「no active -task; resumed from transcript」⇒ 生前已死,询问本身即复活;⑤ 判据永远取正向证据(分支、PR、 -报告、探活回包)。 - -**45 分钟是发探针的门槛,⛔ 不是判死的门槛**(探针代价是一次消息;判死代价是往可能活着 -的 worktree 塞第二个 agent)。判死只有三类正当依据:探针回包表明已死、宿主明确回报 -stopped、超过**本车道实测基线**且连续静默 —— 基线 = 本车道 -实录「派发 → 推分支/开 PR」端到端耗时(三五单即可用,⛔ 非本文任何常数)。`mode:cloud` -的 ~2h 静默是**本轮收集边界**(记 `blocked` 移步下轮),也不是判死。 +**报告通道统一:GitHub 是两种模式共用的真相源。** dev 终报先落 issue 评论、 +再作返回消息 —— 评论是记录(会话中途死掉时它是唯一幸存副本),消息是加速器; +收集先扫 GitHub,标记评论在 = 报告完整,两处皆无才进探活/判死。**标记两种拼写等效**:HTML +注释 `` 与首行纯文本 `os-dev-report`;⛔ 仅凭 HTML 注释形式缺失永不读作 +「报告未达」—— 被 sanitizer 清洗的报告与从未送达的在证据上不可区分, +误读即把一份完整终报送进探活/判死流程。⛔ 永不把「没收到失败通知」 +读作「还在跑」、报告缺席读作成功,永不虚构未回报 agent 的结果。 + +**探活是每轮巡检的固定动作 —— 完成通知不可靠, +缺席什么都不证明。** ① 定时器重挂是每次巡检的**第一动作**(先挂后查,链条对中断免疫); +② 在飞期间主巡检间隔 ≤45 分钟,待命期 60–70;③ 已派发未回报的 dev 逐个发状态询问 +(「回一段简报后继续干活」),派发后 ~45 分钟无远程产出即到门槛,**已有远程分支/PR +不豁免** —— 远程产出证明工作发生过,不证明 agent 还在(常见死格恰在开出正确 PR 之后); +④ 两种回包都有价值:活着 ⇒ 进度与阻塞点;「no active task; resumed from transcript」 +⇒ 生前已死,询问本身即复活;⑤ 判据永远取正向证据(分支、PR、报告、探活回包)。 + +**45 分钟是发探针的门槛,⛔ 不是判死的门槛**(探针代价是一次消息; +判死代价是往可能活着的 worktree 塞第二个 agent)。判死只有三类正当依据: +探针回包表明已死、宿主明确回报 stopped、超过**本车道实测基线**且连续静默 —— 基线 += 本车道实录「派发 → 推分支/开 PR」端到端耗时(三五单即可用,⛔ 非本文任何常数)。 +`mode:cloud` 的 ~2h 静默是**本轮收集边界**(记 `blocked` 移步下轮),也不是判死。 **失报与停摆的处置(细则见 `references/dispatch-runbook.md`)。** 三条原则: -- **停摆永不自愈**:携带任务中途状态的完成通知本身就是停摆信号,立刻 SendMessage 附前台执 - 行姿态句,⛔ 不等任何静默阈值(阈值是给「没有回答」的);复位走梯度,每次比上一次更具 - 体,第三次停摆判 unreliable 按接手协议重派。⛔ 不能写成「派发词写全了就可以不探」。 -- **通知重放先算身份再读内容**:与已验收那份同身份(三元组定义见 runbook)⇒ 记「重放」即 - 结束,⛔ 不重新验收不重复 ACCEPT;到达不读作「还活着」,不到达也不读作「已死」。 -- **直接验收兜底(报告丢失 ≠ 验收停摆)**:(a) draft PR 在且 CI 全绿 + (b) 探活确认已死或 ≥2h - 无 - 推送 + (c) 报告未达 ⇒ 直接按 PR 验收(复核判据不减,细则见 runbook);先探活后翻 ready;舰队 - 级死因(全账号断粮)下取 (a)+(c) 照常收口,PR body 就是报告。 +- **停摆永不自愈**: + 携带任务中途状态的完成通知本身就是停摆信号,立刻 SendMessage 附前台执行姿态句, + ⛔ 不等任何静默阈值(阈值是给「没有回答」的);复位走梯度,每次比上一次更具体, + 第三次停摆判 unreliable 按接手协议重派。⛔ 不能写成「派发词写全了就可以不探」。 +- **通知重放先算身份再读内容**:与已验收那份同身份(三元组定义见 runbook)⇒ 记「重放」 + 即结束,⛔ 不重新验收不重复 ACCEPT;到达不读作「还活着」,不到达也不读作「已死」。 +- **直接验收兜底(报告丢失 ≠ 验收停摆)**:(a) draft PR 在且 CI 全绿 + (b) 探活确认已死或 + ≥2h 无推送 + (c) 报告未达 ⇒ 直接按 PR 验收(复核判据不减,细则见 runbook); + 先探活后翻 ready;舰队级死因(全账号断粮)下取 (a)+(c) 照常收口,PR body 就是报告。 ### 复核 -你是记录在案的复核人(reviewer of record)—— **对 GitHub 核验,不对报告的自述核验**;逐项判据 -展开 -在 `references/review-checklist.md`,每份报告对着它过。骨架: +你是记录在案的复核人(reviewer of record)—— **对 GitHub 核验, +不对报告的自述核验**;逐项判据展开在 `references/review-checklist.md`,每份报告对着它过。骨架: -- **PR 形态与范围**:draft、目标 `main`、`Fixes`/`Part of` 首行判据(翻 ready 前亲核)、`Part of` - 卡 MERGED 时点收口、changed files 范围与 changeset/`skip-changeset` 分流、测试证据 —— 判据全文 - 见 checklist 与 landing-operations B。 +- **PR 形态与范围**:draft、目标 `main`、`Fixes`/`Part of` 首行判据(翻 ready 前亲核)、 + `Part of` 卡 MERGED 时点收口、changed files 范围与 changeset/`skip-changeset` 分流、 + 测试证据 —— 判据全文见 checklist 与 landing-operations B。 - **报告在草稿 PR 时点到达,CI 收敛读数只属于复核侧**(维护者 2026-08-10 裁定):gate `in_progress` 是诚实读数;放行前亲核判据、收敛期补丁轮与「本单等 CI」例外见 checklist。 - **绿色输出 ≠ 该绿证明了被测风险**(拒收断言、全绿方向与时序、pin 翻转、边界后收益 —— 判据在 checklist)。 -- **证伪是好运行**:`premise_still_valid: false` 是再分诊输入;dev 纠正 PM 当众认;判据被测量推翻 - 照 ACCEPT,证据要件在 checklist。 +- **证伪是好运行**:`premise_still_valid: false` 是再分诊输入;dev 纠正 PM 当众认; + 判据被测量推翻照 ACCEPT,证据要件在 checklist。 - **删除与二进制**:死代码删除亲核引用面;`+0/-0` 先疑 NUL;sweep 范围外产出成组列出(判据在 checklist)。 -- **触 `skills/**` 的 PR 加问一题 —— 整包价值密度**:这次新增让**整包**的价值密度升还是 - 降?判据坐在**整包加载的客户 agent** 的座位上读,⛔ 不从功能作者的座位读(作者座位永远 - 觉得自己那段值);超派发预算或「小功能大扩写」⇒ REWORK,⛔ 不因「已经写好了」放行(原 - 则与出处见「派发词原则」)。 - -**判决**:**ACCEPT** 短格式(issue 英文评论):核对清单结论 + 抽查读数 + 偏差,链接 PR —— 论证 -指 -向 PR 本身,⛔ 不复述其叙事 → 驱动落地;**REWORK**(逐项反馈,同认领重派;补丁轮优先 -SendMessage -续派原 dev —— 上下文保留省掉全部重验;最多 2 轮,第三次升 -级);**ESCALATE**(见「升级与决策」)。 - -**ACCEPT 之后的路径分叉(动手之前先分,不是事后对照)。** 翻 ready / 挂 auto-merge / 入队前,先 -取一次 PR 的路径面(`get_files`,⛔ 不看报告自述)。governed 面统一定义(维护者 2026-08-18 -「同意」):`docs/adr/**` + `.claude/**`(全量,含 agents/hooks/settings)+ `skills/**` + -`AGENTS.md` + `CLAUDE.md`;agent 指令文件按此跨仓同判 —— objectui、cloud、objectos 一并在内(维护者 -2026-08-18:「任何对 agents.md 等文件的修改…包括 objectui cloud仓库」→「同意」;objectos 指令面 -PR 照样 draft/人工合并)。路径面**一条命中** ⇒ ACCEPT 换终局四件套:① 复核结论照常写在 -issue 上(不能合 ≠ 不复核;技能面 PR 的复核席须跑在契约复审档位,档位单源见条款②闸门); -② PR 留给维护者,**看得见地悬着**,终局两条:**人工直合即审核记录**(兜底);或**授权人工批 -准钉 head ⇒ 队列放行**(2026-08-27 裁:「os-zhuang hotlong 批准算数」;批准人集合与判定单源 = 队 -列守卫常量 `GOVERNED_APPROVERS`(`scripts/pm/check-governed-queue-guard.mjs`):APPROVED 且 -`commit_id` = PR 当前 head 才算,批准后再推提交即过期转红)。未钉批准 ⛔ 不翻 ready、不入队、不挂 auto-merge;③ 在 draft PR 上**向两个授权批准账户 `os-zhuang` 与 `hotlong` 都 request review**(维护者 2026-08-27:「需要 -批准的主动推送到这两个账户。」主动推,永不等被发现;通道出处 2026-08-19:「还是应该在 pr 的审核流程,发给 os-zhuang 审核。我的手机github 应该会收到推送消息吧」,当日实测推送到达 -(「推送到了」),同日裁定:「只有需要我审核的pr 推给我。」)—— 「等人 -合」清单从此活在 GitHub 的 Review-requested 队列,合并自动消项。**能请审则请审;PR 作者身份即两账户之一的席位,对该账户请审必失败**(GitHub 拒绝向 PR 作者请审,author-identity 422)—— 该账户改为把 PR **assign** 给它替代通知(另一账户照常请审),并在轮次报告点名说明走了 assignee 兜底。 -**请审走免碰 draft 位的专用 REST 端点,MCP 兜底显式带 `draft: true`**(坑与端点事实住 platform-readings);④ 轮次报告单列「awaiting a human merge」(「等人来 -合」与「被忘了」在 GitHub 上长得一模一样)。混 -合 diff 一条命中就分叉,⛔ 不按比例判;要拆就让 dev 单独开 PR;已入队才读到本条 ⇒ 转 draft -与 disable 都做,出队以阳性探针答、ref 缺席只旁证不承载结论(探针与两向相反实测住 platform-readings)。**skills 车道自有 PR 再按 diff 内容分流**(维护者 2026-08-26 裁定,原话:「skills 中的 -pr,只有包含md文件时需要推给我审核,其他代码文件你直接自己审核。」):diff 含任一 `.md` 文件 ⇒ -上述终局四件套照旧;纯代码面(`scripts/pm/` 工具、`.claude/` hooks/workflows/settings、`skills/**` 非 -md 产物)⇒ skills 席按契约复审档自审(清单不减)后直接落地(ready → 入队),⛔ 不推维护者;分 -流只及 skills 车道自有 PR,其它车道 governed 面照旧。路径面干净的才转 ready → 入队 -(队列是唯一被认可的落地路径,⛔ 永不队列外 `--auto` 合并)。**入队资格 = PR 上每一个 check -全绿,⛔ 不是 required 子集** —— required 集是 -队列强制的地板,不是 PM 放行的门槛;非必查门的红要么是真缺陷要么是坏门,两者都归 PM 入 -队前处置(实测:一张 required 全绿、非必查类型门与一个测试分片红着的 PR 经队列落地,该仓 -main 红了约一小时,逐 PR 连环红到 fix-forward 才止)。本段只适用本循环派发的 dev PR;PM 自己的 -工具 PR 留维护者。main-red 修复的跳队例外与事故锚卡约定见 landing-operations B。 +- **触 `skills/**` 的 PR 加问一题 —— 整包价值密度**: + 这次新增让**整包**的价值密度升还是降?判据坐在**整包加载的客户 agent** 的座位上读, + ⛔ 不从功能作者的座位读(作者座位永远觉得自己那段值);超派发预算或「小功能大扩写」 + ⇒ REWORK,⛔ 不因「已经写好了」放行(原则与出处见「派发词原则」)。 + +**判决**:**ACCEPT** 短格式(issue 英文评论):核对清单结论 + 抽查读数 + 偏差, +链接 PR —— 论证指向 PR 本身,⛔ 不复述其叙事 → 驱动落地;**REWORK**(逐项反馈, +同认领重派;补丁轮优先 SendMessage 续派原 dev —— 上下文保留省掉全部重验; +最多 2 轮,第三次升级);**ESCALATE**(见「升级与决策」)。 + +**ACCEPT 之后的路径分叉(动手之前先分,不是事后对照)。** 翻 ready / 挂 auto-merge / 入队前, +先取一次 PR 的路径面(`get_files`,⛔ 不看报告自述)。governed 面统一定义(维护者 +2026-08-18「同意」):`docs/adr/**` + `.claude/**`(全量,含 agents/hooks/settings)+ `skills/**` + `AGENTS.md` + +`CLAUDE.md`;agent 指令文件按此跨仓同判 —— objectui、cloud、objectos 一并在内(维护者 2026-08-18: +「任何对 agents.md 等文件的修改…包括 objectui cloud仓库」→「同意」;objectos 指令面 PR +照样 draft/人工合并)。路径面**一条命中** ⇒ ACCEPT 换终局四件套:① 复核结论照常写在 issue +上(不能合 ≠ 不复核;技能面 PR 的复核席须跑在契约复审档位,档位单源见条款②闸门);② PR +留给维护者,**看得见地悬着**,终局两条:**人工直合即审核记录**(兜底);或**授权人工批准钉 +head ⇒ 队列放行**(2026-08-27 裁:「os-zhuang hotlong 批准算数」;批准人集合与判定单源 += 队列守卫常量 `GOVERNED_APPROVERS`(`scripts/pm/check-governed-queue-guard.mjs`):APPROVED 且 `commit_id` += PR 当前 head 才算,批准后再推提交即过期转红)。未钉批准 ⛔ 不翻 ready、不入队、不挂 +auto-merge;③ 在 draft PR 上**向两个授权批准账户 `os-zhuang` 与 `hotlong` 都 request review**(维护者 +2026-08-27:「需要批准的主动推送到这两个账户。」主动推,永不等被发现;通道出处 2026-08-19: +「还是应该在 pr 的审核流程,发给 os-zhuang 审核。我的手机github 应该会收到推送消息吧」, +当日实测推送到达(「推送到了」),同日裁定:「只有需要我审核的pr +推给我。」)—— 「等人合」清单从此活在 GitHub 的 Review-requested 队列,合并自动消项。 +**能请审则请审;PR 作者身份即两账户之一的席位,对该账户请审必失败**(GitHub 拒绝向 PR +作者请审,author-identity 422)—— 该账户改为把 PR **assign** 给它替代通知(另一账户照常请审), +并在轮次报告点名说明走了 assignee 兜底。**请审走免碰 draft 位的专用 REST 端点,MCP +兜底显式带 `draft: true`**(坑与端点事实住 platform-readings);④ 轮次报告单列「awaiting a human +merge」(「等人来合」与「被忘了」在 GitHub 上长得一模一样)。混合 diff 一条命中就分叉, +⛔ 不按比例判;要拆就让 dev 单独开 PR;已入队才读到本条 ⇒ 转 draft 与 disable 都做, +出队以阳性探针答、ref 缺席只旁证不承载结论(探针与两向相反实测住 platform-readings)。 +**skills 车道自有 PR 再按 diff 内容分流**(维护者 2026-08-26 裁定,原话:「skills +中的 pr,只有包含md文件时需要推给我审核,其他代码文件你直接自己审核。」):diff 含任一 +`.md` 文件 ⇒ 上述终局四件套照旧;纯代码面(`scripts/pm/` 工具、`.claude/` hooks/workflows/settings、 +`skills/**` 非 md 产物)⇒ skills 席按契约复审档自审(清单不减)后直接落地(ready → 入队), +⛔ 不推维护者;分流只及 skills 车道自有 PR,其它车道 governed 面照旧。路径面干净的才转 +ready → 入队(队列是唯一被认可的落地路径,⛔ 永不队列外 `--auto` 合并)。 +**入队资格 = PR 上每一个 check 全绿,⛔ 不是 required 子集** —— required 集是队列强制的地板, +不是 PM 放行的门槛;非必查门的红要么是真缺陷要么是坏门,两者都归 PM 入队前处置(实测: +一张 required 全绿、非必查类型门与一个测试分片红着的 PR 经队列落地, +该仓 main 红了约一小时,逐 PR 连环红到 fix-forward 才止)。本段只适用本循环派发的 dev PR; +PM 自己的工具 PR 留维护者。main-red 修复的跳队例外与事故锚卡约定见 landing-operations B。 **入队与落地(细则见 `references/landing-operations.md`,落地窗口查阅)。** 原则: -- **条款②入队闸门(维护者 2026-08-16 批准;声明肢 2026-08-17 裁定)**:翻 ready / 入队前先取 PR - **实际 diff** —— diff 是事实,卡片语义是预测;`--tier` 嫌疑行是提示不是裁定。**双肢命中 - 任一且派发档位低于契约复审档位 ⇒ ⛔ 禁止入队**:路径肢 = diff 触及契约 - 面(`packages/spec/src/**`,含 error-code-ledger 与 `*.zod.ts` 契约 schema);声明肢 = 认领评论声明 - `Clause-②: yes`,与路径无关(错误的 `no` 是记录在案、可审计的假申报,不再是静默缺口)。⛔ - 永不把路径触发读作条款②的完整覆盖 —— 它只盖路径肢;不触契约文件而改变接受/拒绝 - 行为或扩大公开面的**内容肢**由声明行承载。档位以 dispatch-gates 常量 `CONTRACT_REVIEW_TIER` - 为准(档位单源,⛔ 本文与标签不写模型名,模型升级只改一行一个文件)。派发席职责止 - 于:卡上记一行认定、挂 `needs:contract-review`(标签命名审的对象,恒英文)、停手;⛔ 禁止自查 - 放行。挂标仅当**可复审契约增量已存在**(draft PR,或先到的报告);队列/受阻卡的前瞻预挂 - 已废止(维护者 2026-08-28 裁定)—— 前瞻条款②事实住卡上裁决/分诊评论、认领 `Clause-②` - 申报与 `--tier` 输出;开着的载体恒为一单真实待审。复审链细则(载体纪律、资格与归属、 - 降档保险丝)见 `references/contract-review.md`。 -- **碰生成物的 PR,入队前先同步 + 整体重生成**(os-regen 驱动零冲突标记地**静默丢掉一侧改 - 动**): 四步序已机械化 `bash scripts/pm/os-regen-merge.sh`;陷阱、断言措辞与锚点禁令见 - landing-operations A。 -- **跟到 MERGED 为止;入队后的看护同归车道 PM 的落地窗口**:验收、首次入队 flip 定点、MERGED - 两读 - 数、关键 PR 订阅与退订/归档、落地后再核落地判据 —— 操作细则全在 landing-operations - B。**落地记 - 账**:座位贴落地清单即账本,逐轮即时记;确需全仓核对时首选 `head:claude/` 精确过滤。 -- **红/踢出处置在同一落地窗口内做**:机器输入是 merge-queue triage workflow 落在被踢 PR 上的分 - 诊 - 评论(失败签名与计数,细节以该 workflow 头为权威);判据唯一来源是签名台账,优先于现场判 - 断 —— - 台账留在其锚点 issue 上作查表数据,**只有人工能升级**(疑似新 flaky 只留提请,⛔ 不自行加 - 表;纯 - 计数不追记,只有改变修法作用域时才记)。四分支:已知 flaky ⇒ 原样重投;**已修签名再现 - ⇒ ⛔ 不重 - 投**,判新问题重新诊断;基上缺已合修复 ⇒ merge main 推新提交(重跑无效);新签名 ⇒ ⛔ 不 - 重投,在 PR 与其 `Fixes` 卡各留完整签名与初判;每次处置留审计评论(重投写签名与台账依 - 据)。 -- **依赖前棒才能转绿的 PR:draft 停放 + 签名级预期红清单 + 解除条件**;**多个已实现 PR 全碰 - 生成物 - ⇒ 串行接力一次只放行一个,每棒一整圈、交接语义不是文本** —— 两式全文见 - landing-operations C/D。 +- **条款②入队闸门(维护者 2026-08-16 批准;声明肢 2026-08-17 裁定)**:翻 ready / 入队前先取 + PR **实际 diff** —— diff 是事实,卡片语义是预测;`--tier` 嫌疑行是提示不是裁定。 + **双肢命中任一且派发档位低于契约复审档位 ⇒ ⛔ 禁止入队**:路径肢 = diff 触及契约面 + (`packages/spec/src/**`,含 error-code-ledger 与 `*.zod.ts` 契约 schema);声明肢 = 认领评论声明 + `Clause-②: yes`,与路径无关(错误的 `no` 是记录在案、可审计的假申报,不再是静默缺口)。 + ⛔ 永不把路径触发读作条款②的完整覆盖 —— 它只盖路径肢;不触契约文件而改变接受 + /拒绝行为或扩大公开面的**内容肢**由声明行承载。档位以 dispatch-gates 常量 + `CONTRACT_REVIEW_TIER` 为准(档位单源,⛔ 本文与标签不写模型名,模型升级只改一行一个文件)。 + 派发席职责止于:卡上记一行认定、挂 `needs:contract-review`(标签命名审的对象,恒英文)、 + 停手;⛔ 禁止自查放行。挂标仅当**可复审契约增量已存在**(draft PR,或先到的报告); + 队列/受阻卡的前瞻预挂已废止(维护者 2026-08-28 裁定)—— 前瞻条款②事实住卡上裁决 + /分诊评论、认领 `Clause-②` 申报与 `--tier` 输出;开着的载体恒为一单真实待审。 + 复审链细则(载体纪律、资格与归属、降档保险丝)见 `references/contract-review.md`。 +- **碰生成物的 PR,入队前先同步 + 整体重生成**(os-regen + 驱动零冲突标记地**静默丢掉一侧改动**): 四步序已机械化 `bash scripts/pm/os-regen-merge.sh`; + 陷阱、断言措辞与锚点禁令见 landing-operations A。 +- **跟到 MERGED 为止;入队后的看护同归车道 PM 的落地窗口**: + 验收、首次入队 flip 定点、MERGED 两读数、关键 PR 订阅与退订/归档、 + 落地后再核落地判据 —— 操作细则全在 landing-operations B。**落地记账**: + 座位贴落地清单即账本,逐轮即时记;确需全仓核对时首选 `head:claude/` 精确过滤。 +- **红/踢出处置在同一落地窗口内做**:机器输入是 merge-queue triage workflow 落在被踢 + PR 上的分诊评论(失败签名与计数,细节以该 workflow 头为权威);判据唯一来源是签名台账, + 优先于现场判断 —— 台账留在其锚点 issue 上作查表数据,**只有人工能升级** + (疑似新 flaky 只留提请,⛔ 不自行加表;纯计数不追记,只有改变修法作用域时才记)。 + 四分支:已知 flaky ⇒ 原样重投;**已修签名再现 ⇒ ⛔ 不重投**, + 判新问题重新诊断;基上缺已合修复 ⇒ merge main 推新提交(重跑无效);新签名 ⇒ ⛔ 不重投, + 在 PR 与其 `Fixes` 卡各留完整签名与初判;每次处置留审计评论(重投写签名与台账依据)。 +- **依赖前棒才能转绿的 PR:draft 停放 + 签名级预期红清单 + 解除条件**; + **多个已实现 PR 全碰生成物 ⇒ 串行接力一次只放行一个, + 每棒一整圈、交接语义不是文本** —— 两式全文见 landing-operations C/D。 ### 轮次报告与节奏 -每轮向维护者打**中文**轮次报告(chat 通道,语言政策显式例外):issue → 判决 → PR 链接 → 备 -注的表 -,加升级项、代裁清单(分诊)、awaiting a human merge 项、governed 合并审计清单(实跑 -`node scripts/pm/check-governed-merges.mjs --since <上轮>`,⛔ 不凭记忆汇总;此为车道早警,权威 -合并窗口与认定/回滚处置归总监席,`references/lanes/director.md`)、**`UNRECOGNISED` 行**(对本轮 -门禁日志 grep `UNRECOGNISED`,逐行照录,`NOT APPLICABLE` 行也在内 —— 缺行读作「无未识别项」,实 -则可能是没人 grep)。健康指标四个(总 open 数刻意不在其 -中 —— 债密区发现快于关闭是循环在工作):**可派发库存**(dispatchable inventory;open `pm:queue` 未 -认领及趋势);**决策箱**(decision inbox;待维护者数,分诊简报还要点名带开放下游依赖的决策 -卡 —— 从 `Blocked-by:` 反向索引现算);**finding 数与中位年龄**(裸标签数即未定级数,hold 已换 -标不 -在内;老化 = 首触欠账);**发版阻塞**(release blockers;三仓 `target:`之和,归零 = 三张板都 -空)。 - -**波次收工点(维护者 2026-08-09 裁定)。** ① 收工点 = 会话内在飞归零(⛔ 不在复核中途压 -缩;云卡不挡 —— 热移交见座位贴协议细则);② 收工存档 = 上下文里的判断 flush 到 GitHub(不 -过 -夜义务),随后**立即派下一波**,⛔ 不等人闸。`/compact` 由维护者在终端会话择机执行,永远不 -是派发前提;①② 令任何压缩无损,前提是 GitHub 恒为唯一权威 —— 失守时压缩即丢判断。 +每轮向维护者打**中文**轮次报告(chat 通道, +语言政策显式例外):issue → 判决 → PR 链接 → 备注的表,加升级项、代裁清单(分诊)、awaiting +a human merge 项、governed 合并审计清单(实跑 `node scripts/pm/check-governed-merges.mjs --since <上轮>`, +⛔ 不凭记忆汇总;此为车道早警,权威合并窗口与认定/回滚处置归总监席, +`references/lanes/director.md`)、**`UNRECOGNISED` 行**(对本轮门禁日志 grep `UNRECOGNISED`, +逐行照录,`NOT APPLICABLE` 行也在内 —— 缺行读作「无未识别项」,实则可能是没人 grep)。 +健康指标四个(总 open 数刻意不在其中 —— 债密区发现快于关闭是循环在工作): +**可派发库存**(dispatchable inventory;open `pm:queue` 未认领及趋势);**决策箱**(decision inbox; +待维护者数,分诊简报还要点名带开放下游依赖的决策卡 —— 从 `Blocked-by:` 反向索引现算); +**finding 数与中位年龄**(裸标签数即未定级数,hold 已换标不在内; +老化 = 首触欠账);**发版阻塞**(release blockers;三仓 `target:`之和,归零 = 三张板都空)。 + +**波次收工点(维护者 2026-08-09 裁定)。** ① 收工点 = 会话内在飞归零(⛔ 不在复核中途压缩; +云卡不挡 —— 热移交见座位贴协议细则); +② 收工存档 = 上下文里的判断 flush 到 GitHub(不过夜义务),随后**立即派下一波**, +⛔ 不等人闸。`/compact` 由维护者在终端会话择机执行,永远不是派发前提; +①② 令任何压缩无损,前提是 GitHub 恒为唯一权威 —— 失守时压缩即丢判断。 ### 停止条件与待命 -停:队列空或 `rounds` 用尽(**仅一次性调用适用**);一轮 ≥ 半数派发失败或升级(系统性问 -题,继续 -烧 backlog 是浪费);维护者打断。**常设座位队列清空 ≠ 退场**,是切换待命姿态:巡检间隔 -按「收集」② -(待命放宽、有在飞收紧),待命五项(各项纪律以其主节为准,⛔ 此处不另抄)—— findings 配 -合、`pm:blocked`/`pm:on-hold` -解锁扫描、在飞/已入队 PR 跟到 MERGED、决策箱仅在报告中列出 ⛔ 不 nag、跨车道备忘跟进。 -退场只有两个入口:维护者交接令(走交接收尾清单),或被惰性回收。 +停:队列空或 `rounds` 用尽(**仅一次性调用适用**);一轮 ≥ 半数派发失败或升级(系统性问题, +继续烧 backlog 是浪费);维护者打断。**常设座位队列清空 ≠ 退场**,是切换待命姿态: +巡检间隔按「收集」②(待命放宽、有在飞收紧),待命五项(各项纪律以其主节为准, +⛔ 此处不另抄)—— findings 配合、`pm:blocked`/`pm:on-hold` 解锁扫描、 +在飞/已入队 PR 跟到 MERGED、决策箱仅在报告中列出 ⛔ 不 nag、 +跨车道备忘跟进。退场只有两个入口:维护者交接令(走交接收尾清单),或被惰性回收。 ## 断粮与跨墙恢复(5 小时用量墙) 出处:维护者 2026-08-11 提问(「首先项目经理能不能查到相关的数据,其次是到达时间窗口工作就会停, 是否应该设置一个1小时的定时以监测时间窗口已经解锁」)。检测读数、盲区与恢复 playbook 细则见 `references/platform-readings.md`;常驻原则: -- **检测**:**权威的墙信号是失败本身**——撞墙报文里的重置时刻在那一刻可得、事前查不 - 到,把它记下来(`ccusage blocks` 等工具读数与其盲区在事实表)。 -- **跨墙定时器**:拿到重置时刻 ⇒ 一发定点(reset + 缓冲)优先;没有 ⇒ 挂每小时 cron Routine,⛔ - **不用 send_later 链** —— send_later 是 run-once、fire 后自禁用,投进死窗口那一发是否被重试 - 未实 - 测且文档未承诺,一次性链条可能断在它存在的意义上;第一枪成功的 fire 跑恢复后**删除 - cron**(幸存 cron 是孤儿定时器)。fired 文本照定时器写法纪律。 -- **恢复 playbook 链的是既有规则**:逐个探在飞云卡 → 直接验收兜底或 transcript 复活→ 重挂 - 常规 - 巡检 → 照常跑轮;draft-PR-early 契约守住时零信息丢失。 +- **检测**:**权威的墙信号是失败本身**——撞墙报文里的重置时刻在那一刻可得、 + 事前查不到,把它记下来(`ccusage blocks` 等工具读数与其盲区在事实表)。 +- **跨墙定时器**:拿到重置时刻 ⇒ 一发定点(reset + 缓冲)优先; + 没有 ⇒ 挂每小时 cron Routine,⛔ **不用 send_later 链** —— send_later 是 run-once、fire 后自禁用, + 投进死窗口那一发是否被重试未实测且文档未承诺,一次性链条可能断在它存在的意义上; + 第一枪成功的 fire 跑恢复后**删除 cron**(幸存 cron 是孤儿定时器)。 + fired 文本照定时器写法纪律。 +- **恢复 playbook 链的是既有规则**:逐个探在飞云卡 → 直接验收兜底或 + transcript 复活→ 重挂常规巡检 → 照常跑轮;draft-PR-early 契约守住时零信息丢失。 ## 升级与决策 -**先过升级门槛 —— 大多数「感觉像决定」的不是决定。** 维护者原话:「明显的问题直接修,不是事事 -都需要我确认」。只在至少一条成立时升级:选项在**产品语义或公开契约形状**上真实分歧, -且 issue/AGENTS.md/ADR/既有代码规范都定不了;或修复需要**破坏性/难回滚动作**。其余都是 PM -的 -裁量 —— 裁定、派发、给维护者**否决窗口而非许可门**。具名不升级类(立即行动):恢复不 -变量的修复( -发现本身自带决定 —— 问「可以恢复不变量吗」是反模式);技术任务间的顺序与依赖;验证 -策略 -;dev 的 `needs_decision` 经 PM 复核落进上述类的,PM 直接答复不上传。 - -**第三档:带前提的裁决** —— 分歧关键是一个可被代码证伪的事实时,三件套缺一不可:①裁 -决(选定路线 -);② 把裁决挂在具名、可证伪的前提上,派发令要求 dev 先验前提再动手; ③ 显式禁令「前提不成立就 -报 fork,⛔ 不许硬做,也不许悄悄退回另一个选项」—— 省掉第③ 条就退化成最坏形态:前提不成立时 dev 自行改选,即无人裁决。 - -**两条元判据(同族近似单默认不进决策箱,维护者 2026-08-07 拍板):** ① 静默丢弃的声明默认 -并入既 -有拒收集(兄弟支已裁成响亮编写期错误 ⇒ 新支复用母单裁决直接入队,只有真实语义差异 -才重开;**继承 -的是裁决连同理由** —— 母单理由被实测为分支特有时本条不适用,判法是把母单理由拿到 -新支复核一遍) -。② 一个操作两个实现且行为不一致 ⇒ **带治理的一侧**(权限闸、同意、去重、审计)默认 -胜出,另一侧 -改绑并删除 —— 不是对齐也不是双写;反向裁只在产品语义明确要求时成立且必须写进裁决 -正文;留着未治理侧等于给权限闸留旁路。 - -**落卡/升级流程**:① **先刷新卡片前提** —— 隔夜没动的卡默认按「前提未经验证」处 -理;**卡上每条前提 -行自带一条 re-check 命令**(`git log … -- `、REST compare、带引号精确名 grep、`ls-remote | -grep `),复升级时逐条**跑**一遍,零命中/变形的就地改写或撤卡。② 决策默认**锚在所 -属 issue** -(分析发评论 —— 中文,模板见 references;挂 `needs-user-decision`、退出活动队列),无自然锚才单 -开 -`[Decision] <一句话>` 卡。③ **答复/代裁到手,裁决记录是一个原子动作,四件同笔**(维护者 -2026-08-13) -:鲜度门(录前重读晚于正文最后编辑的评论,有修正的先调和正文)/ 状态转换同笔(决策标签 -或 finding 定 -级换结果态,永不留挂)/ `Blocked-by:` 活性现验(合并一半也算解除,耗尽行同笔删)/ 条件已判即 -判(输入已知的就地判掉);案例与机械两旗见 `references/dispatch-runbook.md`。 +**先过升级门槛 —— 大多数「感觉像决定」的不是决定。 +** 维护者原话:「明显的问题直接修,不是事事都需要我确认」。只在至少一条成立时升级: +选项在**产品语义或公开契约形状**上真实分歧,且 issue/AGENTS.md/ADR/既有代码规范都定不了; +或修复需要**破坏性/难回滚动作**。其余都是 PM 的裁量 —— 裁定、 +派发、给维护者**否决窗口而非许可门**。具名不升级类(立即行动):恢复不变量的修复 +(发现本身自带决定 —— 问「可以恢复不变量吗」是反模式);技术任务间的顺序与依赖; +验证策略;dev 的 `needs_decision` 经 PM 复核落进上述类的,PM 直接答复不上传。 + +**第三档:带前提的裁决** —— 分歧关键是一个可被代码证伪的事实时,三件套缺一不可: +①裁决(选定路线);② 把裁决挂在具名、可证伪的前提上,派发令要求 dev 先验前提再动手; +③ 显式禁令「前提不成立就报 fork,⛔ 不许硬做,也不许悄悄退回另一个选项」—— +省掉第③ 条就退化成最坏形态:前提不成立时 dev 自行改选,即无人裁决。 + +**两条元判据(同族近似单默认不进决策箱,维护者 2026-08-07 拍板): +** ① 静默丢弃的声明默认并入既有拒收集(兄弟支已裁成响亮编写期错误 +⇒ 新支复用母单裁决直接入队,只有真实语义差异才重开;**继承的是裁决连同理由** +—— 母单理由被实测为分支特有时本条不适用,判法是把母单理由拿到新支复核一遍)。 +② 一个操作两个实现且行为不一致 ⇒ **带治理的一侧**(权限闸、 +同意、去重、审计)默认胜出,另一侧改绑并删除 —— 不是对齐也不是双写; +反向裁只在产品语义明确要求时成立且必须写进裁决正文; +留着未治理侧等于给权限闸留旁路。 + +**落卡/升级流程**:① **先刷新卡片前提** —— 隔夜没动的卡默认按「前提未经验证」 +处理;**卡上每条前提行自带一条 re-check 命令**(`git log … -- `、 +REST compare、带引号精确名 grep、`ls-remote | grep `),复升级时逐条**跑**一遍, +零命中/变形的就地改写或撤卡。② 决策默认**锚在所属 issue**(分析发评论 —— 中文, +模板见 references;挂 `needs-user-decision`、退出活动队列),无自然锚才单开 `[Decision] <一句话>` +卡。③ **答复/代裁到手,裁决记录是一个原子动作,四件同笔**(维护者 2026-08-13): +鲜度门(录前重读晚于正文最后编辑的评论,有修正的先调和正文)/ 状态转换同笔(决策标签或 +finding 定级换结果态,永不留挂)/ `Blocked-by:` 活性现验(合并一半也算解除,耗尽行同笔删)/ +条件已判即判(输入已知的就地判掉);案例与机械两旗见 `references/dispatch-runbook.md`。 **每个方案必须沿四条固定评估轴分析,这是决策分析的核心原则,不是可选项:** -- **实际业务需求** — 它服务的是**真实存在的业务场景**,还是投机性能力面?判据要求**实 - 测**(谁在 - 写这个键、谁在读、示例应用与真实部署的用法),「读起来像有用」不作数。这条轴会改 - 变结论,不是陪衬。 -- **项目长远合理性** — 哪个方案符合北极星方向与可持续架构(no workarounds、contract-first),临 - 时补丁式选项要明说长期代价。 -- **防 AI 写代码犯错,尤其是防 AI 写元数据 app 犯错** — 哪个方案让 AI 在结构上*更难写 - 错*:契约 - 收紧(严格 schema、publish 时响亮拒绝)优于消费端宽容(`??` 回退、静默容错)—— 宽容恰是 AI - 批 - 量犯错被掩盖的温床;声明即强制,绝不让 AI 声明一个运行时不兑现的能力。 -- **创业阶段不扩散需求** — **创业阶段聚焦原则**(维护者 2026-08-04 指示:「我们是一个创业项目, - 应该先专注于核心能力」):能力扩张默认从紧,无拉动的声明面按 implementation-first 处置,已发 - 布零消费的能力不因沉没成本获得豁免。 - -推荐意见必须基于这四条轴给出理由;四轴冲突时如实呈现权衡,交维护者拍板。**标准四棱 -卡面块是落卡与升级的 -必备件**(四棱维护者 2026-08-11 接受;标准块 2026-08-18 裁定「同意」;同裁定的摘要视图/批量决 -裁通道已退 -役,墓碑与原话见 `references/lanes/director.md`;收件箱由维护者定期与 AI -讨论消化,⛔ 不 assign 推送 —— 维护者 2026-08-19 裁定:「我感觉决策卡推给我太麻烦了,我需要和ai讨论才能判断,这个还是维 -持之前的样子。我会定期和ai讨论。」),每张 `needs-user-decision` 卡落卡即带、⛔ -不留待维护者到场再补。**四维分析从业务的角度写**(2026-08-20 裁)—— 落卡分析模板、写法 -六项、适用边界与 -四棱块固定形状细则连同出处原话见 `references/decision-analysis.md`;推荐是输入,永不是放行,人 -工地板不变。 -四棱是四条评估轴的卡面序列化,一一对应,同一个框架不是第二套,也是分诊代裁置信门的输 -入。 - -**决策通道优先序:卡先于弹窗**(维护者 2026-08-23 报告:「项目经理干活时经常弹出需要我决策的问题,如果我 -不在旁边工作就卡住了。」)。凡需维护者裁决,第一动作是落 `needs-user-decision` 卡(选项 + 推荐 + 证据 + -四棱块,与弹窗同内容),被阻塞的执行卡**同笔**挂 `pm:blocked` + `Blocked-by:` -指向它,队列其余照常消化,⛔ 永不整席等答复。`AskUserQuestion` 只是**在场加速器**:仅当维护 -者在本会话 +- **实际业务需求** — 它服务的是**真实存在的业务场景**, + 还是投机性能力面?判据要求**实测**(谁在写这个键、谁在读、 + 示例应用与真实部署的用法),「读起来像有用」不作数。这条轴会改变结论,不是陪衬。 +- **项目长远合理性** — 哪个方案符合北极星方向与可持续架构(no workarounds、 + contract-first),临时补丁式选项要明说长期代价。 +- **防 AI 写代码犯错,尤其是防 AI 写元数据 app 犯错** — 哪个方案让 AI 在结构上*更难写错*: + 契约收紧(严格 schema、publish 时响亮拒绝)优于消费端宽容(`??` 回退、静默容错)—— + 宽容恰是 AI 批量犯错被掩盖的温床;声明即强制,绝不让 AI 声明一个运行时不兑现的能力。 +- **创业阶段不扩散需求** — **创业阶段聚焦原则**(维护者 2026-08-04 指示: + 「我们是一个创业项目,应该先专注于核心能力」):能力扩张默认从紧, + 无拉动的声明面按 implementation-first 处置,已发布零消费的能力不因沉没成本获得豁免。 + +推荐意见必须基于这四条轴给出理由;四轴冲突时如实呈现权衡, +交维护者拍板。**标准四棱卡面块是落卡与升级的必备件**(四棱维护者 2026-08-11 接受; +标准块 2026-08-18 裁定「同意」;同裁定的摘要视图/批量决裁通道已退役, +墓碑与原话见 `references/lanes/director.md`;收件箱由维护者定期与 AI 讨论消化,⛔ 不 assign +推送 —— 维护者 2026-08-19 裁定:「我感觉决策卡推给我太麻烦了,我需要和ai讨论才能判断, +这个还是维持之前的样子。我会定期和ai讨论。」),每张 `needs-user-decision` 卡落卡即带、 +⛔ 不留待维护者到场再补。**四维分析从业务的角度写**(2026-08-20 裁)—— 落卡分析模板、 +写法六项、适用边界与四棱块固定形状细则连同出处原话见 `references/decision-analysis.md`; +推荐是输入,永不是放行,人工地板不变。四棱是四条评估轴的卡面序列化, +一一对应,同一个框架不是第二套,也是分诊代裁置信门的输入。 + +**决策通道优先序:卡先于弹窗**(维护者 2026-08-23 报告: +「项目经理干活时经常弹出需要我决策的问题,如果我不在旁边工作就卡住了。」)。 +凡需维护者裁决,第一动作是落 `needs-user-decision` 卡(选项 + 推荐 + 证据 + 四棱块, +与弹窗同内容),被阻塞的执行卡**同笔**挂 `pm:blocked` + `Blocked-by:` 指向它,队列其余照常消化, +⛔ 永不整席等答复。`AskUserQuestion` 只是**在场加速器**:仅当维护者在本会话 ~30 分钟内有过人类输入才可发,每问必带推荐项,被 Skip 或长挂即转卡通道 ⛔ 不重弹 —— -卡先于弹窗存在,弹窗怎么死盘面都诚实。 -**项目总监席:人工召唤,四职 = `needs:contract-review` 复审链、决裁勤务、维护者动作台账、 -governed 合并审计**(维护者 2026-08-27 裁定,原话:「项目总监 由人工定期指挥,负责处理 -contract-review 类别的和需要决裁的。」「需要维护者处理的事情,也归项目总监。」—— 决裁半边自此由 skills 席移交本席, -改写 2026-08-26「skills 和决裁的问题,还是由skills席统一人工处理,我会要求你处理某个仓的skills和 -决裁。」的归属半句,skills 面与其车道照旧归 skills 席)。入口 = `/pm-dispatch director`;⛔ 无 -Routine 无 cron;档位硬门 = `CONTRACT_REVIEW_TIER`(保险丝机读),不达档只做免档整理并停放 -四职;不占 `domain:*`,永不认领 backlog、永不写码;章程见 `references/lanes/director.md`。 +卡先于弹窗存在,弹窗怎么死盘面都诚实。**项目总监席:人工召唤,四职 = `needs:contract-review` +复审链、决裁勤务、维护者动作台账、governed 合并审计**(维护者 2026-08-27 裁定, +原话:「项目总监 由人工定期指挥,负责处理 contract-review 类别的和需要决裁的。」 +「需要维护者处理的事情,也归项目总监。」—— 决裁半边自此由 skills 席移交本席, +改写 2026-08-26「skills 和决裁的问题,还是由skills席统一人工处理,我会要求你处理某个仓的 +skills和决裁。」的归属半句,skills 面与其车道照旧归 skills 席)。入口 = `/pm-dispatch director`;⛔ +无 Routine 无 cron;档位硬门 = `CONTRACT_REVIEW_TIER`(保险丝机读),不达档只做免档整理并停放四职; +不占 `domain:*`,永不认领 backlog、永不写码;章程见 `references/lanes/director.md`。 ## 护栏(Guardrails,有约束力) -- PM **不写任何文件**(唯一例外及其全部条件见全体座位不变量,⛔ 不另抄第二份);合并只 - 对**已复核 - 全绿的 dev-agent PR 经合并队列**发生 —— 永不合自己的 PR、永不合红的或未复核的、永不 - 绕过队列。 -- **版本发布必须人工**(维护者 2026-08-07 拍板;发布动作的完整清单 - 与「围绕发布的工作照旧归座位」 - 细则以 AGENTS.md「release act」段为权威,含**合并 Version Packages PR**)。发现未经人工的发布痕 - 迹按事故立案,⛔ 不代跑补救性发布 —— 机械通道的存在不构成授权,遇到那类通道当缺 - 陷上报。 -- **Governed 面由维护者人工合并,合并即审核记录**(三裁一脉:2026-08-08「adr 只能由维护者自己确 - 认,人工合并,ai 不得擅自合并」;2026-08-11「所有 skills 的更新和adr 类似,需要人工审核」; - 2026-08-18 对「人工合并即人工审核,事后审计代替事前门」整包:「同意。」;2026-08-27 增**授 - 权批准钉 head ⇒ 队列放行**第二路径,细则单源见 ACCEPT 路径分叉)。面 = 该节统一定义; - skills 车道纯代码 PR 的 md-content 分流、禁令三条与离队出口同见该节。⛔ **agent 席位永不 - 以任一账号对受管面 PR 提交批准 review**(授权集合内也有 agent 席,与「永不入队」同级);事 - 后防线 = 审计清单,归因同读合并人与批准人,agent 批准或不认识的合并 = 违规立案回滚。 -- **决定属于维护者:永不代维护者回答产品/架构问题**(唯一例外:分诊职责里已裁的代裁车 - 道,边界恰 - 与其置信门重合,不得更宽);**永不派发 assignee 是别人的 issue;永不派发带 `needs-user-decision` - 的 issue**。 -- 并行度以 `batch` 封顶,同批**按构造文件面不相交**;**分诊座位永不认领、永不派发、永不 - 写代码;执行 - 座位只在自己那一个车道认领、不改标签,误标挂 `pm:retriage` + 异议评论同笔;`domain:*` 只有 - 一个生产者**(豁免、例外两条与全部条件见「多仓协调 4」「域车道」「候选与批次」,⛔ - 不另抄第二份)。 +- PM **不写任何文件**(唯一例外及其全部条件见全体座位不变量,⛔ 不另抄第二份); + 合并只对**已复核全绿的 dev-agent PR 经合并队列**发生 —— 永不合自己的 PR、 + 永不合红的或未复核的、永不绕过队列。 +- **版本发布必须人工**(维护者 2026-08-07 拍板; + 发布动作的完整清单与「围绕发布的工作照旧归座位」细则以 AGENTS.md「release act」 + 段为权威,含**合并 Version Packages PR**)。发现未经人工的发布痕迹按事故立案, + ⛔ 不代跑补救性发布 —— 机械通道的存在不构成授权,遇到那类通道当缺陷上报。 +- **Governed 面由维护者人工合并,合并即审核记录**(三裁一脉:2026-08-08 + 「adr 只能由维护者自己确认,人工合并,ai 不得擅自合并」;2026-08-11「所有 skills 的更新和adr + 类似,需要人工审核」;2026-08-18 对「人工合并即人工审核,事后审计代替事前门」 + 整包:「同意。」;2026-08-27 增**授权批准钉 head ⇒ 队列放行**第二路径, + 细则单源见 ACCEPT 路径分叉)。面 = 该节统一定义;skills 车道纯代码 PR 的 md-content 分流、 + 禁令三条与离队出口同见该节。⛔ **agent 席位永不以任一账号对受管面 + PR 提交批准 review**(授权集合内也有 agent 席,与「永不入队」同级);事后防线 = 审计清单, + 归因同读合并人与批准人,agent 批准或不认识的合并 = 违规立案回滚。 +- **决定属于维护者:永不代维护者回答产品/架构问题**(唯一例外: + 分诊职责里已裁的代裁车道,边界恰与其置信门重合, + 不得更宽);**永不派发 assignee 是别人的 issue;永不派发带 `needs-user-decision` 的 issue**。 +- 并行度以 `batch` 封顶,同批**按构造文件面不相交**; + **分诊座位永不认领、永不派发、永不写代码;执行座位只在自己那一个车道认领、 + 不改标签,误标挂 `pm:retriage` + 异议评论同笔;`domain:*` 只有一个生产者**(豁免、 + 例外两条与全部条件见「多仓协调 4」「域车道」「候选与批次」,⛔ 不另抄第二份)。 ## 报告契约(Report contract,os-dev 返回什么) -终报 JSON 的权威形状住 `.claude/agents/os-dev.md`「终报消息」节 —— 字段与拼写以那里为准,⛔ -本文 -不抄第二份(两份拷贝已实测漂移且无同步门禁)。PM 侧消费规则: +终报 JSON 的权威形状住 `.claude/agents/os-dev.md`「终报消息」节 —— 字段与拼写以那里为准, +⛔ 本文不抄第二份(两份拷贝已实测漂移且无同步门禁)。PM 侧消费规则: `premise_still_valid: false` + `pr: null` 是合法终报 —— 当再分诊输入复核,永不当失败派发。 `status: needs_decision` 时 `open_questions` 必须非空。`out_of_scope_findings` 应已由 dev 立成无 assignee 的卡(查重先行、归挂判据、标签按种分 —— 观察类打 `finding`、具体缺陷不打标留分诊,与 -os-dev 规则 3 同句;立在修复落地仓并带回链);PM 核验它们存在,**并把同轮并行报告互相 -对读** —— 两个 dev 同一小时审相邻代码会立出孪生卡,只有 PM 同时看得见两份报告。 +os-dev 规则 3 同句;立在修复落地仓并带回链);PM 核验它们存在,**并把同轮并行报告互相对读** +—— 两个 dev 同一小时审相邻代码会立出孪生卡,只有 PM 同时看得见两份报告。 ## 机械守卫索引(原则在此,细节以脚本头为权威) | 守卫 | 一句话 | |:--|:--| -| `scripts/pm/check-skill-line-ratchet.mjs` | 本文件行数只降不升(`pnpm check:pm-skill-ratchet`);抬上限需维护者裁决引用在 PR 正文;⛔ re-wrap(折行合并)不得用作筹行 —— 棘轮治理的是内容体量,行数只是机读代理,新增以删减付账;密度优化仅随净减内容的 PR 顺带(维护者 2026-08-17 授权席裁) | +| `scripts/pm/check-skill-line-ratchet.mjs` | 本文件行数只降不升(`pnpm check:pm-skill-ratchet`);抬上限需维护者裁决引用在 PR 正文;⛔ re-wrap(折行合并)不得用作筹行 —— 棘轮治理的是内容体量,行数只是机读代理,新增以删减付账;密度优化仅随净减内容的 PR 顺带(维护者 2026-08-17 授权席裁);筹行(为内容购买行数)⛔ vs 独立密度修复(无内容购买)允许(维护者 2026-08-29 裁) | | `scripts/pm/check-skill-id-lint.mjs` | 本技能与 os-dev 定义的操作文本 ⛔ 不引用 issue 编号(`pnpm check:pm-skill-id-lint`)—— 经验必须自含 | | `scripts/pm/check-half-states.mjs` | label/assignee/PR 半状态的 report-only 巡查(含已复核就绪却无人落地的孤儿 PR 检测) | | `scripts/pm/check-governed-merges.mjs` | governed 面合并清单的 report-only 审计(事后防线;轮报载体,本地枚举零 API,仅归因走查询) | diff --git a/.claude/skills/pm-dispatch/references/compile-surfaces.md b/.claude/skills/pm-dispatch/references/compile-surfaces.md index e75790488c..9d2b8e2d10 100644 --- a/.claude/skills/pm-dispatch/references/compile-surfaces.md +++ b/.claude/skills/pm-dispatch/references/compile-surfaces.md @@ -1,8 +1,9 @@ # 过滤 / 谓词语义的编译面清单(references —— 按需加载) -出处:主文件「派发」的过滤/谓词语义标准条款 —— 命中该条款的派发令把本清单**逐面抄 -进去**,PR 逐面申报。维护纪律与派发前复核串在正文内,一并适用:**这张表由 PR 维护、 -派发前先跑复核串重验,⛔ 不凭记忆抄**。 +出处:主文件「派发」 +的过滤/谓词语义标准条款 —— 命中该条款的派发令把本清单**逐面抄进去**,PR 逐面申报。 +维护纪律与派发前复核串在正文内, +一并适用:**这张表由 PR 维护、派发前先跑复核串重验,⛔ 不凭记忆抄**。 编译面清单(逐面实测 @ `main` `48f98b0`,2026-08-07): @@ -16,11 +17,10 @@ | 半面 | objectql `having-filter` | `packages/objectql/src/having-filter.ts:92` / `:98`(`applyHaving` / `matchesHaving`) | 聚合**后**过滤。算半面是因为词表是子集,**但申报义务不打折** —— 它是**唯一没有 conformance 表覆盖的面**(`FILTER_LOGIC_CASES` 不驱动 HAVING 路径),所以漏了它连门禁都不会红 | | 已解冻 | `driver-memory` / `driver-mongodb` | `packages/drivers/driver-memory/src/memory-matcher.ts:134`(`checkCondition`)、`packages/drivers/driver-mongodb/src/mongodb-filter.ts:700`(`translateFieldOperators`) | 2026-08-05 投入冻结,**2026-08-11 两条裁决解除** ⇒ 「不在范围 + 冻结指令」作废,按普通面申报 | -**这张表本身由 PR 维护 —— 与域表同一纪律。** 增删一面(新驱动、新求值器、某面被合并 -或退役、冻结状态变化)的那个 PR 顺手改这里,不留给下一次裁决重新数。清单**会**过期是 -必然的,清单**没有维护者**才是缺陷。 +**这张表本身由 PR 维护 —— 与域表同一纪律。 +** 增删一面(新驱动、新求值器、某面被合并或退役、冻结状态变化)的那个 PR 顺手改这里, +不留给下一次裁决重新数。清单**会**过期是必然的,清单**没有维护者**才是缺陷。 ⚠️ 派发前复核一遍再抄,⛔ 不要凭这张表的记忆填派发令:本仓的包路径搬过家(驱动进 -`packages/drivers/`、服务进 `packages/services/`),行号更是每天在动。一条够用的复核 -串:`grep -rn 'matchesFilterCondition\|buildWhereSQL\|compileScopedFilterToSql' -packages --include=*.ts | grep -v node_modules`。 +`packages/drivers/`、服务进 `packages/services/`),行号更是每天在动。一条够用的复核串:`grep +-rn 'matchesFilterCondition\|buildWhereSQL\|compileScopedFilterToSql' packages --include=*.ts | grep -v node_modules`。 diff --git a/.claude/skills/pm-dispatch/references/contract-review.md b/.claude/skills/pm-dispatch/references/contract-review.md index 5a19936b0f..1ec587056b 100644 --- a/.claude/skills/pm-dispatch/references/contract-review.md +++ b/.claude/skills/pm-dispatch/references/contract-review.md @@ -9,10 +9,10 @@ 席账号 request review(同裁决:「也可以直接要求复审」—— 仅通知,载体仍是标签)、停手。 - ⛔ **不预挂**(维护者 2026-08-28 裁定):可复审增量存在前永不挂标,队列/受阻卡的提前挂已废 止 —— 前瞻条款②事实走主文件闸门段的三条既有通道;开载体恒 = 真实待审。 -- **载体不迁移**(维护者 2026-08-18,原话:「中期把闸门迁到 PR review 的 Request Changes 上 我觉得 - 没必要」): 闸门载体保持本标签,⛔ 不迁 PR review / Request Changes、不为迁移留门。 -- **重挂前先查裁决**:闸门标签缺失 ⇒ 先 grep 卡评论找复审结论 —— PASS + 无标 + head 未 - 动 = 已清标非被剥;head 后移或无结论才重挂(`get_reviews` 读空 ≠ 未复审)。 +- **载体不迁移**(维护者 2026-08-18,原话:「中期把闸门迁到 PR review 的 Request Changes + 上 我觉得没必要」): 闸门载体保持本标签,⛔ 不迁 PR review / Request Changes、不为迁移留门。 +- **重挂前先查裁决**:闸门标签缺失 ⇒ 先 grep 卡评论找复审结论 —— PASS + + 无标 + head 未动 = 已清标非被剥;head 后移或无结论才重挂(`get_reviews` 读空 ≠ 未复审)。 ## 复审资格与归属 @@ -38,9 +38,9 @@ - 每场开场**必调一次 `get_session`**(claude-code-remote MCP,无参)读 `external_metadata.last_served_model`,⛔ 自述档位不是读数(静默降档腐蚀的恰是自述;实测与配置档陷阱见 platform-readings);读数 ≠ `CONTRACT_REVIEW_TIER` ⇒ 该场整体跳过、标签原样留置 —— 卡在队列外等待是安全态。 -- **保险丝只测座位自会话**:`mode:subagent` 里的 `get_session` 量的是**派发会话**(实测:钉在地板 - 档的子代理读回父档,⛔ 不作互证),传参只是配置 ⛔ 不作达档读数;条款②的 `mode:subagent` - 派发照旧恒保留 `needs:contract-review`,免审跳过仅座位自会话成立。 +- **保险丝只测座位自会话**:`mode:subagent` 里的 `get_session` 量的是**派发会话**(实测: + 钉在地板档的子代理读回父档,⛔ 不作互证),传参只是配置 ⛔ 不作达档读数; + 条款②的 `mode:subagent` 派发照旧恒保留 `needs:contract-review`,免审跳过仅座位自会话成立。 - **转录档位核验**(维护者 2026-08-27 裁)——「派更高档位子代理复审」仅核验通过才合法:采 信/清标前 grep 子代理 transcript 中 harness 逐消息盖章的 `model` 字段,产出裁决的每轮都须读 到契约复审档位,见回退证据 ⇒ 裁决整体作废;父会话仅两个合法动作 —— **逐字采纳或 diff --git a/.claude/skills/pm-dispatch/references/decision-analysis.md b/.claude/skills/pm-dispatch/references/decision-analysis.md index f607568aaa..883fee749f 100644 --- a/.claude/skills/pm-dispatch/references/decision-analysis.md +++ b/.claude/skills/pm-dispatch/references/decision-analysis.md @@ -4,8 +4,9 @@ ## 适用面(边界) -- 只约束 **`needs-user-decision` 卡与决策箱讨论**的四维分析;内部工具卡(dev 派发用)的四维照 - 旧,不强加行业类比。四条轴本身不变,轴定义与绑定句在主文件「升级与决策」。 +- 只约束 **`needs-user-decision` 卡与决策箱讨论**的四维分析; + 内部工具卡(dev 派发用)的四维照旧, + 不强加行业类比。四条轴本身不变,轴定义与绑定句在主文件「升级与决策」。 - 只适用新记录,存量分析 ⛔ 不回改(new-records-only,与四维中文化同款先例)。 ## 常设决裁批流程(2026-08-26 裁;裁决原话与归席见主文件「升级与决策」) @@ -16,31 +17,28 @@ ## 落卡分析模板(主文件「落卡/升级流程」②的 references 细则;中文,2026-08-19 裁) -段落骨架:背景 / 带 re-check 命令的前提 / 具体问题 / 选项 / 推荐 / 相关单与 PR;录裁与状态 -转换归主文件「落卡/升级流程」③。正文六项写法要求: - -1. **一句话问题**:开头一句话说清冲突是什么,不带实现名词 —— 写「三家公司住一个数据库,管理员打 - 开权限管理,三个页面全空」,不写「organization_id = NULL 的行是什么,两个互相矛盾的答案都已落地」。 -2. **选项 × 真实代价表**:每个选项一行「做什么 + 真实代价」,代价写**客户可感知的后果**(「这家客 - 户的审批单出现在别家客户眼前」),不写机制名词;有实测的注明实测。 -3. **业务含义直译**:每个选项配一句「业务上 = …」,允许行业类比(「像 Salesforce 每个 org 有自己 - 的 profiles」)。 -4. **四轴从业务立场论证**:每轴的论据是客户/产品/事故后果,机制只作括号补 - 充;「防 AI 犯错」轴写清 - 出错时**谁看到什么**(响亮拒绝 vs 静默泄露)。 +段落骨架:背景 / 带 re-check 命令的前提 / 具体问题 / 选项 / 推荐 / 相关单与 PR; +录裁与状态转换归主文件「落卡/升级流程」③。正文六项写法要求: + +1. **一句话问题**:开头一句话说清冲突是什么, + 不带实现名词 —— 写「三家公司住一个数据库,管理员打开权限管理, + 三个页面全空」,不写「organization_id = NULL 的行是什么,两个互相矛盾的答案都已落地」。 +2. **选项 × 真实代价表**:每个选项一行「做什么 + 真实代价」,代价写**客户可感知的后果** + (「这家客户的审批单出现在别家客户眼前」),不写机制名词;有实测的注明实测。 +3. **业务含义直译**:每个选项配一句「业务上 = …」, + 允许行业类比(「像 Salesforce 每个 org 有自己的 profiles」)。 +4. **四轴从业务立场论证**:每轴的论据是客户/产品/事故后果, + 机制只作括号补充;「防 AI 犯错」轴写清出错时**谁看到什么**(响亮拒绝 vs 静默泄露)。 5. **推荐 + 回退 + 置信缺口**:荐一项、给回退项、明说本分析看不见什么;格式见批流程。 6. **裁后执行段**:「裁后我会怎么执行(你不用管)」—— 让维护者只裁方向不背执行。 ## 四棱卡面块固定形状(落卡即带,⛔ 不留待维护者到场再补) -首行**机器可寻固定标记** ``(转义拼写写入,写后回读核验存活;提取按 -字 -面文本 grep,不依赖注释形状 —— sanitizer 纪律见平台读数);四棱各一行,用中文写(语言例外 -见主文件 -全体座位的不变量)—— ① 项目长远合理性(缩小还是扩大特例/契约增生);② 实际业务拉 -动(今天谁撞上;零拉动默认 defer/remove);③ 防 AI 犯错(闭合枚举优于自由结构、响亮拒绝优于 -静默容忍);④ 创 -业阶段 -不扩散(remove 优于 declare-and-maintain,每个已声明的键都是永久义务);一行推荐 + 字母选项 -(A/B/…);**一行强制置信缺口(「本分析看不见什么」)**。四棱行同受六项约束:每行论据从业 -务立场写,机制名词只作括号补充。 +首行**机器可寻固定标记** ``(转义拼写写入, +写后回读核验存活;提取按字面文本 grep,不依赖注释形状 —— sanitizer 纪律见平台读数); +四棱各一行,用中文写(语言例外见主文件全体座位的不变量)—— +① 项目长远合理性(缩小还是扩大特例/契约增生);② 实际业务拉动(今天谁撞上; +零拉动默认 defer/remove);③ 防 AI 犯错(闭合枚举优于自由结构、响亮拒绝优于静默容忍); +④ 创业阶段不扩散(remove 优于 declare-and-maintain,每个已声明的键都是永久义务); +一行推荐 + 字母选项(A/B/…);**一行强制置信缺口(「本分析看不见什么」)**。 +四棱行同受六项约束:每行论据从业务立场写,机制名词只作括号补充。 diff --git a/.claude/skills/pm-dispatch/references/dispatch-runbook.md b/.claude/skills/pm-dispatch/references/dispatch-runbook.md index b356b525ed..c580831690 100644 --- a/.claude/skills/pm-dispatch/references/dispatch-runbook.md +++ b/.claude/skills/pm-dispatch/references/dispatch-runbook.md @@ -5,133 +5,127 @@ ## 车道取卡全序与 `pm:blocking`(维护者 2026-08-13) -出处(逐字,未译):「被依赖的卡片是不是应该通过label标注提高优先级。项目经理处理任务清 -单时,bug 是不是应该提高优先级。」全序本体与 `pm:blocking` 推导在主文件;补遗:级序理由 -一行 —— p0 是显式裁定,blocking 一张挡多张,bug 是已坏的不变量、先于增强,卡龄防饿死;写 -入与摘除都在分诊轮 sweep,依赖者全关即摘,手工挂上的按误标处理、sweep 对着索引校正;种子 -与消费者注记在 `scripts/pm/ensure-pm-labels.sh`。 +出处(逐字,未译):「被依赖的卡片是不是应该通过label标注提高优先级。 +项目经理处理任务清单时,bug 是不是应该提高优先级。」 +全序本体与 `pm:blocking` 推导在主文件; +补遗:级序理由一行 —— p0 是显式裁定,blocking 一张挡多张,bug 是已坏的不变量、先于增强, +卡龄防饿死;写入与摘除都在分诊轮 sweep,依赖者全关即摘,手工挂上的按误标处理、 +sweep 对着索引校正;种子与消费者注记在 `scripts/pm/ensure-pm-labels.sh`。 ## 紧急卡 fable 直接分诊(维护者 2026-08-13) -出处(逐字,未译):「对于比较紧急的卡片,是否应该使用 fable 5 子agent直接分诊」。触 -发、授权面与同格式同效力在主文件;补遗:授权面不含派发(⛔ 不写码、不认领、不派发);单 -一生产者纪律照旧(与「代扫」同界)—— 分诊座位在班且已在处理同卡即让行;紧急通道改 -的是 -节奏,不是生产者数目。**半状态治愈积压排序**(维护者 2026-08-19「没有切换 label,导致挂 -了很久」;排序规则本体在主文件):限量 + 最新优先会令最老半状态结构性饿死,活过一个 -sweep 周期的半状态是治愈环自身的缺陷,不是库存;正文自报 P0/data-integrity 的命中即走本 -节紧急通道;机械年龄告警在半状态巡查脚本(细节以脚本头为权威)。 +出处(逐字,未译):「对于比较紧急的卡片,是否应该使用 fable 5 子agent直接分诊」。 +触发、授权面与同格式同效力在主文件;补遗:授权面不含派发(⛔ 不写码、不认领、 +不派发);单一生产者纪律照旧(与「代扫」同界)—— 分诊座位在班且已在处理同卡即让行; +紧急通道改的是节奏,不是生产者数目。**半状态治愈积压排序**(维护者 2026-08-19「没有切换 +label,导致挂了很久」;排序规则本体在主文件):限量 + 最新优先会令最老半状态结构性饿死, +活过一个 sweep 周期的半状态是治愈环自身的缺陷,不是库存;正文自报 P0/data-integrity +的命中即走本节紧急通道;机械年龄告警在半状态巡查脚本(细节以脚本头为权威)。 ## 发现分诊轮细则(维护者 2026-08-13 / 08-25) -出处(逐字,未译),同日三段:「Finding 很多,是否建议集中分诊」…「按照你的建议」= 域分 -批集中轮常设授权;「还有这个积压时常态,是否应该优化。」= 结构修复令;「积压数字本身有误 -导 —— 47 张里大半是带重启条件的健康 hold(它们本来就该躺着),那为什么标 finding」= 状 -态语义裁定。 - -- **状态转换机制**(「finding 恒 = 待首次定级」在主文件):定级出 hold ⇒ 同笔 `finding` - → `pm:on-hold`(域标签保留;hold 评论照既有纪律带日期/理由/具名重启条件,维护者裁 vs - 座位定级的出处写进评论,⛔ 不设第二个标签区分);修法是**状态转换,不是豁免评论**(双 - 态混编曾让健康 hold 顶红裸计数、藏住未定级堆;逐卡豁免评论机制已废弃,⛔ 不复活)。 -- **首触定级补遗**:零定级评论的卡优先 —— 未定级卡前提半衰期以天计,首触延迟是单卡 - 最大成本;关闭 not planned 附理由并列入轮次报告;立单 dev 只有局部视野,照实立单不压级。 +出处(逐字,未译),同日三段:「Finding 很多,是否建议集中分诊」…「按照你的建议」 += 域分批集中轮常设授权;「还有这个积压时常态,是否应该优化。」= 结构修复令; +「积压数字本身有误导 —— 47 张里大半是带重启条件的健康 hold(它们本来就该躺着), +那为什么标 finding」= 状态语义裁定。 + +- **状态转换机制**(「finding 恒 = 待首次定级」在主文件):定级出 hold + ⇒ 同笔 `finding` → `pm:on-hold`(域标签保留;hold 评论照既有纪律带日期/理由/具名重启条件, + 维护者裁 vs 座位定级的出处写进评论,⛔ 不设第二个标签区分); + 修法是**状态转换,不是豁免评论**(双态混编曾让健康 hold 顶红裸计数、 + 藏住未定级堆;逐卡豁免评论机制已废弃,⛔ 不复活)。 +- **首触定级补遗**: + 零定级评论的卡优先 —— 未定级卡前提半衰期以天计,首触延迟是单卡最大成本; + 关闭 not planned 附理由并列入轮次报告;立单 dev 只有局部视野,照实立单不压级。 - **每批约定**:≤5 张同族卡、同上下文逐张读(维护者 2026-08-25,取代 15–20/批);常设授权,⛔ - 不逐次请示。**sweep 打包晋级五条**(维护者 2026-08-07 批准):同类才打包(全部命中同一判 - 据);逐项清单(落点 | before | after)是 PR 正文必备件;N 项之外零改动且 PR 自证;范围外发现照 - 旧单开;sweep 卡是认领对象,成员单保持标签但不再是可派发候选。 + 不逐次请示。**sweep 打包晋级五条**(维护者 2026-08-07 批准):同类才打包(全部命中同一判据); + 逐项清单(落点 | before | after)是 PR 正文必备件;N 项之外零改动且 PR 自证; + 范围外发现照旧单开;sweep 卡是认领对象,成员单保持标签但不再是可派发候选。 - **积压告警**(旧 >15 触发的去处):连续 COMPLETED 清空 fire 后仍 >15 ⇒ 入流 > 吞吐,报维护者。 ## 同趟成员卡写侧打包(维护者 2026-08-16 限流裁定的对价) -出处:反复撞的限流墙经维护者确认为「GitHub API 池」。同一趟派发/定级覆盖多张成员卡 -时,**锚 -卡承载全量认领(或定级)评论**(会话、分支、文件面、交付物、串行约束全量),成员卡各留 -一行 -指针指向锚卡;标签翻转照旧逐卡执行 —— 省的是评论正文写量,不是状态写入;验收与解锁 -扫描的 -读侧不变,仍逐卡读。**写序:标签翻转只在认领评论写成功之后**,两笔不原子 —— 评论 502 -而标 -签已翻即制造一记真 H2(实测一轮三起);顺序反了就带重试义务,重试未成即回滚标签。 +出处:反复撞的限流墙经维护者确认为「GitHub API 池」。同一趟派发/定级覆盖多张成员卡时, +**锚卡承载全量认领(或定级)评论**(会话、分支、文件面、交付物、串行约束全量), +成员卡各留一行指针指向锚卡;标签翻转照旧逐卡执行 —— 省的是评论正文写量, +不是状态写入;验收与解锁扫描的读侧不变, +仍逐卡读。**写序:标签翻转只在认领评论写成功之后**,两笔不原子 —— 评论 502 +而标签已翻即制造一记真 H2(实测一轮三起);顺序反了就带重试义务,重试未成即回滚标签。 ## 座位贴活性巡查(分诊轮常设项;维护者 2026-08-14) 出处:「结论当轮执行」同批裁定;先例是七条 🟢 贴一日内被逐条手工纠正。分诊 Routine 每 fire 附带一次: -- **扫描面**:`label:pm:seat` 列表页上标题挂 `🟢 ` 的贴;`🟢 Routine` 座位以 - 调度器读数为准,不入本巡查。 -- **判据只认在任者自己的产出**(自有评论/认领/正文编辑,作者与时间戳是平台盖章的硬读 - 数), +- **扫描面**:`label:pm:seat` 列表页上标题挂 `🟢 ` 的贴; + `🟢 Routine` 座位以调度器读数为准,不入本巡查。 +- **判据只认在任者自己的产出**(自有评论/认领/正文编辑, + 作者与时间戳是平台盖章的硬读数), ⛔ 不算发给它的跨座位通知 —— 收到消息不是活着的证据。 -- **>24h 无自有产出(与既有回收线同一条)⇒ 当场降级**:标题改 `⏳ vacant` + 摘 assignee - **同笔**,留证据评论(最后自有产出的时间戳与链接);在飞认领照认领协议由原认领者跟 - 完。 +- **>24h 无自有产出(与既有回收线同一条) + ⇒ 当场降级**:标题改 `⏳ vacant` + 摘 assignee **同笔**, + 留证据评论(最后自有产出的时间戳与链接);在飞认领照认领协议由原认领者跟完。 ## 分诊席读数成本三则(维护者 2026-08-20) 出处:三方讨论后维护者「立卡」;实测数百评论座位贴每轮全文重读数千 token。 -- **收班简报索引化**:四段模板 —— 首行机器判据(「分诊轮收尾」起始标记,**逐字不 - 动**,互斥守卫靠 grep 它)+ 索引表(卡号 | 一行判决)+ 健康指标 + 接力清单(后两段 - 沿用主文件轮次报告节定义,含点名带开放下游依赖的决策卡)。**细节禁止复述**:逐卡理 - 由已作审计评论落卡,简报只指不拷。硬预算正文 ≤3000 字符,收班**自报字符数**;连续 - 两轮超限即漂移 —— 没有读数的「写短点」约定会涨回去。 -- **互斥最小尾页读法**(读数定义在主文件):尾页配方只覆盖座位贴两个读数;第三读数 - (车道 `pm:dispatched` 卡最新非本 session `Claim:`)出自车道盘点,不在座位贴线程。 - 配方:`issue_read get` 拿评论总数,按小 `perPage`(~15)算末页页码只读尾页;尾页缺 - 读数再回翻一页,⛔ 不读整线程。 -- **长线程状态读外包**:线程 > ~15 条的**状态提取**(找最新转换评论、抽 - `Restart-when:` 行、确认 claim/report 在不在)派低档只读子代理(sonnet 即可)返回结 - 构化摘录,尾部优先。**裁决级阅读(契约复审、放行判定、代裁)不可外包** —— 那是拿放 - 行质量换 token,禁止。 +- **收班简报索引化**:四段模板 —— 首行机器判据(「分诊轮收尾」 + 起始标记,**逐字不动**,互斥守卫靠 grep 它)+ 索引表(卡号 | 一行判决)+ 健康指标 + + 接力清单(后两段沿用主文件轮次报告节定义,含点名带开放下游依赖的决策卡)。 + **细节禁止复述**:逐卡理由已作审计评论落卡,简报只指不拷。硬预算正文 ≤3000 字符, + 收班**自报字符数**;连续两轮超限即漂移 —— 没有读数的「写短点」约定会涨回去。 +- **互斥最小尾页读法**(读数定义在主文件):尾页配方只覆盖座位贴两个读数;第三读数(车道 + `pm:dispatched` 卡最新非本 session `Claim:`)出自车道盘点,不在座位贴线程。配方:`issue_read get` + 拿评论总数,按小 `perPage`(~15)算末页页码只读尾页;尾页缺读数再回翻一页,⛔ 不读整线程。 +- **长线程状态读外包**:线程 > ~15 条的**状态提取**(找最新转换评论、抽 `Restart-when:` 行、 + 确认 claim/report 在不在)派低档只读子代理(sonnet 即可)返回结构化摘录,尾部优先。 + **裁决级阅读(契约复审、放行判定、代裁)不可外包** —— 那是拿放行质量换 token,禁止。 - **派发前读一次 `rate_limit`**:配额是全舰队共享的单点,耗尽同时杀掉在飞的每个 agent(实测一记限流一次带走三个 dev);余量装不下整批就减批,⛔ 不靠撞墙发现。 ## 分诊两级盘点细则(维护者 2026-08-20) -出处原话逐字住主文件「两级盘点」条。实测全量四仓 ~50k token/轮,`since` 等价 ~8k。小时层 -三读法:sweep 析取①②③ = `list_issues` + `since`(标签变更刷新 `updated_at`,半标注照样入窗);解锁 -扫描反演 = 逐仓 `state=CLOSED` + `since` 与 `Blocked-by:` 反向索引求交,命中走既有回队双查;健康 -指标 = 逐标签 `perPage: 1` 只读 `totalCount`。每日层(当日首 fire)= 四仓全量对账 + 归集本就日频 -的职责(finding 集中轮、`Restart-when:` 判据批扫、决策箱回填)。成本靶:干活轮 ≤50k,空转轮守 -既有探针预算。每条枚举 -都比对返回数与 `totalCount`:不等 ⇒ 本轮没读完,报 `sweep INCOMPLETE` 点名缺口,⛔ 永不报干 -净(同 `check-governed-merges.mjs` 对未审计仓的标准);分页只治当次,治不了下次涨过页宽,故一个 -谓词、⛔ 不加第二条代码路径。 +出处原话逐字住主文件「两级盘点」条。实测全量四仓 ~50k token/轮, +`since` 等价 ~8k。小时层三读法:sweep 析取①②③ = `list_issues` + `since`(标签变更刷新 `updated_at`, +半标注照样入窗);解锁扫描反演 = 逐仓 `state=CLOSED` + `since` 与 `Blocked-by:` 反向索引求交, +命中走既有回队双查;健康指标 = 逐标签 `perPage: 1` 只读 `totalCount`。 +每日层(当日首 fire)= 四仓全量对账 + 归集本就日频的职责(finding 集中轮、 +`Restart-when:` 判据批扫、决策箱回填)。成本靶:干活轮 ≤50k, +空转轮守既有探针预算。每条枚举都比对返回数与 `totalCount`:不等 ⇒ 本轮没读完, +报 `sweep INCOMPLETE` 点名缺口,⛔ 永不报干净(同 `check-governed-merges.mjs` 对未审计仓的标准); +分页只治当次,治不了下次涨过页宽,故一个谓词、⛔ 不加第二条代码路径。 ## 落卡与裁决记录细则(维护者 2026-08-13) -出处(逐字,未译):「还有很多我发现分诊或者决裁后没有改状态,这个也是问题」…「这个也需 -要更新项目经理技能」。实测:一张决策卡三个叠加半状态。 - -- **裁决记录四件补遗**(四件本体在主文件;原子、记录座位全责、维护者裁与代裁同规):① - 鲜 - 度门可内联声明分歧代替调和正文,对过期正文记录的裁决按过期论。 -- **机械两旗(report-only,归半状态巡查;接线是另一张卡的事,⛔ 不随协议文本改脚本)**:旗 - 一 —— open 卡标题带决策标记或线程含裁决记录、却仍挂 `needs-user-decision`;旗二 —— - `pm:blocked` 卡的 `Blocked-by:` 目标已关闭。「交付了一半的阻塞」是判断不是 grep,归四件 - 之③,⛔ 不进机械旗。 -- **卡上 re-check 命令两条硬线**(2026-08-26 三例实测:注释同一句按宽度折行,`git grep` 逐行匹配 - 即返回零 —— 读者把这个零读成「那句话已经不在了」;同批另一条逐字命令又因大小写 - 少 6 个文件):① **每条 grep 自带阳性对照** —— 同文件里确定存在、且 ⛔ 绝不是被测词 - 子串的一个词;对照未通过的零记「没读到」,⛔ 不记「不存在」(对照不要求作者预知自己 - 会犯哪一类错);② **锚点取最短的不折行片段**,⛔ 不抄脑中那整句。 -- **行文纪律**:出处一行(日期 + 原话);实测叙事至多压成一行 —— 故事住在卡上,不进操作 - 文本。 +出处(逐字,未译):「还有很多我发现分诊或者决裁后没有改状态, +这个也是问题」…「这个也需要更新项目经理技能」。实测:一张决策卡三个叠加半状态。 + +- **裁决记录四件补遗**(四件本体在主文件;原子、记录座位全责、维护者裁与代裁同规): + ① 鲜度门可内联声明分歧代替调和正文,对过期正文记录的裁决按过期论。 +- **机械两旗(report-only,归半状态巡查;接线是另一张卡的事, + ⛔ 不随协议文本改脚本)**:旗一 —— open 卡标题带决策标记或线程含裁决记录、 + 却仍挂 `needs-user-decision`;旗二 —— `pm:blocked` 卡的 `Blocked-by:` 目标已关闭。 + 「交付了一半的阻塞」是判断不是 grep,归四件之③,⛔ 不进机械旗。 +- **卡上 re-check 命令两条硬线**(2026-08-26 三例实测:注释同一句按宽度折行, + `git grep` 逐行匹配即返回零 —— 读者把这个零读成「那句话已经不在了」; + 同批另一条逐字命令又因大小写少 6 个文件):① **每条 grep 自带阳性对照** —— + 同文件里确定存在、且 ⛔ 绝不是被测词子串的一个词;对照未通过的零记「没读到」, + ⛔ 不记「不存在」(对照不要求作者预知自己会犯哪一类错); + ② **锚点取最短的不折行片段**,⛔ 不抄脑中那整句。 +- **行文纪律**: + 出处一行(日期 + 原话);实测叙事至多压成一行 —— 故事住在卡上,不进操作文本。 ## 结论当轮执行(维护者 2026-08-14) -出处:维护者裁(逐字,未译)「现在开工派发」;当日实测是成批「建议关闭」复测结论与结论 -表 -躺置多日无人执行。 - -- **结论产生的那一轮就执行它。** 复测/审计/裁决得出结论而不在同一轮完成对应的关 - 闭/换标写 - 入,本身就是半状态,与半状态家族同列 —— 记录后离场(record-and-walk-away)⛔ 禁止;结论 - 表同规,表不是交付物,落账才是。 -- **无权执行 ⇒ 点名有权者,并当轮把状态搬进对方收件箱**(换标进对方的收件箱视图/决策 - 箱), - ⛔ 不许只留一条评论等人路过 —— 评论不是任何人的收件箱,标签才是。 +出处:维护者裁(逐字,未译) +「现在开工派发」;当日实测是成批「建议关闭」复测结论与结论表躺置多日无人执行。 + +- **结论产生的那一轮就执行它。** 复测/审计/裁决得出结论而不在同一轮完成对应的关闭 + /换标写入,本身就是半状态,与半状态家族同列 —— 记录后离场(record-and-walk-away) + ⛔ 禁止;结论表同规,表不是交付物,落账才是。 +- **无权执行 ⇒ 点名有权者,并当轮把状态搬进对方收件箱**(换标进对方的收件箱视图 + /决策箱),⛔ 不许只留一条评论等人路过 —— 评论不是任何人的收件箱,标签才是。 - **机械半边**:旗标由半状态巡查 report-only 浮出(判据以脚本头为权威);当轮执行才是修法。 ## 云卡(`mode:cloud`)四课 @@ -141,138 +135,137 @@ fire 附带一次: draft-PR 时点交报、transcript 复活与接手协议兜底;共享容器争用只来自 build+test, docs/指令类 M 卡碰不到 —— 归档义务因此只落云卡。 -1. **授权面随 source,不随环境**:trigger 拉起的会话无仓库授权(只读勘察); - `create_session` 带 `source_url` 出生即持推送授权。同时带 `outcome_branch`(= 认领分 - 支)、显式 `model`(trigger 流不可指模型)、`title`(车道名开头,⛔ 不叫 os-dev;形如 - `⚡ <车道> #<单号> <短语>`)。 -2. **派发词必带自驱条款**(云会话回合一结束即停摆等 poke):⛔ 不为提问/中期汇报结束回 - 合;开放选择按裁决与评估轴自裁记入终报 open_questions;合法回合终点只有 (a) 推送完成 + - 终报,或 (b) 硬阻塞详报。 -3. **交付通道**:dev 自开 draft PR(`Fixes #`,正文含验证记录)+ 终报以 issue 评论 - (os-dev-report 标记)交付;未 attach 的姊妹仓够不着,跨仓跟进卡 PM 代立;trigger 定时会 - 话维持降级通道 —— 推送 outcome branch + 终报走最后一条会话消息,PM 代开 draft PR。 -4. **云卡 draft PR 一存在,立即 `subscribe_pr_activity` —— 硬步骤**:未订阅的云卡 PR 是轮 - 询负债,订阅把感知从巡检周期缩到秒级。 - -监控与转向:`get_session` 读实时状态(IDLE + 分支未推送 = 停摆待 poke);投递消息用绑 -定会话的 poke 触发器(`create_trigger` 带 `persistent_session_id` + `fire_trigger`,用 -后即 `delete_trigger`);巡检退为兜底心跳,只补订阅盲区(会话停摆、未开 PR 的分支、姊妹 -仓动静)。roster 不可达与 SendMessage 同裁(`ListAgents` 同列不到,⛔ 不复测)。会话句 -柄是**账号作用域**的:`get_session` / `archive_session` / 绑会话 poke 触发器对另一账号 -建的会话一律答 `not found`,与「从不存在」不可区分 —— **⛔ 永不读作死亡信号**(实测判 -not found 的会话数十分钟前还 RUNNING;误判死会往活 worktree 塞第二个 agent);跨账号接 -班活性只认 GitHub 产出读数 —— draft-PR 时点交报正为此存在。 +1. **授权面随 source,不随环境**:trigger 拉起的会话无仓库授权(只读勘察);`create_session` + 带 `source_url` 出生即持推送授权。同时带 `outcome_branch`(= 认领分支)、显式 `model`(trigger + 流不可指模型)、`title`(车道名开头,⛔ 不叫 os-dev;形如 `⚡ <车道> #<单号> <短语>`)。 +2. **派发词必带自驱条款**(云会话回合一结束即停摆等 poke): + ⛔ 不为提问/中期汇报结束回合;开放选择按裁决与评估轴自裁记入终报 open_questions; + 合法回合终点只有 (a) 推送完成 + 终报,或 (b) 硬阻塞详报。 +3. **交付通道**:dev 自开 draft PR(`Fixes #`,正文含验证记录)+ + 终报以 issue 评论(os-dev-report 标记)交付;未 attach 的姊妹仓够不着,跨仓跟进卡 PM 代立;trigger + 定时会话维持降级通道 —— 推送 outcome branch + 终报走最后一条会话消息,PM 代开 draft PR。 +4. **云卡 draft PR 一存在,立即 `subscribe_pr_activity` —— 硬步骤**: + 未订阅的云卡 PR 是轮询负债,订阅把感知从巡检周期缩到秒级。 + +监控与转向:`get_session` 读实时状态(IDLE + 分支未推送 = 停摆待 poke); +投递消息用绑定会话的 poke 触发器(`create_trigger` 带 `persistent_session_id` + `fire_trigger`,用后即 +`delete_trigger`);巡检退为兜底心跳,只补订阅盲区(会话停摆、未开 PR 的分支、姊妹仓动静)。 +roster 不可达与 SendMessage 同裁(`ListAgents` 同列不到,⛔ 不复测)。会话句柄是**账号作用域**的: +`get_session` / `archive_session` / 绑会话 poke 触发器对另一账号建的会话一律答 `not found`, +与「从不存在」不可区分 —— **⛔ 永不读作死亡信号** +(实测判 not found 的会话数十分钟前还 RUNNING;误判死会往活 worktree 塞第二个 agent); +跨账号接班活性只认 GitHub 产出读数 —— draft-PR 时点交报正为此存在。 ## subagent 批(`mode:subagent`)派发前置:先快进本地检出 -subagent 在 PM 容器内运行,agent 定义与技能文本读**本地检出**,不是 `origin/main`。 -派发 subagent 批之前先快进:`git -C pull --ff-only origin main`;检出过期则整 -批拿到过期定义(实测发生过)。用 `--ff-only` 让脏或分叉的检出大声失败,不静默合并。 +subagent 在 PM 容器内运行,agent 定义与技能文本读**本地检出**,不是 `origin/main`。派发 +subagent 批之前先快进:`git -C pull --ff-only origin main`;检出过期则整批拿到过期定义 +(实测发生过)。用 `--ff-only` 让脏或分叉的检出大声失败,不静默合并。 ## 接手中断的 dev(worktree 接手协议) 先试复活、不可用才接手与 ⛔ 不重跑原派发词在主文件;五条增量: -- **死后恢复查三态,不止查远程**:远程(`git ls-remote`)/ 仅容器磁盘 / 真没了 —— 中间那 - 态最值钱且当前无人查(worktree 比 agent 活得久,同容器共享,未提交改动通常还在),只查远 - 程会令下一个 dev「从零开始」。捡到的工作一律标 **UNVERIFIED** 交接 —— 不丢弃也不继 - 承。 +- **死后恢复查三态,不止查远程**: + 远程(`git ls-remote`)/ 仅容器磁盘 / 真没了 —— 中间那态最值钱且当前无人查(worktree + 比 agent 活得久,同容器共享,未提交改动通常还在),只查远程会令下一个 dev「从零开始」。 + 捡到的工作一律标 **UNVERIFIED** 交接 —— 不丢弃也不继承。 - worktree 已存在,⛔ 不要新建,`cd` 进去接着做(第二个 worktree 会劈开工作); - 先读全部既有提交与未提交改动,逐 hunk 决定保留或修正 —— 既不推倒重来也不盲信(死 agent 的一切都未经验证); - 把死 agent 没跑完的验证**完整重跑**并报真实输出(中断的运行没留下测试证据); -- assignee、认领评论、分支**全部不动** —— 既有认领的延续,不是新认领;认领评论记录接 - 手,不被替换。 +- assignee、认领评论、 + 分支**全部不动** —— 既有认领的延续,不是新认领;认领评论记录接手,不被替换。 ## 跨车道简单阻塞项直接接手(维护者 2026-08-13) -出处(逐字,未译):「如果当前任务依赖其他赛道的任务,如果判断简单,是否可以直接接手而不必 -持续等待」。判据与认领纪律(含 `Claim:` 拼写)在主文件;补遗:只覆盖「等一周 vs 做十分钟」 -的形状;`packages/spec` 恒归 spec 座位,本条不豁免(唯一所有者规则更硬);「借调」墓碑在 -主文件多仓协调 4 —— 判据是依赖形状,只做被本车道开卡 `Blocked-by:` 点名的那一个阻塞 -项,做 -完即回,⛔ 不顺手接第二张。 +出处(逐字,未译):「如果当前任务依赖其他赛道的任务, +如果判断简单,是否可以直接接手而不必持续等待」。判据与认领纪律(含 `Claim:` 拼写) +在主文件;补遗:只覆盖「等一周 vs 做十分钟」的形状;`packages/spec` 恒归 spec 座位, +本条不豁免(唯一所有者规则更硬);「借调」墓碑在主文件多仓协调 4 —— 判据是依赖形状, +只做被本车道开卡 `Blocked-by:` 点名的那一个阻塞项,做完即回,⛔ 不顺手接第二张。 ## 停摆复位梯度 -原则三条在主文件;本节是执行细则。姿态句全文:「前台(阻塞)同步执行全部步骤,中途不停 -止、不把构建/测试挂到后台等唤醒」。梯度逐级(原样重发同一句不算一次复位):① 复述执行姿态 -→ ② 点名下一个工具调用 + 明令禁止后台等待 → ③ 第三次停摆判 unreliable,按接手协议重 -派到 -该分支。自己挂的定时器不会唤醒自己;长验证管线的派发/接力词写明前台姿态;生产侧条款 -在 -os-dev 定义。 +原则三条在主文件;本节是执行细则。姿态句全文:「前台(阻塞)同步执行全部步骤, +中途不停止、不把构建/测试挂到后台等唤醒」。梯度逐级(原样重发同一句不算一次复位): +① 复述执行姿态 → ② 点名下一个工具调用 + 明令禁止后台等待 +→ ③ 第三次停摆判 unreliable,按接手协议重派到该分支。自己挂的定时器不会唤醒自己; +长验证管线的派发/接力词写明前台姿态;生产侧条款在 os-dev 定义。 ## 通知重放去重 -原则在主文件;细则:重放形态可以完全正常、报告完整正确 —— monitor 按自己的 deadline 触 -发;身份 = 三元组 `(issue, 分支, PR head sha)` + 通知自报的守护对象(自报缺席就用三元组自 -己算);判定重放 ⇒ 台账记「重放,首达时间 T」即结束。 +原则在主文件;细则:重放形态可以完全正常、报告完整正确 —— +monitor 按自己的 deadline 触发;身份 = 三元组 `(issue, 分支, PR head sha)` + 通知自报的守护对象 +(自报缺席就用三元组自己算);判定重放 ⇒ 台账记「重放,首达时间 T」即结束。 ## 直接验收兜底(报告丢失 ≠ 验收停摆) -触发三条件、舰队级例外与「先探活后翻 ready」在主文件;验收动作:逐文件核对 diff 与认领 -申 -报的文件面,对照 `origin/main` 复核 PR 正文的前提声明与验证叙述,复核清单其余判据不减;抢 -先翻 ready 会撞上 agent 的收尾推送(竞态保护);「推分支 → 开 draft PR → 立即交报告」契约 -(保险,非效率优化)住 os-dev 定义,派发令只带增量。 +触发三条件、舰队级例外与「先探活后翻 ready」在主文件;验收动作: +逐文件核对 diff 与认领申报的文件面,对照 `origin/main` 复核 PR 正文的前提声明与验证叙述, +复核清单其余判据不减;抢先翻 ready 会撞上 agent 的收尾推送(竞态保护);「推分支 +→ 开 draft PR → 立即交报告」契约(保险,非效率优化)住 os-dev 定义,派发令只带增量。 ## 派发词构造细则 -原则(⛔ 默认不整段粘贴 issue 正文;dev 自查正文完整性是「自己读」截断风险的对价)在主文 -件;本节是条款原文与增量: - -- **三分区各自的 dev 义务**(三个区名逐字住主文件「三分区」条):裁决区 dev 执行不重开;机 - 制假设区动手前验证,证伪照实报告并按裁决意图换实现路径,⛔ 不许为顺从假设硬做;建议 - 路线区有更好的就换,⛔ 不得因「派发令写了」照做。 -- **兄弟 dev 报告里的成本/形状估计一律落「机制假设」区并注明须复测**,⛔ 不得穿裁决的衣服转述:被当事实搬运的「两行 - 改动」照字面落地把双字面量的方向循环写成 `desc → desc → null`,度量列永远升不了序而天真测试照绿 —— 错在搬运的派发词。 -- **前提含「spec 有这个槽位」⇒ 派发前先读安装包内的活性账 - 本**(`node_modules/@objectstack/spec/liveness/<域>.json` - 对应行):`status: 'planned'` = 有 carrier、零消费者,`authorHint` 就是证词;不读账本的派发让 dev 交 - 出解析通过、 - 校验通过、加载成功而**渲染为零**的元数据 —— 绿收据背书的假修复比诚实的缺陷更 - 贵,代价是一次文件读对一整轮 agent 运行。 -- **停条件写法:要证据,不要判决**。派发令里的前提/停条件检查必须要 dev 回报**证据 - 面**(搜了什么、找到什么),分叉 - 归 PM 判 —— 写成「发现消费者就停下」把判决权交回被停的一方。 -- **派发那刻现取、随派发词下发的两份读数**(条款主文在主文件;判据同一:PM 已有的读数下 - 发一次,⛔ 不让 N 个 dev 各重跑同样贵 - 的 GraphQL 读):① **门禁清单**单班之内即过期;全 farm 归 CI 跑一次,⛔ 不让 dev 枚举全 farm;点 - 名单当天现取仍会漏(实测漏的门恰被 - 改动打红过)—— dev 对实际改动路径重取补跑。② **去重/看板读数**:取一次(查询式 + 时间戳)整批共用,派发令写「当既有事实 - 用,只复核其后的增量,⛔ 不重跑」。dev 侧对价住 os-dev 定义。 -- **文件面两句原文**:「预期落点是 X;若实测表明真正的生产者在别包,报备后按生产者侧修(落点与理由写进报告和 PR 正文),⛔ 不 - 在消费者侧打补丁」—— 只写一个路径名,是要求 dev 在守约与修对之间二选一;跨包常等于跨车道,PM 事后补跨座位声明。 -- **Same-day churn 行与在飞重叠**:派发时 `git log origin/main --oneline -20 -- ` 见当天合并 ⇒ 加一行「 - 基于合并后的代码工作,issue 引用的片段可能已变,先核对当前 main」(dev 的 worktree 切出后不会自己更新)。在飞重 - 叠每轮拦截(churn 行只覆盖派发瞬间):main 新落 PR 与在飞申报文件面求交,相交即警告四句 - —— 合 main 重跑测试矩 - 阵、读对方 diff 重划边界、只补它没覆盖的部分、被完全覆盖就停下回报 ⛔ 不硬造 diff。 - 晚一轮 = 一次返工。 -- **全仓 pin 清扫两句原文**:① grep 错误码/错误消息**全仓扫描**同语义 pin,一轮翻完,不只改 - 本包(旧立场的 pin 住在 - 被改包之外的消费层);② 翻转后的 pin 必须继续承重 —— 断言新语义的**实质**(行数、译文、状态码),不是「旧断言已 - 删」;真正非法形状的拒收断言**逐字保留**,被守护的面永不缩水。 +原则(⛔ 默认不整段粘贴 issue 正文;dev 自查正文完整性是「自己读」 +截断风险的对价)在主文件;本节是条款原文与增量: + +- **三分区各自的 dev 义务**(三个区名逐字住主文件「三分区」 + 条):裁决区 dev 执行不重开;机制假设区动手前验证,证伪照实报告并按裁决意图换实现路径, + ⛔ 不许为顺从假设硬做;建议路线区有更好的就换,⛔ 不得因「派发令写了」照做。 +- **兄弟 dev 报告里的成本/形状估计一律落「机制假设」 + 区并注明须复测**,⛔ 不得穿裁决的衣服转述: + 被当事实搬运的「两行改动」照字面落地把双字面量的方向循环写成 `desc → desc → null`, + 度量列永远升不了序而天真测试照绿 —— 错在搬运的派发词。 +- **前提含「spec 有这个槽位」 + ⇒ 派发前先读安装包内的活性账本**(`node_modules/@objectstack/spec/liveness/<域>.json` 对应行): + `status: 'planned'` = 有 carrier、零消费者,`authorHint` 就是证词; + 不读账本的派发让 dev 交出解析通过、校验通过、加载成功而**渲染为零**的元数据 + —— 绿收据背书的假修复比诚实的缺陷更贵,代价是一次文件读对一整轮 agent 运行。 +- **停条件写法: + 要证据,不要判决**。派发令里的前提/停条件检查必须要 dev 回报**证据面**(搜了什么、 + 找到什么),分叉归 PM 判 —— 写成「发现消费者就停下」把判决权交回被停的一方。 +- **派发那刻现取、随派发词下发的两份读数**(条款主文在主文件; + 判据同一:PM 已有的读数下发一次,⛔ 不让 N 个 dev 各重跑同样贵的 GraphQL 读): + ① **门禁清单**单班之内即过期;全 farm 归 CI 跑一次,⛔ 不让 dev 枚举全 farm; + 点名单当天现取仍会漏(实测漏的门恰被改动打红过)—— dev 对实际改动路径重取补跑。 + ② **去重/看板读数**:取一次(查询式 + 时间戳)整批共用, + 派发令写「当既有事实用,只复核其后的增量,⛔ 不重跑」。dev 侧对价住 os-dev 定义。 +- **文件面两句原文**:「预期落点是 X;若实测表明真正的生产者在别包,报备后按生产者侧修 + (落点与理由写进报告和 PR 正文),⛔ 不在消费者侧打补丁」—— 只写一个路径名, + 是要求 dev 在守约与修对之间二选一;跨包常等于跨车道,PM 事后补跨座位声明。 +- **Same-day churn 行与在飞重叠**:派发时 `git log origin/main --oneline -20 -- ` + 见当天合并 ⇒ 加一行「基于合并后的代码工作,issue 引用的片段可能已变, + 先核对当前 main」(dev 的 worktree 切出后不会自己更新)。 + 在飞重叠每轮拦截(churn 行只覆盖派发瞬间):main 新落 PR 与在飞申报文件面求交, + 相交即警告四句 —— 合 main 重跑测试矩阵、读对方 diff 重划边界、 + 只补它没覆盖的部分、被完全覆盖就停下回报 ⛔ 不硬造 diff。晚一轮 = 一次返工。 +- **全仓 pin 清扫两句原文**:① grep 错误码/错误消息**全仓扫描**同语义 pin, + 一轮翻完,不只改本包(旧立场的 pin 住在被改包之外的消费层); + ② 翻转后的 pin 必须继续承重 —— 断言新语义的**实质**(行数、译文、状态码), + 不是「旧断言已删」;真正非法形状的拒收断言**逐字保留**,被守护的面永不缩水。 - **条件性标准条款,命中判据才抄,不命中就省掉别硬套**: - - 多实现面组件(同一契约 ≥2 个实现面)⇒ 「测试放在**未来的分叉会被抓住的地方**,进共享一致性覆盖,不是独立测试文 - 件」;不变量形:与 `find()` 给出相同行集,或以 `INVALID_FILTER` 拒收 —— 不允许有第三种、更安静的答案。 + - 多实现面组件(同一契约 ≥2 个实现面)⇒ 「测试放在**未来的分叉会被抓住的地方**, + 进共享一致性覆盖,不是独立测试文件」;不变量形: + 与 `find()` 给出相同行集,或以 `INVALID_FILTER` 拒收 —— 不允许有第三种、更安静的答案。 - 新增/改写拒收类用例 ⇒ 信封断言本体是 os-dev 标准条款,只补边界「不回填存量」。 - - 改过滤/谓词语义 ⇒ 把 `references/compile-surfaces.md` 的编译面清单**按其复核串重验后逐面 - 抄进派发令**(⛔ 不 - 凭记忆),并带:「每一面都必须在 PR 正文有一个结论:已改 / 本就合规(证据)/ 明确不在范围(理由);⛔ 静默略过 —— - 评审把没提到的面读作漏掉的面」。防的不是做错,是做对了一部分然后以为做完了。 -- **测量先行卡**(修复由测量结果**有条件授权**)⇒ 派发令写 - 明「⛔ 测量存在之前不写修复」—— 测量姿态让 dev 看得见 - 卡面没列的探针,实现姿态只看得见要交的 diff。 + - 改过滤/谓词语义 ⇒ 把 `references/compile-surfaces.md` + 的编译面清单**按其复核串重验后逐面抄进派发令**(⛔ 不凭记忆), + 并带:「每一面都必须在 PR 正文有一个结论:已改 / 本就合规(证据)/ 明确不在范围(理由); + ⛔ 静默略过 —— 评审把没提到的面读作漏掉的面」。 + 防的不是做错,是做对了一部分然后以为做完了。 +- **测量先行卡**(修复由测量结果**有条件授权**) + ⇒ 派发令写明「⛔ 测量存在之前不写修复」—— 测量姿态让 dev 看得见卡面没列的探针, + 实现姿态只看得见要交的 diff。 ## security-object 无判决枚举(座位贴常设 ⑦)的方法与校准 - **表面半边(⛔ 不比总数)**:`git diff <基线ref> origin/main -- '<两插件>/src/objects/*.object.ts'` 过 `grep -E "^[+-] [a-z_][a-z0-9_]*: Field\."`;零命中 = 成员级同一,必记基线 ref(2026-08-26 `b000ab59`)。 - **读者半边**:`git grep -I -n -w "<键>" -- . ':(exclude)<声明该列的 *.object.ts>' ':(exclude).claude'`(⛔ - 缺后者会命中本节),逐命中行计一次:① `*.generated.ts` 不是读者;② `packages/spec` 契约声 - 明**算**读点;③ 裸字面量 `key:` 拼写**算**。 -- **正对照恒先跑**:`sys_share_link.email_allowlist` = **3**(2026-08-26 记;漏 ① 得 7,多减 ② 得 2)—— - 跑不出 3 即仪器坏了,⛔ 记下任何零之前停;⛔ 无对照的零记「没读到」不记 0(`name` 这类 - 列名到处匹配,未校准的仪器平凡地回 0)。 + 缺后者会命中本节),逐命中行计一次:① `*.generated.ts` 不是读者; + ② `packages/spec` 契约声明**算**读点;③ 裸字面量 `key:` 拼写**算**。 +- **正对照恒先跑**:`sys_share_link.email_allowlist` = **3**(2026-08-26 记; + 漏 ① 得 7,多减 ② 得 2)—— 跑不出 3 即仪器坏了,⛔ 记下任何零之前停; + ⛔ 无对照的零记「没读到」不记 0(`name` 这类列名到处匹配,未校准的仪器平凡地回 0)。 diff --git a/.claude/skills/pm-dispatch/references/landing-operations.md b/.claude/skills/pm-dispatch/references/landing-operations.md index 9119fba00c..7e8c678a85 100644 --- a/.claude/skills/pm-dispatch/references/landing-operations.md +++ b/.claude/skills/pm-dispatch/references/landing-operations.md @@ -1,13 +1,13 @@ # 入队与落地细则(references —— 按需加载) -出处:主文件「复核」的入队与落地原则。本表是 ACCEPT 之后把 PR 送到 MERGED 的操作 -细则,在落地窗口查阅;⛔ 不引用 issue 编号。 +出处:主文件「复核」的入队与落地原则。 +本表是 ACCEPT 之后把 PR 送到 MERGED 的操作细则,在落地窗口查阅;⛔ 不引用 issue 编号。 ## A. 碰生成物的 PR:入队前先同步 + 整体重生成 批次选择只保证同批 file-disjoint,管不到先后两单都碰生成物(协议变更几乎必然)。 -`merge=os-regen` 路径清单**当场读**:`grep os-regen .gitattributes`(唯一权威清 -单,⛔ 不抄进派发令当常量 —— 散文没法被类型检查;文档产物同在清单、同样被吞)。 +`merge=os-regen` 路径清单**当场读**:`grep os-regen .gitattributes`(唯一权威清单, +⛔ 不抄进派发令当常量 —— 散文没法被类型检查;文档产物同在清单、同样被吞)。 四步序已机械化:`bash scripts/pm/os-regen-merge.sh`(⛔ 禁 rebase / force-push; 步骤以脚本自身为权威)。顺序防的陷阱: @@ -15,19 +15,19 @@ - **MERGE 状态下跑 `gen:schema` 会把 authorable-surface 锚点静默倒退回旧分叉点**, 且全部门放行 ——「先 commit 再重生成」的由来。 -重生成后**断言所有兄弟单的条目都还在**;更硬的旁证是查**上一单的实现体**完好(带 -引号精确名 `git grep … origin/main -- <实现文件>`)—— 条目是索引,实现体才是被吞 -的重灾区。**锚点断言的正确措辞**(写错会教唆 dev 手改锚点):断言 `pnpm --filter -@objectstack/spec check:authorable-surface` **绿**即可;`baseRev` 允许滞后(一行 -提示,不是错误);⛔ 禁为凑「相等」手改锚点,⛔ 不得要求 `baseRev == merge-base`。 +重生成后**断言所有兄弟单的条目都还在**;更硬的旁证是查**上一单的实现体**完好 +(带引号精确名 `git grep … origin/main -- <实现文件>`)—— 条目是索引, +实现体才是被吞的重灾区。**锚点断言的正确措辞**(写错会教唆 dev 手改锚点): +断言 `pnpm --filter @objectstack/spec check:authorable-surface` **绿**即可;`baseRev` 允许滞后(一行提示, +不是错误);⛔ 禁为凑「相等」手改锚点,⛔ 不得要求 `baseRev == merge-base`。 ## B. 跟到 MERGED 为止;入队后的看护归车道 PM 落地窗口 车道 PM 的权责:验收(复核清单);**首次入队** —— ACCEPT 后挂 6–9 分钟 flip 定点,到点核门禁 -job 结论,绿即转 ready + 挂 auto-merge,未绿阶梯重挂;CI success webhook 不可靠,⛔ 不坐等不忙 -轮询;定点文本照定时器写法纪律;确认 **MERGED** —— 每轮同时读队列分支与 `origin/main` 两个 -读数。**契约复审链 PASS 落地的 PR 到窗口时已 ready + auto-merge 在挂**(清标与落地同一笔,见 -`contract-review.md`)—— 窗口自身权责不变:跟到 MERGED、踢出处置、落地后对账。 +job 结论,绿即转 ready + 挂 auto-merge,未绿阶梯重挂;CI success webhook 不可靠,⛔ 不坐等不忙轮询; +定点文本照定时器写法纪律;确认 **MERGED** —— 每轮同时读队列分支与 `origin/main` +两个读数。**契约复审链 PASS 落地的 PR 到窗口时已 ready + auto-merge 在挂**(清标与落地同一笔, +见 `contract-review.md`)—— 窗口自身权责不变:跟到 MERGED、踢出处置、落地后对账。 **转 ready / 挂 auto-merge 之前先判受管面**:`node scripts/pm/check-governed-merges.mjs --test` 加 PR 变更路 径,一条命中 ⇒ 整 PR 改走人工合并道(复核照写 + 留 draft + 向授权批准人请审 + 状态评 @@ -49,18 +49,18 @@ job 结论,绿即转 ready + 挂 auto-merge,未绿阶梯重挂;CI success webhoo 落地后**再核一次落地判据本身**:队列的合并同样走 os-regen 驱动,A 的静默吞并在队 列合并这一步一样能发生。**MERGED 不是终点**:发版后义务见 `release-aftercare.md`。 -**落地窗口给关键 PR 挂 `subscribe_pr_activity`**(会话型座位专用;Routine 座位收不到,维持轮询):⛔ -不订阅 dev 交报告前的 PR —— 双驾驶员互踩;订阅是感知补充,不替代 flip 定点;**MERGED / 关闭 -即退订,同刻把 `mode:cloud` 派的会话 `archive_session`** —— 触发条件是卡终局且报告已收复 -核,⛔ 合并前不归档(活会话是 dirty 自救的执行手;误归档可 unarchive,但容器现场已失,宁晚勿 -早);暂停/交接把在挂订阅清点进座位贴,⛔ 不留孤儿订阅。 - -**main-red 事故两条约定**:① **p0 fix-forward 允许跳队**(维护者 2026-08-25「同意」):main 红的 -止血 PR(p0、机械、根因已核实)可跳队(GitHub 队列自带 jump-the-queue),或按既有 governed -例外由维护者人工直合一行修复 —— 排在事故自己堵住的队列后面是具名反模式;仅限 -main-red 修复,⛔ 不放宽其它任何 PR 的 queue-only 落地。② **一个失败 check 只锚一张卡**(维 -护者 2026-08-25「同意」):main-red 事故按失败 check 名锚一张卡,先立者赢;后见者把读数评论 -到锚卡上,⛔ 不另立。 +**落地窗口给关键 PR 挂 `subscribe_pr_activity`**(会话型座位专用;Routine 座位收不到, +维持轮询):⛔ 不订阅 dev 交报告前的 PR —— 双驾驶员互踩;订阅是感知补充, +不替代 flip 定点;**MERGED / 关闭即退订,同刻把 `mode:cloud` 派的会话 `archive_session`** —— +触发条件是卡终局且报告已收复核,⛔ 合并前不归档(活会话是 dirty 自救的执行手;误归档可 +unarchive,但容器现场已失,宁晚勿早);暂停/交接把在挂订阅清点进座位贴,⛔ 不留孤儿订阅。 + +**main-red 事故两条约定**:① **p0 fix-forward 允许跳队**(维护者 2026-08-25「同意」):main +红的止血 PR(p0、机械、根因已核实)可跳队(GitHub 队列自带 jump-the-queue),或按既有 +governed 例外由维护者人工直合一行修复 —— 排在事故自己堵住的队列后面是具名反模式; +仅限 main-red 修复,⛔ 不放宽其它任何 PR 的 queue-only 落地。 +② **一个失败 check 只锚一张卡**(维护者 2026-08-25「同意」):main-red +事故按失败 check 名锚一张卡,先立者赢;后见者把读数评论到锚卡上,⛔ 不另立。 ## C. 依赖前棒才能转绿的 PR:draft 停放 + 签名级预期红清单 diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 03d3b89bf7..ac074f15df 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -16,8 +16,8 @@ 没订阅就取不回,故只作旁证,⛔ 不作决策依据。⛔ `auto_merge` 字段不只是空,是**不稳 定**:同一 PR 一分钟内先 `set` 后 `None`(2026-08-26 实测),入队后又回落为 off(维护者 2026-08-11 裁定)—— 永不据它判「没挂上」而重挂(重挂踢队重排)。 -- **成功序列读间隔不读事件名**:`removed_from_merge_queue` 后 ~1 秒内跟 `merged` 是落地不是被 - 踢;真被踢是其后无 `merged`、几分钟后 PR 仍 open。 +- **成功序列读间隔不读事件名**:`removed_from_merge_queue` 后 ~1 秒内跟 `merged` 是落地不是被踢; + 真被踢是其后无 `merged`、几分钟后 PR 仍 open。 - 「不在 `origin/main` 上」是二义读数(在队列里等 / 没入队,处置相反)—— 落地检查永远两个 读数:**队列成员资格 和 `origin/main`**,缺一不可;`origin/main` 那一读**按内容读**(grep 本 PR 该 产出的产物),⛔ 不按 PR head sha 的祖先性、也不按 `merged` 布尔:队列落的是**另一个提 @@ -30,9 +30,9 @@ 地试合并:fetch PR ref 后 `git merge-tree --write-tree origin/main `(冲突文件直接列出;随 fetch 老化,重跑先 fetch;与 enable 序列的队列 ref/update-branch 探针互补,彼答入队与暗冲突、此在挂 前答头脏)。入队决策点才 `get` 一次:挂了 flip 定点(landing-operations)到点读,⛔ 不又查又等。 -- **状态核验用最小字段**(search/list + `fields`)或等事件,整对象 `get` 留给入队决策点;门禁放行 - 判据 = 承载门禁族 job 的 conclusion,聚合(`blocked`/`dirty`)只作阴性筛查再定位,放行按名定向读 - 单条 job,⛔ 不拉全表(按名定位失败才拉)。 +- **状态核验用最小字段**(search/list + `fields`)或等事件,整对象 `get` 留给入队决策点; + 门禁放行判据 = 承载门禁族 job 的 conclusion,聚合(`blocked`/`dirty`) + 只作阴性筛查再定位,放行按名定向读单条 job,⛔ 不拉全表(按名定位失败才拉)。 - **转 draft 不是可靠的踢队手段 —— 两向相反实测,处置按最坏走**:本仓转 draft 同时掉 auto-merge 与队列成员资格(均不自动恢复,转正后重挂);objectui 2026-08-25 已入队 PR 转 draft 条目 保位、~40 分钟后队列照样合并(仓别/时机未分辨)。补救:转 draft + disable 都做(本仓 @@ -40,12 +40,12 @@ 答不在队向,加未落地;ref 缺席只作旁证,⛔ 永不承载结论、不据单读数报补救。 - **`update_pull_request` 不管传不传都发送 `draft` 位 ⇒ 对 draft PR 的任何调用必须显式带 `draft: true`**(reviewers/title/body/labels 单字段调用同坑;objectui 2026-08-25 实测:一次只传 - reviewers 的请审把治理面 draft 发布进合并队列,后果见上条);请审免碰 draft 位的专用路 = REST - `POST /pulls/{n}/requested_reviewers`(文档载明、未实测:载荷只有 reviewers/team_reviewers;门开席位优 - 先,MCP-only 席才用 update + 显式 `draft: true`)。undraft 可用路径只有 MCP 这条:传 `draft: false` - 落地(2026-08-24 三张 PR 逐张回读确认);**裸 GraphQL 会话内被拒**(回「only the pinned set of - PR-review operations is served」,它建议的「改用 REST」对 undraft **是错的**);**裸 REST - `PATCH /pulls/{n}` 传 `draft: false` 回 200 而无操作** —— 接口性质 ⇒ 池 0 只能等重置。 + reviewers 的请审把治理面 draft 发布进合并队列,后果见上条);请审免碰 draft 位的专用路 + = REST `POST /pulls/{n}/requested_reviewers`(文档载明、未实测:载荷只有 reviewers/team_reviewers; + 门开席位优先,MCP-only 席才用 update + 显式 `draft: true`)。undraft 可用路径只有 MCP 这条: + 传 `draft: false` 落地(2026-08-24 三张 PR 逐张回读确认);**裸 GraphQL 会话内被拒**(回「only + the pinned set of PR-review operations is served」,它建议的「改用 REST」对 undraft **是错的**);**裸 + REST `PATCH /pulls/{n}` 传 `draft: false` 回 200 而无操作** —— 接口性质 ⇒ 池 0 只能等重置。 - **`enable_pr_auto_merge` 一律显式传 `mergeMethod: "SQUASH"`**(不传时静默退回被禁的 merge-commit = 无操作);**回显两向不可靠,空回显≠未挂上**:传 SQUASH 后回读 `auto_merge.merge_method` 仍 `merge`(2026-08-24 两张 PR、一张 disable→enable 复验同值)、队列路径回显空字段而入队照发,落 @@ -64,13 +64,13 @@ 挂 auto-merge。`enable_pr_auto_merge` 回应只答本次调用:时戳形有动作、空字段形无动作;⛔ enable 与其验证间永不插 `disable`(入队 webhook 乱序迟到,会撤掉真实入队)。**踢出成因两 则**:兄弟抢先落地 ⇒ `MERGE_CONFLICT`;缺必需批准 ⇒ 治理守卫 merge_group 腿 `CI_FAILURE`。 -- **队列踢出先认签名再决定重投**:已知 flaky 核对失败签名一致 ⇒ 原样重投;止血修复合入 - 后**同一签名再现就不再是那条 flaky**,是新问题必须重新诊断,⛔ 禁止条件反射式重投;第 - 三种签名:本 PR 名下**没有任何** `merge_group` run 且批次同伴的 run 全部 `success` = 队列重建的 - 连带取消不是红 —— 带签名读数收据重投一次(收据留在 PR 上),⛔ 无收据不重投;同一 PR - 第二次被踢 ⇒ 停止重投,按签名四分支重判。 -- **实测吞吐两则**:合并队列落地 ≈ 每 PR 15–30 分钟且串行(⛔ 不据「还没落」提前判异 - 常);单容器重验证(build+test)并发甜点 ≈3,排批按它定上限。 +- **队列踢出先认签名再决定重投**:已知 flaky 核对失败签名一致 ⇒ 原样重投; + 止血修复合入后**同一签名再现就不再是那条 flaky**,是新问题必须重新诊断, + ⛔ 禁止条件反射式重投;第三种签名:本 PR 名下**没有任何** `merge_group` run 且批次同伴的 run + 全部 `success` = 队列重建的连带取消不是红 —— 带签名读数收据重投一次(收据留在 PR 上), + ⛔ 无收据不重投;同一 PR 第二次被踢 ⇒ 停止重投,按签名四分支重判。 +- **实测吞吐两则**:合并队列落地 ≈ 每 PR 15–30 分钟且串行(⛔ 不据「还没落」 + 提前判异常);单容器重验证(build+test)并发甜点 ≈3,排批按它定上限。 ## API 配额 @@ -99,26 +99,26 @@ - **默认读序 git → payload → REST → MCP/GraphQL**(2026-08-23 策略翻转,2026-08-25 增补 payload 档; ⚠️ REST 档以**本班 repo-scoped 探针绿**为前提 —— 前提就住本行,403 会话改按降级梯读)。 list/查重/卡与 PR 读/标签回读默认走容器 curl 的 REST 通道 —— App installation token,core - 15,000/时,与 GraphQL 池**独立计**(实测 GraphQL 池两次耗尽时 core 余 14,938);GraphQL 池 - (5000/时)只留给**没有 REST 对应物**的那几件:draft 翻转、auto-merge/入队挂载、语义 - `/search/*`、Projects field_values、`issue transfer`。逐操作通道归属(✓ 按席位类别限定)、写侧配 - 方与队列路由三读法见 `references/rest-channel.md`,⛔ 不在本表复述。 -- **MCP list/search 家族整个走 GraphQL 稀缺池**(反复撞上的限流墙就是它;`issue_write` 连查找半 - 边都吃);配额红时认领类动作排队,评论(REST 桶)先行把结论发出去。 + 15,000/时,与 GraphQL 池**独立计**(实测 GraphQL 池两次耗尽时 core 余 14,938);GraphQL 池(5000/时) + 只留给**没有 REST 对应物**的那几件:draft 翻转、auto-merge/入队挂载、 + 语义 `/search/*`、Projects field_values、`issue transfer`。逐操作通道归属(✓ 按席位类别限定)、 + 写侧配方与队列路由三读法见 `references/rest-channel.md`,⛔ 不在本表复述。 +- **MCP list/search 家族整个走 GraphQL 稀缺池**(反复撞上的限流墙就是它; + `issue_write` 连查找半边都吃);配额红时认领类动作排队,评论(REST 桶)先行把结论发出去。 - **`gh` CLI 的动词按传输分两桶,池枯竭时只死一半**(2026-08-24 同分钟实测:GraphQL 0 / core 4987):porcelain 家族(`gh issue view` / `gh pr list`)与 `gh pr create` 走 GraphQL 当场回限流,同一批事实 改走 `gh api` 的 REST 路径照常返回(含开 draft PR)。⚠️ 容器无 `gh`,本条只对本机席位适用。 -- **红窗调度**:`until remaining > 阈值` 的守候**只给上面那几件 GraphQL-only 的**(逐件判据与官方 - 文档核对日期住 `references/rest-channel.md`),⛔ 其余一切不为配额空等;走队列的仓落地必经 - auto-merge ⇒ 红窗里**无退路**,直合仓有(合并本身有 REST 端点)。 -- **`issue transfer` 因配额或权限拿不到 ⇒ 当轮改走多仓协调条款的「在目的仓重建」配 - 方**(出处头 + 裸 `#N` 改全名 + 关源单为 moved):纯 REST、配额免疫,⛔ 不为转移空等重置。 +- **红窗调度**:`until remaining > 阈值` 的守候**只给上面那几件 GraphQL-only + 的**(逐件判据与官方文档核对日期住 `references/rest-channel.md`),⛔ 其余一切不为配额空等; + 走队列的仓落地必经 auto-merge ⇒ 红窗里**无退路**,直合仓有(合并本身有 REST 端点)。 +- **`issue transfer` 因配额或权限拿不到 ⇒ 当轮改走多仓协调条款的「在目的仓重建」 + 配方**(出处头 + 裸 `#N` 改全名 + 关源单为 moved):纯 REST、配额免疫,⛔ 不为转移空等重置。 - **两个「瘦身参数」都不省池**:`fields` 省载荷不省池 —— MCP list/search 服务器端无条件抓 - Project field_values,池枯竭时**最小字段请求同样全体失败**(报错串 - `failed to fetch issue field values: API rate limit already exceeded`);⛔ **`minimal_output: true` 不裁 - `list_issues` 的 `body`**(2026-08-22 实测:返回字段仍含 `body`),**永不当省额度手段写进任何 - skill**;没有参数能关掉 `body`:要么整表 107 点要么换窄接口(点数未测)。⚠️ 站得住的证据 - 是直接观察 `body` 在,不是前后体积对比(两次调用相隔数小时、population 已变)。 + Project field_values,池枯竭时**最小字段请求同样全体失败**(报错串 `failed to fetch issue field + values: API rate limit already exceeded`);⛔ **`minimal_output: true` 不裁 `list_issues` 的 `body`**(2026-08-22 + 实测:返回字段仍含 `body`),**永不当省额度手段写进任何 skill**;没有参数能关掉 `body`: + 要么整表 107 点要么换窄接口(点数未测)。⚠️ 站得住的证据是直接观察 `body` 在, + 不是前后体积对比(两次调用相隔数小时、population 已变)。 - **git 先行**:本地检出 / `git log` / `ls-remote` 不花配额,断粮期分支存在性检查照常可用,PR 文 件读取同走 git(REST PR files 端点实测可瞬态 404)。**零成本等价物四条**(API 两次挂掉期间实 测可用):合并队列 `git ls-remote origin 'refs/heads/gh-readonly-queue/*'`;是否落地 @@ -136,8 +136,8 @@ 只因仓库公开成立;⛔ 覆盖单卡读、**不覆盖 issue search**(搜索页无 SSR 结果);⛔ 永不拿渲染 列表定规模(静默只显一页,实测 12 vs 权威 147)。渲染层 WebFetch 仍在(~15 分缓存、有损)。 - **查重先 `search_issues`**(2026-08-18 实测:单次调用按 issue body 内文本命中且 `total_count` 精确; - 「search 对本会话不可用」的继承说法实测为**假** —— 继承说法不是读数,复述必带实测 - 日期):body 文本匹配是 repo-scoped `list` 做不到的,`list` + 对照组降为回退。 + 「search 对本会话不可用」的继承说法实测为**假** —— 继承说法不是读数, + 复述必带实测日期):body 文本匹配是 repo-scoped `list` 做不到的,`list` + 对照组降为回退。 - **`search_issues` 可整会话静默归零 —— 控制词一并归零**(2026-08-23 实测:某会话对**每个**查 询回 `total_count: 0`,含已知必中的控制词;同时刻另一会话正常 ⇒ 故障是**会话级**)。⛔ **空查重结果不是读数,除非本会话内一个已知必中的控制词答了** —— ⛔ 不是「可疑时 @@ -164,17 +164,17 @@ - **会话中途轮换凭据把 GitHub MCP 服务器杀到不可恢复**:此后一切 `mcp__github__*` 回 `Streamable HTTP error: invalid session`,只有新会话重绑 —— 轮换前提醒维护者:在飞席位丢整条 GitHub 通道;配额池按身份计,换身份即清零燃烧,共享身份结构不变。 -- **组织侧授权变更后仓库访问逐步传播**(同一端点数分钟内 403→200);该 403 体同样解析成净 - 零 ⇒ 空车道先对仓库 `open_issues_count` 反查再信,零命中纪律覆盖 list 读。 -- **MCP 参数两陷阱**:`list_issues` 多标签过滤是 **OR(并集)**不是 AND —— 混入别车道同状态卡 - 与本车道全状态卡,结果良构、失效全静默;**判据 = 结果比任一输入都宽**(三席独立实测: - 两标签的「交集」回 135 张,而其中一个车道自身只有 132 张)。正确读法 = **整车道单标签 - 一次读全 + 本地对 labels 求交**,或改走 REST —— **两个通道的 `labels` 语义相反**:REST 列表 - 端点的 `labels=a,b` 是**真 AND**(交集),MCP 的 `labels` 数组是 **OR** ⇒ 要交集按上面的探针与 - 降级梯选档,⛔ 不无条件「改走 REST」。`issue_write` 的 `labels` 是**整组替换**不是追加 —— - 同一动作内重读现值合并再写(隔轮旧读数 = 无效快照,按其回写静默剥别的标签);真追加走 - REST `POST /issues/{n}/labels`,⚠️ 同样先过探针 —— 403 会话没有真追加通道,只能整组替换; - 写后照标签纪律回读。 +- **组织侧授权变更后仓库访问逐步传播**(同一端点数分钟内 403→200);该 403 + 体同样解析成净零 ⇒ 空车道先对仓库 `open_issues_count` 反查再信,零命中纪律覆盖 list 读。 +- **MCP 参数两陷阱**:`list_issues` 多标签过滤是 **OR(并集)**不是 + AND —— 混入别车道同状态卡与本车道全状态卡,结果良构、失效全静默;**判据 = + 结果比任一输入都宽**(三席独立实测:两标签的「交集」回 135 张,而其中一个车道自身只有 + 132 张)。正确读法 = **整车道单标签一次读全 + 本地对 labels 求交**, + 或改走 REST —— **两个通道的 `labels` 语义相反**:REST 列表端点的 `labels=a,b` 是**真 AND** + (交集),MCP 的 `labels` 数组是 **OR** ⇒ 要交集按上面的探针与降级梯选档,⛔ 不无条件「改走 + REST」。`issue_write` 的 `labels` 是**整组替换**不是追加 —— 同一动作内重读现值合并再写 + (隔轮旧读数 = 无效快照,按其回写静默剥别的标签);真追加走 REST `POST /issues/{n}/labels`, + ⚠️ 同样先过探针 —— 403 会话没有真追加通道,只能整组替换;写后照标签纪律回读。 - **PR 标签的三条读腿全盲、两条静默**(2026-08-28 同日实测):① `issue_read get_labels` 传 PR 号 回「Could not resolve to an Issue」—— REST「PR 也是 issue」的惯例在此方法不成立;**响亮失败即 路由信号**,改走腿③。② `pull_request_read get` 的 `labels` **时缺时滞**:dev 席同一张新 PR 两读 @@ -191,46 +191,46 @@ 原样回写;⚠️ 但读侧**并非一律可逆** —— 行内反引号里的尖括号片段被 MCP 读路径**整 个丢弃**(不是转义,无从解码回来),判据见「读数陷阱」判截断行。写侧剥除是**真实存储 损耗**,⛔ 两类不并成一条「API 会改 body」,写后回读必做;实体归属与 `&` 类未实测。 -- **`Blocked-by:` 行归 BODY(单通道反向索引)**:追加按上条「解码后写回」执行;历史上寄放在评 - 论里的行按同程序**增量**回填(⛔ 不搞批量突击 —— 限流压力);解锁扫描只 grep body,⛔ 不 - 加常设评论读;旧「连评论一起扫(`in:comments`)」提示作废,扫描走直读(`list_issues` + `issue_read` - 读 body)。 -- **`list_issue_types` 对本集成 403,而 `issue_write type:` 正常**(读权限缺口): 直接写已知好 - 值(`Bug`/`Feature`/`Task`),写侧报错才是真信号,⛔ 不先探列表定可用性(列表 403 - ≠「类型不可用」);非法值是响错还是静默丢弃未实测,写非已知值前先小样验证。 +- **`Blocked-by:` 行归 BODY(单通道反向索引)**:追加按上条「解码后写回」 + 执行;历史上寄放在评论里的行按同程序**增量**回填(⛔ 不搞批量突击 —— 限流压力); + 解锁扫描只 grep body,⛔ 不加常设评论读; + 旧「连评论一起扫(`in:comments`)」提示作废,扫描走直读(`list_issues` + `issue_read` 读 body)。 +- **`list_issue_types` 对本集成 403,而 `issue_write type:` 正常**(读权限缺口): + 直接写已知好值(`Bug`/`Feature`/`Task`),写侧报错才是真信号,⛔ 不先探列表定可用性(列表 + 403 ≠「类型不可用」);非法值是响错还是静默丢弃未实测,写非已知值前先小样验证。 ## 读数陷阱 -- **被拦的下载不是缺席证明**:出口策略 403(如 `cdn.playwright.dev`)只说「取不来」不说「没 - 有」—— 先找产物再下结论(实测:Chromium 预装、`PLAYWRIGHT_BROWSERS_PATH` 已设)。 -- **读数五坑**:`cd X && cmd` 会短路(路径不存在时命令在当前仓继续执行,产出假读数)—— 跨 - 仓一律 `git -C `; `git grep -c | wc -l` 数文件数不是命中数;裸名 grep 被幸存家族当子 - 串命中 —— 退役核验带引号精确名,更硬判据是查声明 - 式(`^(export )?(const|type|interface) \b`)而非查提及;浅检出上的历史读数不可信 - (`merge-base --is-ancestor` 假「非祖先」、`rev-list --count` 截断、`branch -r --contains` 零输出)—— - 先 `--deepen` 再判,或走 REST `compare`;**容器里没有 `gh`**,于是 `gh … || echo "none"` 是个 - **不可证伪的否定** —— 127「命令不存在」与「grep 没命中」在输出上同值(实测五张 PR 跑 - 五次「无重叠文件」全部打印安心结论、一次都没检查)。安全拼写:先 `command -v ` 确认 - 存在,或在 `||` 之前捕获状态;⛔ 一般规则:**任何可能不存在的命令上挂 `|| 回退` 都是不可 - 证伪的否定**,PR / 查重类核验改走 MCP GitHub 工具或 git。 +- **被拦的下载不是缺席证明**:出口策略 403(如 `cdn.playwright.dev`)只说「取不来」 + 不说「没有」—— 先找产物再下结论(实测:Chromium 预装、`PLAYWRIGHT_BROWSERS_PATH` 已设)。 +- **读数五坑**:`cd X && cmd` 会短路(路径不存在时命令在当前仓继续执行, + 产出假读数)—— 跨仓一律 `git -C `; `git grep -c | wc -l` 数文件数不是命中数; + 裸名 grep 被幸存家族当子串命中 —— 退役核验带引号精确名,更硬判据是查声明式 + (`^(export )?(const|type|interface) \b`)而非查提及;浅检出上的历史读数不可信 + (`merge-base --is-ancestor` 假「非祖先」、`rev-list --count` 截断、`branch -r --contains` + 零输出)—— 先 `--deepen` 再判,或走 REST `compare`;**容器里没有 `gh`**,于是 `gh … || echo "none"` + 是个**不可证伪的否定** —— 127「命令不存在」与「grep 没命中」在输出上同值 + (实测五张 PR 跑五次「无重叠文件」全部打印安心结论、一次都没检查)。安全拼写:先 + `command -v ` 确认存在,或在 `||` 之前捕获状态;⛔ 一般规则:**任何可能不存在的命令上挂 + `|| 回退` 都是不可证伪的否定**,PR / 查重类核验改走 MCP GitHub 工具或 git。 - **auto 档分类器的判定随命令形状变,不随能力变 ⇒ 被拒的复合命令先拆成裸核心动作重试 再报 blocked**(2026-08-22 同席同分钟:`git rev-parse … && git push origin <分支> 2>&1 | tail` 被拒,裸 `git push origin <分支>` 放行并成功 —— 只差链接与管道,拒绝文案不点名违规元素;判定还跨 天翻面)⇒ ⛔ 一次拒绝不是能力边界,`permissions.allow` 条目才是仓库侧唯一确定性通道。 -- `rerun_failed_jobs` 复用原 run 的提交与合并 ref,不拿新 main 重算 —— 红因是基上缺一个已合 - 修复时重跑无效,只能推提交(`git merge origin/main`);判别:修复的合并时间晚于 run 创建时间即 - 是。 -- **同一 head 上轻量兄弟 workflow `success` + 重量级载体 `cancelled` 是普通取代的预期签名,不是 - 选择性失败**(cancel-in-progress 窗口只罩得住跑得慢的载体):先比对 run `head_sha` 与 PR 当前 - head(取代必有新 head),不开「为何只取消它」调查。 -- **CI 红了先取完整日志归档再下结论 —— 断言文本只在归档里,直读工具拿不到** (2026-08-18 - 实测):`get_check_run` 对本仓 CI job 回空 `output.text`,`get_job_logs` 无论 `tail_lines` 只回占满日志尾 - 部的 post-step service-container teardown ⇒ 两者都答不了「到底挂在哪」;失败 step 名免下载即 - 得(`actions_get method=get_workflow_job`),真实断言文本走 run 日志归 - 档:`actions_get method=get_workflow_run_logs_url` → 下载解压,分步文件在 - `{Job name}/{step number}_{step name}.txt`。「completeness check 绿」只断言没有 worker 静默死 ≠ 测试 - 通过;并发输出的「相邻」≠「因果」(先查 `turbo.json` 依赖边),⛔ 不只看 tail; 公开发出的 - 诊断被推翻时,更正发在同样公开的位置,据它开的 PR 撤回 draft、解绑 `Fixes`。 +- `rerun_failed_jobs` 复用原 run 的提交与合并 ref, + 不拿新 main 重算 —— 红因是基上缺一个已合修复时重跑无效, + 只能推提交(`git merge origin/main`);判别:修复的合并时间晚于 run 创建时间即是。 +- **同一 head 上轻量兄弟 workflow `success` + 重量级载体 `cancelled` 是普通取代的预期签名, + 不是选择性失败**(cancel-in-progress 窗口只罩得住跑得慢的载体): + 先比对 run `head_sha` 与 PR 当前 head(取代必有新 head),不开「为何只取消它」调查。 +- **CI 红了先取完整日志归档再下结论 —— 断言文本只在归档里, + 直读工具拿不到** (2026-08-18 实测):`get_check_run` 对本仓 CI job 回空 `output.text`, + `get_job_logs` 无论 `tail_lines` 只回占满日志尾部的 post-step service-container teardown + ⇒ 两者都答不了「到底挂在哪」;失败 step 名免下载即得(`actions_get method=get_workflow_job`), + 真实断言文本走 run 日志归档:`actions_get method=get_workflow_run_logs_url` → 下载解压,分步文件在 + `{Job name}/{step number}_{step name}.txt`。「completeness check 绿」只断言没有 worker 静默死 + ≠ 测试通过;并发输出的「相邻」≠「因果」(先查 `turbo.json` 依赖边),⛔ 不只看 tail; + 公开发出的诊断被推翻时,更正发在同样公开的位置,据它开的 PR 撤回 draft、解绑 `Fixes`。 - **判「正文被截断」必须双读取**:`.body` 原文 + `Accept: application/vnd.github.full+json` 的 `.body_html`,两者同一处断掉才算 issue 端截断。读侧实测有确定性触发:正文含字面 script 开 标记形状的 token(less-than 紧跟 script 字样;doctype 开标记、object 标签形状同触发)时,API/MCP 读 @@ -251,12 +251,12 @@ 紧跟左方括号**即触发(TS 非空断言下标),**无需 less-than**(2026-08-29 PR 正文四处实测,MCP 与渲 染页双读一致、盘上未变 ⇒ 落库丢字符;围栏/行内代码四处全丢),幸存文本仍像代码但意 义已变;感叹号不接左方括号则存活。作者侧:运算符**用词拼出**,或占位词定义一次。 -- **写侧实测行为 · 评论(形状是「截断」不是「删片段」)**:sanitizer 从**首个命名 HTML 元素 - 的尖括号片段**起把评论体一路吃到结尾(2026-08-21 实测:一份用**字面文本**标记发出的 dev - 报告,正文在 `this.error(` 处断掉、JSON 不可解析)⇒ ⛔ **字面文本标记只保住标记、保不住 - 正文** —— 标记扫描照报成功,只有真去解析才发现;引信是普通 TS 形状(泛型一类)不是奇 - 异语法。⚠️ 边界:姊妹仓一次受控探针测到的是**选择性删除**而非截断到尾 ⇒ **写侧按 - 最坏的截断防护**。 +- **写侧实测行为 · 评论(形状是「截断」 + 不是「删片段」)**:sanitizer 从**首个命名 HTML 元素的尖括号片段**起把评论体一路吃到结尾 + (2026-08-21 实测:一份用**字面文本**标记发出的 dev 报告,正文在 `this.error(` 处断掉、 + JSON 不可解析)⇒ ⛔ **字面文本标记只保住标记、保不住正文** —— 标记扫描照报成功, + 只有真去解析才发现;引信是普通 TS 形状(泛型一类)不是奇异语法。⚠️ 边界: + 姊妹仓一次受控探针测到的是**选择性删除**而非截断到尾 ⇒ **写侧按最坏的截断防护**。 - **写侧实测行为 · PR 正文(尾部 `---` 与其后的署名页脚一并被吃)**:写调用照报成功;去掉横 线只写页脚则原样存活(2026-08-28 两仓同轮、两张 PR 全文回读)。**评论不受影响**(两种拼法 都活)⇒ 失效既**依拼写**又**依载体**:评论里验过页脚**对 PR 正文什么都没证明**。⇒ PR @@ -264,20 +264,20 @@ - **并行 spec PR 同动 pin 计数断言**(被踢不是事故,按 os-regen 序再解一轮):解冲突两侧收据都 保留、按合并顺序堆叠,新计数**从合并后源码重数**(操作数是文件本身不是历史),⛔ 不从 两侧收据做算术;双方占同一编号是常态(各取当时 max+1),重编号后进侧。 -- **容器重启杀死在飞 dev,现场三态判读**:① 分支已推 + PR 已开 ⇒ 只欠验收(CI 重跑 + 复 - 核,不动代码); ② 死在 regen 中途(未提交全是生成物、merge commit 已在)⇒ PM 直接续作 —— - build → 整链 regen → 生成物门禁全绿 → 提交推送,恢复 commit 带 `Recovery commit:` 前缀留审 - 计;⚠️ 有的现场 regen 一件没跑,推送前先跑生成物门禁别赌; ③ 死在源码编辑中途 ⇒ 先 - 读 diff 判完整性 —— docblock 写全动机/失效模式/判据的,PM 可代跑终验后提交,写一半意图 - 不明的 ⛔ 不代提交、记进交接;dev 临时目录(`.os-scratch/` 一类)是工作物不是交付物,清 - 掉,⛔ 不进 feature PR。 -- **零提交的探针分支不是在飞工作**:容器发不出分支删除 refspec(实测 - `git push origin --delete ` 回 `send-pack: unexpected disconnect while reading sideband packet`,三次退避全 - 败;**同会话普通 push 正常** ⇒ 不是连通性问题),于是测量型派发留下的探针分支永久堆在 - origin 上。读法规则:`claude/issue-*` 分支**零提交领先 `origin/main` 且没有开着的 PR** = 不承载 - 任何工作,⛔ 不据 `ls-remote | grep issue-` 正命中回避该卡 —— 失效方向是**活卡被永久读成 - 已被认领**,无红信号、只增不减。判据两读:`git rev-list --count origin/main..origin/` 为 0,且 - 分支名下无 open PR。边界:一容器一会话三次,成因未诊断,存量未普查。 +- **容器重启杀死在飞 dev,现场三态判读**:① 分支已推 + PR 已开 ⇒ 只欠验收(CI 重跑 + 复核, + 不动代码); ② 死在 regen 中途(未提交全是生成物、 + merge commit 已在)⇒ PM 直接续作 —— build → 整链 regen → 生成物门禁全绿 → 提交推送, + 恢复 commit 带 `Recovery commit:` 前缀留审计;⚠️ 有的现场 regen 一件没跑, + 推送前先跑生成物门禁别赌; ③ 死在源码编辑中途 ⇒ 先读 diff 判完整性 —— + docblock 写全动机/失效模式/判据的,PM 可代跑终验后提交,写一半意图不明的 ⛔ 不代提交、 + 记进交接;dev 临时目录(`.os-scratch/` 一类)是工作物不是交付物,清掉,⛔ 不进 feature PR。 +- **零提交的探针分支不是在飞工作**:容器发不出分支删除 refspec(实测 `git push origin --delete + ` 回 `send-pack: unexpected disconnect while reading sideband packet`,三次退避全败;**同会话普通 push + 正常** ⇒ 不是连通性问题),于是测量型派发留下的探针分支永久堆在 origin 上。读法规则: + `claude/issue-*` 分支**零提交领先 `origin/main` 且没有开着的 PR** = 不承载任何工作,⛔ + 不据 `ls-remote | grep issue-` 正命中回避该卡 —— 失效方向是**活卡被永久读成已被认领**, + 无红信号、只增不减。判据两读:`git rev-list --count origin/main..origin/` 为 0, + 且分支名下无 open PR。边界:一容器一会话三次,成因未诊断,存量未普查。 - **会话从上下文检测不到自己的静默降档**(2026-08-20 实测:一次分诊 fire 两级静默降档,横幅 只在 UI 侧渲染、上下文零信号,子轮开场自述「跑在契约复审档」)——服役档的权威读数 是 `get_session`(claude-code-remote MCP,无参)的 `external_metadata.last_served_model`(最近一轮实 @@ -286,10 +286,10 @@ 话** ⇒ 保险丝无输入(2026-08-24),另一台宿主省 `session_id` 正常回两键(2026-08-25)⇒ ⛔ 不据一 台宿主推全体;无它时的合法替代 = grep 本会话 transcript 里 harness 写的 `"model":`(逐请求写 入、非模型自述,用时在卡上申报)。 -- **档位额度终止是第三种死法**(2026-08-27 实测):子代理死在编辑中途、宿主报本账户档位 - 额度到顶 —— 有**宿主信号**故非普通子代理死亡,亦非维护者中止:**派发已死、前提完 - 好、卡在资源** ⇒ 死认领回收 + worktree 抢救,⛔ 不重核前提、不升级;⚠️ 无前置探针 - (只在 dev 死在里面时可观测),缓解只在 dev 侧的早 WIP 提交。 +- **档位额度终止是第三种死法**(2026-08-27 实测):子代理死在编辑中途、 + 宿主报本账户档位额度到顶 —— 有**宿主信号**故非普通子代理死亡,亦非维护者中止: + **派发已死、前提完好、卡在资源** ⇒ 死认领回收 + worktree 抢救,⛔ 不重核前提、 + 不升级;⚠️ 无前置探针(只在 dev 死在里面时可观测),缓解只在 dev 侧的早 WIP 提交。 - **档位不可用时 ⛔ 不凭记忆宣告车道阻塞,逐文件面现推 mandate**:强制档不得因不可用而 降档(那正是降档保险丝要拒的替换),但「本车道 fable 强制」多是过宽的回忆 —— `dispatch-gates.mjs --tier PATH` 逐路径现推(实测:`SKILL.md` 与 `.claude/agents/**` 强制,`scripts/pm/**` @@ -298,11 +298,11 @@ ## 闭合关键词解析(PR 正文写侧) - **PR 正文里「不修某卡」的否定句照样关卡**:闭合关键词解析器匹配 - `fix/fixes/fixed/close/closes/closed/resolve/resolves/resolved` + `#N`,**不理会前面的否定词** —— 声明 - 不修的那句话恰在合并时关卡;安全写法 = 号码不被关键词打头 (`#N is not addressed here` / - `out of scope: #N` / `#N remains open`)。实测边界三条:关键词只绑**同一行**的 `#N`;动名 - 词(closing/fixing)不是关键词;行内反引号里的关键词不触发(code span 实测不建闭合链接;围栏 - 块未独立实测,按同规则对待但留待复测)。 + `fix/fixes/fixed/close/closes/closed/resolve/resolves/resolved` + `#N`,**不理会前面的否定词** —— + 声明不修的那句话恰在合并时关卡;安全写法 = 号码不被关键词打头 (`#N is not addressed here` + / `out of scope: #N` / `#N remains open`)。实测边界三条:关键词只绑**同一行**的 `#N`; + 动名词(closing/fixing)不是关键词;行内反引号里的关键词不触发(code span 实测不建闭合链接; + 围栏块未独立实测,按同规则对待但留待复测)。 - **PR body 与 squash commit message 是两个独立解析源**(commit 干净 ≠ body 干净,只查 commit 会 漏);误关的卡以 `completed` 状态对一切「只看 open」的过滤与巡检隐身,无任何机械守卫覆盖 这条路径 —— 消费侧检查 = 合并后读 `closed_by_pull_requests`(在复核清单)。 diff --git a/.claude/skills/pm-dispatch/references/release-aftercare.md b/.claude/skills/pm-dispatch/references/release-aftercare.md index 5b13c985d3..b757de2565 100644 --- a/.claude/skills/pm-dispatch/references/release-aftercare.md +++ b/.claude/skills/pm-dispatch/references/release-aftercare.md @@ -1,22 +1,22 @@ # 发版后义务(references —— 按需加载) -出处:落地窗口止于 MERGED,而 MERGED 不是用户拿到东西的时刻。本表是 tagged 发版滚 -上生产**之后**车道 PM 仍欠的动作,发版窗口查阅;⛔ 不引用 issue 编号。实测底账: -2026-08-21/23 云侧连续两日的发版运维记录。 +出处:落地窗口止于 MERGED, +而 MERGED 不是用户拿到东西的时刻。本表是 tagged 发版滚上生产**之后**车道 PM 仍欠的动作, +发版窗口查阅;⛔ 不引用 issue 编号。实测底账:2026-08-21/23 云侧连续两日的发版运维记录。 ## A. 每次 fleet roll 重掷容器落位 —— 先读落位,再读延迟 -tagged 发版滚容器,滚容器就在区域约束内**重掷**落位;区域约束只定边界、不定城市 -(实测同一 ENAM 内 Ashburn ~4ms / Atlanta ~17ms / Houston ~35ms 每 leg,9 倍差)。 -折算用实测形状 `server ≈ 33 + 23 × RTT`:35ms/leg ≈ ~870ms/请求,在 ≤200ms 的性能 -门禁**外**;~4ms 一档 ≈ ~120ms,门禁内有余量。**所以发版后必须重读落位,⛔ 不得假 -设它没变** —— 上一版读到的好数字不是这一版的读数。 +tagged 发版滚容器,滚容器就在区域约束内**重掷**落位;区域约束只定边界、 +不定城市(实测同一 ENAM 内 Ashburn ~4ms / Atlanta ~17ms / Houston ~35ms 每 leg,9 倍差)。 +折算用实测形状 `server ≈ 33 + 23 × RTT`:35ms/leg ≈ ~870ms/请求, +在 ≤200ms 的性能门禁**外**;~4ms 一档 ≈ ~120ms,门禁内有余量。**所以发版后必须重读落位, +⛔ 不得假设它没变** —— 上一版读到的好数字不是这一版的读数。 重掷有两条反直觉物理,顺序错了读数就是废的: -- **落位跟随唤醒者(WAKER),不跟随 `locationHint`** —— 从运维者自己的机器唤醒就 - 掷到运维者附近。实测:加州机器重掷反复落 Houston;改用 us-east CI runner 唤醒,第一次就落 - Ashburn。 +- **落位跟随唤醒者(WAKER), + 不跟随 `locationHint`** —— 从运维者自己的机器唤醒就掷到运维者附近。 + 实测:加州机器重掷反复落 Houston;改用 us-east CI runner 唤醒,第一次就落 Ashburn。 - **测量本身污染下一次掷点** —— 换实例中途发出的探针,自己就成了新实例的唤醒者。 - **协议(顺序不可换)**:rollout → 运维侧**零 HTTP** → us-east runner 唤醒 (`gh workflow run keep-warm`)→ 读 CF instances API 拿到城市 → **才**开始测量。 @@ -24,35 +24,35 @@ tagged 发版滚容器,滚容器就在区域约束内**重掷**落位;区域约 ## B. 一次真实用户路径探针 —— health 绿证明不了用户能进来 -发版后至少跑**一条真实用户走的完整链路**(登录 → SSO 跳转 → 落地页有数据),⛔ 不 -以 `/health` 200、部署 job 绿或合成 E2E 绿代替。实测失效模式:平台 SSO 跳转对每个 -真实用户失败了**五周**(2026-07-17 最后一次成功换 token,2026-08-22 才被发现),期 -间健康检查全绿、E2E 也全绿 —— E2E 用邮箱密码直登,从不跑那段交换。**合成路径绕开 -的那一段,正是只有真实用户才会走的那一段。** +发版后至少跑**一条真实用户走的完整链路**(登录 → SSO 跳转 → 落地页有数据), +⛔ 不以 `/health` 200、部署 job 绿或合成 E2E 绿代替。 +实测失效模式:平台 SSO 跳转对每个真实用户失败了**五周**(2026-07-17 最后一次成功换 +token,2026-08-22 才被发现),期间健康检查全绿、E2E 也全绿 —— E2E 用邮箱密码直登, +从不跑那段交换。**合成路径绕开的那一段,正是只有真实用户才会走的那一段。** ## C. 手改线上状态 = 止血带 —— 先点名谁重放它、什么时候重放 -改任何**由重放层拥有**的线上状态(库里的行、配置行、绑定)之前,先答两个问题并写进 -卡:**谁**重放这份状态(seed / reseed / migration / boot binder),**什么时候**重放。 +改任何**由重放层拥有**的线上状态(库里的行、配置行、绑定)之前,先答两个问题并写进卡: +**谁**重放这份状态(seed / reseed / migration / boot binder),**什么时候**重放。 - 手改是止血带,**重放层的修复才是真卡** —— 不立卡,修复就只活在一个人的记忆里。 -- **修好的代码必须赶在下一次重放事件之前发出去**,否则事故原样重开。实测:一次 SSO - 补救手翻了库里的认证方法行,一次跑在修复之前的 reseed 把它整批翻了回去,直到修复 - 落进 seed 本身才止住。 +- **修好的代码必须赶在下一次重放事件之前发出去**, + 否则事故原样重开。实测:一次 SSO 补救手翻了库里的认证方法行, + 一次跑在修复之前的 reseed 把它整批翻了回去,直到修复落进 seed 本身才止住。 - 手改**同刻**记录:改了哪张表哪些行、多少行、谁重放、真卡在哪。 ## D. 被打断的长循环 —— 恢复的第一个动作是重读现实 -后台长跑循环(重掷、恢复轮询、灰度推进)被会话重启打断时,**它最后记下的「意图」不 -是线上此刻的状态**。恢复的第一个动作恒为**重读线上真实状态**,⛔ 永不从循环的最后 -已知意图往下接;⛔ 也不把长循环留在无人认领的后台。实测:一个被孤儿化的重掷循环,把 -生产控制面停在它自己掷出的**最差**一档上数小时,而循环留下的最后一行写着「继续重 -掷」。 +后台长跑循环(重掷、恢复轮询、灰度推进)被会话重启打断时,**它最后记下的「意图」 +不是线上此刻的状态**。恢复的第一个动作恒为**重读线上真实状态**, +⛔ 永不从循环的最后已知意图往下接;⛔ 也不把长循环留在无人认领的后台。 +实测:一个被孤儿化的重掷循环,把生产控制面停在它自己掷出的**最差**一档上数小时, +而循环留下的最后一行写着「继续重掷」。 ## E. 诚实条款 —— 后来的测量推翻已合并 PR 的断言,更正公开落到卡上 -已合并 PR 正文里的事实断言被后来的测量证伪时,**更正公开发到卡上**,⛔ 不只是自己 -知道、也不只在下一份报告里顺带带过。实测:一张卡的正文断言「SQL DEFAULT 会回填已有 -行」,后续实测是已有行仍为 NULL(add-column 并不把默认值带进 DDL);更正当场发到卡 -上,回填那一半因此留在原卡等人做,而不是被当成已交付。**已合并 ≠ 已证实** —— PR 正 -文是当时的最好理解,卡才是事实的现居地。 +已合并 PR 正文里的事实断言被后来的测量证伪时,**更正公开发到卡上**, +⛔ 不只是自己知道、也不只在下一份报告里顺带带过。实测:一张卡的正文断言 +「SQL DEFAULT 会回填已有行」,后续实测是已有行仍为 NULL(add-column 并不把默认值带进 DDL); +更正当场发到卡上,回填那一半因此留在原卡等人做,而不是被当成已交付。 +**已合并 ≠ 已证实** —— PR 正文是当时的最好理解,卡才是事实的现居地。 diff --git a/.claude/skills/pm-dispatch/references/rest-channel.md b/.claude/skills/pm-dispatch/references/rest-channel.md index 3c6baa2411..17e8b35514 100644 --- a/.claude/skills/pm-dispatch/references/rest-channel.md +++ b/.claude/skills/pm-dispatch/references/rest-channel.md @@ -1,8 +1,8 @@ # REST 通道操作对照表(references —— 按需加载) -出处:`platform-readings.md` API 配额段(**默认读序 git → payload → REST → MCP/GraphQL** 的策略住那 -里,本表是逐操作的通道归属)。做一件事之前查一行:它有没有 REST 对应物。⛔ 不引用 issue -编号 —— 每行自含边界与日期。 +出处:`platform-readings.md` API 配额段(**默认读序 git → +payload → REST → MCP/GraphQL** 的策略住那里,本表是逐操作的通道归属)。做一件事之前查一行: +它有没有 REST 对应物。⛔ 不引用 issue 编号 —— 每行自含边界与日期。 **通道边界**:容器 curl = App installation token,REST core 15,000/时、与 GraphQL 池独立计;出口代理按设 计只放 **repo-scoped 路径**(`/repos/{o}/{r}/...`)加 `/rate_limit`,org 级端点未实测。⚠️ **✓ 按席位 @@ -21,8 +21,8 @@ `list_issues` 永不返回 assignees,这条差别本身就是走 REST 的理由)。 - ✓ 整条评论线:`GET .../issues/{n}/comments?per_page=100`。 - ✓ Timeline 事件:`GET .../issues/{n}/timeline`(cross-ref、`added_to_merge_queue`、ready_for_review)。 -- ✓ PR diff / 文件清单:`GET .../pulls/{n}` 带 Accept `application/vnd.github.diff` · `.../pulls/{n}/files`(后 - 者实测可瞬态 404 ⇒ PR 文件读取优先走 git)。 +- ✓ PR diff / 文件清单:`GET .../pulls/{n}` 带 Accept + `application/vnd.github.diff` · `.../pulls/{n}/files`(后者实测可瞬态 404 ⇒ PR 文件读取优先走 git)。 - ✓ 取某 ref 上的文件:`GET .../contents/{path}?ref=...`(raw accept)。 - ✓ 祖先 / 对比:`GET .../compare/{base}...{head}` —— 浅检出上本地祖先判据不可信时的正解。 - ✓ 门禁 / workflow:`GET .../commits/{sha}/check-runs` · `GET .../actions/runs`。 @@ -47,10 +47,10 @@ (2 与 5 同批:2026-08-24 核对官方文档,未逐个实调)。断粮出路:等 MCP 恢复,或人工点一下。 2. **auto-merge / 入队挂载**:GraphQL mutation(MCP `enable_pr_auto_merge`)。走合并队列的仓落地必经它 ⇒ 配额红窗**无退路**;直合仓有退路(合并本身有 REST 端点 `PUT .../pulls/{n}/merge`)。 -3. **语义搜索**:`/search/*` 被出口代理按设计拒绝。退路 = REST 列表端点 + 本地 grep(既有纪 - 律);REST 也被会话门关掉的席位 = 一次定向 MCP `search_issues`,⛔ 不宽表扫。 -4. **Projects field_values**:GraphQL-only —— 舰队并不需要它;MCP 服务器端**无条件**抓它才是漏 - 点,不是需求。 +3. **语义搜索**:`/search/*` 被出口代理按设计拒绝。退路 = REST 列表端点 + + 本地 grep(既有纪律);REST 也被会话门关掉的席位 = 一次定向 MCP `search_issues`,⛔ 不宽表扫。 +4. **Projects field_values**:GraphQL-only —— 舰队并不需要它;MCP 服务器端**无条件**抓它才是漏点, + 不是需求。 5. **`issue transfer`**(2026-08-24 官方文档核对补入):issues 端点表无 transfer 路由 ⇒ 同为 GraphQL-only。拿不到时当轮改走「在目的仓重建」配方 —— 纯 REST、配额免疫,配方住 `platform-readings.md`。 @@ -68,20 +68,20 @@ 合」零分辨力(一周内三席据人形 `merged_by` 误判「绕队」,三次全假 —— 都是队列合并)。 - **问「本仓 auto-merge 是否经队列」,答案来自尝试动作,不来自属性字段**:① 直接合并 `PUT .../pulls/{n}/merge`,强制队列 ruleset 下回 **405 `Changes must be made through the merge queue`**;② PR - 上的 `added_to_merge_queue` timeline 事件;③ 对已入队 PR 调 update-branch 回「已入队分支不能更 - 新,要改先出队」。①② 拼写与边界是 `platform-readings.md` 队列段既有行,本条只归拢判据。 + 上的 `added_to_merge_queue` timeline 事件;③ 对已入队 PR 调 update-branch 回「已入队分支不能更新, + 要改先出队」。①② 拼写与边界是 `platform-readings.md` 队列段既有行,本条只归拢判据。 - ⚠️ **计数不是机理读数(被当天推翻的推断的墓碑)**:「`GET .../actions/runs?event=merge_group` - 计数 0 ⇒ required 集为空」提出当天即被自身推翻 —— 同一姊妹仓 2026-08-24 首现 - merge_group run(0 → 8),同日再测 224(阳性对照 `event=pull_request` 全程非零)。计数答「至今发生 - 过没有」,不答「机制在不在」:零计数只作**弱先验**,判 required 集为空要读 ruleset 的 - required 集本身、或看队列合并是否真在等检查;⛔ 别处写下的计数值一律先复测再用。 -- **required job 名与分片矩阵的改名耦合(现行,自 2026-08-24)**:队列 required 集按 **job / check-run - 名**匹配,**workflow 名从不作为 check context 出现**(所以拿 workflow 名在选择器里搜什么也搜不 - 到);改其中任一 job 名**或 test 分片矩阵的形状**,必须**同一笔**更新队列的 required 集,否则 - 队列静默挂起。姊妹仓 objectui 当日配置为 **9 个**:`Lint` · `Type Check` · - `Test (shard 1/4 … 4/4)` · `Build & E2E` · `Build Docs` · `Changeset Declaration`。⛔ required 选择只 - gate**等待**、不 gate**触发** —— 未列入的检查照跑、算力相同,红了不再挡队列(维护者当 - 日裁定,原话:「我觉得够了」)。 -- **配 required 集时先排掉 push-only job**:`if: github.event_name == 'push'` 的 job 在 `merge_group` 构建上 - 永不报到,列为 required 即挂死队列;未展开的矩阵名(带字面 `${{ }}` 的串)是被跳过的占位 - 符,不是真 context。 + 计数 0 ⇒ required 集为空」提出当天即被自身推翻 —— 同一姊妹仓 2026-08-24 首现 merge_group + run(0 → 8),同日再测 224(阳性对照 `event=pull_request` 全程非零)。计数答「至今发生过没有」, + 不答「机制在不在」:零计数只作**弱先验**,判 required 集为空要读 ruleset + 的 required 集本身、或看队列合并是否真在等检查;⛔ 别处写下的计数值一律先复测再用。 +- **required job 名与分片矩阵的改名耦合(现行,自 2026-08-24)**: + 队列 required 集按 **job / check-run 名**匹配,**workflow 名从不作为 check context 出现**(所以拿 + workflow 名在选择器里搜什么也搜不到);改其中任一 job 名**或 test 分片矩阵的形状**, + 必须**同一笔**更新队列的 required 集,否则队列静默挂起。 + 姊妹仓 objectui 当日配置为 **9 个**:`Lint` · `Type Check` ·`Test (shard 1/4 … 4/4)` · `Build & E2E` + · `Build Docs` · `Changeset Declaration`。⛔ required 选择只 gate**等待**、不 gate**触发** —— + 未列入的检查照跑、算力相同,红了不再挡队列(维护者当日裁定,原话:「我觉得够了」)。 +- **配 required 集时先排掉 push-only job**: + `if: github.event_name == 'push'` 的 job 在 `merge_group` 构建上永不报到,列为 required 即挂死队列; + 未展开的矩阵名(带字面 `${{ }}` 的串)是被跳过的占位符,不是真 context。 diff --git a/.claude/skills/pm-dispatch/references/review-checklist.md b/.claude/skills/pm-dispatch/references/review-checklist.md index 6ee92c0ac3..c70b0715c9 100644 --- a/.claude/skills/pm-dispatch/references/review-checklist.md +++ b/.claude/skills/pm-dispatch/references/review-checklist.md @@ -1,84 +1,84 @@ # 复核清单细则(references —— 按需加载) -出处:主文件「复核」。你是记录在案的复核人(reviewer of record)—— 对 GitHub 核 -验,不对报告的自述核验;本表逐项展开每份 dev 报告的复核判据。⛔ 不引用 issue 编号。 +出处:主文件「复核」。你是记录在案的复核人(reviewer of record)—— 对 GitHub 核验, +不对报告的自述核验;本表逐项展开每份 dev 报告的复核判据。⛔ 不引用 issue 编号。 -- **PR 形态**:存在、是 draft、目标 `main`、正文首行引用卡片 —— **`Fixes #` 仅 - 当合并应当关卡**;只落地了可实施一半(另一半在决策箱或按范围排除)⇒ 必须 `Part of - #`,否则合并会静默关掉一张正躺在决策箱里的卡,而 `needs-user-decision` 的收件 - 箱过滤只看 open issue。翻 ready 之前亲核首行,别只信报告。 -- **闭合关键词两读**:翻 ready 前亲扫正文 —— 合并前唯一的人工关口(⛔ 关键词永不挨着另 - 一张 open 卡编号;解析器不理会否定句);合并后那一读见落地细则,解析事实见平台读数。 +- **PR 形态**:存在、是 draft、目标 `main`、正文首行引用卡片 + —— **`Fixes #` 仅当合并应当关卡**;只落地了可实施一半(另一半在决策箱或按范围排除) + ⇒ 必须 `Part of #`,否则合并会静默关掉一张正躺在决策箱里的卡, + 而 `needs-user-decision` 的收件箱过滤只看 open issue。翻 ready 之前亲核首行,别只信报告。 +- **闭合关键词两读**: + 翻 ready 前亲扫正文 —— 合并前唯一的人工关口(⛔ 关键词永不挨着另一张 open 卡编号; + 解析器不理会否定句);合并后那一读见落地细则,解析事实见平台读数。 - **`Part of` 收口的卡不会自动关,`pm:dispatched` 必须手工摘**(动作要件见落地细则 B): ACCEPT 那一刻记进落地待办,⛔ 不留给下次巡检 —— 漏摘让在飞视图多算一张无主开卡。 -- **范围检查**(取 changed files,⛔ 不看报告自述):无 `content/docs/releases/` 改 - 动、用户可见改动有 changeset、无与卡无关的文件。Tests/docs-only 按仓库分流:本仓 - 库走 `skip-changeset` 标签、不走空 changeset(空 changeset 在本仓库滞留发布),含 - 读者可见生成产物时 dev 改选 changeset 亦对;objectui 无此标签 —— 空 frontmatter - changeset 即声明、即正确形态,⛔ 永不要求或铸出该标签,⛔ 别来回改。 -- **就地修了范围外的邻接缺陷?**四条件逐条核(同缺陷类·机械·文件无他人认领·同门禁 - 族),再核 claim 文件面同轮已修订、PR 正文点名该修并载证据;缺一条即判 REWORK。 -- **改动触及的每个包,`private: false` 即已发布 ⇒ 核 changeset 在不在**:判据是包 - 的发布状态(读 `package.json`,十秒),不是改动大小,也不是「用户可见」的感觉判 - 断 —— 那个判断 dev 在时间压力下会乐观化。⛔ 缺了不入队 —— 合进 main 却永不发 - 布,看起来像修好了,比不合更糟。 -- **测试证据**要有真实命令与通过输出,不是一句 tests pass。**测量类交付先看阳性对 - 照**:对照本身失败 ⇒ 该读数记 INCONCLUSIVE,⛔ 不把它的「绿」当被测风险的证据入账。 -- **引 entry `.d.ts` 逐字节相同,必须同块带阳性对照**:该读数只判**名字集**(增删再导 - 出名会移动 barrel 字节),对 barrel 已转发符号的**形状**恒无效 —— `export *` 与 - `export type { X } from` 都不复述形状。判据:同块点名**声明**该符号的模块那份移动了的 - 产物,或本会移动它的具名探针;缺则记 INCONCLUSIVE。实测 2026-08-24(清 dist 与 - tsbuildinfo 的三腿重建):声明包 `dist/base.d.ts` 随探针移动又移回,转发文件与 entry - barrel 三腿全同;同日三处误用。 +- **范围检查**(取 changed files,⛔ 不看报告自述):无 `content/docs/releases/` 改动、 + 用户可见改动有 changeset、无与卡无关的文件。Tests/docs-only 按仓库分流: + 本仓库走 `skip-changeset` 标签、不走空 changeset(空 changeset 在本仓库滞留发布), + 含读者可见生成产物时 dev 改选 changeset 亦对;objectui 无此标签 + —— 空 frontmatter changeset 即声明、即正确形态,⛔ 永不要求或铸出该标签,⛔ 别来回改。 +- **就地修了范围外的邻接缺陷? + **四条件逐条核(同缺陷类·机械·文件无他人认领·同门禁族), + 再核 claim 文件面同轮已修订、PR 正文点名该修并载证据;缺一条即判 REWORK。 +- **改动触及的每个包,`private: false` 即已发布 ⇒ 核 changeset 在不在**: + 判据是包的发布状态(读 `package.json`,十秒),不是改动大小, + 也不是「用户可见」的感觉判断 —— 那个判断 dev 在时间压力下会乐观化。 + ⛔ 缺了不入队 —— 合进 main 却永不发布,看起来像修好了,比不合更糟。 +- **测试证据**要有真实命令与通过输出,不是一句 tests pass。**测量类交付先看阳性对照**: + 对照本身失败 ⇒ 该读数记 INCONCLUSIVE,⛔ 不把它的「绿」当被测风险的证据入账。 +- **引 entry `.d.ts` 逐字节相同, + 必须同块带阳性对照**:该读数只判**名字集**(增删再导出名会移动 barrel 字节), + 对 barrel 已转发符号的**形状**恒无效 —— `export *` 与 `export type { X } from` 都不复述形状。 + 判据:同块点名**声明**该符号的模块那份移动了的产物,或本会移动它的具名探针; + 缺则记 INCONCLUSIVE。实测 2026-08-24(清 dist 与 tsbuildinfo 的三腿重建): + 声明包 `dist/base.d.ts` 随探针移动又移回,转发文件与 entry barrel 三腿全同;同日三处误用。 - **报告 `tests`/证据里有 git 本可回答的 API 读吗?**(dev 契约的读序 git 先行) 判据:MCP `list_issues`/`search_issues` 一类 GraphQL 读,或重跑派发词已下发的去重读数 —— fetch 之后本地 git 就答得了文件内容、diff、提交史与分支态。⛔ 不因此判 REWORK,ACCEPT 照给,但把这条记进 ACCEPT 评论:复核不记它,退化就没有任何地方看得见。 -- **CI 收敛读数只属于复核侧**(维护者 2026-08-10 裁定;dev 的契约是草稿 PR 时点交报,报告里 - gate `in_progress` 是诚实读数、预期内常态):翻 ready / 挂 auto-merge / 入队前亲核 Lint & Repo Gates - 与 TypeScript Type Check 两个 job 的 `conclusion` 已为 `success`(门禁族跑在其内),⛔ 不因报告写 - 了「本地绿」跳过;两 job 只是 required 地板,入队资格另要求 PR 全部 check 全绿(主文件条 - 款),各仓真绿跑法与 CI 日志看不见的门禁见 `true-green.md`。收敛期转红走补丁轮 (SendMessage - 续派原 dev —— 那是这笔交换已付过的价钱,不是 REWORK 的理由;红着合并才是)。重量级卡 - 可在派发令显式写「本单等 CI」。 -- **每个门禁读数先钉到 PR 的当前 head**:比对 run `head_sha` 与 PR `head.sha` —— 不一致 - 的是死提交读数,绿与红**双向都不入账**(旧 head 的绿把「新推送未验」读成「消费者干 - 净」,旧 head 的红把已修掉的缺陷重新挂回 PR);⛔ 非当前 head 上的 `cancelled` 零动作、 - 永不重跑 —— 新推送自带全套 run,重跑只会给绿 PR 挂一个已修缺陷的假红。 -- **dev 本地跑的门禁并集,同样先钉 head —— 同一条纪律**:契约要求**最后一次提交之 - 后**跑并集、把 `git rev-parse --short HEAD` 抄进报告与 PR 正文;与 PR 当前 - `head.sha` 比一次,对不上即死树读数、**双向都不入账**;没抄 ⇒ 按**没有读数**处理,以门禁 - job 结论为准。复核后又推提交而 HEAD 未动 ⇒ 补跑并集(至少棘轮族)再更报告。 -- **收益穿过必经边界之后还在吗?** 判据(不是每单都做):价值主张依赖下游如实转发 - (HTTP 错误信封、序列化、日志汇聚、跨进程传输)⇒ 至少端到端验一次收益在边界之后 - 仍在 —— 精心写的拒收正文可能被 4xx 直通层整条替换。 -- **裁决实施 PR:旧立场的 pin 全仓翻转了吗?** grep 消费层(REST 信封测试、 - objectql、runtime)确认旧立场零拷贝,**且**真正非法形状的拒收断言仍逐字在(派发 - 侧两句的对账)。 -- **拒收类用例的绿,是不是「它抛了」的绿?** 判据:验收点含「应当被拒收」。抽查 - diff 里的拒收用例有没有断言 `code` 与 `status`(ADR-0112 信封)—— 只写 - `toThrow()` / `rejects.toThrow()` 的用例,在未修实现本就抛裸 Error 的那一族上恒 - 绿,证不了拒收;缺断言判 REWORK 补齐,不接受绿色输出。 -- **「N 个包全绿」问清方向与时序**,否则不算清扫证据。判据:含跨包签名收窄/导出类 - 型变更/契约收紧。两问:(1) filter 用的是**前缀** `'...pkg'`(下游消费者)还是后 - 缀 `'pkg...'`(上游依赖)?方向没写就无法复核;(2) typecheck 之前**建过依赖闭 - 包**吗?没建则读的是陈旧 `dist/*.d.ts`,绿可能是假绿。两问都没答案 ⇒ 以全仓门禁 - 结论为准,或判 REWORK 要证据。 -- **dev 验证过 issue 的前提吗?** `premise_still_valid: false` 是**再分诊输入**不 - 是失败 —— 证伪 issue(或 PM 自己的派发框架)的报告是好运行。dev 纠正 PM 要**当 - 众认**:更正落在 PR/issue 评论,错前提的正文另立跟进卡,⛔ 不静默丢弃。 -- **报告清掉了它被要求停下的停条件?亲核证据再 ACCEPT** —— 与上条成对:证伪是好运 - 行,**清掉**停条件却不可自证(实测:dev 找到了停条件点名的消费者、推理着绕过去就 - 提交,靠一次无关停机才逼出复查)。判据是它报的证据面(搜了什么、找到什么)+ PM 自 - 己在 `origin/main` 上复核,⛔ 不接受结论散文 —— 绕过去的报告与守约的长得一样。 -- **验收判据本身也可被证伪**:dev 用测量推翻字面判据、换上等价或更强的不变量门禁 - = 好运行照 ACCEPT;但推翻过程必须写在 PR 正文并附 main 语料上的实测信噪比(误报 - 为零的证据),否则按 REWORK 要证据。 -- **`+0/-0` 不是空文件的证明**:NUL 字节让 git 当二进制渲染、还让整个文件对 grep - 隐身 —— 先疑 NUL,以 blob 定论(`git show : | wc -l`),要求源侧写转 - 义序列不写原始字节。 -- **以「死代码/不可达」为由的删除,PM 在 `origin/main` 上自己核一次引用面再 - ACCEPT**(带引号精确名、查声明式)——「这是死代码」是断言不是 diff 里的事实;删 - 除比修改难回滚,而这一查只花十秒。 +- **CI 收敛读数只属于复核侧**(维护者 2026-08-10 裁定;dev 的契约是草稿 PR 时点交报, + 报告里 gate `in_progress` 是诚实读数、预期内常态): + 翻 ready / 挂 auto-merge / 入队前亲核 Lint & Repo Gates 与 TypeScript Type Check 两个 job 的 `conclusion` + 已为 `success`(门禁族跑在其内),⛔ 不因报告写了「本地绿」跳过;两 job 只是 required 地板, + 入队资格另要求 PR 全部 check 全绿(主文件条款),各仓真绿跑法与 CI 日志看不见的门禁见 + `true-green.md`。收敛期转红走补丁轮 (SendMessage 续派原 dev —— 那是这笔交换已付过的价钱, + 不是 REWORK 的理由;红着合并才是)。重量级卡可在派发令显式写「本单等 CI」。 +- **每个门禁读数先钉到 PR 的当前 head**:比对 run `head_sha` 与 PR `head.sha` + —— 不一致的是死提交读数,绿与红**双向都不入账**(旧 head 的绿把「新推送未验」 + 读成「消费者干净」,旧 head 的红把已修掉的缺陷重新挂回 PR);⛔ 非当前 head 上的 `cancelled` + 零动作、永不重跑 —— 新推送自带全套 run,重跑只会给绿 PR 挂一个已修缺陷的假红。 +- **dev 本地跑的门禁并集,同样先钉 head —— 同一条纪律**: + 契约要求**最后一次提交之后**跑并集、把 `git rev-parse --short HEAD` 抄进报告与 PR 正文;与 + PR 当前 `head.sha` 比一次,对不上即死树读数、**双向都不入账**;没抄 ⇒ 按**没有读数**处理, + 以门禁 job 结论为准。复核后又推提交而 HEAD 未动 ⇒ 补跑并集(至少棘轮族)再更报告。 +- **收益穿过必经边界之后还在吗?** 判据(不是每单都做):价值主张依赖下游如实转发(HTTP + 错误信封、序列化、日志汇聚、跨进程传输)⇒ 至少端到端验一次收益在边界之后仍在 + —— 精心写的拒收正文可能被 4xx 直通层整条替换。 +- **裁决实施 PR:旧立场的 pin 全仓翻转了吗?** grep 消费层(REST 信封测试、objectql、 + runtime)确认旧立场零拷贝,**且**真正非法形状的拒收断言仍逐字在(派发侧两句的对账)。 +- **拒收类用例的绿,是不是「它抛了」的绿?** 判据:验收点含「应当被拒收」。 + 抽查 diff 里的拒收用例有没有断言 `code` 与 `status`(ADR-0112 信封)—— + 只写 `toThrow()` / `rejects.toThrow()` 的用例,在未修实现本就抛裸 Error 的那一族上恒绿, + 证不了拒收;缺断言判 REWORK 补齐,不接受绿色输出。 +- **「N 个包全绿」 + 问清方向与时序**,否则不算清扫证据。判据:含跨包签名收窄/导出类型变更/契约收紧。 + 两问:(1) filter 用的是**前缀** `'...pkg'`(下游消费者)还是后缀 `'pkg...'`(上游依赖)? + 方向没写就无法复核;(2) typecheck 之前**建过依赖闭包**吗?没建则读的是陈旧 `dist/*.d.ts`, + 绿可能是假绿。两问都没答案 ⇒ 以全仓门禁结论为准,或判 REWORK 要证据。 +- **dev 验证过 issue 的前提吗?** `premise_still_valid: false` + 是**再分诊输入**不是失败 —— 证伪 issue(或 PM 自己的派发框架)的报告是好运行。 + dev 纠正 PM 要**当众认**:更正落在 PR/issue 评论,错前提的正文另立跟进卡,⛔ 不静默丢弃。 +- **报告清掉了它被要求停下的停条件?亲核证据再 ACCEPT** —— 与上条成对:证伪是好运行, + **清掉**停条件却不可自证(实测:dev 找到了停条件点名的消费者、推理着绕过去就提交, + 靠一次无关停机才逼出复查)。判据是它报的证据面(搜了什么、找到什么)+ + PM 自己在 `origin/main` 上复核,⛔ 不接受结论散文 —— 绕过去的报告与守约的长得一样。 +- **验收判据本身也可被证伪**:dev 用测量推翻字面判据、 + 换上等价或更强的不变量门禁 = 好运行照 ACCEPT;但推翻过程必须写在 + PR 正文并附 main 语料上的实测信噪比(误报为零的证据),否则按 REWORK 要证据。 +- **`+0/-0` 不是空文件的证明**:NUL 字节让 git 当二进制渲染、还让整个文件对 grep 隐身 + —— 先疑 NUL,以 blob 定论(`git show : | wc -l`),要求源侧写转义序列不写原始字节。 +- **以「死代码/不可达」为由的删除,PM 在 + `origin/main` 上自己核一次引用面再 ACCEPT**(带引号精确名、查声明式)——「这是死代码」 + 是断言不是 diff 里的事实;删除比修改难回滚,而这一查只花十秒。 - **卡的交付物含系统性 sweep 时**(退场审计、消费半径 grep、语料扫描一类), ACCEPT 评论把范围外产出**成组列出**并写明 sweep 判据,让分诊能一致地给整批定级。 diff --git a/.claude/skills/pm-dispatch/references/seat-post-protocol.md b/.claude/skills/pm-dispatch/references/seat-post-protocol.md index 0a8e9015a2..c38a489916 100644 --- a/.claude/skills/pm-dispatch/references/seat-post-protocol.md +++ b/.claude/skills/pm-dispatch/references/seat-post-protocol.md @@ -3,65 +3,66 @@ 出处与原则(一座位一贴、单写手、正文为权威)住主文件「座位贴协议」;本表是接管/ 移交/回收那一刻要查的**协议细则**。 -- **贴 = 座位**,标签 `pm:seat`,正文固定四段:**当前 PM | 继承台账 | 热文件串行 - 队 | 说明** —— 段段皆**现值**,没有一段随时间增长;范围与常设承诺是岗位说明,版 - 本化在 `lanes/.md`,「说明」段放一行指针(两裁决出处均在主文件);存量贴 - 由在任座位在下次写侧刷新时按四段收缩(⛔ 岗位说明 PR 不代改贴正文)。 -- **标题即状态板**:固定格式 `[PM seat] <座位名> — <状态>`,状态词表 - `🟢 `(在任)/ `🟢 Routine` / `⏳ vacant` / `⏸️ paused`。标题只放慢 - 状态(换班级频率);轮次、在飞、队列快照等快状态 ⛔ 不进标题,留在「说明」段。 - `label:pm:seat` 的列表页因此就是全舰队状态板。 -- **assignee = 在任 PM 的 GitHub 账号**;退场/回收时摘除,无 assignee = 空缺,与 - 标题互为校验。例外:Routine 座位(bot 身份通常不可被 assign)以标题为准。 +- **贴 = 座位**,标签 `pm:seat`,正文固定四段:**当前 PM | 继承台账 | 热文件串行队 | + 说明** —— 段段皆**现值**,没有一段随时间增长;范围与常设承诺是岗位说明, + 版本化在 `lanes/.md`,「说明」段放一行指针(两裁决出处均在主文件); + 存量贴由在任座位在下次写侧刷新时按四段收缩(⛔ 岗位说明 PR 不代改贴正文)。 +- **标题即状态板**:固定格式 `[PM seat] <座位名> — <状态>`, + 状态词表 `🟢 `(在任)/ `🟢 Routine` / `⏳ vacant` / `⏸️ paused`。 + 标题只放慢状态(换班级频率);轮次、在飞、队列快照等快状态 ⛔ 不进标题, + 留在「说明」段。`label:pm:seat` 的列表页因此就是全舰队状态板。 +- **assignee = 在任 PM 的 GitHub 账号**;退场/回收时摘除,无 assignee = 空缺, + 与标题互为校验。例外:Routine 座位(bot 身份通常不可被 assign)以标题为准。 - **「当前 PM」段登记三元**:GitHub 账号(`get_me` 自查)+ 会话 ID 或 Routine ID - + 上任时刻。审计/认领评论的**作者字段**是平台盖章、不可自述错的硬读数 —— 接管仲 - 裁与活性判定优先用它对账正文。 -- **读侧边界(接管与巡检)**:只读晚于正文最后编辑时间的评论(评论无界增长,读全评论是 - 纯 token 税;两个时刻都是平台盖章的硬读数,比对即得,批准出处在主文件)。 -- **班次叙事不进贴正文**:逐卡状态在卡与 PR 上本就必填,轮次合计走轮次报告;贴正 - 文按写侧刷新点(下方)编辑,⛔ 不逐事件追加(无界贴会超出单次读取上限)。 -- **接管压缩细则**:接任 PM 把交接的有效内容按四段模板重述为新正文,**编辑历史即 - 存档** —— 旧账留在上一版 body revision,审计评论带版本指针(哪一版、何时)。超 - 大贴由半状态巡查的 report-only 项浮出,不等读取失败。 -- **热文件串行队**(跨轮、跨班次的常设事实):文件 → 有序卡片清单 → 每张卡认领 - 的**区域**(并行判据在主文件:区域写不清就只能整文件串行)。 + + 上任时刻。审计/认领评论的**作者字段**是平台盖章、 + 不可自述错的硬读数 —— 接管仲裁与活性判定优先用它对账正文。 +- **读侧边界(接管与巡检)**:只读晚于正文最后编辑时间的评论(评论无界增长, + 读全评论是纯 token 税;两个时刻都是平台盖章的硬读数,比对即得,批准出处在主文件)。 +- **班次叙事不进贴正文**:逐卡状态在卡与 PR 上本就必填,轮次合计走轮次报告; + 贴正文按写侧刷新点(下方)编辑,⛔ 不逐事件追加(无界贴会超出单次读取上限)。 +- **接管压缩细则**:接任 PM 把交接的有效内容按四段模板重述为新正文, + **编辑历史即存档** —— 旧账留在上一版 body revision,审计评论带版本指针(哪一版、 + 何时)。超大贴由半状态巡查的 report-only 项浮出,不等读取失败。 +- **热文件串行队**(跨轮、跨班次的常设事实):文件 → 有序卡片清单 + → 每张卡认领的**区域**(并行判据在主文件:区域写不清就只能整文件串行)。 - **残余竞态补遗**(三招在主文件):贴正文是多席可写面(接管即换写手)⇒ 写后读回 **恒不降级**;新增座位贴(拆域)同样先查 `pm:seat` 索引再立贴。 -- **无心跳,活性判定两条路**:惰性半边在**接管冲突**时评估一次 —— Routine 座位查 - 调度器(`last_fired` / `next_run`),会话座位查最近一条产出评论的时间戳, - **>24h 无产出即可回收**(改贴正文 + 审计评论);常设半边是分诊轮的座位贴活性巡 - 查,同一判据(细则见 `dispatch-runbook.md`)。**⛔ 永不从贴的 `updated_at`/标题 - 推死活**:写侧只在轮次边界刷(下条),轮中陈旧是设计 —— 越忙的座位贴越显死(实 - 测:贴陈旧 18h 被报「疑似下班」的座位,15 张卡在飞、产出新鲜到分钟级)。可跑读 - 法:本车道 `pm:dispatched` 卡按 `updated_at` 降序一搜,或最近一条认领/ACCEPT/审 - 计评论的时间戳 —— 分钟级即活,贴怎么说都不算。 -- **写侧刷新点 = 轮次边界**:派发时、收班时、暂停/交接前 —— 接管场景是贴存在的理 - 由,边界刷足以覆盖;中途状态的承载见上「班次叙事」条(原话在主文件)。协议/结构 - 升级迁移状态、或巡检发现正文不符时,当场改正文 + 审计评论。Routine 座位的收尾简报也 - 落自己的座位贴(它是下一轮自退守卫的读数)。 -- **收班 = 状态 flush + 在飞显式安置,⛔ 不等于在飞归零**(维护者 2026-08-13 拍板;云卡与队列 - 尾巴是持久、GitHub 锚定的进程)。安置默认**离任留守**(下条);留不了的才热移交:在飞卡落 - **收单注记**(评审判据、落地步骤、当前状态)+ 点名接手看护者 —— 默认下任座位,在跑 - 云会话经 poke 触发器投递(⛔ 非 `SendMessage` 直投,见 runbook);看护只守落地,**评审判断不可外 - 包**。**收班序列**(维护者 2026-08-27 裁「落协议」):贴正文/标题刷新在先,**收班简报评论是 - 最终一笔**;继任的释放判据 = 简报在;标题滞后是可修半状态,坐席时顺手修,⛔ 不是阻塞。 -- **离任留守(linger)= 收班后的默认看护形态**(维护者 2026-08-27 裁「落协议」;提案片段: - 「立刻进行交接,并继续处理完手上的任务到合并」;「清标即落地」的延伸,谁评审 - 谁落地):离任 PM 可继续把在手项驱动到 MERGED;写面恰为**简报点名的项**(已 ACCEPT 待队列 - PR、落地中评审链载体),⛔ 不读队列、不新派发、不碰未点名卡,残余定时器同界;末尾巴 - 合并 ⇒ 贴上一条尾清注记。继任立即坐席,点名集作围栏(声明式,同热文件串行队);标题词 - 表不扩,收班座位恒 `⏳ vacant`,留守登记(谁、哪些尾巴)= 「说明」段一行。 -- **交接收尾清单(退场序列,漏一步就是留残缺现场)**:① 立即停止新派发;② 在手工件逐件 - 处置 —— 能收则收,收不完留守或热移交(⛔ 不为清零而等);③ 全量枚举本车道队列 + 决 - 策箱 + findings,形成接任台账;④ 贴正文改「⏳ vacant」+ 完整台账(前任会话 ID、注销时间、 - 队列快照、**热文件串行队**、跨车道备忘);⑤ 收班简报/审计评论存档(最终一笔;接任指 - 引:`/pm-dispatch 接手` + 先读座位贴);⑥ `list_triggers` 清点本会话全部自设定时器,逐个清理、 - 随移交物转交(移交中 PR 的定时器随 PR 走)或随留守保留(只触点名项);⑥ʹ 本座位派出的 - dev 会话由**离任 PM 自己**逐个 `archive_session`,归档义务**不可移交**(会话句柄是账号作用域 - 的,细则见 `dispatch-runbook.md`);确须留跑的会话在座位贴里点名、写明「归档不随交接转移」 +- **无心跳,活性判定两条路**:惰性半边在**接管冲突**时评估一次 —— Routine 座位查调度器 + (`last_fired` / `next_run`),会话座位查最近一条产出评论的时间戳,**>24h 无产出即可回收** + (改贴正文 + 审计评论);常设半边是分诊轮的座位贴活性巡查,同一判据(细则见 + `dispatch-runbook.md`)。**⛔ 永不从贴的 `updated_at`/标题推死活**:写侧只在轮次边界刷(下条), + 轮中陈旧是设计 —— 越忙的座位贴越显死(实测:贴陈旧 18h 被报「疑似下班」 + 的座位,15 张卡在飞、产出新鲜到分钟级)。可跑读法:本车道 `pm:dispatched` 卡按 `updated_at` + 降序一搜,或最近一条认领/ACCEPT/审计评论的时间戳 —— 分钟级即活,贴怎么说都不算。 +- **写侧刷新点 = 轮次边界**:派发时、收班时、暂停/交接前 —— 接管场景是贴存在的理由, + 边界刷足以覆盖;中途状态的承载见上「班次叙事」条(原话在主文件)。 + 协议/结构升级迁移状态、或巡检发现正文不符时,当场改正文 + 审计评论。 + Routine 座位的收尾简报也落自己的座位贴(它是下一轮自退守卫的读数)。 +- **收班 = 状态 flush + 在飞显式安置, + ⛔ 不等于在飞归零**(维护者 2026-08-13 拍板;云卡与队列尾巴是持久、GitHub 锚定的进程)。 + 安置默认**离任留守**(下条);留不了的才热移交:在飞卡落**收单注记**(评审判据、 + 落地步骤、当前状态)+ 点名接手看护者 —— 默认下任座位,在跑云会话经 poke 触发器投递 + (⛔ 非 `SendMessage` 直投,见 runbook);看护只守落地,**评审判断不可外包**。**收班序列** + (维护者 2026-08-27 裁「落协议」):贴正文/标题刷新在先,**收班简报评论是最终一笔**; + 继任的释放判据 = 简报在;标题滞后是可修半状态,坐席时顺手修,⛔ 不是阻塞。 +- **离任留守(linger)= 收班后的默认看护形态**(维护者 2026-08-27 裁「落协议」; + 提案片段:「立刻进行交接,并继续处理完手上的任务到合并」;「清标即落地」的延伸, + 谁评审谁落地):离任 PM 可继续把在手项驱动到 MERGED;写面恰为**简报点名的项**(已 ACCEPT + 待队列 PR、落地中评审链载体),⛔ 不读队列、不新派发、不碰未点名卡,残余定时器同界; + 末尾巴合并 ⇒ 贴上一条尾清注记。继任立即坐席,点名集作围栏(声明式,同热文件串行队); + 标题词表不扩,收班座位恒 `⏳ vacant`,留守登记(谁、哪些尾巴)= 「说明」段一行。 +- **交接收尾清单(退场序列,漏一步就是留残缺现场)**:① 立即停止新派发; + ② 在手工件逐件处置 —— 能收则收,收不完留守或热移交(⛔ 不为清零而等); + ③ 全量枚举本车道队列 + 决策箱 + findings,形成接任台账;④ 贴正文改「⏳ + vacant」+ 完整台账(前任会话 ID、注销时间、队列快照、**热文件串行队**、跨车道备忘); + ⑤ 收班简报/审计评论存档(最终一笔;接任指引:`/pm-dispatch 接手` + 先读座位贴); + ⑥ `list_triggers` 清点本会话全部自设定时器,逐个清理、随移交物转交 + (移交中 PR 的定时器随 PR 走)或随留守保留(只触点名项);⑥ʹ 本座位派出的 dev + 会话由**离任 PM 自己**逐个 `archive_session`,归档义务**不可移交**(会话句柄是账号作用域的, + 细则见 `dispatch-runbook.md`);确须留跑的会话在座位贴里点名、写明「归档不随交接转移」 (⛔ 不留作接任者的欠账);⑦ 向维护者交最终报告(零建议与三类上报纪律在主文件)。 -- **epic 委托不入座位贴体系**(父单正文自带会话与领地,`label:pm:epic` 即全量索 - 引);座位贴只记常设座位,一件事只记一处。`packages/spec` 恒归 spec 座位。 +- **epic 委托不入座位贴体系**(父单正文自带会话与领地,`label:pm:epic` 即全量索引); + 座位贴只记常设座位,一件事只记一处。`packages/spec` 恒归 spec 座位。 ## 座位 Routine 创建细则 @@ -73,33 +74,32 @@ - 创建后**先手动 fire 一轮烟测**,判据取 **GitHub 上的产出**(标签写入/审计评论/ 座位贴编辑),不取「会话看起来起来了」;零产出即技术性失败,回滚: `delete_trigger` + 清空座位登记 + 失败注记。 -- 档位按职责挑,不按重要性挑;档位与 cron 是维护者在 UI 上的可调项,协议文本 ⛔ 不 - 复制其当前值 —— 座位贴才是现状。 +- 档位按职责挑,不按重要性挑;档位与 cron 是维护者在 UI 上的可调项, + 协议文本 ⛔ 不复制其当前值 —— 座位贴才是现状。 ## Epic 车道收尾与僵尸回收细则 -- 收尾四步一组(缺一步就是过夜半状态):最后一个 sub-issue 关闭 → 父单留总结评 - 论、关闭父单、摘 `pm:epic`(即从索引注销)、正文领地段标注收官。 -- 僵尸判据:父单正文有登记但整棵子树 ~48h 无任何认领/分支/PR 动静 → **分诊座位** - 在父单评论询问,再静默一窗后摘 `pm:epic` 收回子树;子树内仍在飞的认领按认领协议 - 由原认领者跟完。 -- 领地防撞是声明式的,不是机械保证 —— 撞上由合并队列兜底(代价是返工,不是脏数 - 据),所以领地声明越窄越诚实,越宽越要在父单正文里说明为什么。 +- 收尾四步一组(缺一步就是过夜半状态):最后一个 sub-issue 关闭 → 父单留总结评论、 + 关闭父单、摘 `pm:epic`(即从索引注销)、正文领地段标注收官。 +- 僵尸判据: + 父单正文有登记但整棵子树 ~48h 无任何认领/分支/PR 动静 → **分诊座位**在父单评论询问, + 再静默一窗后摘 `pm:epic` 收回子树;子树内仍在飞的认领按认领协议由原认领者跟完。 +- 领地防撞是声明式的,不是机械保证 —— 撞上由合并队列兜底(代价是返工, + 不是脏数据),所以领地声明越窄越诚实,越宽越要在父单正文里说明为什么。 ## 发版板运维细则(`target:`) -- 生产者:主仓 → 分诊座位;objectui / cloud → 各自整仓座位(维护者 2026-08-11 裁 - 定)。其余座位不打不摘,误判走上报;⛔ 三个生产者各扫各的 backlog。 -- 消费者:维护者的发版清单 = 三仓三条查询(`label:target: is:open` 各一 - 条);等价的 org 级搜索仅是备用写法。「归零 = 可发版」指三张板都空,单看主仓归零 - 不是。⛔「姊妹仓命中即误标」的旧读法已废除 —— 它教读者销毁真实阻塞的唯一证 - 据。 -- 鲜度:每 ~5 轮对板上 open 项做过时前提检查(首触定级改为每轮后,本板自持此节 - 奏),已修/不成立的摘牌 + 一句评论。 -- 发版时刻 = 清板,不是重扫:板上每条三选一 —— 修掉 / 摘牌(不再成立)/ **明示接 - 受带病发布**(摘标签 + accepted-for-GA 评论留痕,进 release notes 的 known - issues);三仓各自执行、读数回贴,⛔ 不因「前端仓/独立部署」整批默认接受。 -- 发版前置(维护者 2026-08-10 拍板):清板动手之前先取**一次** pin 读数(⛔ 一次即 - 止,不是重扫);pin 滞后 ⇒ console bump 单必须**已存在且已上板**,或按标准形态 - 明示接受;两者都不成立 ⇒ **不 cut**。这是「板已清空」与「console bump 已就位」 - 之间唯一的机械关联。 +- 生产者:主仓 → 分诊座位;objectui / cloud → 各自整仓座位(维护者 2026-08-11 裁定)。 + 其余座位不打不摘,误判走上报;⛔ 三个生产者各扫各的 backlog。 +- 消费者:维护者的发版清单 = 三仓三条查询(`label:target: is:open` 各一条); + 等价的 org 级搜索仅是备用写法。「归零 = 可发版」指三张板都空,单看主仓归零不是。 + ⛔「姊妹仓命中即误标」的旧读法已废除 —— 它教读者销毁真实阻塞的唯一证据。 +- 鲜度:每 ~5 轮对板上 open 项做过时前提检查(首触定级改为每轮后, + 本板自持此节奏),已修/不成立的摘牌 + 一句评论。 +- 发版时刻 = 清板,不是重扫:板上每条三选一 —— 修掉 / 摘牌(不再成立)/ + **明示接受带病发布**(摘标签 + accepted-for-GA 评论留痕,进 release notes 的 known issues); + 三仓各自执行、读数回贴,⛔ 不因「前端仓/独立部署」整批默认接受。 +- 发版前置(维护者 2026-08-10 拍板):清板动手之前先取**一次** pin 读数(⛔ 一次即止, + 不是重扫);pin 滞后 ⇒ console bump 单必须**已存在且已上板**, + 或按标准形态明示接受;两者都不成立 ⇒ **不 cut**。 + 这是「板已清空」与「console bump 已就位」之间唯一的机械关联。 diff --git a/.claude/skills/pm-dispatch/references/state-machine.md b/.claude/skills/pm-dispatch/references/state-machine.md index 093dce0d9d..ee3dd5e16d 100644 --- a/.claude/skills/pm-dispatch/references/state-machine.md +++ b/.claude/skills/pm-dispatch/references/state-machine.md @@ -9,18 +9,18 @@ - **`pm:queue` 腐化视界 3 天**:队列是唯一「等待不是一种状态」的态,越界即欠**一次显 式转换**(派发 / 转 `needs-user-decision` / 停放 / 撤单 / 改写前提),⛔ 不是排期。 - **生成物不分叉**:`skills/**` 生成器产物跑 `check-governed-merges.mjs --test`,⛔ 不按路径手判。 -- **`needs:contract-review` 双载体**:卡与交付 PR 两边都挂好、挂与清各一笔、两向都读回(被剥不 - 是红灯是放行);卡侧先挂而 PR 尚不存在是合法中间态,不是半写;**交接即标签** —— 只写 - 交接评论而不同笔挂标 = 空交接,收件箱只认标签。 +- **`needs:contract-review` 双载体**:卡与交付 PR 两边都挂好、 + 挂与清各一笔、两向都读回(被剥不是红灯是放行);卡侧先挂而 PR 尚不存在是合法中间态, + 不是半写;**交接即标签** —— 只写交接评论而不同笔挂标 = 空交接,收件箱只认标签。 ## `pm:on-hold` —— 重启条件、触发文件与放行双查 - **合法性**:仅当正文或评论带机器可读行 `Restart-when: closed #N`(由 `Blocked-by:` 的同一遍解锁扫描点火)或 `Restart-when: <一行可执行判据>` 时才合法; hold 评论带日期、理由、出处(维护者裁或座位定级,⛔ 不设第二个标签区分)。 -- **机会主义重启的触发文件**走同族正典行 **`Restart-touch: <仓内相对路径>`**(一行一 - 路径,大小写敏感、行锚定,与 `Blocked-by:`/`Restart-when:` 同双通道;值须为 tracked - 文件)—— 喂巡查 H17 的触发文件索引;存量 hold ⛔ 不迁移、不产 finding。 +- **机会主义重启的触发文件**走同族正典行 **`Restart-touch: <仓内相对路径>`**(一行一路径, + 大小写敏感、行锚定,与 `Blocked-by:`/`Restart-when:` 同双通道; + 值须为 tracked 文件)—— 喂巡查 H17 的触发文件索引;存量 hold ⛔ 不迁移、不产 finding。 - **放行双查(两查皆机械、零判断)**:① 只对**最近一次** `pm:on-hold`/`pm:blocked` 转换评论的条 件放行,⛔ 永不对更早的 blocker;② 该评论之后卡上有**更新的 merged PR** ⇒ 拒绝放行。 @@ -32,8 +32,8 @@ - **工已完、PR 被外部门禁缺陷卡住者同用本态,⛔ 不设新标签**:`Blocked-by:` 指向门禁卡,正文 加机器可读行 `Unlock-action: re-check PR #M`(**只认此一值**,别的静默回落重派,散文另起行),解 锁扫描改出口为「重查该 PR 落地」,⛔ 永不给完工卡重派 dev;停放 PR 正文须点名门禁卡。 -- **上游已关 ⇒ 先重新推导再决定**:改判是否有**新**阻塞并改写该行,⛔ 不反射式放行;正 - 文是正典家 —— 新 blocker 停评论、正文留已关旧目标,巡查报 stale 并要求迁回。 +- **上游已关 ⇒ 先重新推导再决定**:改判是否有**新**阻塞并改写该行,⛔ 不反射式放行; + 正文是正典家 —— 新 blocker 停评论、正文留已关旧目标,巡查报 stale 并要求迁回。 ## `pm:awaiting-maintainer` 与 `pm:retriage` —— 出口、挂/摘两方 diff --git a/.claude/skills/pm-dispatch/references/true-green.md b/.claude/skills/pm-dispatch/references/true-green.md index 1f7b58c854..e89bcfc5e3 100644 --- a/.claude/skills/pm-dispatch/references/true-green.md +++ b/.claude/skills/pm-dispatch/references/true-green.md @@ -19,9 +19,8 @@ ## objectui(前端) -- 正典跑法:**仅仓根 `pnpm test`**。vitest 守卫拒绝 package 目录内的运行 —— 那种跑法 - 曾假绿(无关 console 文件通过、目标用例 0 个在跑,被计为通过);守卫的拒绝是保护, - ⛔ 不绕。 +- 正典跑法:**仅仓根 `pnpm test`**。vitest 守卫拒绝 package 目录内的运行 —— 那种跑法曾假绿 + (无关 console 文件通过、目标用例 0 个在跑,被计为通过);守卫的拒绝是保护,⛔ 不绕。 - typecheck 脚本拼作 `type-check`(连字符);拼错脚本名的 `pnpm --filter` 匹配零脚本、 **退出码 0**、静默假绿 —— 核对输出确实回显了脚本名再信绿。 @@ -29,6 +28,6 @@ - 本地 preflight:`preflight-workspace-dist`(workspace 依赖的 dist 新鲜度守卫)—— 按其自身输出的提示跑,先建再测。 -- 严格区 `check-test-typecheck` 的失败**不以 `error TS` 行出现在 CI 日志**:turbo 汇总 - 只写 `#typecheck` failed —— 要看到台账消息必须本地跑该包自己的 `typecheck` 脚本;对 CI 日志 - grep `error TS` 的阴性读数在这一族上不成立。 +- 严格区 `check-test-typecheck` 的失败**不以 `error TS` 行出现在 CI 日志**:turbo + 汇总只写 `#typecheck` failed —— 要看到台账消息必须本地跑该包自己的 `typecheck` 脚本; + 对 CI 日志 grep `error TS` 的阴性读数在这一族上不成立。