diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index 379f8b07e9..d13a952ebd 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -54,7 +54,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 | `triage` | 以分诊座位身份运行(只扫/分类/路由,永不认领) | — | | ``(如 `spec`、`skills`) | 以该 `domain:*` 车道的执行座位身份运行 | — | | `epic:#` | 以父单 #n 的 epic PM 身份运行(见 Epic 子树车道 节) | — | -| `director` | 以项目总监席身份运行(人工召唤;四职见 升级与决策 节与 `references/lanes/director.md`) | — | +| `director` | 以项目总监席身份运行(人工召唤;三职见 升级与决策 节与 `references/lanes/director.md`) | — | | `label:` | backlog 过滤标签;`label:all` = 全部 open 未认领 | `pm:queue` | | `repo:` | 扫哪个仓的 backlog(单 issue 的落地仓看它自己的 `repo:*` 标签) | `objectstack-ai/objectstack` | | `batch:` | 同时在飞的 dev 上限 | 默认 `3`;`n` 的维护者天花板 `5` | @@ -114,6 +114,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 | `pm:blocking` | 有 open 下游依赖者(自 `Blocked-by:` 索引推导的缓存,⛔ 不手工挂);进选择全序 | | `pm:retriage` | 向分诊提问(改判、跨域 PR 指定车道、改路由、拆卡、裁 dev 报告留下的分叉),定车道与改路由限未派发卡,异议评论写明所求;与现行 `pm:*` 并存、⛔ 不摘原标;带本标签的 `pm:queue` 卡跳过派发 | | `finding` | 立卡三类内待首次定级,定级即离标;三类外关 not planned;不占队列不进收件箱 | +| `tooling` | 修复落在门禁/脚本/workflow/技能/席位协议/PM 工具面而非产品包;分诊首触打,与 `domain:*` 同笔;四具名读者 = 候选查询排除、首触即关、舰队一张在飞、普查半态行 | | `target:` | 发版阻塞:每个 backlog 恰好一个生产者 | | `pm:epic`(父单或 sub-issue) | 已由 epic PM 保留;其它 PM 永不取;⛔ 永不与 `pm:queue` 同挂 | | `pm:seat` | 座位登记贴:协议载体,不是待分诊的工作 | @@ -170,6 +171,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 仓不可达 ⛔ 不当查过了干净:在 issue 上贴出给对应座位的现成命令,等读数回贴再派。 - 读数与认领等座位文本恒带 UTC 取数时刻 `YYYY-MM-DDThh:mmZ`;树读数另带 ref/tip,无者按未取。 - 失效修法按序取:先删容许出错的构造,再让正确形态成唯一拼写,最后才加检查。 +- 门禁两次误报(假红、实测假绿、处方句点名不存在路径)⇒ 删肢或删门禁,PR 引两次测量。 +- 只有护产品落地或用户可见契约的门禁才立修复卡;门禁上「稳定 > 功能」= 更少零件。 - 自设定时器的文本以先重读状态开头,只写关键判据(若 X 则 Y),其余指针化。 - 定时器文本 ⛔ 不写结论、不含未经重读即可执行的祈使句。 - 放行认门禁 job 的结论(`completed: success`),⛔ 不认聚合读数。 @@ -337,7 +340,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 分类动作每张三选一,外加一个修复通道。 - ⛔ 不挂 `needs:contract-review`:随 draft PR 或 `Clause-②: yes` 认领;裁定写方向、给六态之一。 - 方向在 ADR/本卡裁决/不可重裁规则:贴 `check-prior-rulings.mjs` 的 `Prior rulings read:` 行,或不点。 -- `pm:queue` = 有具名落点或复现的具体缺陷,或范围明确的工具/门禁修复,无可问之事。 +- `pm:queue` = 有具名落点或复现的具体缺陷,无可问之事;⛔ 工具/门禁修复不由此进。 +- `tooling` 入 `pm:queue` 仅当首行带 `Unblocks: #N`(open 产品卡)或点名所护的已发布面。 - `pm:queue` 也收恢复不变量的 finding、test-only pin,与实现未被裁错的说明书脱节(修文档)。 - `needs-user-decision` = 设计卡、feature/契约形状提案、需要 appetite 的多周程序。 - 碰迁移形状或删已发布能力也进决策箱;说明书脱节不进:有裁定出处才是 (b),否则改文档。 @@ -346,6 +350,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - `finding` = 三类内待定级:(a) 可复现缺陷(复现或失败探针);(b) 违背已声明契约(引契约文); - (c) AI 写元数据会被运行时拒收或静默丢弃的陷阱;其余进 PR `## Acceptance notes`,⛔ 不立卡。 - (a) 的分界是不完整 vs 错误,不是文档 vs 代码:示例照抄即失败是 (a),漏列成员不是。 +- 门禁头注、self-test 文案与 `check-*` 处方句 ⛔ 非已声明契约;(b) 须用户或已发布包读得到。 - (c) 元数据 = 由写它的人以外的人存储并再作者化的键:React prop 不是,存储的视图配置是。 - 把作者引向运行时会兑现却让事情更糟的元数据的警告不在 (c) 内;记为边界,⛔ 不扩类。 - (a) 须今天可达,(c) 须具名生产者;观察、休眠、零拉动 ⛔ 不立卡、不进汇总卡、无配额。 @@ -360,9 +365,11 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 判据:违背已声明契约 ⇒ `Bug`,扩大接受集/公开面越出已声明 ⇒ `Feature`,其余 ⇒ `Task`。 - `Bug` 无具名落点或复现路径不入 `pm:queue`(标记补复现)。 - ⛔ 不回填存量 backlog 的 type;新卡即时打、存量卡下次碰到补。 -- 定级按北极星「优先级」1、2 条;首行 `Path: <定义项> | <清单项 id/缺项> | P<路步> | none`。 +- 定级按北极星「优先级」1–3 条;首行 `Path: <定义项> | <清单项 id/缺项> | P<路步> | none`。 - 定义项取北极星「做出来的是什么」或仪器卡的车队决定;无则关;`none` 非分诊缺口。 - 清单项会 fail 才算断,继承其 `priority`;缺项先补账本;⛔「有人在等」不是定级判据。 +- 「无则关」= 首触即关 not_planned,带理由与入队两条件,⛔ 不定 p3、不 hold;下行同此。 +- 产品仓 P0/P1 开着时,无解锁对象的 p2/p3 `tooling` 卡同样关。 - 路由是分诊的技术判断,⛔ 永不升级哪个仓的问题;父单是协调节点,永不派发。 - 父单已有子结构的:父单队列标签即可,分诊逐个展开路由、补 `Blocked-by:` 排序。 - 每张留一条英文审计评论(`Triage: lands in …; rationale: …`),可选带 `Size/model suggestion:` 行。 @@ -426,7 +433,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 ### 候选与批次 - 整车道一次读全,本地求交:`list_issues` 带 `labels: [domain:X]` + 最小字段拿回全车道 open 集。 -- 候选 = open、未 assign、无 `needs-user-decision`、无 `pm:retriage`。 +- 候选 = open、未 assign、无 `needs-user-decision`、无 `pm:retriage`;⛔ 排除两行皆无的 `tooling` 卡。 - 已排队父单的 open sub-issue 自动是候选,`pm:epic` 父单的子树除外。 - 每张候选读全文 + 全部评论,写派发词前做决策复读:评论读到最后一页。 - 维护者裁决逐字引入派发词裁决分区作约束,无则写明无裁决。 @@ -438,6 +445,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 工作项面:卡片与分诊评论列的每条工作项逐条对树核验是否仍未完成,⛔ 不对卡核验。 - 每条工作项写进派发令时都是 dev 首先证伪的前提。 - 并行度以 `batch` 封顶,等待不填槽;同批独立按文件面不相交判,⛔ 不按包、不按 check 名。 +- 舰队至多一张 `tooling` 卡带 `pm:dispatched`,第二张等;带 `Unblocks:` 者继承产品级不计数。 - single-writer 路径 = `SINGLE_CLAIM_PATHS` 所枚举;共享其它路径是普通并发,后落地方解冲突。 - 第 N 单派发前读 `scripts/pm/os-verify-lock.sh --status`:到达深度 ≥ `LOCK_DEPTH_HOLD`(= 2)即等。 - 到达深度 = `queue N:` 行数 + 1(待派 dev 的运行算作到达);`state:` holder 与 `parked` 行不计。 @@ -671,9 +679,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 ### 轮次报告与节奏 - 每轮向维护者打中文轮次报告(chat 通道):issue → 判决 → PR 链接 → 备注的表。 -- 报告加升级项、代裁清单(分诊)、awaiting a human merge 项、governed 合并审计清单。 -- 审计清单实跑 `node scripts/pm/check-governed-merges.mjs --since <上轮>`,⛔ 不凭记忆汇总。 -- 车道审计是早警;权威合并窗口与认定/回滚处置归总监席,见 `references/lanes/director.md`。 +- 报告加升级项、代裁清单(分诊)、awaiting a human merge 项。 - 报告含 `UNRECOGNISED` 行:对本轮门禁日志 grep `UNRECOGNISED` 逐行照录,`NOT APPLICABLE` 行也在内。 - 健康指标五个:可派发库存(open `pm:queue` 未认领及趋势);决策箱(待维护者数)。 - 决策箱指标还要点名带开放下游依赖的决策卡,从 `Blocked-by:` 反向索引现算。 @@ -764,7 +770,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - `AskUserQuestion` 只是在场加速器:仅当维护者在本会话 ~30 分钟内有过人类输入才可发。 - 每问必带推荐项,被 Skip 或长挂即转卡通道,⛔ 不重弹。 - 项目总监席:维护者在所在仓召唤 `/pm-dispatch director`;⛔ 无 Routine/cron;未回字 = 不在 = 停。 -- 四职 = `needs:contract-review` 事后审计、决裁勤务、维护者动作台账、governed 合并审计。 +- 三职 = `needs:contract-review` 事后审计、决裁勤务、维护者动作台账。 - 每场召唤把带席内 ACCEPT 的受管草稿呈为一批 ≤5 行决裁;批准与合并仍是维护者的点击。 - 总监席档位由维护者按项目人工定,每场记入摘要台账;⛔ 无档位硬门、无免档整理态。 - 总监席是唯一裁决者:决策箱、代裁与一类自裁只出自本席,⛔ 无子代理无自述。 @@ -786,7 +792,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 | `scripts/pm/check-skill-line-ratchet.mjs` | 本文件行数只降不升(`pnpm check:pm-skill-ratchet`);抬上限需维护者裁决引用在 PR 正文;⛔ re-wrap 不得用作筹行,新增以删减付账;不买内容的密度修复允许 | | `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,仅归因走查询) | +| `scripts/pm/check-governed-merges.mjs` | governed 面合并清单的 report-only 审计(事后防线;本地枚举零 API,仅归因走查询) | | `scripts/pm/dispatch-gates.mjs` | 文件面 → 该跑的门禁族(派发令取数) | | `scripts/pm/git-history.mjs` | 窗口化 commit 计数:回答或 REFUSE(浅 clone 对窗口化 `git log`/`rev-list` 以 exit 0 无警告答错);`historyHorizon()` 是只读谓词 | | `scripts/pm/os-regen-merge.sh` | 碰生成物 PR 的 merge 四步序(防静默吞并与锚点倒退) | diff --git a/.claude/skills/pm-dispatch/references/core-rules.md b/.claude/skills/pm-dispatch/references/core-rules.md index 4efc27146e..b7bbebfd3b 100644 --- a/.claude/skills/pm-dispatch/references/core-rules.md +++ b/.claude/skills/pm-dispatch/references/core-rules.md @@ -82,7 +82,7 @@ - sweep 扫全裸卡、队列卡缺域或缺定级、域卡缺 pm 状态,排除跟踪、停放与协议载体卡。 - 首触定级跑到清空 ⛔ 无总量预算、未跑完断点续跑;清得空最新优先,否则最老优先。 - 裸卡超过十五张则下一轮改域分批集中模式,每批不超过五张同族卡。 -- 有落点或可复现的缺陷、范围明确的工具修复与实现未被裁错的说明书脱节进 `pm:queue`。 +- 有落点或可复现的缺陷、实现未被裁错的说明书脱节进 `pm:queue`;工具卡另须带解锁行。 - 设计卡、契约形状提案、碰迁移形状或删已发布能力的进决策箱;无出处说明书脱节不进。 - 立卡限三类:今日可达可复现缺陷、契约违背、具名生产者陷阱;截断卡发修复指令不派。 - 三类边界:缺陷问错不问缺、文档同判;元数据须他人再作者化;引向更糟的警告在类外。 @@ -125,7 +125,7 @@ - 唯一例外:源码自述 pushed 上按设计而红、不跑 `merge_group`、评论记明门与因,三条全立。 - 跟到合并为止并每轮读队列成员资格与 `origin/main`;踢出按签名台账四分支处置。 - 合并即发布的仓无验证层不合并,落地判据是已发布且探测通过 ⛔ 不是 MERGED。 -- 每轮打中文轮次报告,含判决表、升级项、代裁清单、等人合项、受管合并审计与五指标。 +- 每轮打中文轮次报告,含判决表、升级项、代裁清单、等人合项与五指标。 - 收工点是会话内在飞归零、存档后立即派下一波 ⛔ 不等人闸;清空转待命而不是退场。 ## 断粮与跨墙恢复 - 权威的用量墙信号是失败本身,重置时刻只在撞墙那一刻可得,拿到就记下来。 @@ -144,7 +144,7 @@ - 方案逐轴过升级与决策段的四轴:业务需求、长远合理性、防 AI 写错、创业阶段聚焦。 - 推荐须逐轴给理由、长远权重不低于一半;有拉动荐长远终态一次付清,零拉动荐不扩散。 - 每张决策卡落卡即带标准四棱块;卡先于弹窗,被阻塞的执行卡同笔转 `pm:blocked`。 -- 项目总监席由人工召唤,未回字 = 不在 = 停;四职:复核审计、决裁、动作台账、合并审计。 +- 项目总监席由人工召唤,未回字 = 不在 = 停;三职:复核审计、决裁、动作台账。 ## 报告契约 - 终报 JSON 的权威形状住 `.claude/agents/os-dev.md`,⛔ 本协议不另存第二份。 - 前提被证伪且无 PR 是合法终报,当再分诊输入复核,⛔ 永不当失败派发。 diff --git a/.claude/skills/pm-dispatch/references/lanes/director.md b/.claude/skills/pm-dispatch/references/lanes/director.md index ebf93911fa..a725ebc48b 100644 --- a/.claude/skills/pm-dispatch/references/lanes/director.md +++ b/.claude/skills/pm-dispatch/references/lanes/director.md @@ -14,7 +14,7 @@ - 入口:维护者说处理决裁或处理 contract-review,或 `/pm-dispatch director`。 - 未回字 = 不在 = 停:维护者不在则本席不运行,⛔ 无巡检、审计、快照、聊天、卡评论。 - 回来后先补跑审计与重挂复位一次,再只发一行「批 #N 待字;箱内另有 K 张新到未呈」。 -- 开场读一次服役档记入会话审计行,读法见 `../platform-readings.md`;⛔ 不因档位拒裁停四职。 +- 开场读一次服役档记入会话审计行,读法见 `../platform-readings.md`;⛔ 不因档位拒裁停三职。 - 双射 carve-out:一张 `pm:seat` 座位贴,四段照旧;状态块逐场一行,各记己锚,⛔ 无占席人。 - 不占 `domain:*` 车道,范围按职责标签跨车道跨仓;永不认领 backlog、永不写码。 @@ -58,15 +58,6 @@ - 待您清单与待字索引随所属批只呈一次,⛔ 不逐轮重印;座位贴散文降为指针,标签即状态。 - 出口执行:核验动作确已发生,再摘标加证据评论同笔;出口条款见 `../state-machine.md`。 -## 职责四:受管合并审计 - -- 检测双层、处置单席:车道轮报 sweep 只作早警,权威合并窗口在本席。 -- 每场召唤实跑 check-governed-merges,`--since-ref` 锚上一场的 tips;403 归因逐条走 MCP 补齐。 -- 锚行住座位贴说明段;脚本零存储,自打印下一场参数,跑后新 tips 同笔记回。 -- INCOMPLETE(exit 2)照实报,⛔ 不作干净;清单并入决裁批次,一行一条认定 y 或 n。 -- 未认定条目 = 席位违规,同笔立 `needs-user-decision` 卡立案回滚,事后审计制。 -- ⛔ 不新增标签:枚举本地树推导零 API。⛔ 无 cron,节奏与停放同授权段。 - ## 与 skills 席的分界 - 改 skill、指令或治理文本归 skills 席;出裁决、清复审标、清点待人工清单归本席。 diff --git a/.claude/skills/pm-dispatch/references/lanes/skills.md b/.claude/skills/pm-dispatch/references/lanes/skills.md index bcc4eedc71..fdacb3441e 100644 --- a/.claude/skills/pm-dispatch/references/lanes/skills.md +++ b/.claude/skills/pm-dispatch/references/lanes/skills.md @@ -15,7 +15,6 @@ - 四维分析先于派发与复核。 - 规则层受管 PR 恒 draft 等维护者的字;flip 或 arm 前跑 `check-governed-merges --test` 带路径。 -- 轮报的受管合并审计清单带 `--since` 四仓实跑,⛔ 不凭记忆汇总。 - 档位从 `--tier` 推导引用;pm-dispatch 根恒契约复审档;条款②闸门照现行。 - 额度耗尽豁免的地板是默认判断档,⛔ 不再往下。 - 棘轮逐行付账,⛔ re-wrap 筹行;砍点逐条核幸存,被砍内容若在别处无家,砍掉就是丢规则。 diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index d78ac4eb18..4668a63382 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -332,7 +332,33 @@ export const CEILINGS = new Map([ // clause is refused on the state-machine precedent. Ruled content is not // growth (the 811 → 812 entry above). Landed count, headroom 0, same // convention. - ['.claude/skills/pm-dispatch/SKILL.md', 813], + // Raised 813 → 819 by the product-only-queue charter ruling — an ORDINARY + // raise under this map's own maintainer exit, ⛔ not a cross-file move. + // Maintainer, 2026-09-21, live PM chat with the director seat, verbatim and + // untranslated: 「205 否,天花板抬到 819」 — the second clause is this ruling + // (the first is batch #205 item 1, on a different card); recorded by the + // director on #19457, comment 5754521737. The content is the six ruled edits + // of #19457 (ruling batch #202, letter B, plus the audit-retirement directive + // 「受管合并审计 以后不需要了,浪费时间。」 landed as its edit 6): the dev queue + // becomes product-only and a `tooling` card enters `pm:queue` only with an + // `Unblocks: #N` line or a named published surface; triage closes at first + // grading; a gate that misfires twice is deleted rather than repaired; at most + // one tooling card is dispatched fleet-wide; and `tooling` becomes a + // first-touch label with four named readers. + // It could not be paid in place — measured over three rounds, not assumed: the + // cost went 9 → 8 → 6 as everything payable was paid (three rules folded into + // existing lines, the four readers folded into the length-exempt glossary ROW, + // the close rule folded onto the 「无则关」 clause a sibling PR had landed + // meanwhile, and edit 6's deletions gave two lines back); every ceilinged file + // in this map stands at headroom 0, so no reference file can absorb the rest; + // the six that remain are one ruled rule each, 78–120 bytes, and no two of them + // pair under the 120-byte cap; and a declared cross-file move is zero-sum by + // construction — the destination's raise may not exceed the source's net + // decrease — so it can fund a move but never new content. Ruled content is not + // growth (the 811 → 812 entry above). SKILL.md is not a CROSS_FILE_MOVES + // destination, so no `ruledRaises` record applies. Landed count, headroom 0, + // same convention. + ['.claude/skills/pm-dispatch/SKILL.md', 819], // Raised 223 → 244 by the triage reading-cost card (maintainer ruling // 2026-08-20, quoted in the raising PR): three mandated conventions land in // the runbook's triage sections. Landed count, headroom 0, same convention. diff --git a/scripts/pm/ensure-pm-labels.sh b/scripts/pm/ensure-pm-labels.sh index 9be245e956..5fa9b65154 100644 --- a/scripts/pm/ensure-pm-labels.sh +++ b/scripts/pm/ensure-pm-labels.sh @@ -275,6 +275,25 @@ for R in objectstack-ai/objectstack objectstack-ai/objectui objectstack-ai/cloud # entirely from objectui). gh label create pm:retriage -R "$R" -c d4c5f9 -d "Question for triage, answered each fire; coexists with the standing pm:* label; no dispatch" 2>/dev/null || true gh label create finding -R "$R" -c c2e0c6 -d "Recorded observation — held, not dispatchable until the findings triage round grades it" 2>/dev/null || true + # tooling marks a card whose fix lands in a gate, script, workflow, skill, + # seat protocol or PM tooling file (scripts/**, .github/**, .claude/**, + # packages/lint gate rules, packages/spec/scripts/**) rather than in a product + # package. Triage applies it at FIRST GRADING, in the same label write as + # domain:* and priority:*; a filer may pre-apply it. Four named consumers, all + # in the pm-dispatch charter (SKILL.md 状态模型 row, 分诊座位职责 and 候选与批次): + # the execution seat's candidate query, which excludes a tooling card carrying + # neither an `Unblocks: #N` line nor a named published surface; the triage + # first-touch close; the fleet-wide one-tooling-card-in-flight count; and the + # census / half-state patrol, for which a tooling card open in pm:queue with + # neither line is a half-state. It is in this five-repo loop on the rule stated + # beside priority:p0 above — the sweep that reads it is repo-parameterized + # (PM_SWEEP_REPO) and first-touch grading is a five-repo triage duty. Measured + # 2026-09-21 in objectstack, where the label is live on 44 queue cards: the + # object is GitHub's default `ededed` with an EMPTY description, because until + # this row nothing here named it — the exact drift the header describes, and + # one no rerun of the default mode can repair. The -d below is 100 characters, + # at the hard cap (check:pm-label-desc-cap). + gh label create tooling -R "$R" -c fbca04 -d "Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface" 2>/dev/null || true gh label create pm:epic -R "$R" -c 5319e7 -d "Reserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue" 2>/dev/null || true done