Skip to content

docs(pm-dispatch): add the witness-grep leg to the in-flight overlap interception - #17956

Open
claude[bot] wants to merge 1 commit into
mainfrom
claude/issue-17935-inflight-overlap-witness-grep
Open

docs(pm-dispatch): add the witness-grep leg to the in-flight overlap interception#17956
claude[bot] wants to merge 1 commit into
mainfrom
claude/issue-17935-inflight-overlap-witness-grep

Conversation

@claude

@claude claude Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

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:

- 在飞重叠每轮拦截: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

- ⛔ 不在消费者侧打补丁;只写一个路径名,是要求 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.

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

…interception

The in-flight overlap check asked one question — do the file faces
intersect — so a PR whose assertion NAMES a symbol another in-flight PR
deletes or renames passes both seats' checks and goes red only once both
land on one tree. Add a second leg: grep this round's deleted/renamed
identifiers against every in-flight PR's diff, not its file list, and
never skip it because the file faces are disjoint.

Paid at 241/241 by deleting one line in the same section whose rule
survives in SKILL.md (「⛔ 不在消费者侧打补丁」) and whose remainder was a
rationale tail for the copy-both-sentences rule stated one line above.

Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
Co-authored-by: Claude <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 13, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 13, 2026
@claude

claude Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Contract review

Head: da4eee77 (PR #17956, card #17935) — read at 2026-09-13T08:11Z by the skills seat at the contract-review tier (served model claude-fable-5-1, get_session external_metadata.last_served_model at 2026-09-13T08:08Z); the build was default-tier (model: opus; dispatch-gates --tier derives no path mandate for references/**), so this record is the compensating control.

① derived judgments: the diff is one file, +1/−1 against merge-base bdb247d9 (origin/main has since moved to c8a006fc by PR #17908, which touches no .claude/** path — measured, empty diffstat on this file between merge-base and main). (a) The new leg at :220 states the card's one-line criterion — grep the identifiers this round's diff deletes or renames against every in-flight PR's DIFF, a hit gets the same four-sentence disposition as a file-face intersection, and ⛔ never skipped on file-face disjointness — and sits directly under the interception line (:219) it extends, above the four sentences (:221) it reuses; the seat's own measured instance (objectui#9338 / objectui#9343, two PRs each green alone and red on one tree because one PR's assertion named a row the other deleted) is what the leg would have caught, and no rule or tool on origin/main asks for it (dev's grep witness|点名证人|deleted or renamed over .claude/skills/pm-dispatch + scripts/pm → only script-header prose; control 在飞重叠 hits SKILL.md :550/:551 and runbook :220). (b) Payment: the deleted :213 「⛔ 不在消费者侧打补丁;只写一个路径名,是要求 dev 在守约与修对之间二选一。」 — its prohibition is stated on origin/main at SKILL.md :549 (「…⛔ 不在消费者侧打补丁。」) and AGENTS.md :234 (Prime Directive 12, no lenient alias or ?? fallback in a consumer); 「只写一个路径名」 is the single X of :211 「预期落点是 X」; what is lost is the rationale tail (「是要求 dev 在守约与修对之间二选一」), which appears nowhere else — a density trade, flagged to the maintainer in the 速读 with the alternative the dev noted (SKILL.md :550 already carries a compressed copy of runbook :220, so :220 itself is the next density candidate). (c) Declared deviation accepted: the claim fixed the surface as :220–:221 AND payment inside 〈派发词构造细则〉; :220–:221 carry no deletable clause, so payment at :213 in the same section satisfies the section constraint and breaches the line-range one — declared in the report, not silent. Measured on the head by the seat: 241 → 241 lines (ceiling 241, headroom 0), no line over 120 bytes (new line 118 B), control-character scan clean, 不因文件面不相交跳过 0 → 1, 不在消费者侧打补丁 1 → 0, 只写一个路径名 1 → 0, control 在飞重叠 1 → 1 and 四句:合 main 1 → 1; single commit, Fixes #17935 once, one footer, ## 维护者速读(草稿) present. No accept-set or public-surface change (check-clause2-carriers --pair 17956 exit 0, seat-run, both carriers Clause-②: no, no widening tell).
② semver: .claude/** publishes nothing ⇒ skip-changeset (present on the PR, read back); consistent with the declared Clause-②: no.
③ boundary flags: none raised (open_questions: []). Two out-of-scope notes carried as the dev named them (SKILL.md :550 as the next density candidate for the #17905 SKILL.md chain; the /labels write silently no-ops without Content-Type: application/json, already in this seat's platform readings).

Implemented-by: claude/issue-17935-inflight-overlap-witness-grep (mode:subagent)
Reviewed-by: session_01DAcomhvR9kKizeYgg89Vo8

Verdict: PASS. Governed surface (.claude/**): no gate carrier was hung (the content limb is reviewed here); the PR stays a draft for the maintainer's hand merge.


Generated by Claude Code

@claude

claude Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)

改了什么 —— 只动 .claude/skills/pm-dispatch/references/dispatch-runbook.md 两行(加一、删一,241 → 241)。「在飞重叠」拦截从一问变两问:文件面求交之外,把本轮 diff 删除/改名的标识符 grep 每个在飞 PR 的 diff,命中同发那四句,⛔ 不因文件面不相交跳过。

为什么改 —— 你今早点名的第三张卡(#17935):两个 PR 各自全绿、合到一棵树才红,因为一个 PR 的断言点名了另一个 PR 删掉的那一行;现行规则只问文件面,答不到这种耦合。ledger、豁免表、drift 表这类「在缩小的表」都会再撞到。

风险与代价(含回滚) —— 每轮派发多一次 grep;无新工具、无新门禁。买单的是同节 :213 那行:它的禁令(不在消费者侧打补丁)原文仍在 SKILL.md :549 与 AGENTS.md 第 12 条,「只写一个路径名」就是 :211 的那个 X;真正丢的是半句理由(「要求 dev 在守约与修对之间二选一」),别处没有。若你想留这半句,替代买单是 :220 本行——SKILL.md :550 已有它的压缩副本——那要等 #17905 的 SKILL.md PR 一起做。回滚 = 还原这一个文件的两行。

席位意见 —— 收。本席在 head da4eee77 上亲核:新句 1、被删句 0、对照句在;无行超 120 字节;控制字符扫描干净;单父提交;check-clause2-carriers --pair 17956 exit 0;dev 侧 14 个派生门禁全 exit 0 并对账(含 check:pm-skill-ratchet 241/241);契约复核 PASS 记录在本 PR 上一条。dev 申报了一处偏离:认领指定 :220–:221 且同节买单,两者不能同时成立(那两行无可删子句),故买单落在同节 :213——已申报,本席接受。CI 在读时 Lint & Repo Gates(棘轮所在)仍在跑,其余全绿。base 已被 #17908 推进(不碰本文件),合入无冲突。

你要做的(一个动作) —— 受管面(.claude/**):CI 转绿后,若接受 :213 的买单就 approve 并人工合入;若要留那半句理由,一句话回我,本席退回 dev 改按 :220 买单。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 13, 2026 08:12
@os-zhuang
os-zhuang enabled auto-merge September 13, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-user-decision size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants