Skip to content

Commit f62787c

Browse files
claude[bot]claude
andauthored
docs(pm-dispatch): add the witness-grep leg to the in-flight overlap interception (#17956)
Fixes #17935 The in-flight overlap interception asked exactly one question — do the file faces intersect — and the card measures a coupling that question cannot reach: two PRs, each green on its own, red only once both sit on one tree, because one PR's assertion NAMES a row the other deletes. This lands the second leg the card's one-line criterion asks for. ## The rule as landed `.claude/skills/pm-dispatch/references/dispatch-runbook.md`, section 〈派发词构造细则〉, the new line sitting directly under the file-face leg it extends: ```text - 在飞重叠每轮拦截:main 新落 PR 与在飞申报文件面求交,相交即发四句警告。 - 另一腿:本轮删/改名标识符 grep 每个在飞 PR 的 diff,命中同发,⛔ 不因文件面不相交跳过。 - 四句:合 main 重跑测试矩阵、读对方 diff 重划边界、只补它没覆盖的、被完全覆盖就停下。 ``` Measured against the card's criterion (quoted verbatim, untranslated): > 在飞重叠的检查项里,除文件清单外出现一条:核对是否有任一在飞 PR 的**断言点名了本轮 diff 删除或改名的 > 符号 / 行 / 标识符**;⛔ 且该条不得以文件面互不相交为由跳过。 - it greps against each in-flight PR's **diff**, not its file list — the cheapest of the two shapes the card suggests, and it needs no new tool; - 「命中同发」 gives a hit the same disposition an intersection gets: the four sentences, defined on the next line, so the two legs converge on one action; - 「⛔ 不因文件面不相交跳过」 puts the card's prohibition in the rule's own text, so the skip is refused where a seat reads it, not only in the card that filed it. ## Line budget — 241 / 241, net 0 | | lines | bytes | note | |:--|--:|--:|:--| | ceiling (`check:pm-skill-ratchet`) | 241 | — | headroom 0 | | before | 241 | 17542 | | | after | 241 | 17554 | +12 bytes, 0 lines | | added | +1 | 118 | the new line, under the 120-byte cap | | deleted | -1 | 106 | the density payment, below | The payment is a deletion inside the same section, not a re-wrap: the diff is exactly one removed line and one added line, and no other line was re-flowed. The line deleted is ```text - ⛔ 不在消费者侧打补丁;只写一个路径名,是要求 dev 在守约与修对之间二选一。 ``` and both of its clauses survive without it: - 「⛔ 不在消费者侧打补丁」 is already stated **in `SKILL.md` line 549** — 「文件面写两句:预期落点;生产者在别包时修生产者侧并报落点,⛔ 不在消费者侧打补丁。」 — and again in AGENTS.md Prime Directive 12 ("never add a lenient alias or `??` fallback in a consumer"). - 「只写一个路径名,是要求 dev 在守约与修对之间二选一」 is a rationale tail for the rule stated two lines above it (「文件面两句原文照抄」), which already requires both sentences to be copied. Those are the two categories this file's own ceiling comment names as removable, quoted from `scripts/pm/check-skill-line-ratchet.mjs` at the `dispatch-runbook.md` entry: "provenance narratives, incident post-mortems and rationale tails leave the corpus; one rule per ≤120-byte line, no rule already stated in SKILL.md". ## Acceptance greps — both directions Run in the worktree at this branch's head against `origin/main`: | check | before | after | |:--|:--|:--| | `不因文件面不相交跳过` in the runbook | 0 (exit 1) | 1 (exit 0) | | literal control `在飞重叠` in the runbook | 1 | 1 | | `git diff --stat origin/main -- .claude/skills/pm-dispatch/SKILL.md` | — | empty (SKILL.md untouched) | | `wc -l` on the runbook | 241 | 241 | | `LC_ALL=C awk 'length($0)>120'` over the runbook | prints nothing | prints nothing | | control-character self-scan over the runbook | clean | clean | SKILL.md is deliberately untouched: it is serial with another in-flight card this wave, and a pointer there, if it is ever wanted, rides that file's next PR. ## The new rule, applied to this PR The leg this PR adds is cheap enough to run on the PR that adds it. This diff deletes exactly one line; its distinctive identifiers were grepped against the diff — not the file list — of all 26 open PRs in this repository: | grepped identifier | hits across 26 open PR diffs | |:--|:--| | `只写一个路径名` | 0 | | `二选一` | 0 | | `不在消费者侧打补丁` | 0 | | positive control `⛔` (CJK rule text, same corpus, same grep) | 21 of 26 | The control is what makes the three zeros a reading rather than a broken grep. Same pass re-checked the serial constraint the claim comment declared: no open PR touches `dispatch-runbook.md`. ## The second shape — recorded, NOT built The card offers a stronger shape that this PR deliberately does not implement: > 更强的形状:凡编辑「在缩小的表」(ledger / 豁免表 / drift 表)的 PR,在派发令里互相点名,因为这类表的 > 对照**必然**点名其成员。 It is recorded here as an option, not a deliverable. It costs a standing classification (which tables count as shrinking tables) that the grep leg does not need, and the grep leg already covers the measured instance. If the grep leg proves to be run inconsistently, this is the escalation. ## Adjacent rules that do NOT already cover this `SKILL.md` line 479 — 「本卡 pin 断言兄弟卡在改的行为 ⇒ 派发令注明」 — is the mirror direction (this card asserts on a sibling's behaviour) and fires only when triage already knows the pair. Line 450 — 「文件面不相交只保证文本可合并;跨文件语义耦合由队列 CI 逮住,⛔ 不读作不可能冲突」 — names the coupling but routes it to queue CI, which is precisely the expensive half the card measured: the queue does catch it, on the second PR, as a red. Neither is a mechanical pre-check, so this is not a duplicate rule. ## Gates Derived from the tree with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths passed; derived at commit `da4eee77`), all run, reconciled with `--ran`: **14 derived, 14 run, 0 NOT-MEASURED, 0 UNRUN** — a derived zero, every family carrying a recorded exit code. ```text node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-skill-id-lint :: exit 0 pnpm check:pm-skill-ratchet :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:skill-frame-sync :: exit 0 pnpm check:watch-hint-literal :: exit 0 pnpm check:pm-governed-prose :: exit 0 (named by the dispatch, outside the derived 14) ``` `check:doc-formula-expressions` first returned exit 3 — PREREQUISITE NOT MET, the gate's own "nothing was measured" code, because `@objectstack/formula` and `@objectstack/lint` were unbuilt in a fresh worktree. Built through the shared verify lock (`scripts/pm/os-verify-lock.sh`, slot `issue-17935`, command exit 0) and re-run to a real exit 0. The repo-wide sweep (`pnpm lint` and the whole gate farm) belongs to CI, not to this worktree. No changeset: `.claude/**` ships nothing — the path is not inside any package's published `files[]` — so this carries the `skip-changeset` label. ## 维护者速读(草稿) **改了什么** —— PM 派发手册里「在飞重叠」的拦截从一问变成两问:除了文件面求交,还要把本轮 diff 删除或 改名的标识符,拿去 grep 每一个在飞 PR 的 diff(不是它的文件清单),命中与相交同样发那四句警告,并且 ⛔ 不许以「文件面互不相交」为由跳过这一问。全文只动这一个文件的两行(加一行、删一行)。 **为什么改** —— 实测到一次两个 PR 各自全绿、合到一棵树才红:一个 PR 的测试点名断言某一行存在,另一个 PR 正好把那一行删了。两个席位都按现行规则查了文件面,结论都对 —— 规则问的问题本身答不到这个耦合。这个形状 不罕见:凡 ledger、豁免表、drift 表这类「在缩小的表」,它们的对照**必须**点名成员,否则对照没有意义。 **风险与代价(含回滚)** —— 代价是每轮派发多一次 grep,没有新工具、没有新门禁、没有新脚本。规则面净增 零行:新增那一行由同节内一行的删除买单,被删那行的禁令原文仍在 `SKILL.md` 第 549 行与 AGENTS.md 第 12 条 里,余下半句是上两行已有规则的理由尾巴。回滚 = 还原这一个文件的两行,不牵动任何代码、门禁或产物。 **席位意见** —— **你要做的** —— 只需判断两件事:① 这一问是否值得每轮都问(代价是一次 grep);② 那条被删的行,它的禁令 落在 `SKILL.md` 与 AGENTS.md 上是否够。若都同意,人工合入即可 —— 这是受管面(`.claude/**`),按 Prime Directive 14 由维护者手工确认合并,本 PR 全程保持 draft,席位不翻 ready、不排队、不开自动合并。 --- _Generated by [Claude Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 45b90b6 commit f62787c

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

.claude/skills/pm-dispatch/references/dispatch-runbook.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,14 @@
210210
- ⛔ 仓内任何文件不得另立第三份,`check:skill-frame-sync` 全树扫;os-dev 定义没带就停下索取。
211211
- 文件面两句原文照抄:预期落点是 X。
212212
- 若实测表明真正的生产者在别包,直接按生产者侧修,落点与理由写进报告和 PR 正文。
213-
- ⛔ 不在消费者侧打补丁;只写一个路径名,是要求 dev 在守约与修对之间二选一。
214213
- 跨包常等于跨车道,PM 事后补跨座位声明。
215214
- 模型标识只禁内容工件:PR 标题与正文、代码注释、文档、changeset、评论。
216215
- 豁免不再申报为偏差:一是 harness 的 `Co-Authored-By` 尾注,免的是申报,trailer pair 仍 model-free。
217216
- 另一条是 `.claude/agents/*` frontmatter 的 `model:`,`check:agent-model-declared` 要求。
218217
- same-day churn 行:派发时 `git log origin/main --oneline -20 -- <paths>` 见当天合并即加一行。
219218
- 该行原文:基于合并后的代码工作,issue 引用的片段可能已变,先核对当前 main。
220219
- 在飞重叠每轮拦截:main 新落 PR 与在飞申报文件面求交,相交即发四句警告。
220+
- 另一腿:本轮删/改名标识符 grep 每个在飞 PR 的 diff,命中同发,⛔ 不因文件面不相交跳过。
221221
- 四句:合 main 重跑测试矩阵、读对方 diff 重划边界、只补它没覆盖的、被完全覆盖就停下。
222222
- ⛔ 不硬造 diff。中途收窄标准条款须点名替换承接人与时点,缺一 dev 报 blocked 不半执行。
223223
- 全仓 pin 清扫两句原文:① grep 错误码与错误消息全仓扫同语义 pin,一轮翻完,不只改本包。

0 commit comments

Comments
 (0)