Skip to content

Commit 0c681c3

Browse files
os-zhuangclaude
andauthored
feat(agents): pm-dispatch 持续分诊职责 + 过时前提核查 + 进程纪律 (#4591)
* feat(agents): pm-dispatch backlog sweep duty + stale-premise triage checks + PID-only process discipline - Step 0: classifying the unlabeled backlog is a standing PM duty — auto-queue concrete/no-risk work, flag design cards and programs for the maintainer, request repair for sanitizer-truncated bodies. - Fetch step now requires reading issue comments and running a stale-premise check against recent main history before dispatch (three same-day cases: #4525, #4379, #4075 step 1). - os-dev resource discipline: never kill by process name; PID-scoped operations only (from the #3182 agent's pkill disclosure). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 * feat(agents): pm-dispatch cross-shard transfer protocol — work crosses shards via the target queue, PMs never do A sharded PM whose task needs a change in another shard's repo files it into the target repo's queue (pm:queue + source line) instead of dispatching across the line; dependencies via Blocked-by, follow-up chores belong to the consuming shard, and anything touching packages/spec transfers to the main-backlog PM. The queue label is the inter-PM channel — no direct PM-to-PM coordination needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 * feat(agents): pm-dispatch shard ownership registry — caretaker mode is explicit, never assumed A registry issue in the main backlog records which session owns which shard; taking over or handing off a shard is a comment there. Unowned shards may be caretaken by the main-backlog PM, but a registered shard ends caretaking immediately — in-flight claimed tasks finish under their claimant, everything else belongs to the new owner. Claim comments state the mode so registry and claims never disagree silently. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2382580 commit 0c681c3

3 files changed

Lines changed: 78 additions & 4 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
Internal agent tooling only (`.claude/` pm-dispatch backlog-sweep duty + stale-premise checks + process discipline) — releases nothing.

.claude/agents/os-dev.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ build/test runs OOM it.** Binding rules:
4949
4. **Clean up when done**: after the PR is up, remove your worktree
5050
(`git worktree remove <path> --force`) — leftover `node_modules` trees
5151
exhaust the container's disk, which fails as confusingly as OOM.
52+
5. **Never kill by process name.** `pkill -f vitest` (or any name-matched
53+
kill) can take down a parallel agent's run — AGENTS.md's server rule,
54+
applied to every process. Record the PID of what you start and operate
55+
on that PID only (`kill $PID`, liveness via `kill -0 $PID` — a
56+
`pgrep -f` pattern can match your own watcher and never terminate).
5257

5358
Definition of done, in order:
5459

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

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,45 @@ shared files, and the merge queue is one lane regardless. Scaling order:
114114
2. When one PM genuinely can't keep up: a second session takes a **whole
115115
repo** as its shard (`/pm-dispatch repo:objectstack-ai/objectui`) —
116116
file universes are disjoint by construction. A sharded PM states its
117-
shard in every claim comment and **never claims outside it**; cross-repo
118-
parent/sub-issue chains stay with the main-backlog PM.
117+
shard in every claim comment and **never claims outside it**.
119118
3. Multiple PMs on the SAME queue: prohibited — all cost, no throughput.
120119

120+
**Shard ownership is registered, never assumed.** A registry issue in the
121+
main backlog (`[PM] 分片分工登记表`) records which session owns which
122+
shard; a PM taking over a shard comments there as its FIRST action, and
123+
comments again when handing off. An unowned shard may be **caretaken** by
124+
the main-backlog PM (triage + dispatch), but the moment a shard is
125+
registered to another session, the caretaker stops dispatching into it —
126+
in-flight claimed tasks finish under whoever claimed them (the claim
127+
protocol makes the handoff collision-free), and everything else belongs to
128+
the new owner. State the mode in claim comments (「cloud 分片,主 PM 代管」
129+
vs a registered shard PM's own tag) so the registry and the claims never
130+
disagree silently.
131+
132+
**Cross-shard transfer protocol — work crosses shard lines, PMs never
133+
do.** When a sharded PM's task (or a sub-task of its parent issue) needs a
134+
change in another shard's repo:
135+
136+
- **Transfer via the target queue**: file the piece as an issue in the
137+
target repo with `pm:queue` and a source line (`Part of
138+
<owner/repo>#<n>`). The target shard's PM picks it up through its own
139+
backlog sweep — the queue label IS the inter-PM channel; PMs never need
140+
to talk directly, and never dispatch into a repo whose in-flight batch
141+
they cannot see (that is the same collision the same-queue ban exists
142+
for).
143+
- **Dependencies via `Blocked-by:`** on the waiting side; the waiting PM's
144+
batch selection skips it until the upstream merges.
145+
- **Follow-up chores belong to the consuming shard**: when the upstream
146+
change lands (say spec gained a key), the dependent-repo adaptation issue
147+
is filed by the PM of the repo that consumes it — it knows its surfaces.
148+
- **Shared contract surfaces have one owner**: anything touching
149+
`packages/spec` transfers to the main-backlog (objectstack) PM
150+
regardless of who needs it — only that PM sees the repo's in-flight
151+
batch and generated-baseline collisions.
152+
- Cross-repo parent/sub-issue chains as a whole stay coordinated by the
153+
main-backlog PM; sharded PMs coordinate only chains fully inside their
154+
shard.
155+
121156
**5. One board, no second tracker.** The pm labels above are the state
122157
machine; an org-level GitHub Project pulling issues/PRs from all three repos
123158
gives the maintainer a single view (filter by `repo:*` and `pm:*`). The PM
@@ -126,13 +161,43 @@ the loop resumable and the board honest.
126161

127162
## The round loop
128163

164+
### 0. Backlog sweep — classification is a standing duty, not a request
165+
166+
The maintainer does not pre-sort the backlog. On every round (and every
167+
idle check-in), sweep issues that carry no `pm:*` / `needs-user-decision`
168+
label and classify each:
169+
170+
- **Auto-queue (`pm:queue`)**: a concrete defect with a named location or
171+
repro; a scoped tooling/gate fix; a restore-invariant finding; a
172+
test-only pin. Nothing to ask — label it and it becomes dispatchable.
173+
- **Maintainer confirm (`needs-user-decision`)**: design cards, feature/
174+
contract-shape proposals, multi-week programs needing appetite and
175+
sequencing, anything touching stored-data migration shape or removing a
176+
shipped capability. The label alone is the inbox entry; the deep two-axis
177+
analysis is written when the card is actually taken up.
178+
- **Repair first**: a body truncated by GitHub's sanitizer (bare `<x>`
179+
swallows the rest at rest) cannot be dispatched — comment the repair
180+
instruction and move on.
181+
129182
### 1. Fetch candidates
130183

131184
List open issues matching the filter, excluding anything assigned or labeled
132185
`needs-user-decision`. **Open sub-issues of a matching parent are candidates
133186
too** — they inherit the parent's queue membership and need no label of their
134-
own. Read each candidate's full body — triage, batch selection (steps 2–3)
135-
and the dispatch prompt all need it.
187+
own. Read each candidate's full body **and its comments** — a comment may
188+
record that half the work already shipped (#4075's step 1 had been merged
189+
for three days; the claim went out without reading the comment that said
190+
so). Triage, batch selection (steps 2–3) and the dispatch prompt all need
191+
the full picture.
192+
193+
**Stale-premise check before every dispatch.** Issues describe the repo as
194+
of their filing date; main moves ~18 merges a day. Before dispatching,
195+
check the named files/subsystem against recent main history (`git log
196+
--oneline -20 -- <paths>`, or search merged PRs referencing the issue's
197+
keywords). Three same-day cases: #4525 (spec key landed 3 days before
198+
filing), #4379 (fix merged via #4459 with the exact proposed sketch),
199+
#4075 (step 1 shipped via objectui#3032). A dispatch that starts with "is
200+
this still true?" costs minutes; one that doesn't costs an agent-run.
136201

137202
### 2. Triage — routing is the PM's job, never the maintainer's
138203

0 commit comments

Comments
 (0)