From fe2510d4cba4c0a0fbfae7b96c490ac04ccb6d78 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 09:19:54 +0000 Subject: [PATCH 1/3] feat(agents): pm-dispatch backlog sweep duty + stale-premise triage checks + PID-only process discipline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 --- .changeset/pm-dispatch-triage-lessons.md | 4 +++ .claude/agents/os-dev.md | 5 ++++ .claude/skills/pm-dispatch/SKILL.md | 34 ++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .changeset/pm-dispatch-triage-lessons.md diff --git a/.changeset/pm-dispatch-triage-lessons.md b/.changeset/pm-dispatch-triage-lessons.md new file mode 100644 index 0000000000..6127cad648 --- /dev/null +++ b/.changeset/pm-dispatch-triage-lessons.md @@ -0,0 +1,4 @@ +--- +--- + +Internal agent tooling only (`.claude/` pm-dispatch backlog-sweep duty + stale-premise checks + process discipline) — releases nothing. diff --git a/.claude/agents/os-dev.md b/.claude/agents/os-dev.md index 6f67067ce3..5f351b529b 100644 --- a/.claude/agents/os-dev.md +++ b/.claude/agents/os-dev.md @@ -49,6 +49,11 @@ build/test runs OOM it.** Binding rules: 4. **Clean up when done**: after the PR is up, remove your worktree (`git worktree remove --force`) — leftover `node_modules` trees exhaust the container's disk, which fails as confusingly as OOM. +5. **Never kill by process name.** `pkill -f vitest` (or any name-matched + kill) can take down a parallel agent's run — AGENTS.md's server rule, + applied to every process. Record the PID of what you start and operate + on that PID only (`kill $PID`, liveness via `kill -0 $PID` — a + `pgrep -f` pattern can match your own watcher and never terminate). Definition of done, in order: diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index ec94231039..1a95269dea 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -126,13 +126,43 @@ the loop resumable and the board honest. ## The round loop +### 0. Backlog sweep — classification is a standing duty, not a request + +The maintainer does not pre-sort the backlog. On every round (and every +idle check-in), sweep issues that carry no `pm:*` / `needs-user-decision` +label and classify each: + +- **Auto-queue (`pm:queue`)**: a concrete defect with a named location or + repro; a scoped tooling/gate fix; a restore-invariant finding; a + test-only pin. Nothing to ask — label it and it becomes dispatchable. +- **Maintainer confirm (`needs-user-decision`)**: design cards, feature/ + contract-shape proposals, multi-week programs needing appetite and + sequencing, anything touching stored-data migration shape or removing a + shipped capability. The label alone is the inbox entry; the deep two-axis + analysis is written when the card is actually taken up. +- **Repair first**: a body truncated by GitHub's sanitizer (bare `` + swallows the rest at rest) cannot be dispatched — comment the repair + instruction and move on. + ### 1. Fetch candidates List open issues matching the filter, excluding anything assigned or labeled `needs-user-decision`. **Open sub-issues of a matching parent are candidates too** — they inherit the parent's queue membership and need no label of their -own. Read each candidate's full body — triage, batch selection (steps 2–3) -and the dispatch prompt all need it. +own. Read each candidate's full body **and its comments** — a comment may +record that half the work already shipped (#4075's step 1 had been merged +for three days; the claim went out without reading the comment that said +so). Triage, batch selection (steps 2–3) and the dispatch prompt all need +the full picture. + +**Stale-premise check before every dispatch.** Issues describe the repo as +of their filing date; main moves ~18 merges a day. Before dispatching, +check the named files/subsystem against recent main history (`git log +--oneline -20 -- `, or search merged PRs referencing the issue's +keywords). Three same-day cases: #4525 (spec key landed 3 days before +filing), #4379 (fix merged via #4459 with the exact proposed sketch), +#4075 (step 1 shipped via objectui#3032). A dispatch that starts with "is +this still true?" costs minutes; one that doesn't costs an agent-run. ### 2. Triage — routing is the PM's job, never the maintainer's From 27b62d5aae138130862dfd645f48f16d4eb86719 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 09:28:53 +0000 Subject: [PATCH 2/3] =?UTF-8?q?feat(agents):=20pm-dispatch=20cross-shard?= =?UTF-8?q?=20transfer=20protocol=20=E2=80=94=20work=20crosses=20shards=20?= =?UTF-8?q?via=20the=20target=20queue,=20PMs=20never=20do?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 --- .claude/skills/pm-dispatch/SKILL.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index 1a95269dea..f6fc46e33a 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -114,10 +114,33 @@ shared files, and the merge queue is one lane regardless. Scaling order: 2. When one PM genuinely can't keep up: a second session takes a **whole repo** as its shard (`/pm-dispatch repo:objectstack-ai/objectui`) — file universes are disjoint by construction. A sharded PM states its - shard in every claim comment and **never claims outside it**; cross-repo - parent/sub-issue chains stay with the main-backlog PM. + shard in every claim comment and **never claims outside it**. 3. Multiple PMs on the SAME queue: prohibited — all cost, no throughput. +**Cross-shard transfer protocol — work crosses shard lines, PMs never +do.** When a sharded PM's task (or a sub-task of its parent issue) needs a +change in another shard's repo: + +- **Transfer via the target queue**: file the piece as an issue in the + target repo with `pm:queue` and a source line (`Part of + #`). The target shard's PM picks it up through its own + backlog sweep — the queue label IS the inter-PM channel; PMs never need + to talk directly, and never dispatch into a repo whose in-flight batch + they cannot see (that is the same collision the same-queue ban exists + for). +- **Dependencies via `Blocked-by:`** on the waiting side; the waiting PM's + batch selection skips it until the upstream merges. +- **Follow-up chores belong to the consuming shard**: when the upstream + change lands (say spec gained a key), the dependent-repo adaptation issue + is filed by the PM of the repo that consumes it — it knows its surfaces. +- **Shared contract surfaces have one owner**: anything touching + `packages/spec` transfers to the main-backlog (objectstack) PM + regardless of who needs it — only that PM sees the repo's in-flight + batch and generated-baseline collisions. +- Cross-repo parent/sub-issue chains as a whole stay coordinated by the + main-backlog PM; sharded PMs coordinate only chains fully inside their + shard. + **5. One board, no second tracker.** The pm labels above are the state machine; an org-level GitHub Project pulling issues/PRs from all three repos gives the maintainer a single view (filter by `repo:*` and `pm:*`). The PM From d0b642a3843c3768a830667717aae4d8518018ec Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Aug 2026 10:00:37 +0000 Subject: [PATCH 3/3] =?UTF-8?q?feat(agents):=20pm-dispatch=20shard=20owner?= =?UTF-8?q?ship=20registry=20=E2=80=94=20caretaker=20mode=20is=20explicit,?= =?UTF-8?q?=20never=20assumed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5 --- .claude/skills/pm-dispatch/SKILL.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index f6fc46e33a..74eb49e38f 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -117,6 +117,18 @@ shared files, and the merge queue is one lane regardless. Scaling order: shard in every claim comment and **never claims outside it**. 3. Multiple PMs on the SAME queue: prohibited — all cost, no throughput. +**Shard ownership is registered, never assumed.** A registry issue in the +main backlog (`[PM] 分片分工登记表`) records which session owns which +shard; a PM taking over a shard comments there as its FIRST action, and +comments again when handing off. An unowned shard may be **caretaken** by +the main-backlog PM (triage + dispatch), but the moment a shard is +registered to another session, the caretaker stops dispatching into it — +in-flight claimed tasks finish under whoever claimed them (the claim +protocol makes the handoff collision-free), and everything else belongs to +the new owner. State the mode in claim comments (「cloud 分片,主 PM 代管」 +vs a registered shard PM's own tag) so the registry and the claims never +disagree silently. + **Cross-shard transfer protocol — work crosses shard lines, PMs never do.** When a sharded PM's task (or a sub-task of its parent issue) needs a change in another shard's repo: