Skip to content

Commit 6862ef6

Browse files
objectstack-fleet[bot]os-warrenclaude
authored
docs(pm-dispatch): the seat that sees a main-red files and dispatches it; triage first-touch follows (#26210)
Fixes #26143 Clause-②: no Metadata-protocol: none ## What changed Skill text only, four files under `.claude/skills/pm-dispatch/**` (Tier S), every file line-neutral against its `check-skill-line-ratchet` ceiling, every touched line at or under 120 bytes, no issue numbers in operative text. **`references/landing-operations.md` §B — the main-red convention gains its actor.** 约定① now reads: the seat that sees a full-battery red on `main` or a merge-queue build looks for the anchor card first; finding none, it files the p0 anchor card (filing-gate class ①) with the failing surface's lane domain, claims it, and dispatches the stanch — in the words the card asks for, `⛔ 不等分诊首触、不等维护者`. The first stanch is the revert of the commit that introduced the red, found on `main` between the last green and the first red; root cause goes on its own card. Triage first-touch follows after the fact and may change the domain, never the action. The two existing conventions stay: p0 fix-forward jumps the queue (mechanical, root cause verified) and the maintainer may hand-merge a one-line fix — compressed from two lines to one; 约定② (one failing check anchors one card, first filer wins, later seers comment on the anchor) is byte-unchanged. The fourth existing convention, no lane PR arms the queue meanwhile, lives in `AGENTS.md`'s Two-speeds paragraph and was never in this file. **`references/execution-duties.md` — the candidate rule gains main-red as its second exception**, in the same shape as the sub-issue clause: line 10 names both exceptions and points at `landing-operations.md`; line 40 (dispatched past triage, sweep audits after) now covers both instead of being duplicated. **`references/triage-duties.md` — one line beside the urgent-triage rule** tells the triage seat that a main-red anchor the seat already filed and dispatched still gets its first touch, as a recorded grade: domain may change, action never, and the card's in-flight state is no reason to skip it. The blanket "in-flight cards are not touched" line (70) names that first touch as an exception so the two lines cannot be read against each other. **`SKILL.md` lines 170–171, edited in place** (no line added): `domain:*` production and the queue/level/claim-eligibility line now say 两例外 (sub-issue, main-red anchor) instead of 例外一. Without this the new rule would contradict SKILL.md's own "only triage produces `domain:*`" and "no triage audit, no claim" lines, and SKILL.md's stricter-rule tie-break would have sent the seat back to waiting for triage. The lane charter `references/lanes/skills.md` line 「本车道 finding 同走分诊席首触,⛔ 不自分诊」 is untouched: it is about lane findings, and main-red is now the named exception. Not touched, by the card's own scope: `AGENTS.md`'s main-red sentence ("triage files it") is Tier H prose and is the seat's to raise with the maintainer; machine-filed anchor cards (option B) were not chosen. ## Line budget | file | before | after | ceiling | |:--|--:|--:|--:| | `references/landing-operations.md` | 101 | 101 | 101 | | `references/execution-duties.md` | 188 | 188 | 188 | | `references/triage-duties.md` | 103 | 103 | 103 | | `SKILL.md` | 319 | 319 | 319 | New and edited lines, measured in bytes: landing-operations 118 / 109 / 92 / 116; execution-duties 114 / 116; triage-duties 109 / 116; SKILL.md 118 / 118. Nothing re-wrapped; no ceiling moved. ## Rules retired (every deleted clause and where it now lives) - `landing-operations.md` old line 61 (受管路径全在 `.claude/**` 者 Tier S:席内达档复核过落地前检两条即转正式入队) → `SKILL.md` 路径分叉 line 204 (受管面两层:Tier S = `.claude/**` 全树 … S 经达档复核 PASS 后 ready → 入队) and `references/contract-review.md` line 37 (落地前检两条,过则 Tier S 入队、Tier H 等人批), which this file's line 59 already points at. - `landing-operations.md` old line 62 (Tier H(其余受管面)者:四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地) → `SKILL.md` 路径分叉 lines 186–189 and 197, `references/lanes/skills.md` line 17 (Tier H 受管 PR 恒 draft 等维护者的字), `references/contract-review.md` line 37. Line 60 of this file keeps the operational step (`check-governed-merges.mjs --pr N`:受管面照两层) and line 63 keeps ⛔ 两层不由席位批准. - `landing-operations.md` old lines 82–83 (p0 fix-forward 允许跳队 … / 也可按既有 governed 例外由维护者人工直合一行修复;仅限 main-red 修复) → compressed into the new line 4 of the block; "仅限 main-red" is carried by the block's position between 约定① and 约定②. - `execution-duties.md` line 10, clause 预贴 `pm:queue` 视同无 → `SKILL.md` line 171 (预贴标签只是建议,队列与级别只由分诊落笔). Clause 例外一的 sub-issue 承父卡首触 is kept, now beside the second exception. - `execution-duties.md` line 40, clause 带父卡域与优先级 → generalised to 各带域与级; the sub-issue's inheritance is stated at line 39 (优先级继承) and `SKILL.md` line 170 (承父卡域). - `triage-duties.md` old line 78 (裁决恒归维护者人工:分诊只分析、推荐、入箱;⛔ 无代裁车道、置信门与 `auto-adjudicated`) → `SKILL.md` 红线 line 30 (⛔ 永不代维护者答产品或架构问题,⛔ 无代裁通道:席位只分析与推荐,裁决恒出自人工), `SKILL.md` line 276 (⛔ 无代裁无自裁无子代理), this file's line 5 tail (⛔ 无代裁通道) and `references/lanes/director.md` line 22 (⛔ 无裁决线程、代裁、置信门). A true duplicate of a 红线, which the rules-only rewrite convention already names as the class to retire. - `triage-duties.md` line 70, clause 敲门在先 → lines 71–72 of the same file, whose sequence (敲门一次 → 敲门后 … 无答复 ⇒ 释放) is that rule. ## Tests and gates Docs-only diff: no package is touched, so there is no ① closure build and no ② package test; no ablation (the diff pins no tested behaviour). Local readings are on the final head `46774c37` (the merge of `origin/main` `7111e14a` into the change commit `6fb2d7eb`); the full derived union was run after that merge. Local derived subset — `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths (change set derived from git: 4 paths vs merge base `7111e14a`), 22 families, every exit code captured by redirect before any pipe, then reconciled: `✓ dispatch-gates --ran: 22 derived famil(ies) accounted for — 22 run, 0 NOT-MEASURED (a DERIVED zero — all 22 recorded an exit code and none of them is 3)`. | command | exit | |:--|--:| | `node scripts/check-closing-keyword-parity.mjs` | 0 | | `node scripts/check-closing-keyword-parity.mjs --self-test` | 0 | | `node scripts/check-comment-mask-corpus.mjs` | 0 | | `node scripts/pm/check-governed-queue-guard.mjs --self-test` | 0 | | `node scripts/pm/check-harness-current.mjs --self-test` | 0 | | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 3 on the unbuilt tree (PREREQUISITE NOT MET: `@objectstack/formula` and `@objectstack/lint` not built — "Nothing was measured"), then 0 after `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under the verify lock (`VERDICT command-exit 0 · held the lock 114s`) | | `pnpm check:agent-test-spelling` | 0 | | `pnpm check:cross-package-test-inputs` | 0 | | `pnpm check:doc-authoring` | 0 | | `pnpm check:driver-memory-census` | 0 | | `pnpm check:gitlink-declared` | 0 | | `pnpm check:nul-bytes` | 0 | | `pnpm check:pm-expected-skips` | 0 | | `pnpm check:pm-governed-merges` | 0 | | `pnpm check:pm-governed-prose` | 0 | | `pnpm check:pm-half-states` | 0 | | `pnpm check:pm-label-write` | 0 | | `pnpm check:pm-skill-id-lint` | 0 — `✓ check-skill-id-lint: 104 file(s) clean (pattern /#[0-9]{3,}/g)` | | `pnpm check:pm-skill-ratchet` | 0 — `SKILL.md is 319 lines (ceiling 319; headroom 0)` · `landing-operations.md is 101 lines (ceiling 101; headroom 0)` · `triage-duties.md is 103 lines (ceiling 103; headroom 0)` · `execution-duties.md is 188 lines (ceiling 188; headroom 0)`; no line-length offender | | `pnpm check:refd-timer-probe` | 0 | | `pnpm check:skill-frame-sync` | 0 — `✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md …)` | | `pnpm check:watch-hint-literal` | 0 | Local-only family, not derived but owed because `SKILL.md` holds the four-axis frame: `pnpm check:skill-frame-freshness` exit 0 — `✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now)`. Reading stays local, as the role file says. Every family CI runs on this PR: its check-runs had not started when this body was written (the PR is created by this write), so they are `in_progress` here, the honest value; the seat reads the PR's check-runs. Not waited for. Dogfood battery: n/a — no `!` in the title and no `(narrowing)` arm. ## Acceptance notes - Cross-lane claiming of the anchor: the ruling says the seat that sees the red claims it, and the failing surface's lane may not be that seat's lane. The text states the ruling as given; the existing cross-lane channel it rides is `SKILL.md` line 175 「接手无主阻塞项」 together with `execution-duties.md` line 45 (阻塞项无主 ⇒ 被挡席认领做掉) — a main-red blocks every lane's landing. The 红线 line 34 (执行席只在本车道认领) is not edited; the maintainer's ruling outranks it by `SKILL.md`'s own 优先序. Named for the seat's review, not resolved here. - The after-the-fact clause (首触事后补,可改域、⛔ 不改动作) appears twice on purpose: once in landing-operations §B from the acting seat's side, once in triage-duties from the triage seat's side, where the in-flight exemption also has to be said. - Carrier: the seat raises `AGENTS.md`'s "triage files it" sentence with the maintainer (Tier H, the maintainer's hand only); noted, not filed. ## 维护者速读(草稿) ### 改了什么 pm-dispatch 技能里的 main-red 约定补上了「谁来做」:看见主干或合并队列全量红的席位先找锚卡,没有就自己立 p0 锚卡(域按出红的面所属车道)、认领、派止血;首道止血是回退引入红的那个提交,根因另立卡;⛔ 不等分诊首触、不等维护者。分诊首触事后补,可以改域、不改动作。既有约定(一个签名一张卡、p0 fix-forward 跳队、维护者可直合一行修复、止血期间车道 PR 不挂队列)全部保留。执行席的候选规则把 main-red 锚卡列为 sub-issue 之外的第二个免分诊例外;分诊席职责加一行:在飞的 main-red 锚卡照样补首触,只作记录级。四个文件行数一行不增,全部按 120 字节/行写。 ### 为什么改 你 2026-10-26 在席位线程的原话:「主干 Test Core 超时红这种应该立刻立卡啊,skills 没有约定吗?」「所以 main红这一类卡应该是 devx 立卡并立刻处理吗」「按照目前的规则,等分诊太慢了」,决策卡上选的是「席位直接立卡派发,分诊后补」。当天实测的延迟全在「看见红 → 立卡」这一段(两个半小时),立卡之后 47 分钟就修好了。 ### 风险与代价(含回滚) - 风险一:主干红时可能出现两张锚卡。约定②(一个签名一张卡、先立者赢、后见者评论到锚卡)原样保留,sweep 事后查重,重复的关 duplicate。 - 风险二:看见红的席位可能跨车道认领。规则文本照裁决写「认领并派止血」,走的是既有「接手无主阻塞项」越界通道;红线「执行席只在本车道认领」没有动,按技能自己的优先序由裁决压过。席位复核时请留意这一点。 - 代价:为保持行数不增,从 landing-operations 退了两行 Tier S/Tier H 说明(SKILL.md 路径分叉与 contract-review.md 已有同样的规则),从 triage-duties 退了一行「裁决归人工」(SKILL.md 红线第 30 行原文)。所有退掉的内容在 PR 正文「Rules retired」逐条列了去处。 - 回滚:revert 这一个提交即可,无数据、无发布面、无门禁常量改动。 ### 席位意见 (留空,席位定稿) ### 你要做的 一个动作:AGENTS.md「Two speeds」段里的「triage files it」一句是你亲手的 Tier H 文字,本 PR 没碰;要不要把它改成「the seat that sees it files it」,由你定。 --- _Generated by [Claude Code](https://claude.ai/code/session_01LqKsGyMNFwwnbF5FTAqyPn)_ --------- Co-authored-by: os-warren <warren@objectstack.ai> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 326a559 commit 6862ef6

4 files changed

Lines changed: 11 additions & 11 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
167167

168168
- 表未覆盖的包首次分诊时归类并走 PR 更新本表;新增或退役 `domain:*` 必须同批改本表。
169169
- 退役 `domain:*` 只退流通,对象保留;`domain:engine`/`domain:services`/`domain:cli` 读作 `domain:server`。
170-
- `domain:*` 只由分诊席产出,例外一:在飞卡衍生 sub-issue 承父卡域;无标签的卡 ⛔ 不得认领。
171-
- 预贴标签只是建议,队列与级别只由分诊落笔(例外一同承);无分诊审计评论 ⛔ 不得认领。
170+
- `domain:*` 只由分诊产出,两例外:sub-issue 承父卡域、main-red 锚卡;无标签的卡 ⛔ 不得认领。
171+
- 预贴标签只是建议,队列与级别只由分诊落笔;无分诊审计评论 ⛔ 不得认领;两例外豁免。
172172
- 跨域例外路径:拆不动的跨域单 PR 由分诊席指定一个车道 PM 认领,认领评论申报文件面。
173173
- 派发前在飞检查:读 `pm:dispatched` 卡认领评论申报的文件面,本地求交、不另发查询。
174174
- 跨域例外路径的范围加上该单文件面触及各域的在飞单;相交 ⇒ 排该 PR 之后串行或让行。
175-
- 跨域相交只经三条越界通道:跨域例外路径、认领席跟到底的越界面、接手无主阻塞项。
175+
- 越界只四通道:跨域例外路径、认领席跟到底的越界面、接手无主阻塞项、main-red 锚卡。
176176
- 合并队列是共享串行资源:车道买到的是并行编写,不是并行落地。
177177
- 谁发现 flake 谁修或立单,⛔ 不绕行。
178178

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- 整车道一次读全,本地求交:`list_issues` 带 `labels: [domain:X]` + 最小字段拿回全车道 open 集。
88
- 候选 = open、未 assign、无 `needs-user-decision`、无 `pm:retriage`;⛔ 排除三门皆无的 `tooling` 卡。
99
- `tooling` 卡至多占一轮派发的 10%,溢出留积压、⛔ 不入 `pm:queue`;⛔ 无门禁无脚本强制。
10-
- 无分诊审计评论的卡不是候选,预贴 `pm:queue` 视同无;例外一的 sub-issue 承父卡首触。
10+
- 无分诊审计评论即非候选;例外:sub-issue 承父卡首触,main-red 锚卡见 `landing-operations.md`。
1111
- 已排队父单的 open sub-issue 自动是候选,`pm:epic` 父单的子树除外。
1212
- 每张候选读全文 + 全部评论,写派发词前做决策复读:评论读到最后一页。
1313
- 维护者裁决逐字引入派发词裁决分区作约束,无则写明无裁决。
@@ -37,7 +37,7 @@
3737
- 阻塞解除后延后单重定价:前一单派发词必答 #X 变简单、变难、不必要或无影响。
3838
- 派发后一单前用该回答重读它的选项与成本,⛔ 不沿用立单时那份。
3939
- 在飞卡衍生三分:不修它验收过不过;in-scope ⇒ 父卡 sub-issue,认领席自有、优先级继承。
40-
- 该 sub-issue 带父卡域与优先级直接派发,绕过分诊;sweep 事后扫,重复关 `duplicate`。
40+
- 该 sub-issue 与 main-red 锚卡各带域与级直接派发,绕过分诊;sweep 事后扫,重复关 `duplicate`。
4141
- 排队卡含他车道项 ⇒ 发现席自拆:新卡无 `domain:*`,首行 `carries item k of #N; #N keeps items …`。
4242
- 分诊首触定域可改判;拆出卡 ⛔ 不承父卡域(承域只及本车道 sub-issue),父卡余项照 `Fixes`。
4343
- 自在飞派发升级出的卡首行一句:本卡承哪一半、父卡留哪一半;缺此行不入队不入箱。

‎.claude/skills/pm-dispatch/references/landing-operations.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@
5858
- 落地评论 = 两个读数的探针表 + 一行状态变更(摘标/关卡/收口),⛔ 不复述 `## 席位核对`。
5959
- 契约复核 PASS 落地的 PR 到窗口时已 ready 且 auto-merge 在挂,见 `contract-review.md`。
6060
- 转 ready/入队前跑 `check-governed-merges.mjs --pr N`:受管面照两层;>3000 行(含生成物)照 Tier H。
61-
- 受管路径全在 `.claude/**` 者 Tier S:席内达档复核过落地前检两条即转正式入队。
62-
- Tier H(其余受管面)者:四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地。
6361
- ⛔ 两层不由席位批准;清标即落地同受此闸,漏判会被队列守卫在 merge group 里拒收。
6462
- 再读 `mergeable_state`:`dirty` ⇒ 先 merge `origin/main` 再挂;生成物在面上按 A 的固定序。
6563
- 挂 auto-merge 的同一动作里重测生成物漂移,⛔ 不复用更早的零;非零 ⇒ 按 A 的固定序。
@@ -79,8 +77,10 @@
7977
- MERGED 或关闭即退订,同刻把 `mode:cloud` 派的会话 `archive_session`。
8078
- 触发条件是卡终局且报告已收复核;⛔ 合并前不归档,误归档可 unarchive 但容器现场已失。
8179
- 暂停或交接时把在挂订阅清点进座位贴,⛔ 不留孤儿订阅。
82-
- main-red 约定①:p0 fix-forward 允许跳队,限 p0、机械、根因已核实的止血 PR。
83-
- 也可按既有 governed 例外由维护者人工直合一行修复;仅限 main-red 修复。
80+
- main-red 约定①:见主干/队列全量红的席位先找锚卡,无则立 p0 锚卡(门类 ①),域随失败面。
81+
- 认领并派止血,⛔ 不等分诊首触、不等维护者;首触事后补,可改域、⛔ 不改动作。
82+
- 首道止血 = 回退引入红的提交(主干末绿与首红之间找),根因另立卡。
83+
- p0 fix-forward 止血跳队,限机械、根因已核实;维护者可按 governed 例外人工直合一行修复。
8484
- main-red 约定②:一个失败 check 只锚一张卡,先立者赢,后见者评论到锚卡,⛔ 不另立。
8585

8686
## C. 依赖前棒才能转绿的 PR:draft 停放 + 签名级预期红清单

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- 裸卡数 >15 ⇒ 下一 fire 整轮改域分批集中模式,每批 ≤5 张同族卡,照样跑到清空。
2323
- 紧急卡直接分诊:维护者点名或 p0 嫌疑 ⇒ 立即起默认判断档分诊子代理,不等定时轮。
2424
- 紧急分诊的授权面 = 分诊本身,⛔ 不写码不认领;产出落卡,与定时轮分诊同格式同效力。
25+
- main-red 锚卡由席位先立先派,首触事后补作记录级:可改域,⛔ 不改动作,在飞照补。
2526
- 分类动作每张三选一,外加一个修复通道;裁定写方向、给六态之一。
2627
- 方向在 ADR/本卡裁决/不可重裁规则:贴 `check-prior-rulings.mjs` 的 `Prior rulings read:` 行,或不点。
2728
- `pm:queue` = 有具名落点或复现的具体缺陷,无可问之事;⛔ 工具/门禁修复不由此进。
@@ -67,15 +68,14 @@
6768
- 三类外首触关闭只清门前存量,关 not planned(不等批准可否决重开);三类内无证据拒收。
6869
- 三类内再过时前提检查,三选一:晋级 / 关闭 not planned / hold;判级只在此轮,不在立单时。
6970
- ⛔ 写入前对每张卡现读当前状态;任何列表快照读数一律作废。
70-
- ⛔ 带 `pm:dispatched`/assignee/open 或 merged PR 引用的卡不动;例外仅下三行:敲门在先。
71+
- ⛔ 带 `pm:dispatched`/assignee/open 或 merged PR 引用的卡不动;例外:下三行、main-red 锚卡首触。
7172
- 在飞活性复查:认领逾一天无自有产出(commit/PR/评论)⇒ 敲门一次,首行键 `Owned-24h re-check:`。
7273
- 敲门后 `RECLAIM_AFTER_HOURS = 12` 小时无答复 ⇒ `label-write.mjs --release` 一笔中继释放,贴不动。
7374
- 释放:`Release:` 评论(出处三件)+ `Resume-from:` 行 + `pm:dispatched`→`pm:queue` + 清 assignee。
7475
- 车道席可附证据/前提重验,⛔ 不定级不改标;每张卡欠一次分诊首触,车道 ⛔ 不自分诊。
7576
- 域分批与 sweep 打包晋级五条照用;每批约定与积压告警见 `references/dispatch-runbook.md`。
7677
- `pm:retriage` 每 fire 先答异议评论所求,答后同笔摘标;须维护者答的进收件箱,标照摘。
7778
- retriage 的异议判据认内容(有评论写明所求)⛔ 不认形状(有一条异议评论)。
78-
- 裁决恒归维护者人工:分诊只分析、推荐、入箱;⛔ 无代裁车道、置信门与 `auto-adjudicated`。
7979
- 人工地板(恒呈维护者):功能新增;ADR;协议/公开契约变化;破坏性或难回滚动作。
8080
- 人工地板同含:安全/权限边界;门禁削弱(降阈/删必查/抬上限/跳测);新增运行时第三方依赖;
8181
- 花费/配额/舰队形态/默认模型档位;新增必需门禁/hook/棘轮(卡具名所守契约与预期捕获)。

0 commit comments

Comments
 (0)