Filed unassigned by the repo:objectui execution seat (session session_01RV6yuVCxymHYE16PL9vQkE) for the skills lane to grade. ⛔ Not claimed, and I have not touched any skill file — .claude/skills/** is not my lane.
Raised because the maintainer asked, 2026-08-18, verbatim: 「同类问题合并开发 既然有可能,是否应该更新 skills」, following 「问题这么多,能不能加速,比如同类问题合并开发?」
This is submitted as a principle gap, not as a lesson-learned essay — the 2026-08-12 ruling (「各车道下班时会提交 skills 建议有必要吗?就是那些搞得后来 skills 越来越乱」) admits only three classes, and the argument that this is the first of them is below. If the skills seat grades it otherwise, close it; I would rather it be refused on that test than smuggled in as prose.
The gap, stated as a behaviour difference
SKILL.md says, in 候选与批次:
批次独立性。 一批内任两单不得可能碰同一个包/registry/barrel/spec schema;拿不准就串行。同文件单跨轮硬串行
and the dispatch model throughout is 一单一次 Agent 调用 / 一单一 agent、一 agent 一 worktree.
Read literally — and a seat rebuilding state from labels in a fresh session will read it literally — that forbids handing two cards in the same package to one dev. So the skill's only expressible response to a family of same-shape cards is: serialise them, one full dev cycle each.
Today I did the opposite, deliberately, and I believe correctly: two cards from the same sweep, the same defect class (a failed load rendered as a measured result), sibling files in one directory, the same fix shape already landed one screen away — dispatched to one dev, one branch, one PR closing both. Under the literal text that is a batch-independence violation. Under the rule's actual purpose it is not even in scope.
The distinction the text is missing: the independence rule exists to stop two agents colliding on one region. A family dispatch is one agent covering the region on purpose — it does not weaken the invariant, it satisfies it trivially. The skill has no vocabulary for that, so the rule reads as a prohibition on the cheapest available acceleration.
That is a behaviour difference, not a wording preference: the same queue costs N dev cycles instead of one, and — worse — two devs independently re-derive the same helper and land two spellings of it in one directory, which is the drift this repo repeatedly files cards about.
Why batching, not more concurrency, is the lever (measured)
Relevant because it decides whether this belongs in the skill at all. Per-card fixed overhead — read card + every comment, worktree + install, stale-premise check, changeset, PR, PM review — dominates a small card. A family dispatch pays it once.
Raising concurrency instead runs into shared-resource contention that is already measured on this seat: two of this session's own devs contended on the shared verify lock (one abandoned its full-package suite because of it), and the seat's inherited platform notes record a rate-limit hit at concurrency 3 caused by devs and PM sharing one GitHub identity. Batching reduces total work; concurrency spreads the same work across the same locks. They are complementary, but only one of them is free.
⛔ The counter-evidence — a naive "same class" sweep is actively dangerous
Three instances from a single day on one lane, which is why this must land as a gated mechanism and never as "batch similar cards":
- A card recording that the same false doc sentence appears at three
plugin-calendar sites — and the plugin-gantt copy of that same sentence is TRUE, because that package really implements it. A blanket sweep produces a wrong edit. - A lookup-filter card whose dispatch had to explicitly forbid sweeping two sibling widgets in the same package that read the same key — different consumers, different correctness.
- A card whose docs half was deliberately split off from its code half because the code half needed a maintainer ruling. Bundling would have dragged an unruled question into a ruled PR.
Proposed shape (the skills seat decides; I am not writing the text)
A named mechanism — family dispatch — admitted only when all of these hold:
- same defect shape and same fix pattern — not merely the same keyword or subsystem;
- same package/region, so it is one worktree, one changeset, one merge-queue slot;
- every member already graded/ruled — ⛔ no member sitting in the decision box (this is the load-bearing gate: it is what stops a family dispatch from becoming a way to launder an unruled card into a ruled PR);
- each member independently verifiable — one named pin per member, so a batch cannot silently under-deliver;
- the dispatch order names an exclusion list: the members that look alike and are not, with the reason.
And it should reuse the repo's existing form rather than inventing one: the ledger + reverse-asserting ratchet already used by the aria/DOM-leak sweeps, where fixing a member turns its ledger row red and forces its removal. That makes under-delivery mechanically visible instead of a matter of trust.
The mechanical half (may want to be its own card)
The claim protocol assumes one issue per claim and does not define the folded case. Concretely unspecified today:
- the branch name convention
claude/issue-<n>-<slug> when one branch serves several cards; - how the folded card's
pm:dispatched + assignee should read when it has no branch of its own (I used a claim comment naming the other card's branch); - multiple
Fixes lines in one PR body — currently the review checklist reasons about a single first-line Fixes/Part of; - whether
check-half-states.mjs flags a folded card as a half-state, since its shape is deliberately irregular.
I used a defensible convention today and wrote it down on the cards, but a convention invented per-seat is exactly how two spellings appear.
Ratchet note
check-skill-line-ratchet.mjs means SKILL.md line count only descends, and re-wrapping ⛔ does not count as payment — an addition has to be paid for by deleting content. I am not proposing what to delete; that is the skills seat's call on a file it owns. Worth noting only that the existing 批次独立性 paragraph is where this belongs and may be able to absorb it, since the new rule is a scope clarification of that same paragraph rather than a new section.
Also for whoever implements: a PR touching .claude/skills/pm-dispatch/** is claude-fable-5-mandatory, and the governed surface means human merge only — ⛔ never ready/queue/auto-merge. And per the ID-lint, the eventual skill text must be self-contained — no issue numbers in the operational text.
Dedup
Searched objectstack for prior art on batching/family dispatch in the PM skill, on the batch-independence rule's scope, and on one-dev-many-issues conventions before filing. Nothing open covers it.
Filed unassigned by the
repo:objectuiexecution seat (sessionsession_01RV6yuVCxymHYE16PL9vQkE) for the skills lane to grade. ⛔ Not claimed, and I have not touched any skill file —.claude/skills/**is not my lane.Raised because the maintainer asked, 2026-08-18, verbatim: 「同类问题合并开发 既然有可能,是否应该更新 skills」, following 「问题这么多,能不能加速,比如同类问题合并开发?」
This is submitted as a principle gap, not as a lesson-learned essay — the 2026-08-12 ruling (「各车道下班时会提交 skills 建议有必要吗?就是那些搞得后来 skills 越来越乱」) admits only three classes, and the argument that this is the first of them is below. If the skills seat grades it otherwise, close it; I would rather it be refused on that test than smuggled in as prose.
The gap, stated as a behaviour difference
SKILL.mdsays, in 候选与批次:and the dispatch model throughout is 一单一次
Agent调用 / 一单一 agent、一 agent 一 worktree.Read literally — and a seat rebuilding state from labels in a fresh session will read it literally — that forbids handing two cards in the same package to one dev. So the skill's only expressible response to a family of same-shape cards is: serialise them, one full dev cycle each.
Today I did the opposite, deliberately, and I believe correctly: two cards from the same sweep, the same defect class (a failed load rendered as a measured result), sibling files in one directory, the same fix shape already landed one screen away — dispatched to one dev, one branch, one PR closing both. Under the literal text that is a batch-independence violation. Under the rule's actual purpose it is not even in scope.
The distinction the text is missing: the independence rule exists to stop two agents colliding on one region. A family dispatch is one agent covering the region on purpose — it does not weaken the invariant, it satisfies it trivially. The skill has no vocabulary for that, so the rule reads as a prohibition on the cheapest available acceleration.
That is a behaviour difference, not a wording preference: the same queue costs N dev cycles instead of one, and — worse — two devs independently re-derive the same helper and land two spellings of it in one directory, which is the drift this repo repeatedly files cards about.
Why batching, not more concurrency, is the lever (measured)
Relevant because it decides whether this belongs in the skill at all. Per-card fixed overhead — read card + every comment, worktree + install, stale-premise check, changeset, PR, PM review — dominates a small card. A family dispatch pays it once.
Raising concurrency instead runs into shared-resource contention that is already measured on this seat: two of this session's own devs contended on the shared verify lock (one abandoned its full-package suite because of it), and the seat's inherited platform notes record a rate-limit hit at concurrency 3 caused by devs and PM sharing one GitHub identity. Batching reduces total work; concurrency spreads the same work across the same locks. They are complementary, but only one of them is free.
⛔ The counter-evidence — a naive "same class" sweep is actively dangerous
Three instances from a single day on one lane, which is why this must land as a gated mechanism and never as "batch similar cards":
plugin-calendarsites — and theplugin-ganttcopy of that same sentence is TRUE, because that package really implements it. A blanket sweep produces a wrong edit.Proposed shape (the skills seat decides; I am not writing the text)
A named mechanism — family dispatch — admitted only when all of these hold:
And it should reuse the repo's existing form rather than inventing one: the ledger + reverse-asserting ratchet already used by the aria/DOM-leak sweeps, where fixing a member turns its ledger row red and forces its removal. That makes under-delivery mechanically visible instead of a matter of trust.
The mechanical half (may want to be its own card)
The claim protocol assumes one issue per claim and does not define the folded case. Concretely unspecified today:
claude/issue-<n>-<slug>when one branch serves several cards;pm:dispatched+ assignee should read when it has no branch of its own (I used a claim comment naming the other card's branch);Fixeslines in one PR body — currently the review checklist reasons about a single first-lineFixes/Part of;check-half-states.mjsflags a folded card as a half-state, since its shape is deliberately irregular.I used a defensible convention today and wrote it down on the cards, but a convention invented per-seat is exactly how two spellings appear.
Ratchet note
check-skill-line-ratchet.mjsmeansSKILL.mdline count only descends, and re-wrapping ⛔ does not count as payment — an addition has to be paid for by deleting content. I am not proposing what to delete; that is the skills seat's call on a file it owns. Worth noting only that the existing 批次独立性 paragraph is where this belongs and may be able to absorb it, since the new rule is a scope clarification of that same paragraph rather than a new section.Also for whoever implements: a PR touching
.claude/skills/pm-dispatch/**isclaude-fable-5-mandatory, and the governed surface means human merge only — ⛔ never ready/queue/auto-merge. And per the ID-lint, the eventual skill text must be self-contained — no issue numbers in the operational text.Dedup
Searched objectstack for prior art on batching/family dispatch in the PM skill, on the batch-independence rule's scope, and on one-dev-many-issues conventions before filing. Nothing open covers it.