Skip to content

Commit 6ea8342

Browse files
pm-dispatch(execution): an empty-queue report is a per-card table with live labels and a named blocker; a remainder under ui/ is dispatched, never skipped (#28773)
<!-- claude-projects-attribution: {"github_login":"marchtian"} --> _Requested by **田騏** · [project thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSiHXKqxUqDPJKZyNHP7BoqTb)_ Fixes #28638 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:席位报「无卡可派」时必须逐卡列表(卡号、当轮现读的标签与 assignee、具名卡点),无具名卡点的卡就是候选,不得报「空」;余项落在 `ui/**` 的排队卡照常派发,不再当「UI 的」或「别的仓的」跳过。三个文件各改一两行,行数棘轮内付清。 - 为什么改:server 车道席位对着 7 张已定级、无人认领的卡报了「队列空」,只因每张卡剩下的一半是 UI;`ui/` 早已并入本仓,无任何外部阻塞。没有逐卡表,唯一的核对就是维护者亲手再跑一次查询。 - 风险与回滚:只改 `.claude/skills/pm-dispatch/**` 规则文本,无代码、无门禁改动;风险是付行数时删掉的五行(各自主节仍载同一规则,PR 正文逐行列出处)。回滚 = revert 本 PR。 - 先看:① `references/seat-lifecycle.md` 〈停止条件与待命〉新增三行(规则本体);② `references/execution-duties.md` 〈候选与批次〉新增两行(`ui/**` 余项与「他车道项」的边界);③ 五处删行的出处对照(本正文 What changes)。 - 两分钟验证:`pnpm check:pm-skill-ratchet && pnpm check:pm-skill-id-lint && pnpm check:skill-frame-sync && pnpm check:pm-governed-prose` 全绿;`wc -l` 三文件仍为 319 / 96 / 188。 - 需要你做的:Tier S(`.claude/**`):席位达档复核 PASS 后由席位落地;无需维护者动作。 ## What changes Scope is the three Wanted items of the card, text only, under `.claude/skills/pm-dispatch/**`. **Item 1 — an empty-queue report is a per-card table** (`references/seat-lifecycle.md` 〈停止条件与待命〉, three lines after 「队列空是待命非退场」): - 「队列空」is a per-card table, not a verdict: whoever hears "nothing to dispatch" (maintainer, coordinator, round report) gets every card the lane's queue filter returns at that moment. - Per card: the number, the labels and assignee read in the same turn (never a cached reading), and a named blocker. A card with no named blocker is a candidate, and the report may not say "empty". - One blocker vocabulary, not two: the inverse of the candidate definition in `execution-duties.md` (assigned, `needs-user-decision`, `pm:retriage`, the `tooling` exclusion), plus an open `Blocked-by:` line, a missing triage audit comment and a sibling seat's `Claim:`. - `SKILL.md` L74 (the self-exit line) now points at that section — a net-zero edit, 120 bytes. **Item 2 — a remainder under `ui/` is dispatched as normal** (`references/execution-duties.md` 〈候选与批次〉, two lines right after the self-split pair): - A queue card whose remaining work lands under `ui/**` is dispatched as normal: `ui/` is in this repo, so the same worktree, gates and merge queue apply; it is never skipped as "UI". **Item 3 — reconciliation with the self-split line and the `domain:ui` lane row**, measured on `origin/main` at 706ac52: - The lane table's `domain:ui` row does make `ui/**` a `domain:ui` surface — for *file ownership*. The same section says a `domain:*` label decides file ownership only and is never a queue unit (域车道 bullet 2), and the cross-boundary channels name "the claiming seat follows its own cross-boundary surface to the end" (域车道, 越界只四通道). `cross-repo-coordination.md` already ships a new spec key in the same PR as its first `ui/` reader. So dispatching the `ui/**` remainder from the lane that holds the card on its queue needs no change to the lane row, and no choice the maintainer did not make: the maintainer's own words (「写明 UI 已在 objectstack 的 `ui/` 里,剩下部分是 UI 的卡照常派」, approved with 「立卡更新skills」) pick dispatch over split-at-once, and the corrected seat then dispatched three of the seven cards that way. - The self-split line beside it (「排队卡含他车道项 ⇒ 发现席自拆」) is where "skip" and "dispatch" could sit side by side, so the second new line draws the boundary: a `ui/**` remainder is not "another lane's item" — this seat dispatches it and does not split; self-split applies only to a card-listed, independently landable item that lands wholly in another lane's tree outside `ui/**` (spec, skills, devx, cloud keep their own routing). The lane row is untouched (it sits at 332 of its 341-byte table-row cap, with nothing to add). **Paying the line ratchet** — every file stays at its ceiling (`SKILL.md` 319, `seat-lifecycle.md` 96, `execution-duties.md` 188), every edited line is within the 120-byte cap, and no line was re-wrapped to buy room. Five lines were deleted, each one restating a rule its main section still carries: | Deleted line | Where the rule still lives | |:--|:--| | `seat-lifecycle.md` 开轮互斥 「同 session 的 subagent dev 认领不触发自退,甄别靠分支」 | reading three in the same section is defined as the newest `Claim:` *not* from this session, which already excludes a same-session dev; `execution-duties.md` 认领 「`mode:subagent` 下 dev 与 PM 同 ID,身份看分支」 | | `seat-lifecycle.md` Epic 子树车道 「顺带发现只经立卡门:三类内缺陷才立…其余进 Acceptance notes 或座位贴」 | `SKILL.md` 报告契约 (dev files nothing; the seat files the three classes; the rest goes to Acceptance notes) and `triage-duties.md` 立卡门 | | `seat-lifecycle.md` 断粮与跨墙恢复 「权威的墙信号是失败本身:撞墙报文里的重置时刻在那一刻可得…」 | `platform-readings.md` 断粮检测与跨墙恢复 「撞墙报文 `limit reached, resets at HH:MM`,重置时刻只此刻可得」 | | `execution-duties.md` 候选与批次 「每轮每次唤醒首读本车道开着的 `priority:p0`,无人认领即同轮认领派发」 | `SKILL.md` 状态模型 `priority:p0` row (插队:同轮立即派发) and the 取卡前置 line above it (开放 P0/P1 每次取卡现读) | | `execution-duties.md` 候选与批次 「该假设以机制假设身份进派发令,被证伪就在同一张卡公开更正」 | `execution-duties.md` 派发 三分区 lines (PM 机制假设须实测、鼓励证伪;⛔ 不把假设写成裁决) and `os-dev.md` 三分区义务 (证伪照实报告) | No issue number is cited in the skill text (`pnpm check:pm-skill-id-lint` green). No package publishes from this diff: `skip-changeset`. ## Tests No code changes; the gates are the tests. Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on the final diff (merge base 706ac52, 3 paths, +6/−6) and run one by one with the exit code captured before any pipe: <details><summary>20 derived commands — see Verification for the exit codes</summary> ``` node scripts/check-closing-keyword-parity.mjs node scripts/check-closing-keyword-parity.mjs --self-test node scripts/check-comment-mask-corpus.mjs node scripts/pm/check-governed-queue-guard.mjs --self-test node scripts/pm/check-harness-current.mjs --self-test pnpm --filter @objectstack/lint run check:doc-formula-expressions pnpm check:agent-test-spelling pnpm check:cross-package-test-inputs pnpm check:doc-authoring pnpm check:driver-memory-census pnpm check:gitlink-declared pnpm check:nul-bytes pnpm check:pm-expected-skips pnpm check:pm-governed-merges pnpm check:pm-governed-prose pnpm check:pm-skill-id-lint pnpm check:pm-skill-ratchet pnpm check:refd-timer-probe pnpm check:skill-frame-sync pnpm check:watch-hint-literal ``` </details> ## Acceptance notes - `execution-duties.md` 认领 「部分落地…余项整树归他席 ⇒ 点名该席改标,拆分加 `pm:retriage`」 is the release-time route for a card whose remainder belongs to another seat's tree. It is not a "skip" (the card returns to `pm:queue` on this lane and is a candidate at the next refill under item 2), and the `domain:ui` seat may still relabel it, so both routes stand; it is outside this card's file surface and left as is. Noted, not filed. - The `domain:ui` lane row and `references/lanes/ui.md` 「跨层功能的 `ui/` 子单归本席」 speak of sub-cards that triage split per layer, not of an unsplit remainder; no edit needed. ## Verification Head sha and readings are in the `os-dev-report` comment on #28638 (session `session_017ihL2g7RyXa8ErM6GAkHyc`, seat `domain:skills#2`). Line budget after the edit: `SKILL.md` 319/319, `seat-lifecycle.md` 96/96, `execution-duties.md` 188/188; longest edited line 120 bytes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: marchtian <noreply@anthropic.com>
1 parent 2cba2eb commit 6ea8342

3 files changed

Lines changed: 8 additions & 8 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
7171
- 席位两形:Routine 席与项目席(会话是车队项目的线程);细则见 `references/seat-lifecycle.md`。
7272
- 项目席唤醒 = PR 订阅 + 每席一个自建自绑巡查 routine(总监席除外);⛔ 无 `send_later` 链。
7373
- 探针先行:fire 的第一动作是一次最便宜的车道盘点查询,⛔ 在它之前不读任何长文本。
74-
- 队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
74+
- 队列空(逐卡表见 `references/seat-lifecycle.md`)+ 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
7575
- 分诊席与车道席常驻,断粮即换账号重开该席与信箱;分诊席默认判断档;裁决归总监席。
7676
- 子代理裁决逐份过转录核验采信。
7777

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,30 @@
3939
- 阻塞解除后延后单重定价:前一单派发词必答 #X 变简单、变难、不必要或无影响。
4040
- 派发后一单前用该回答重读它的选项与成本,⛔ 不沿用立单时那份。
4141
- 在飞卡衍生三分:不修它验收过不过;in-scope ⇒ 父卡 sub-issue,认领席自有、优先级继承。
42-
- 该 sub-issue 与 main-red 锚卡各带域与级直接派发,绕过分诊;sweep 事后扫,重复关 `duplicate`。
4342
- 排队卡含他车道项 ⇒ 发现席自拆:新卡无 `domain:*`,首行 `carries item k of #N; #N keeps items …`。
4443
- 分诊首触定域可改判;拆出卡 ⛔ 不承父卡域(承域只及本车道 sub-issue),父卡余项照 `Fixes`。
44+
- 余项落 `ui/**` 的排队卡照常派:`ui/` 在本仓,同 worktree、门禁、合并队列;⛔ 不作 UI 跳过。
45+
- `ui/**` 余项不是他车道项:本席自派不拆;自拆只对整落 `ui/**` 外他车道树的卡自列独立项。
46+
- 派 `ui/**` 余项前,在飞求交加读 `domain:ui` 的 `pm:dispatched` 认领文件面;相交 ⇒ 串行或让行。
4547
- 自在飞派发升级出的卡首行一句:本卡承哪一半、父卡留哪一半;缺此行不入队不入箱。
4648
- 分诊预见的后续工作是一张卡,触发条件落地时立卡;⛔ 分诊一句话永不授权无卡编辑。
4749
- 阻塞项无主 ⇒ 被挡席认领做掉,不限大小;在该卡走完整认领、尊重其热文件串行队。
4850
- 阻塞项在飞 ⇒ 等:`pm:blocking` 在其车道排最前、等待者写该卡;p0/p1 优先级沿链传递。
4951
- 取卡前置 = `docs/NORTH-STAR.md`「优先级」第 3 条:本车道队列开放 P0/P1 每次取卡现读。
5052
- 开放 = 未派发(无 `pm:dispatched`、无 assignee);在飞的 P0/P1 不挡任何候选,只余取卡全序。
51-
- 每轮每次唤醒首读本车道开着的 `priority:p0`,无人认领即同轮认领派发,⛔ 不等下轮。
5253
- 取卡全序:维护者直派插队卡(出处三件)> 契约面卡(判据见 `references/lanes/spec.md`)> 标签序。
5354
- 标签序:`priority:p0` > `pm:blocking` > 功能点位次 > `target:` 板上项 > p1 > p2 > p3 > 无级。
5455
- `pm:blocking` 级内先按解锁扇出(从 `Blocked-by:` 反向索引现算,⛔ 扇出数不落标签)。
5556
- 全序每级现读/现算,零逐卡维护;同级先 `Bug` 再卡龄;无级/缺 `Path:` 轮报记分诊缺口。
5657
- 一车道多席按全序交替取卡:席 1 奇位、席 2 偶位;只为破交替才发 `split`;认领戳仲裁。
5758
- 解锁那一刻 PM 自己的判断最不可信:裁决收窄或关掉了那张卡是假设不是前提。
58-
- 该假设以机制假设身份进派发令,被证伪就在同一张卡公开更正。
5959

6060
## 认领(先认领后动工)
6161

6262
- 归属 = session ID,⛔ 不认作者字段;`Account:` 派生自 assignee,不等即半态、持卡席下笔补正。
6363
- 卡 assignee 归 PM,dev 恒不写;PR ⛔ 不派席位账号;在飞 PR 读 `head:claude/` 开 PR 正文点名的卡。
6464
- 部分落地(PR 带 `Refs #N (item k)`,⛔ 不 `Fixes`)即释放:合入同笔回 `pm:queue` + 清 assignee。
65-
- 同笔 `Release:` 行点名已落项与余项;余项整树归他席 ⇒ 点名该席改标,拆分加 `pm:retriage`。
65+
- `Release:` 行点名已落与余项;余项整落 `ui/**` 外他席树 ⇒ 点名其改标,拆分加 `pm:retriage`。
6666
- 派发前按序执行原子对:① Assign @me,并把 `pm:dispatched` 与摘 `pm:queue` 放进同一次标签写入。
6767
- step ① 之后获得 assignee 的直接弃出本批。
6868
- ② 认领评论照抄 SKILL.md 模板:`Branch:`、`Clause-②:`、`Metadata-protocol:` 各占一行且行首。

‎.claude/skills/pm-dispatch/references/seat-lifecycle.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
- 读数四:本车道 `state=CLOSED` 按 `updated_at` 降序首张带同席号 `Claim:` 卡的 session ID。
1111
- 评审链与总监席的笔迹是跨席作业不算占席;读数三、四只增加自退、永不清座位。
1212
- 总监席多场并行、无在任者:读数一、二与自退对它不成立;`domain:*` 席互斥照旧。
13-
- 同 session 的 subagent dev 认领不触发自退,甄别靠分支。
1413
- 收班简报是前任不再写的显式声明,是释放标记不是锁:简报即最新事件 ⇒ 立即坐席。
1514
- 维护者明示召唤是仲裁:有简报径直坐席;无简报才走保守确认,确认终止即坐席。
1615
- 互斥清 ⇒ fetch 后 SKILL.md、阶段 references、本席章程的最新触碰 sha 走 `git-history.mjs touch`。
@@ -58,7 +57,6 @@
5857
- `pm:epic` + `pm:queue` 同卡 = 半状态(保留兼移交);后者即已移交,取回走全套认领协议含重读。
5958
- 单车道仓(无 `domain:*`)开卡即认领合法;多车道仓域标签前置照旧,子树标记即保留。
6059
- 新立 spec/公共契约 sub-issue 照旧转 spec 座位队列,epic 侧写 `Blocked-by:`;衍生按三分留席。
61-
- 顺带发现只经立卡门:三类内缺陷才立,带查询与命中数;其余进 Acceptance notes 或座位贴。
6260
- 每次分流留一行审计评论;父单维护 checklist 汇总评论,决策仍锚在具体 sub-issue。
6361
- 收尾四步、僵尸回收与领地防撞细则见 `references/seat-post-protocol.md`。
6462

@@ -86,11 +84,13 @@
8684

8785
- 停:队列空或 `rounds` 用尽(仅一次性调用适用);一轮 ≥ 半数派发失败或升级;维护者打断。
8886
- 队列空是待命非退场:巡查跑到收班,只维护者明令停;⛔ 不按「N 次无变化即停」的习惯。
87+
- 队列空是逐卡表非结论:报无卡可派(维护者/协调者/轮报)即列队列过滤当刻返回的各卡。
88+
- 逐卡:卡号、同轮现读标签与 assignee(⛔ 不用缓存)、具名卡点;无卡点即候选,⛔ 不得报空。
89+
- 卡点一份词表:候选定义反面(`execution-duties.md`),open `Blocked-by:`、无分诊审计、他席 `Claim:`。
8990
- 巡查每轮探针后读信箱、认领满 `batch`,跑待命五项;间隔按 `execution-duties.md` 收集节②。
9091
- 待命五项各以其主节为准,⛔ 此处不另抄:findings 配合;`pm:blocked`/`pm:on-hold` 解锁扫描。
9192
- 在飞/已入队 PR 跟到 MERGED;决策箱仅在报告中列出 ⛔ 不 nag;跨车道备忘跟进。
9293

9394
## 断粮与跨墙恢复(5 小时用量墙)
9495

95-
- 权威的墙信号是失败本身:撞墙报文里的重置时刻在那一刻可得、事前查不到,记下来。
9696
- 恢复 playbook 链既有规则:逐个探在飞云卡 → 直接验收兜底或 transcript 复活 → 照常跑轮。

0 commit comments

Comments
 (0)