Skip to content

Commit 8a608d8

Browse files
docs(pm-dispatch): review seats take contract reviews first, the lane next, never triage (#29967)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} --> _Requested by **Yibo Wang** · [project thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBUyArWn6eHL33NNgvdpkwiW)_ Fixes #29242 ## 维护者速读 - **改了什么:** 新增复核席章程 `lanes/review.md`(21 行):`review#N` 席位坐在能达 `CONTRACT_REVIEW_TIER` 的其他账号上,专职契约复审;车道的 `Request: contract-review` 门铃改敲复核席信箱,无复核席在座时敲车道兄弟席;互斥沿用既有 `Contract-review-claim:` 行,同 head 先贴者持有;复核席不复核本账号派发或实现的 PR,不 merge、不 ready、不派发、不定级。`contract-review.md`(60/60)、`project-forms.md`(59/59)、`lanes/triage.md`(20/20)、`SKILL.md` 车道表(319/319)各在上限内改词指向它。脚本侧:`review` 成为可签名、可开信箱的席位词;`check-owed-reviews.mjs` 先点名复核席(坐在本 PR 派发或实现账号上的复核席回避,不点名),车道只在无复核席可接或多等一轮无认领后接;`fleet-roster.mjs` 把复核席列成行,在办 = 其活认领持有的 PR。 - **为什么改:** 您的原话「契约复审我想分拆到其他账户,怎么处理。」与裁定「选 B,立卡」。此前所有契约复审都在分诊一个账号一个会话上跑,写预算和模型额度互相挤占。 - **风险与回滚:** 文本三处零增行、不抬上限,新文件一行新棘轮行(21);脚本改动全是纯函数加自测,不加门禁、不加标签、不加信箱键。回滚 = revert 本 PR;已坐席的复核席只需撤座位贴。 - **先看:** ① `lanes/review.md` 全文;② `contract-review.md` 第 5、23 行(复核席先接,车道次之,⛔ 非分诊);③ `check-owed-reviews.mjs` 的 `takerOf` / `reviewSeatsOf`;④ `fleet-roster.mjs` 的 `reviewClaims`。 - **两分钟验证:** `node scripts/pm/check-owed-reviews.mjs --self-test`(预期 `84 cases pass in 10 batteries`)、`node scripts/pm/fleet-roster.mjs --fixture scripts/pm/fleet-roster.fixture.json --now 2026-10-23T14:00:00Z`(表中出现 `review` 行,在办 `objectstack#25433`)、`pnpm check:pm-skill-ratchet`。 - **需要你做的:** 一处与卡面不同,请知悉(见下 Deviations):回退席不是分诊而是车道兄弟席,依据您 11-03 的话「目前各车道都有fable,应该不需要你契约复审」。无其他动作;席位落地。 Clause-②: no Metadata-protocol: none ## What changes **New `references/lanes/review.md` (21 lines, new ratchet row at 21, every line ≤ 120 bytes).** The card's points 1–6 only, pointing at `contract-review.md` for the review itself: the seat (`review#N`, `review#1` first, one seat post each, any account that reaches `CONTRACT_REVIEW_TIER`; session effort `high`, review subagents at the review tier, a declaration-face-only review at `TIER_DEFAULT`; one `pm:mailbox` PR per seat through `mailbox-open.mjs --seat review#N`); the routing (lanes ring `Request: contract-review` at any review seat's mailbox, a free one takes it; with none seated the bell goes to a sibling lane seat, ⛔ never triage; mutual exclusion is the existing `Contract-review-claim:` line, the earlier claim on a head holds, between review seats too, the later withdraws and drops its output; `check-owed-reviews.mjs` names a review seat first and the lane only when none is seated or a further round after (b) passed with no claim; the delta re-review stays with the original reviewer, and a review seat off duty with a stale record hands the delta to the next review seat, named in the hand-off line); independence and bounds (⛔ never a PR its own account dispatched or implemented, records keep `Implemented-by:`/`Reviewed-by:`; ⛔ no merge, ready, dispatch, grading or human-floor action; security findings per `security-findings.md`). **`references/contract-review.md` (60/60, net 0 lines, no raise).** The 〈复核归属与资格〉 heading now points at `lanes/review.md`; line 23 folds the routing into the existing owed-review sentence (「复核席先接,车道次之,⛔ 非分诊」, 119 bytes); the seat word is `复核席` throughout (the older `复审席` spelling retired on four lines). The claim template line and the 2-hour lapse are untouched (pinned by `record-recognisers.mjs`). **`references/project-forms.md` (59/59, net 0 lines).** The seat-word line names `复核 = review.md` beside 总监 and 分诊 (115 bytes); the `Request: contract-review` row's taker reads `复核席`. **`references/lanes/triage.md` (20/20, net 0 lines).** Edited only after #29940 merged and `origin/main` was merged into this branch (the serial constraint): the 不推 line now reads 「契约复核(归复核席,`review.md`)」 in place of 「PASS/FAIL 归车道」 (117 bytes), so the triage charter points at the review seat and never calls itself the fallback. **`scripts/pm/check-skill-line-ratchet.mjs`.** One added `CEILINGS` row for the new lane file at its landed count (21, headroom 0) with the card's verbatim ruling quoted in the row comment, and its `MAX_TABLE_ROW_BYTES` pin (0). No existing row moves. **`.claude/skills/pm-dispatch/SKILL.md` (319/319, net 0 lines; patch round 1, S1).** The lane table's `security` row now reads `security` · `review` and ends 「复核席 `review#N` 见 `references/lanes/review.md`」 (333 bytes, within the 341-byte row pin), so the charter has an entry point from the skill itself; the skills token ratchet stays within its ceiling on the merged head. **`scripts/pm/mailbox-open.mjs` and `scripts/pm/check-half-states.mjs`.** `review` joins `SEAT_BARE_LANES` and the signature alternation `SIGNATURE_LANE_SOURCE` (the two lists `fleet-roster.mjs` pins equal), so `review#N` can sign a comment, open a mailbox (`mailbox/LOGIN/review-N`) and post a claim; `domain:review` stays refused. **`scripts/pm/record-recognisers.mjs`.** `contractReviewClaims` reads a claim's side off its signature: `triage#N` is the legacy `triage` side (still yields), `review#N` is the `review` side, everything else is `lane`. Between review and lane there is no precedence: the earliest live claim holds, which is what keeps two review seats off one head. **`scripts/pm/check-owed-reviews.mjs`.** `reviewSeatsOf(seats)` reads the roster for seated review seats; the row carries `reviewSeat` (seated / stood-down / absent / unknown) and `reviewSeats`; `takerOf` names `a review seat (review#1, …) first` while one is seated, adds `or the LANE seat (a further round waited, no claim)` after `LANE_JOINS_AFTER_ROUNDS` (2) × `TRIAGE_ROUND_MINUTES`, and names `the LANE seat (no review seat seated)` while none is. A hand-off still names its seat whatever the roster says. Patch round 1 (S2): `ownAccountsOf(pull)` reads the PR's own accounts — the implementing account from the body's `claude-projects-attribution` login and the dispatching account from the signer of each `Claim:` comment on the delivered card — and `reviewSeatsOf` bars a review seat seated on either (`lanes/review.md` 独立性); a barred seat is never named, and when every seated review seat is barred the state is `barred` and the lane's own seat takes at once, no further round. The printed row shows `review seat STATE SEATS (barred SEATS)`. Patch round 2 (S4): when the delivered card's comments could not be read, `ownAccountsOf` returns null and the state is `unjudged` — the seated review seats are named only with the caveat 「unless on this PR's own account (card comments unread)」, the lane's own seat beside them, so no seat the rule may bar is printed as free. **`scripts/pm/fleet-roster.mjs` and its fixture.** A `review` seat post is a row like the lanes; its in-flight is `reviewClaims`: the open pulls whose CURRENT head a live `Contract-review-claim:` signed `review#N` holds, read off the signed-comment read the roster already makes (the claim lapses in 2 h, the read starts `STALE_HOURS` = 6 h back). Review rows never share (`= seat N`) and hold no card. The fixture gains a review seat post, its mailbox pull, head shas on two pulls and three review-signed claims (one live, one expired, one on a moved head); the rendered roster shows `| objectstack | review | 1 | 🟢 os-zhuang | objectstack#25433 | … |`. **Not added:** no gate, no label, no mailbox key (the existing `Request: contract-review` key carries the routing), no ceiling raise, no changeset (`.claude/**` and `scripts/pm/**` publish nothing). ## Deviations from the card, declared The card's rule 2 and 3 and its acceptance line say triage is the fallback reviewer (「With no review seat seated, the bell goes to triage, as today」, 「falls back to triage」), and `lanes/triage.md` was to read 「triage becomes the fallback reviewer」. This PR builds the fallback as the lane's own seat (a sibling lane seat), never triage, for two reasons: (1) `origin/main` already says so — `contract-review.md` 「车道或复审席接,⛔ 非分诊」, `triage-duties.md` 「⛔ 分诊不再审」, and `check-owed-reviews.mjs`' taker never named triage at the branch point — so building triage back in would reverse a landed rule; (2) the maintainer's later word on 2026-11-03, verbatim: 「目前各车道都有fable,应该不需要你契约复审」. The self-test covers the no-review-seat case as 「the lane's own seat takes」 and pins that the row never names triage. Agreed with the skills seat before building. ## Tests - `node scripts/pm/check-owed-reviews.mjs --self-test` — 84 cases in 10 batteries, new battery `review-seat first …` (16): seated review seat first, the lane joins after a further round, no review seat ⇒ the lane's own seat (the card's acceptance case, never triage), stood-down ≠ seated, lane gone, roster unread, hand-off, a review seat's live claim ⇒ HELD, the printed row; S2: own accounts read from the attribution line and the card claim's signer, the only review seat on the implementing account ⇒ barred and the lane takes at once, a review seat on the dispatching account barred while a third-account seat still takes first, the lane gone with the only seat barred, a seat with no account never barred; S4: an unread card thread ⇒ `unjudged` with the caveat, a readable empty thread or no card still judges the bar. - `node scripts/pm/fleet-roster.mjs --self-test` — 110 cases in 9 batteries: the review row (lane, seat, account, in-flight = the live claim's pull, mailbox, last activity), only the live claim on the current head counts of three, a lane-signed or unsigned claim is nothing, the lane-word pin against `SEAT_BARE_LANES`, the rendered row. - `node scripts/pm/record-recognisers.mjs --self-test` — 366 cases: review side holds when first, lane first ⇒ lane holds, two review seats ⇒ earliest holds. - `node scripts/pm/mailbox-open.mjs --self-test` — 83 cases in 10 batteries (`review#2` opens `review-2`; `domain:review#1` refused); S3 fixed the 「The same three / four words」 comment above `SEAT_LANE_KINDS`. - `node scripts/pm/check-half-states.mjs --self-test` — 5222 cases on the merged head (the `review` alternation beside main's H74). - `pnpm check:pm-skill-ratchet` — review.md 21/21, contract-review.md 60/60, project-forms.md 59/59, triage.md 20/20, SKILL.md 319/319 (widest row 341, pin 341), widest prose line ≤ 120 bytes; `node scripts/check-skills-token-ratchet.mjs` — exit 0 (that ratchet walks `skills/` only, so `.claude/skills/pm-dispatch/SKILL.md` is outside it; the binding gates on SKILL.md are the line ratchet and the row pin); `pnpm check:pm-skill-id-lint` clean; `npx eslint` on the edited scripts exit 0. ## Acceptance notes - `lanes/review.md` exists with points 1–6; `contract-review.md` (heading and line 23), `project-forms.md` (seat-word line) and `lanes/triage.md` (the 不推 line) point at it. - `check-owed-reviews.mjs` prints the review-seat-first routing; its self-test covers no review seat seated (⇒ the lane's own seat, see Deviations). - `fleet-roster.mjs` lists review seats, in-flight = claimed heads. - Line budget: contract-review.md 60/60 · project-forms.md 59/59 · lanes/triage.md 20/20 · lanes/review.md 21/21 (new row) · SKILL.md 319/319. No raise. - `Writes:` `git push` ×4 (WIP head 618cdf4, review head 9da0cd8, patch round 1 head 6e66dd4, patch round 2 head f850ac1), relay `pr_create` ×1 (draft, `labels: ["skip-changeset"]`, no assignees), `post-stamped.mjs --comment` ×1 for the `os-dev-report`. `mcp_calls`: GitHub MCP reads only (`issue_read`, `pull_request_read`); no MCP write. ## Verification Final head `f850ac1b` (the change, the merge of `origin/main` at `82f60ebb` which carried #29940, the triage.md commit, a second merge of `origin/main` at `3b8c724c`, patch round 1 — contract review r0's three should-fixes — and patch round 2 — r1's S4; both merges were conflict-free). On the review head `9da0cd8c`, derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on that head (11 paths), 55 commands run serially in the worktree with each exit code captured before any pipe, plus the five self-tests and the eslint run above, then reconciled: `✓ dispatch-gates --ran: 55 derived famil(ies) accounted for — 54 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)`. - Patch round 2 (check-owed-reviews.mjs only) re-ran its self-test (84 cases), fleet-roster's (110) and `npx eslint` on `f850ac1b` — exit 0. Patch round 1 (SKILL.md, check-owed-reviews.mjs, mailbox-open.mjs) re-ran the gates that diff can move on `6e66dd44`: `pnpm check:pm-skill-ratchet`, `node scripts/check-skills-token-ratchet.mjs`, `pnpm check:pm-skill-id-lint`, `pnpm check:pm-half-states`, the self-tests of check-owed-reviews (82), fleet-roster (110), record-recognisers (366), mailbox-open (83) and `npx eslint` on the two scripts — all exit 0. - 54 of 55 derived commands exit 0 on `9da0cd8c`, among them `pnpm check:pm-skill-ratchet`, `pnpm check:pm-skill-id-lint` (110 files clean), `pnpm check:pm-half-states` (5222 cases), `pnpm check:pm-record-recognisers`, `pnpm check:pm-dispatch-gates`, `pnpm check:pm-governed-merges`, `pnpm check:pm-post-stamped`, `pnpm check:skill-frame-sync`, `pnpm check:single-claim-paths`, `pnpm check:scripts-symbol-anchors`, `pnpm check:ratchet-remedy-authority`, `node scripts/check-self-test-wired.mjs`, `node scripts/check-release-section-coverage.mjs --strict`. - `pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 3` — PREREQUISITE NOT MET (the lint package's built output is absent in a fresh worktree; `--ran` classifies the recorded exit 3 as NOT MEASURED). CI builds it; read the PR's `Lint & Repo Gates` check-run for the verdict. - Not run locally, by the derivation's own account: the artifact-roster, wide-population and pending-changeset families, the Type Check lanes and the test-core shards — CI's runs on this PR are the readings for those. No package test or typecheck is owed: the diff touches no package. Repeat the two-minute check: `node scripts/pm/check-owed-reviews.mjs --self-test` → `✓ check-owed-reviews self-test: 84 cases pass in 10 batteries`; `node scripts/pm/fleet-roster.mjs --fixture scripts/pm/fleet-roster.fixture.json --now 2026-10-23T14:00:00Z` → a `review` row with `objectstack#25433` in flight. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WGufzhXV3ABCbTkU1iRRn7 <!-- signed: domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 04cbdf7 commit 8a608d8

12 files changed

Lines changed: 282 additions & 66 deletions

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
162162
| `domain:spec` | `packages/spec` 整包:schema 形状、`contracts/**`、退役行为半边、strictness 台账;describe/JSDoc/墓碑散文/错误 guidance 与 alias 表;`packages/spec/scripts/**`、`packages/spec/docs/**` 及按锚定规则的例外归本域的工具链(域边界枚举与席内分派见 `references/lanes/spec.md`) |
163163
| `domain:ui` | `ui/**` 全部代码:`@object-ui/*` 库与 `ui/apps/*`、`ui/packages/types` 与 schema 语料、`ui/scripts` 与门禁工具、文档随所记录的面走;`packages/console`(dist 由 `pnpm console:build` 生成 ⛔ 不手改);协议恒归 `domain:spec`,受管面归 `domain:skills`;详见 `references/lanes/ui.md` |
164164
| `domain:cloud` | 涉 cloud 即整卡归 cloud PM(`repo:cloud` 席,同挂 `repo:cloud`):读或改 cloud 代码、生产方、事实或带 cloud 半边;本仓车道 ⛔ 不认领;cloud PM 跟到关卡,余下纯本仓活由它写明 cloud 事实后另立卡;判据见 `references/cross-repo-coordination.md` |
165-
| `security`(车道,无 `domain:*` 标签) | 安全发现(无文件面;修复经无卡派发令落在归属包);席位 `security#N`、接收、台账、派修与复核见 `references/lanes/security.md`;永不公开的规则只住 `references/security-findings.md` |
165+
| `security` · `review`(车道,无 `domain:*` 标签) | 安全发现(无文件面;修复经无卡派发令落在归属包);席位 `security#N`、接收、台账、派修与复核见 `references/lanes/security.md`;永不公开的规则只住 `references/security-findings.md`。复核席 `review#N` 见 `references/lanes/review.md` |
166166
| (无固定归属,按落点分诊) | `packages/apps/*`、`examples/*`(归它演练的子系统)、`docs/audits/**` |
167167

168168
- 表未覆盖的包首次分诊时归类并走 PR 更新本表;新增或退役 `domain:*` 必须同批改本表。

‎.claude/skills/pm-dispatch/references/contract-review.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
见 landing-operations.md 〈入队与落地〉的条款②闸门;本文只放复核归属、资格与等复核标记。
44

5-
## 复核归属与资格(按面)
5+
## 复核归属与资格(按面;复核席章程见 `lanes/review.md`)
66

77
- 欠不欠按面判 ⛔ 不按车道:diff 或认领申报碰下列任一面即欠达档复核,交付后当轮完成。
88
- 复核面 = 契约四面:`Clause-②: yes` 申报、收窄申报、已发布 schema(`packages/spec/src/**` 非测
@@ -18,12 +18,12 @@
1818
- 已发布面以包的 `exports` 映射为准:从入口类型图不可达、且 `exports` 不可寻址的 `.d.ts` 是
1919
出货字节,⛔ 不是已发布接受集,改它不触发 `Clause-②: yes`;legacy node10 深引用在契约之外。
2020
- 四面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。
21-
- 派发席席内达档审;被配额拒(HTTP 429)⇒ ⛔ 不降档,留标记落交接行,点复审席,无则兄弟席:
21+
- 派发席席内达档审;被配额拒(HTTP 429)⇒ ⛔ 不降档,留标记落交接行,点复核席,无则兄弟席:
2222
- `Contract-review-handoff: <review#N|domain:<lane>#N> — CONTRACT_REVIEW_TIER unavailable (<HTTP status / error>, <UTC time>) · head <sha>`
23-
- 欠审 PR(含 draft)现 head 无记录、无活认领且 (a)(b)(c) 之一 ⇒ 车道或复审席接,⛔ 非分诊。
23+
- 欠审 PR(含 draft)现 head 无记录无活认领且 (a)(b)(c) 之一 ⇒ 复核席先接,车道次之,⛔ 非分诊
2424
- (a) 交接行点名现 head 或带等复核标记,同轮由所点席接;(b) 现 head 已等满一轮(约 60 分钟);
25-
- (c) 车道收班或离总表:欠审入交班简报待下席或复审席;清单 `scripts/pm/check-owed-reviews.mjs`。
26-
- 车道或复审席起审前读 PR:现 head 有记录或活认领 ⇒ ⛔ 不起;否则先落认领行,一 head 一行:
25+
- (c) 车道收班或离总表:欠审入交班简报待下席或复核席;清单 `scripts/pm/check-owed-reviews.mjs`。
26+
- 复核席或车道起审前读 PR:现 head 有记录或活认领 ⇒ ⛔ 不起;否则先落认领行,一 head 一行:
2727
- `Contract-review-claim: <session> · head <full sha> · <UTC>`
2828
- 认领随 head 移动或贴后 2 小时无记录失效;双认 ⇒ 先贴者持有,后者回帖撤回、弃产出。
2929
- 车道暂缓本 head 送审落 `Contract-review-hold: <session> · head <sha> · <reason> · until <condition>`
@@ -50,7 +50,7 @@
5050
而已挂 auto-merge ⇒ 派发席读到即照 AGENTS.md disarm 句撤挂,FAIL 记录点名欠撤挂;重挂照 ①。
5151
- ② PR check 全绿,⛔ 非 required 子集;例外:merge-base 同签名的红不计、按设计而红见 SKILL.md。
5252
- 签名 = 失败步 + 首错行,读 base check runs 的 API ⛔ 不凭口述;主干红止血立单不变。
53-
- 落地时仍欠复核的 PR 在落地 head 复审,车道席或复审席按 (a)(b)(c) 接;FAIL ⛔ 不修已关 PR。
53+
- 落地时仍欠复核的 PR 在落地 head 复审,复核席或车道席按 (a)(b)(c) 接;FAIL ⛔ 不修已关 PR。
5454
- 每条 must-fix 引该记录立新卡、按发现定级;回退仅限主干红(p0,main-red 约定①)或安全边界。
5555

5656
## 等复核标记 `needs:contract-review`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# 席位章程:复核席(review)
2+
见 contract-review.md;本文是本席的岗位说明,现值状态恒在座位贴,⛔ 不迁入;复核本身照该文。
3+
4+
## 座位
5+
6+
- 席位 `review#N`,首席 `review#1`,一席一座位贴;坐席者 = 能达 `CONTRACT_REVIEW_TIER` 的账号的会话。
7+
- 会话 effort `high`;复核子代理恒契约复审档;仅申报面 `TIER_DEFAULT`,档随面定照 contract-review.md
8+
- 每席开一个 `pm:mailbox` PR(`mailbox-open.mjs --seat review#N`);签名、坐席与收班同他席。
9+
10+
## 路由
11+
12+
- 车道 `Request: contract-review` 敲任一复核席信箱,空闲者接;无复核席在座敲兄弟席,⛔ 非分诊
13+
- 互斥 = 既有 `Contract-review-claim:` 行:同 head 先贴者持有,复核席之间同此;后者撤回弃产出。
14+
- 欠审表 `check-owed-reviews.mjs` 先给复核席;车道只在无复核席在座或 (b) 后再一轮无认领才接
15+
- delta 复审归原复核者;复核席下班留下旧记录 ⇒ 下一复核席接 delta,交接行点名它。
16+
17+
## 独立性与边界
18+
19+
- ⛔ 不复核本账号派发或实现的 PR;记录恒带 `Implemented-by:`/`Reviewed-by:` 对。
20+
- ⛔ 不 merge、不 ready、不派发、不定级、不做人工地板动作;只写复核记录、认领行与门铃
21+
- 安全发现照 `security-findings.md`:记录只停在规则层,机制只进本席本地笔记。

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- ⑥车道不动:p1 卡在无席车道逾 4h;点名升级逾 6h 无答且回收需其一句;open PR 逾 6h 未更新,
1313
先敲其席(无信箱按名)过下轮无答且回收需其一句;待裁或被具名 `Blocked-by:`、`status:parked`
1414
卡、所骑栈阻者与信箱、Version PR 不算。⑦席位或子代理被拒、需人做的动作,⛔ 不代做。
15-
- 不推:定级、治半状态、解锁、契约复核(PASS/FAIL 归车道)、门铃答复、健康绿读数。
15+
- 不推:定级、治半状态、解锁、契约复核(归复核席,`review.md`)、门铃答复、健康绿读数。
1616
- sweep 加推导 `pm:queue`/`pm:blocked` 无审计评论卡(豁免照 H74 行),照未定级首触补审计并报数。
1717
- 每轮扫 `pm:dispatched` 卡与非信箱 open PR,进展=head 提交/非分诊评论/其席改标,非 `updated_at`。
1818
- 进展逾 3h 即敲认领席 `Request: progress`,下轮读答复,无答列轮次记录;两轮无答视为掉线。

‎.claude/skills/pm-dispatch/references/project-forms.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
- 项目指令只有一行:`pm-dispatch <席位> [<席位>…]`,如 `pm-dispatch 总监`、`pm-dispatch ui skills`。
1414
- 首词恒为技能目录名 `pm-dispatch`;⛔ 不用 `fleet`,它已是 bot 与中继的名字。
15-
- 席位词 = 中文名或车道文件名:总监 = `lanes/director.md`,分诊 = `lanes/triage.md`。
15+
- 席位词 = 中文名或车道文件名:总监 = `lanes/director.md`,分诊 = `triage.md`,复核 = `review.md`。
1616
- 其余席位词同 `lanes/<lane>.md` 文件名:ui、skills、devx、server、spec、hotcrm、mobile。
1717
- 一车道多席:协调者取 🟢 行写本账号的那一席;无则取空席;再无则问维护者一次。
1818
- 其余一切住本文:⛔ 不往项目里贴模板;⛔ 不在账号层复制技能。
@@ -37,7 +37,7 @@
3737
- 正文首行 `Mailbox-of: <席位> · <login>`;坐席即开(`mailbox-open.mjs`)并订阅,存根记 `Mailbox:`。
3838
- 永不合并,不欠 CI,落地与台账查询排除它;移交或换账号关旧开新;评论首行 `To: <席位>`。
3939
- 次行恒为一键,下列事件必敲;一事一行 ≤200 字节,只写键与编号;表外即半态。
40-
- 车道→复审席或兄弟席同交接行 `Request: contract-review`;反向随记录 `Notify: contract-review`。
40+
- 车道→复核席或兄弟席同交接行 `Request: contract-review`;反向随记录 `Notify: contract-review`。
4141
- 任一席→分诊:p0 嫌疑、main 红、确定性队列红 `Request: urgent-triage`。
4242
- 立锚卡者→分诊(缺则总监)`Request: main-red`,→破坏 PR 的席与锚卡车道 `Notify: main-red`。
4343
- 锚卡关闭:分诊(缺则总监)→正文带 `Waits-on: main-red #n` 的每张 open PR 之席 `Notify: main-green`。

‎scripts/pm/check-half-states.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ export const RELEASE_COMMENT_MARKER = /^\s*>?\s*Release\s*:/mi;
12551255
//
12561256
// LANE a seat as the role table spells it: `domain:` or `repo:` plus a lowercase
12571257
// name (`domain:engine-core` carries a hyphen, measured on the label set),
1258-
// `epic:#` plus the parent card, `triage`, `director`, `coordinator` or `security`
1258+
// `epic:#` plus the parent card, `triage`, `director`, `coordinator`, `security` or `review`
12591259
// N the seat number, from 1
12601260
// ACCOUNT the login a claim's `Account:` line carries — GitHub's own login rule
12611261
// SESSION the full id, in the relay envelope's shape (`SESSION_SHAPE`, fleet-write/ops.mjs,
@@ -1279,7 +1279,7 @@ export const RELEASE_COMMENT_MARKER = /^\s*>?\s*Release\s*:/mi;
12791279
// ---------------------------------------------------------------------------
12801280

12811281
/** The four parts' patterns, unanchored, in order — the ONE spelling every reader and writer composes from. */
1282-
const SIGNATURE_LANE_SOURCE = '(?:domain:[a-z][a-z0-9-]*|repo:[a-z][a-z0-9-]*|epic:#[1-9][0-9]*|triage|director|coordinator|security)';
1282+
const SIGNATURE_LANE_SOURCE = '(?:domain:[a-z][a-z0-9-]*|repo:[a-z][a-z0-9-]*|epic:#[1-9][0-9]*|triage|director|coordinator|security|review)';
12831283
const SIGNATURE_ACCOUNT_SOURCE = '[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}';
12841284
/** The relay envelope's session shape without its anchors — `SESSION_SHAPE` in `fleet-write/ops.mjs`. */
12851285
export const SEAT_SIGNATURE_SESSION_SOURCE = 'session_[A-Za-z0-9]{6,}';

0 commit comments

Comments
 (0)