Skip to content

skills(pm-dispatch): hard serial across rounds applies to the same claimed region, not the same file — SKILL.md :441 and its core-rules twin - #19317

Queued
os-steve wants to merge 1 commit into
mainfrom
claude/issue-18891-region-level-serial
Queued

os-steve wants to merge 1 commit into
mainfrom
claude/issue-18891-region-level-serial

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes #18891
Clause-②: no
Ruling-ref: 5727164406 — director seat, batch 157 item 2, letter 甲, maintainer 「其他同意」 2026-09-18T08:10Z

What changed — two lines, one word each, net 0 in both files

File Line Before After Bytes
.claude/skills/pm-dispatch/SKILL.md :441 「- 同文件单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。」 「- 同区域单跨轮硬串行;延后不是搁置,被延后那一刻就把已知的坑记到该 issue 上。」 107 → 107
.claude/skills/pm-dispatch/references/core-rules.md :105 「- 同批独立性按文件面不相交判,⛔ 不按包;同文件硬串行,冲突交合并队列仲裁 ⛔ 不手排。」 「- 同批独立性按文件面不相交判,⛔ 不按包;同区域硬串行,冲突交合并队列仲裁 ⛔ 不手排。」 119 → 119

Line counts: SKILL.md 813 / 813, core-rules.md 151 / 151. :437 is untouched; SINGLE_CLAIM_PATHS stays the only whole-file single-writer set; the 「延后不是搁置…」 half stays byte-verbatim; the core-rules twin lands in the same PR as SKILL.md:44 orders. No script, no gate, no other line of either file. The commit is 5676515 on claude/issue-18891-region-level-serial, base 801415a.

Why this rendering and not the ruling's sentence verbatim — measured, not assumed

The ruling's :441 text 「同区域(认领申报的文件面重叠)单跨轮硬串行;同文件不同区域是普通并发,后落地方解冲突。」 is 123 bytes as a bullet line, and 198 bytes with the 「延后不是搁置…」 half the ruling keeps. scripts/pm/check-skill-line-ratchet.mjs (pnpm check:pm-skill-ratchet, not check:pm-governed-prose as the dispatch assumed) caps every non-exempt line of this file at MAX_LINE_BYTES = 120 and holds the file at ceiling 813 with headroom 0, so the ruling's own sentence cannot land as written under the file's own gate without a script edit that both the ruling (「⛔ no new script, no gate」) and the dispatch (net 0, no script) refuse. Readings taken on the real gate, each mutation restored to the HEAD blob (hash-verified, git diff HEAD empty) before the next:

Run :441 rendering check:pm-skill-ratchet verdict
R0 unmodified ✓ SKILL.md is 813 lines (ceiling 813; headroom 0)
R1 ruling sentence + deferral half, ONE physical line (198 B) ✗ 1 line over the 120-byte budget: L441 (198B)
R2 ruling sentence (123 B) / deferral half (79 B), TWO lines ✗ L441 (123B) over budget AND ✗ 814 lines; the ratchet ceiling is 813
R3 ruling sentence with 不同区域→异区域 (120 B) / deferral half, TWO lines ✗ 814 lines; the ratchet ceiling is 813
R4 core-rules :105 同文件硬串行 → 同区域硬串行 (119 B) ✓ core-rules.md is 151 lines (ceiling 151; headroom 0)
landed :441 同文件 → 同区域 (107 B) plus R4 ✓ both files at ceiling, headroom 0 (exit 0)

The neighbours cannot absorb the 74-byte deferral half either: :436 to :452 measure 118 / 114 / 112 / 114 / 118 / 107 / 117 / 104 / 67 / 115 / 79 / 111 / 82 / 98 / 120 / 117 / 109 bytes, and the only other line that speaks of deferral (:452, 「阻塞解除后延后单重定价…」, 109 B) has 11 bytes of slack. A bigram-Jaccard scan over the file's 627 bullet lines finds no provable duplicate to retire: the top pairs (J 0.59 down to 0.35) are distinct pointer lines into references/dispatch-runbook.md carrying different topics.

What the one-word rendering keeps, and what it delegates to lines the ruling left standing: 「同区域…硬串行」 IS the ruling's narrowing (its facet ①: one line narrower, a special case removed). The 「同文件不同区域是普通并发,后落地方解冲突」 clause is exactly what :437 already states for every non-single-writer path (「共享其它路径是普通并发,后落地方解冲突」): once :441 no longer claims the whole file, the same file in different regions is one of those other paths by elimination, and the two lines contradict on no path. The parenthetical definition of 区域 is carried by :449 (「认领申报文件面到区域级,拿不准就串行」, the escape hatch the ruling names as staying), by :278 (「区域写不清就只能整文件串行」) and by references/seat-post-protocol.md :20 (every serial-queue entry is 「每张卡认领的区域」).

The alternative the seat may prefer at review: land the ruling's sentence as R3 (120 B, two lines) and raise the SKILL.md ceiling 813 → 814 under the ratchet's own maintainer exit (「Raising a ceiling requires a maintainer ruling quoted in the PR」). The precedent is the last landing on this file, e872ef4 (PR #19033, 2026-09-19): 812 → 813 for one ruled line, with the ratchet comment 「Ruled content is not growth」. That route is a scripts/pm/check-skill-line-ratchet.mjs edit and a net +1, both outside this dispatch's constraints, so it is stated here and not taken.

Tier and landing

  • node scripts/pm/check-governed-merges.mjs --test with both paths: exit 3, GOVERNED — Tier S (席内达档复核落地), .claude/** ×2; size NOT MEASURED by --test (dispatch-gates' derived count: 4 changed lines, +2 / −2, under 5000).
  • node scripts/pm/dispatch-gates.mjs --tier on both paths: MANDATORY at CONTRACT_REVIEW_TIER (clause ①: the PM dispatch skill MAIN file).
  • This PR stays DRAFT; it lands on the owning seat's ## Contract review record for head 5676515 (AGENTS.md Prime Directive feat: Comprehensive CRM example demonstrating all ObjectStack protocol features #14). Label: skip-changeset (.claude/** publishes nothing); no changeset file.

Gates — derived union on head 5676515, each exit captured before any pipe

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from the worktree with no paths (changeset 2 committed / 0 working tree / 0 untracked vs merge base 801415a) derived 20 commands, identical to the dispatch-time lead; --ran reconciles 20 derived / 20 run / 0 UNRUN. Two extras were run because the derivation flags them: check:pm-settings-deny-roster (a roster under .claude, marked silence-is-not-evidence) and check:skill-frame-freshness (pins the four-axis block).

Command Exit
pnpm check:pm-skill-ratchet 0
pnpm check:pm-skill-id-lint 0 (27 files clean)
pnpm check:pm-governed-prose 0
pnpm check:skill-frame-sync 0
pnpm check:skill-frame-freshness 0 (current with origin/main)
pnpm check:pm-governed-merges 0
pnpm check:pm-expected-skips 0
pnpm check:pm-half-states 0
pnpm check:doc-authoring 0
pnpm check:nul-bytes 0 (9034 text files, no raw control bytes)
pnpm check:agent-test-spelling 0
pnpm check:cross-package-test-inputs 0
pnpm check:driver-memory-census 0
pnpm check:refd-timer-probe 0
pnpm check:watch-hint-literal 0
pnpm check:pm-settings-deny-roster 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions 3 then 0 — the first run was PREREQUISITE NOT MET (@objectstack/formula and @objectstack/lint not built; the gate says nothing was measured); after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the verify lock (4/4 cached), the rerun is exit 0: 58 self-test cases, 22 / 9 / 14 examples judged clean
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 (6920 files, 0 disagree)
node scripts/pm/check-governed-queue-guard.mjs --self-test 0
node scripts/pm/check-harness-current.mjs --self-test 0
node scripts/pm/check-governed-merges.mjs --test (both paths) 3 = GOVERNED, Tier S (the expected code)

The last commit is 5676515 and every command above ran after it. origin/main moved by one commit since the base (e3b3cdd, metadata-protocol) that touches neither edited file nor the ratchet, so no merge is owed before review.

Acceptance notes

  • noted, not filed: SKILL.md :120 (the priority:p0 table row 「⛔ 不豁免同文件串行、深度等待与认领协议」), its core-rules twin :36, and references/lanes/services.md :26 (「同文件卡跨轮硬串行」, a lane-specific stricter rule) still name the serial discipline by FILE. The ruling scoped :441 and :105 only; these are name references to the discipline, not a second definition, so they are a naming nit rather than a defect class. 承接者: the domain:skills seat's next SKILL.md card.
  • noted, not filed: check-closing-keyword-parity prints an informational line that packages/spec/api-surface-declarations/system.txt (3,568,357 bytes) exceeds its 2 MiB cutoff for unregistered files; exit 0 and pre-existing on origin/main. 承接者: none identified.
  • The two neighbouring lines the ruling names as staying were read and left alone: :437 (unchanged by the ruling) and :449 (「拿不准就串行」).

维护者速读(草稿)

改了什么

派发协议「候选与批次」一节里的一条并发规则改了一个词:原来写「同文件单跨轮硬串行」,现在写「同区域单跨轮硬串行」;核心条款摘要里的同一条规则同步改成「同区域硬串行」。两处各改一个词、各不增减行数;:437(single-writer 路径只由 SINGLE_CLAIM_PATHS 枚举,其它路径普通并发)原样不动。

为什么改

同一节里原有两条互相打架的规则:一条说除 .objectui-sha 之外的所有共享文件都是普通并发、后落地的一方解冲突;四行之后另一条说同一文件的卡跨轮必须硬串行。SINGLE_CLAIM_PATHS 只有一条,所以对仓里的每一个文件两条规则都给出相反指令;各席位各自选了一条执行,一张停在决策箱里的 PR(25 个 spec 文件)就把 spec 车道大半冻住。裁决(甲)把「硬串行」收窄到「认领申报的文件面重叠的区域」:同文件不同区域是普通并发,后落地方解冲突。改动后,同文件异区域自然落到 :437 的「其它路径普通并发」,两条规则在任何路径上都不再冲突。

风险与代价(含回滚)

风险:裁决原句(「同区域(认领申报的文件面重叠)单跨轮硬串行;同文件不同区域是普通并发,后落地方解冲突。」)本身 123 字节,超过本文件 120 字节的行宽门禁;加上裁决要求保留的「延后不是搁置…」半句共 198 字节;文件又顶在 813 行的棘轮上限、余量为零,所以裁决原句无法原样落地(门禁实测:一行写法红,两行写法也红)。本 PR 采用最小改法(一个词),把「同文件异区域普通并发」这半句交给紧邻的 :437 承担,把「区域」的定义交给 :449 与串行队条款承担。若席位认为裁决原句必须逐字落地,替代路线是按棘轮自己的维护者例外把上限抬到 814(先例:2026-09-19 的 e872ef4),那需要改脚本、净增一行,不在本单授权内。回滚:两个文件各回退一个词,零副作用。

席位意见

(留空,席位定稿)

你要做的

无需你操作:这是 Tier S 受管面,由 skills 席位做契约档复核后经队列落地。只有一处可能需要你一句话:若你希望裁决原句逐字进入 SKILL.md(而不是本 PR 的一词改法),请回「抬上限」,席位据此改走 813 → 814 的路线。


Generated by Claude Code

…aimed REGION, not the same file — SKILL.md :441 and its core-rules twin, one word each

Clause-②: no

The 候选与批次 section gave two opposite serial rules for every shared path
but `.objectui-sha`: :437 (「共享其它路径是普通并发,后落地方解冲突」) and :441
(「同文件单跨轮硬串行」). Ruling 甲 narrows :441 to the REGION the claim
declared: hard serial across rounds only where the two claims' declared file
surfaces overlap; the same file in different regions is ordinary concurrency
and the later lander resolves the conflict — which is what :437 already says
for every non-single-writer path once :441 stops claiming the whole file.

- SKILL.md :441 — 同文件 → 同区域 (107 B → 107 B); the 「延后不是搁置…」 half
  stays byte-verbatim; :437 untouched; `SINGLE_CLAIM_PATHS` stays the only
  whole-file single-writer set; 813 / 813.
- references/core-rules.md :105 — 同文件硬串行 → 同区域硬串行 (119 B → 119 B),
  the twin SKILL.md:44 orders; 151 / 151.

The ruling's own :441 sentence (「同区域(认领申报的文件面重叠)单跨轮硬串行;
同文件不同区域是普通并发,后落地方解冲突。」) measures 123 B alone and 198 B
with the deferral half, against the ratchet's 120-byte line cap and a 813-line
ceiling with zero headroom; measured red on the gate in both one-line and
two-line forms. The one-word narrowing is the rendering that keeps the
deferral half verbatim, net 0, no script, no gate — the PR body carries the
measurements and the alternative (a ceiling raise under the ratchet's own
maintainer exit).

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

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 567651564c2ea9962cb110d64d39def7611c3d35

① Derived judgments

  • Accept set / public surface: none moves — two one-word edits in protocol prose (SKILL.md :441, core-rules.md :105), no script, no gate. Judged correct.
  • Ruling 甲 (5727164406) realised clause by clause on this head: same-REGION hard serial across rounds (:441 「同区域单跨轮硬串行」); same file, different regions = ordinary concurrency, the later lander resolves — now stated unopposed by :437 (「共享其它路径是普通并发,后落地方解冲突」, byte-unchanged, as the ruling requires); the region is what the claim declares (:449 「① 认领申报文件面到区域级,拿不准就串行」 — 「拿不准就串行」 kept); the 「延后不是搁置…」 half byte-verbatim; SINGLE_CLAIM_PATHS stays the only whole-file single-writer set; the core-rules twin moved in the same PR. Judged correct: after the change the two lines contradict on no path, which is what the card was filed for.
  • The ruling's own :441 sentence (123 B alone, 198 B with the deferral half) does not fit MAX_LINE_BYTES = 120 on a file at headroom 0, and the dev measured that red on the real gate in one- and two-line forms with no retirable duplicate (627-bullet scan). The seat adopts rendering A (this PR) over B (the verbatim sentence plus a ceiling raise 813 → 814): B restates what :437 already says and costs a ratchet raise that belongs to the maintainer's floor; A loses no operative clause. The ruling's owner keeps the veto — this is a wording choice under a mechanical cap, ⛔ not a re-ruling.
  • Ratchet / lint / prose, seat-run on this head: check-skill-line-ratchet.mjs exit 0 (813 / 813, 151 / 151), check-skill-id-lint.mjs exit 0, check-governed-prose.mjs exit 0.

② Semver level

None — .claude/** publishes nothing; skip-changeset on the PR is the correct declaration. Judged correct.

③ Boundary flags

open_questions[0] (A vs B) — answered A above by the seat; not a contract fork. Two noted, not filed read: three sites still NAME the discipline by file (SKILL.md :120 p0 row, core-rules.md :36, references/lanes/services.md :26 — references, not a second definition) — recorded on the seat post as the next SKILL.md card's rider; the 2 MiB informational line from check-closing-keyword-parity is pre-existing on origin/main. Neither owes a card.

Implemented-by: claude/issue-18891-region-level-serial
Reviewed-by: session_017ETYWqMQD4qMtZzAGovWNi

VERDICT: PASS


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review September 20, 2026 12:42
@os-steve
os-steve added this pull request to the merge queue Sep 20, 2026
Any commits made after this event will not be merged.
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 size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant