Skip to content

Commit 212d613

Browse files
pm-dispatch: retire the fleet one-tooling-slot rule; a lane’s open P0/P1 is an undispatched one (#20967)
Fixes #20957 Clause-②: no ## What Retires the fleet one-`tooling`-slot rule from the pm-dispatch skill and states, in the two lines that gate a lane's p2/p3 `tooling` cards on its open P0/P1, that "open" means undispatched. The take-order (`execution-duties.md` 取卡全序 / 标签序) is now the only sequencing of tooling cards; a P0/P1 already in development holds no card back. Maintainer ruling — three messages to the `domain:skills` seat on 2026-09-30, verbatim (the card body carries them too): 1. 「spec工具卡的全舰队名额仍被 #20765 占着, 车道p0p1 是应该优先,但p0p1已经在开发中时,不应该卡住其他卡的派发,这个应该立卡优化」 2. 「或者简单点,直接撤掉这个规矩,只要优先派高优先级的卡片就可以」 3. 「这个应该是 skills卡片吧?你可以直接派发处理」 ## Edits — three skill files at net 0 lines each, plus one comment in `scripts/pm` - `.claude/skills/pm-dispatch/references/execution-duties.md` - `:22` deleted whole: 「舰队至多一张 `tooling` 卡带 `pm:dispatched`,第二张等;带 `Unblocks:` 者继承产品级不计数。」 Its inheritance half already has two other homes (item 3 below), so nothing of it is kept. - `:45` unchanged; the freed line is spent directly under it: 「开放 = 未派发(无 `pm:dispatched`、无 assignee);在飞的 P0/P1 不挡任何候选,只余取卡全序。」 — a reading of NORTH-STAR rule 3's 开放, not a change to it; the 取卡全序 / 标签序 lines that follow are the only sequencing left. - Why a line of its own rather than the in-line rewrite the card sketched: `check:pm-skill-ratchet` also budgets every non-table line at 120 bytes (`MAX_LINE_BYTES`), and `:45` is already 111 bytes; the new line is 113. - `.claude/skills/pm-dispatch/references/triage-duties.md:64` — 「所入车道队列 P0/P1 开着时,无解锁对象的 p2/p3 `tooling` 卡同样关。」 becomes 「所入车道队列 P0/P1 开着(= 未派发,在飞不算)时,无解锁对象的 p2/p3 `tooling` 卡同样关。」 (87 → 113 bytes). - `.claude/skills/pm-dispatch/SKILL.md:112` — the `tooling` label row: 「四具名读者 = 候选查询排除、首触即关、舰队一张在飞、普查半态行」 becomes 「三具名读者 = 候选查询排除、首触即关、普查半态行」 (row 227 → 206 bytes; pin 342). The four-axis frame block (`:240-:260`) is untouched; `check:skill-frame-sync` is green. - `scripts/pm/ensure-pm-labels.sh:282-289` — the `tooling` label's provenance comment mirrored the SKILL.md row ("Four named consumers … the fleet-wide one-tooling-card-in-flight count"); it now names the three that remain and says why there is no fleet count. Comment only: the label description (the `Unblocks:` / named-surface ENTRY condition) is unchanged. This file is outside the claim comment's named surface and inside the dispatch order's census clause ("whatever item 2's census finds inside `scripts/pm/**`"); declared here and in the report. ## Census (dispatch item 2) Trees: `.claude/**`, `AGENTS.md`, `scripts/pm/**`, `scripts/*.mjs`, read at `3693a1b50` (my base: `013f97df9` plus the merges since, none of which touched these files — `git log 013f97d..3693a1b` over the five files is empty). Named queries (`grep -rnE`): `一张在飞` 1 · `舰队至多` 1 · `第二张等` 1 · `tooling slot` 0 · one `tooling` 0 · `at most one .tooling` 0 — the hits are `SKILL.md:112` and `execution-duties.md:22` (matched twice), both retired here. Widened spellings: `one-tooling` 1 · `in-flight count` 1 · `dispatched fleet-wide` 1 · `fleet-wide` 22 (2 near `tooling`) · `名额` 0 · `第二张` 3 (2 unrelated: `dispatch-runbook.md:160`, `spec-property-retirement/SKILL.md:189`). - `scripts/pm/ensure-pm-labels.sh:286` — retired (above). - `scripts/pm/check-skill-line-ratchet.mjs:346-347` — "at most one tooling card is dispatched fleet-wide; and `tooling` becomes a first-touch label with four named readers": the provenance comment of a past ruled ceiling raise, recording what that raise paid for. History, not an operative rule; left as is. - `AGENTS.md`: 0 hits on every query; not edited. ## Item 3 — where the `Unblocks:` priority inheritance lives - `docs/NORTH-STAR.md:114`, 优先级 rule 3: 「…解锁产品 P0/P1 的仪器卡沿链继承其优先级。」 - `execution-duties.md:44`: 「阻塞项在飞 ⇒ 等:`pm:blocking` 在其车道排最前、等待者写该卡;p0/p1 优先级沿链传递。」 - (a third: `references/dispatch-runbook.md:162` 「父卡 p0/p1 ⇒ 阻塞卡同笔升同级,沿链重复。」) Both named homes carry it, so `:22` went whole. ## NORTH-STAR (item 8) Rule 3 reads 「本车道队列还有开放的 P0/P1 时,该车道不派 p2/p3 的工具卡、契约卫生卡」. The skill lines now say 开放 = 未派发 and 在飞不算 — an execution of 开放 (a card in development is no longer open in the queue), not a contradiction of it. `docs/NORTH-STAR.md` is not edited (Tier H). ## Line readings (item 6) | file | lines before | lines after | ceiling | widest table row (pin) | |---|---|---|---|---| | `.claude/skills/pm-dispatch/SKILL.md` | 319 | 319 | 319 | 342 → 342 (342); the edited row 227 → 206 | | `.claude/skills/pm-dispatch/references/execution-duties.md` | 183 | 183 | 183 | 0 (0) | | `.claude/skills/pm-dispatch/references/triage-duties.md` | 120 | 120 | 120 | 0 (0) | Net 0 per file; no untouched line re-wrapped; no ceiling row moved — `check-skill-line-ratchet.mjs` judges at-most ("over the ceiling ⇒ red") and only prints a hint on headroom, and every file still sits at headroom 0, so there is nothing to lower. The changed non-table lines are 113 and 113 bytes against the 120-byte per-line budget. ## Gates (local, at `2f2869206`) Derived with `node scripts/pm/dispatch-gates.mjs --commands` (no paths; the change set from the merge base): 36 families — the dispatch's 21 at `013f97df9` plus 15 `scripts/**` families pulled in by `ensure-pm-labels.sh`. All 36 run, all exit 0, exit codes recorded per line; reconciled with `--ran`: `✓ dispatch-gates --ran: 36 derived famil(ies) accounted for — 36 run, 0 NOT-MEASURED (a DERIVED zero — all 36 recorded an exit code and none of them is 3).` Verdict lines of the load-bearing ones: - `✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/execution-duties.md is 183 lines (ceiling 183; headroom 0).` · `…/triage-duties.md is 120 lines (ceiling 120; headroom 0).` · `…/SKILL.md is 319 lines (ceiling 319; headroom 0).` · `…/SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).` - `✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md; …)` - `✓ check-skill-id-lint: 34 file(s) clean (pattern /#[0-9]{3,}/g).` - `✓ check-governed-prose: 2 instruction surface(s) name all 6 registered governed surfaces (…) and claim no others.` - `✓ check-half-states self-test: 4912 cases pass.` - `✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 458 files / 1382 TS blocks judged clean by @objectstack/formula.` — after `pnpm --filter '@objectstack/lint...' build` under `os-verify-lock.sh` (`VERDICT command-exit 0 · held the lock 93s · waited 0s`). - Control-character self-scan of the four files: clean (grep exit 1); `pnpm check:nul-bytes` exit 0. CI-measured only: `check-governed-queue-guard` (reads the workflow event payload). ## Acceptance notes - **Stale fourth reader (dispatch item 4).** `SKILL.md:112` names 普查半态行 as a reader of `tooling`; `grep -n tooling scripts/pm/check-half-states.mjs` finds nothing (exit 1): none of its rows reads the `tooling` label, and `Unblocks` appears in that file only inside test fixture text. The row keeps 普查半态行 among the three named readers, as the order says; whether a half-state row for a `tooling` card open in `pm:queue` with neither line should exist, or the reader should leave the row, is a second question for the seat. carrier: the seat reviewing this PR; noted, not filed. - `ensure-pm-labels.sh:287-288` makes the same claim ("the census / half-state patrol, for which a tooling card open in pm:queue with neither line is a half-state"); left as is for the same reason. ## Changeset `.claude/**` ships in no package's `files[]`; `scripts/pm/**` is repo tooling and publishes nothing. No changeset; the seat applies `skip-changeset`. ## 维护者速读(草稿) **改了什么**:撤掉「全舰队同时只派一张 `tooling` 卡」的规矩;把「车道有开放 P0/P1 时不派 p2/p3 工具卡」里的「开放」写明为「还没派出去」,已在开发中的 P0/P1 不再挡住任何卡的派发。剩下的排序只有取卡全序:高优先级的候选先取。 **为什么改**:你 9 月 30 日的三条指示(原话见上)。这条规矩没有脚本强制,舰队实际也没守(同一时刻 7 张 `tooling` 卡在飞),却在本车道挡住了 p1 卡,直到你破例。 **风险与代价(含回滚)**:三个技能文件各净零行,不碰四轴决策框、不碰 NORTH-STAR。风险是工具卡可能并发更多、抢验证锁;锁自身已有深度等待兜底。回滚 = revert 本 PR 的两个 commit。 **席位意见**:(留空,席位定稿) **你要做的**:无需操作;Tier S,席位达档复核后落地。 --- _Generated by [Claude Code](https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5f6b63a commit 212d613

4 files changed

Lines changed: 8 additions & 7 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
109109
| `pm:blocking` | 有 open 下游依赖者(自 `Blocked-by:` 索引推导的缓存,⛔ 不手工挂);进选择全序 |
110110
| `pm:retriage` | 向分诊提问(改判、跨域 PR 指定车道、改路由、拆卡、裁 dev 报告留下的分叉),定车道与改路由限未派发卡,异议评论写明所求;与现行 `pm:*` 并存、⛔ 不摘原标;带本标签的 `pm:queue` 卡跳过派发 |
111111
| `finding` | 立卡三类内待首次定级,定级即离标;三类外关 not planned;不占队列不进收件箱 |
112-
| `tooling` | 修复落在门禁/脚本/workflow/技能/席位协议/PM 工具面而非产品包;分诊首触打,与 `domain:*` 同笔;四具名读者 = 候选查询排除、首触即关、舰队一张在飞、普查半态行 |
112+
| `tooling` | 修复落在门禁/脚本/workflow/技能/席位协议/PM 工具面而非产品包;分诊首触打,与 `domain:*` 同笔;三具名读者 = 候选查询排除、首触即关、普查半态行 |
113113
| `target:<major>` | 发版阻塞:每个 backlog 恰好一个生产者 |
114114
| `pm:epic`(父单或 sub-issue) | 已由 epic PM 保留;其它 PM 永不取;⛔ 永不与 `pm:queue` 同挂 |
115115
| `pm:seat` | 座位登记贴:协议载体,不是待分诊的工作 |

‎.claude/skills/pm-dispatch/references/execution-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
- 工作项面:卡片与分诊评论列的每条工作项逐条对树核验是否仍未完成,⛔ 不对卡核验。
2020
- 每条工作项写进派发令时都是 dev 首先证伪的前提。
2121
- `batch` 封顶全部子代理,等待不填槽;同批独立按文件面不相交判,⛔ 不按包、不按 check 名。
22-
- 舰队至多一张 `tooling` 卡带 `pm:dispatched`,第二张等;带 `Unblocks:` 者继承产品级不计数。
2322
- single-writer 路径 = `SINGLE_CLAIM_PATHS` 所枚举;共享其它路径是普通并发,后落地方解冲突。
2423
- 第 N 单派发前读 `scripts/pm/os-verify-lock.sh --status`:到达深度 ≥ `LOCK_DEPTH_HOLD`(= 2)即等。
2524
- 到达深度 = `queue N:` 行数 + 1(待派 dev 的运行算作到达);`state:` holder 与 `parked` 行不计。
@@ -43,6 +42,7 @@
4342
- 阻塞项无主 ⇒ 被挡席认领做掉,不限大小;在该卡走完整认领、尊重其热文件串行队。
4443
- 阻塞项在飞 ⇒ 等:`pm:blocking` 在其车道排最前、等待者写该卡;p0/p1 优先级沿链传递。
4544
- 取卡前置 = `docs/NORTH-STAR.md`「优先级」第 3 条:本车道队列开放 P0/P1 每次取卡现读。
45+
- 开放 = 未派发(无 `pm:dispatched`、无 assignee);在飞的 P0/P1 不挡任何候选,只余取卡全序。
4646
- 取卡全序:维护者直派插队卡(出处三件)> 契约面卡(判据见 `references/lanes/spec.md`)> 标签序。
4747
- 标签序:`priority:p0` > `pm:blocking` > 功能点位次 > `target:` 板上项 > p1 > p2 > p3 > 无级。
4848
- `pm:blocking` 级内先按解锁扇出(从 `Blocked-by:` 反向索引现算,⛔ 扇出数不落标签)。

‎.claude/skills/pm-dispatch/references/triage-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
- 定义项取北极星「做出来的是什么」或仪器卡的车队决定;无则关;`none` 非分诊缺口。
6262
- 清单项三态定级(会 fail / 步骤够不到 / 无项断言)与定级判据见 `references/filing-gate.md`。
6363
- 「无则关」= 首触即关 not_planned,带理由与入队两条件,⛔ 不定 p3、不 hold;下行同此。
64-
- 所入车道队列 P0/P1 开着时,无解锁对象的 p2/p3 `tooling` 卡同样关。
64+
- 所入车道队列 P0/P1 开着(= 未派发,在飞不算)时,无解锁对象的 p2/p3 `tooling` 卡同样关。
6565
- 路由是分诊的技术判断,⛔ 永不升级哪个仓的问题;父单是协调节点,永不派发。
6666
- 父单已有子结构的:父单队列标签即可,分诊逐个展开路由、补 `Blocked-by:` 排序。
6767
- 跨层功能点(≥2 层)立父单带 `area:*`+`pm:epic`+清单项级,逐层子单按 `Blocked-by:` 排。

‎scripts/pm/ensure-pm-labels.sh‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,14 @@ for R in objectstack-ai/objectstack objectstack-ai/objectui objectstack-ai/cloud
279279
# seat protocol or PM tooling file (scripts/**, .github/**, .claude/**,
280280
# packages/lint gate rules, packages/spec/scripts/**) rather than in a product
281281
# package. Triage applies it at FIRST GRADING, in the same label write as
282-
# domain:* and priority:*; a filer may pre-apply it. Four named consumers, all
282+
# domain:* and priority:*; a filer may pre-apply it. Three named consumers, all
283283
# in the pm-dispatch charter (SKILL.md 状态模型 row, 分诊座位职责 and 候选与批次):
284284
# the execution seat's candidate query, which excludes a tooling card carrying
285285
# neither an `Unblocks: #N` line nor a named published surface; the triage
286-
# first-touch close; the fleet-wide one-tooling-card-in-flight count; and the
287-
# census / half-state patrol, for which a tooling card open in pm:queue with
288-
# neither line is a half-state. It is in this five-repo loop on the rule stated
286+
# first-touch close; and the census / half-state patrol, for which a tooling
287+
# card open in pm:queue with neither line is a half-state. (No fleet-wide
288+
# in-flight count: the take-order alone sequences tooling cards.) It is in this
289+
# five-repo loop on the rule stated
289290
# beside priority:p0 above — the sweep that reads it is repo-parameterized
290291
# (PM_SWEEP_REPO) and first-touch grading is a five-repo triage duty. Measured
291292
# 2026-09-21 in objectstack, where the label is live on 44 queue cards: the

0 commit comments

Comments
 (0)