Skip to content

feat(pm): free-claim multi-seat — one lane, a set of seats, one post per seat - #18436

Merged
os-elon-musk merged 2 commits into
mainfrom
claude/issue-18394-free-claim-multi-seat
Sep 16, 2026
Merged

os-elon-musk merged 2 commits into
mainfrom
claude/issue-18394-free-claim-multi-seat

Conversation

@os-elon-musk

Copy link
Copy Markdown
Collaborator

Fixes #18394

Option D — free-claim multi-seat: several execution PMs on one lane, each on its own numbered seat, claiming from the same queue. Protocol text in .claude/skills/pm-dispatch/SKILL.md, references/core-rules.md, references/seat-post-protocol.md; patrol reader scripts/pm/check-half-states.mjs H38 filtered by seat number, with self-test cases. Rules-layer governed PR: draft, hangs as a four-piece for an authorized APPROVED; the dev never flips it ready, never arms auto-merge, never requests review.

维护者速读(草稿)

改了什么:协议正文由「一座位一车道双射、每域恰一 PM」改为「一个 PM 恰管一车道,一车道由一组席位管,一席一贴」。认领评论多写一行 Seat: domain:X#N(缺省席 1);开轮互斥读数三/四只读同席号的认领,他席的认领不再让本席自退;派发前多读一次本车道 pm:dispatched 卡认领申报的文件面,相交就排在那张 PR 之后串行或让行(候选枚举已整车道一次列出,本地求交,不新增查询)。多席车道的座位贴标题为 [PM seat] domain:X · seat N,席 1 沿用现贴。巡查 check-half-states 的 H38 按席号过滤:座位贴只和本席的认领比先后。

为什么改:spec 车道排队 95 张,近三天出口 9 / 9 / 3,瓶颈是一车道一账号的写额度与复核时间。第二个账号今天进不来,是因为协议把「一车道一 PM」写成了不变量、互斥读数把任何他会话认领都读成占席。改这几句,第二个账号跑 /pm-dispatch spec 即可坐席;ui、devx 车道拿同一份文本直接可用。

风险与代价(含回滚):三个文件的行数棘轮零余量,新增全部就地以删减付账:SKILL.md 812 → 812(上限 812),core-rules.md 151 → 151(上限 151),seat-post-protocol.md 90 → 91(上限 91,用掉仅有的一行余量)。被删的三行「跨域例外路径 / 定向在飞检查 / 日常同域不跑在飞检查」合并成两行,规则一条不丢(跨域范围、读认领文件面、相交让行都在)。风险:同一车道多席在全序顶端偶发认领撞车,由既有的原子认领 + 回读 + 时间戳仲裁处理;Seat: 行写错席号会让 H38 少报(不误报)。回滚 = revert 本 PR 一个 commit,座位贴标题后缀与 Seat: 行随之失效,不留状态。

席位意见:(留空,席位填)

你要做的:一个动作 —— 批准 review(authorized APPROVED),之后由 skills 席按裁决 C 落地。

四棱(对 D)

  • 实际业务需求 — 实测读数:spec pm:queue 95(objectstack)+ 15(objectui),近三天出口 9 / 9 / 3,12 天净增 34;ui 133、devx 63 同样积压。写这份文本的是 skills 席,读它的是每个坐席的 PM 会话与巡查脚本;第二个账号今天就想坐进 spec 车道而进不去,是真实存在的场景,不是投机能力面。
  • 项目长远合理性 — D 与既有「分席(域×仓)」先例同构,只把分席轴从仓换成席号;不加标签、不加跟踪器、不改分诊、不改 batch。A(按目录切分区)只对 spec 成立,ui/devx 还要各自再切;D 车道无关,一份文本三个车道用。规则层文本只改被 D 触碰的句子,存量中文不追溯改写。
  • 防 AI 犯错 — 撞车三道防线:认领原子写 + 回读(已有)、Seat: 行让互斥读数不误退、派发前读他席在飞文件面。机器判据收紧而不是消费端宽容:Seat: 行存在却读不出席号 ⇒ 视为不可读、匹配不到任何席(少报方向),⛔ 不默认成席 1;标题 · seat N 后缀先剥离再判车道,判据与裸贴完全一致。H38 只和本席认领比先后,第二席不再每次 fire 都被巡查误报 STALE。
  • 创业阶段不扩散需求 — 一张 PR、零新标签、零新门禁、零新账号形态、batch 不动;三个棘轮零余量下全部就地付账,没抬任何上限。先 spec 两席试一轮,验证 Seat: 行与 H38 后再开 ui / devx。

What changed, per file

  • SKILL.md 入口与角色: readings three and four read only claims carrying the same seat number.
  • SKILL.md 全体座位的不变量: the bijection clause becomes one PM ⇒ one lane, one lane ⇒ a set of seats, one post per seat.
  • SKILL.md 多仓协调: the 分席 pair generalised from repo to seat number and carries the Seat: domain:X#N claim line (absent = seat 1; same-seat claims exclusive, another seat's claim does not trigger self-exit); rule 4 restated as one PM ⇒ exactly one lane, a lane may seat several.
  • SKILL.md 域车道: the seat index clause becomes one set of posts per lane, exactly one per seat; the three in-flight-check lines fold into two — the same-domain in-flight check before every dispatch (dispatched cards' claimed file faces, local intersection, no new query) plus the cross-domain exception path's wider scope and the serial-or-yield remedy.
  • SKILL.md 模板与表: the claim template gains Seat:.
  • core-rules.md: the four-readings digest, the bijection digest and the in-flight-check digest follow.
  • seat-post-protocol.md: title vocabulary gains the domain:X · seat N suffix (seat 1 keeps the bare title); a new post (split domain or added seat) numbers itself as the lane's current maximum plus one.
  • check-half-states.mjs (H38 region only): seatLane strips a · seat N suffix into a seat field before the lane test (absent = 1); claimSeatNumber reads the claim's Seat: line with the file's key-line tolerance (absent = 1, present-but-unreadable = null); newestLaneClaim takes the seat and filters the rows handed to the reused latestClaimComment; the finding sentence names the seat; the call site passes the post's seat. 26 self-test cases added (4270 → 4296): same-seat newer claim ⇒ finding, other-seat newer claim ⇒ null, absent Seat: ⇒ seat 1, · seat N title ⇒ the lane and not foreign, the refused > - key-line shape pinned as invisible. No other H-row touched; the file's entry/argv tail untouched ([finding] check-half-states.mjs --help prints no usage and silently runs the full sweep — argv is never validated, so a mistyped --repo reads the wrong repo and looks successful #18369 remains open on that region; whichever lands later merges origin/main).

Line ratchets (before / after / ceiling)

file before after ceiling
.claude/skills/pm-dispatch/SKILL.md 812 812 812
.claude/skills/pm-dispatch/references/core-rules.md 151 151 151
.claude/skills/pm-dispatch/references/seat-post-protocol.md 90 91 91

Every added line paid by an in-place deletion in the same file (SKILL.md: 分席 pair rewritten 2 → 2, in-flight trio 3 → 2, template +1; core-rules: three lines rewritten in place; seat-post-protocol: +1 inside the existing one-line headroom). No re-wrap counted as payment; no ceiling raised. Every edited line is within the 120-byte line budget.

Gates (run at a07d739f, exit codes captured before any pipe)

node scripts/pm/dispatch-gates.mjs --commands derived 47 families from the merge-base changeset; --ran reconciles 47 derived / 47 run / 0 NOT-MEASURED, all exit 0. Named: pnpm check:pm-skill-ratchet 0 · pnpm check:pm-skill-id-lint 0 · pnpm check:skill-frame-sync 0 · pnpm check:skill-frame-freshness 0 · pnpm check:pm-half-states 0 (4296 cases) · pnpm check:nul-bytes 0 · pnpm check:pm-governed-prose 0 · pnpm check:pm-governed-merges 0 · pnpm check:pm-dispatch-gates 0. pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 (prerequisite: unbuilt @objectstack/formula + @objectstack/lint dist — not a measurement), exit 0 after building that two-package closure under the verify lock. Full farm runs in CI.

Changeset

skip-changeset, on AGENTS.md Post-Task Checklist step 3: 「that label is for a diff that publishes nothing from any released package」 — .claude/** and scripts/pm/** ship in no package files[]; nothing published moves.

Acceptance notes

  • Scope honoured per ruling 5695364899: no domain:* split, no new label, no batch change, no objectui edit. The objectui mirror of check-half-states.mjs H38 is out of scope here: [finding] objectui's half-state findings reach no reader: the board has no anchor by ruling, and its copy of check-half-states still refuses in agent containers with the conclusion #13544 disproved #18290 remains open and owns it.
  • origin/main moved three commits past the base (588475c30c573f09) while this branch was open; none touches the four files here, so no merge was performed — the queue rebuilds as merged.
  • Existing Chinese outside the lines D changes is not retouched. Two lines whose 「只在 / 只此路径」 wording became false under D (SKILL.md 域车道 cross-domain-only clause; core-rules digest of it) were reworded as part of the D change.
  • noted, not filed: seatLane's docblock census (「2026-08-25 census, all 12 open seat posts」) is a dated reading; the fourth shape was appended rather than the census re-measured. 承接者: the skills seat on its next check-half-states.mjs touch.
  • noted, not filed: the H38 finding sentence still narrates the 2026-08-30 specimen (「~31h to wave 4」); unchanged, as the ruling did not open the sentence. 承接者: none.

Generated by Claude Code

…per seat

Protocol text (option D): a PM manages exactly one lane, a lane is managed
by a set of seats, one seat post per seat. The claim template gains a
`Seat: domain:<x>#<n>` line; mutex readings three and four read only the
same seat number's claims; the same-domain in-flight check reads the lane's
dispatched claims' file faces before each dispatch (local intersection, no
new query). Seat posts on a multi-seat lane are titled
`[PM seat] domain:X · seat N`; seat 1 keeps today's post.

check-half-states H38: `seatLane` parses the `· seat N` suffix as a seat
number (absent = 1) and keeps the lane; `claimSeatNumber` reads the claim's
`Seat:` line (absent = 1, present-but-unreadable = null); `newestLaneClaim`
takes the seat and filters the rows handed to the shared claim predicate,
so a post is compared only against its own seat's claims. Self-test cases
cover both readings, the defaults and the cross-seat null.

Line ratchets paid in place: SKILL.md 812 -> 812, core-rules 151 -> 151,
seat-post-protocol 90 -> 91 (ceiling 91).

Claude-Session: https://claude.ai/code/session_01HPfcjvF23QBoBj7P47DDxs
Co-authored-by: Claude <noreply@anthropic.com>
The reader mirrors `claimedBranches`: bullet-then-blockquote is in,
blockquote-then-bullet is out. The fixture now pins both directions.

Claude-Session: https://claude.ai/code/session_01HPfcjvF23QBoBj7P47DDxs
Co-authored-by: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator Author

维护者速读(终稿)

skills 席,session_01HPfcjvF23QBoBj7P47DDxs,2026-09-16T10:41Z。席内复核 ACCEPT 记录在卡 #18394;裁决 D 出处 5695364899(「我已经同意了。」)。受管规则层 ⇒ 等一位授权批准账号 APPROVED 后由本席按裁决 C 落地;在此之前保持 draft。

改了什么
四个文件。SKILL.md ±10 行:互斥读数三/四改按「同席号」过滤;「一座位一车道双射」改为「一 PM 恰管一车道,一车道由一组座位管,一席一贴」(规则 4、座位索引句同改);分席条改成席号轴并规定认领评论带 Seat: domain:X#N(缺省席 1,他席认领不触发自退);「日常同域不跑在飞检查」改为派发前读本车道在飞卡申报的文件面、本地求交、相交即串行或让行;认领模板加 Seat: 行。core-rules 三处摘要同步。seat-post-protocol +1:多席车道每席一贴,标题 domain:X · seat N,席 1 沿用现贴;新贴席号取最大加一。check-half-states.mjs 只动 H38:座位贴标题解析席号、认领读 Seat: 行、H38 只拿同席认领比对,加 26 条自测。

为什么改
spec 车道 95 张排队、近三日出口 9/9/3,瓶颈是「一车道一账号」的写额度与复核时间。D 让第二个账号直接在同一车道坐第二席,各自认领、各自派 dev、各自复核落地;认领撞车靠既有的原子写 + 时间戳仲裁,巡查 H38 按席号过滤才不会把他席的认领误报成本贴过时。不切目录、不加标签、分诊不改。

风险与代价(含回滚)
棘轮全部在上限:SKILL.md 812/812、core-rules 151/151、seat-post-protocol 91/91(用掉唯一 1 行余量),新增全靠就地删减付账——删掉的是 D 下已不成立的「分席不改协议文本」与「只在跨域路径跑在飞检查」两句。代码侧默认 seat = 1,现有单席贴与所有旧认领读法不变(有用例钉住)。objectui 的 H38 镜像未同步(裁决明列不在范围,归 #18290),同步前 objectui 巡查会把带 · seat N 的贴读作 foreign——只是巡查静默,不挡认领。回滚 = revert 本 PR 一个 squash 提交。

席位意见
建议批准。四处协议改动逐句对得上裁决授权的范围,没有多做;代码只在 H38 区,自测、棘轮、id-lint、frame-sync 都在 PR head 上由本席亲跑通过。合入后第二个账号即可 /pm-dispatch specdomain:spec · seat 2 坐席。

你要做的
一个动作:在本 PR 上 Approve。


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Landing-window note — this queue build is expected to go red, and the red is NOT this PR's — skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T11:12Z.

Ruling C readings at this instant: os-zhuang APPROVED 5221866521 on the current head a07d739f ✓ · check-clause2-carriers.mjs --pair 18436 exit 0 ✓ · ready + auto-merge + enqueue by the approver at 11:10Z ✓ (queue ref gh-readonly-queue/main/pr-18436-* present; added_to_merge_queue 11:10:01Z). The seat's needs-user-decision strip is refused by its harness classifier (same as on PR #18423) — the label stays and does not gate the queue.

Expected failure, measured before it happens: the queue builds this PR on top of PR #18430 (queued ahead, commit b6fe311a). In this PR's queue commit 9c31e270, scripts/pm/check-half-states.mjs is 2,103,266 bytes (git cat-file -s); scripts/check-closing-keyword-parity.mjs skips any file over 2,097,152 bytes before reading it and then reports the registered parser as 「is registered as carrying the closing-keyword grammar but no longer matches the sweep. Stale registry entries verify nothing -- remove it, or fix the signature.」 — inside Lint & Repo Gates, which runs on merge_group. The registry row is correct; the size is the cause; the text names neither.

Signature (for the merge-queue triage): failing step = check-closing-keyword-parity in Lint & Repo Gates; first error line = the stale-registry sentence above naming scripts/pm/check-half-states.mjs. Root cause card: #18435 (p2 Bug, dispatched 11:00Z by this seat: registered parsers are never size-skipped). ⛔ Do not re-enqueue until #18435's fix is on origin/main; ⛔ do not remove the registry row; ⛔ no change to this PR's diff is owed (it adds 7,767 B of protocol code and cases exactly as the ruling asked). Once the fix lands, the base carries it and this seat re-arms auto-merge on this head — no new commit needed. PR #18437 (#18385, the H44 fix) waits in the same line for the same reason.


Generated by Claude Code

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 16, 2026
@os-elon-musk
os-elon-musk added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit 62ab658 Sep 16, 2026
46 checks passed
@os-elon-musk
os-elon-musk deleted the claude/issue-18394-free-claim-multi-seat branch September 16, 2026 12:37
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/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

4 participants