feat(pm): free-claim multi-seat — one lane, a set of seats, one post per seat - #18436
Conversation
…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>
维护者速读(终稿)skills 席, 改了什么 为什么改 风险与代价(含回滚) 席位意见 你要做的 Generated by Claude Code |
|
Landing-window note — this queue build is expected to go red, and the red is NOT this PR's — skills seat, Ruling C readings at this instant: os-zhuang APPROVED 5221866521 on the current head Expected failure, measured before it happens: the queue builds this PR on top of PR #18430 (queued ahead, commit Signature (for the merge-queue triage): failing step = Generated by Claude Code |
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 readerscripts/pm/check-half-states.mjsH38 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)
pm:queue95(objectstack)+ 15(objectui),近三天出口 9 / 9 / 3,12 天净增 34;ui 133、devx 63 同样积压。写这份文本的是 skills 席,读它的是每个坐席的 PM 会话与巡查脚本;第二个账号今天就想坐进 spec 车道而进不去,是真实存在的场景,不是投机能力面。batch。A(按目录切分区)只对 spec 成立,ui/devx 还要各自再切;D 车道无关,一份文本三个车道用。规则层文本只改被 D 触碰的句子,存量中文不追溯改写。Seat:行让互斥读数不误退、派发前读他席在飞文件面。机器判据收紧而不是消费端宽容:Seat:行存在却读不出席号 ⇒ 视为不可读、匹配不到任何席(少报方向),⛔ 不默认成席 1;标题· seat N后缀先剥离再判车道,判据与裸贴完全一致。H38 只和本席认领比先后,第二席不再每次 fire 都被巡查误报 STALE。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 theSeat: domain:X#Nclaim 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 gainsSeat:.core-rules.md: the four-readings digest, the bijection digest and the in-flight-check digest follow.seat-post-protocol.md: title vocabulary gains thedomain:X · seat Nsuffix (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):seatLanestrips a· seat Nsuffix into aseatfield before the lane test (absent = 1);claimSeatNumberreads the claim'sSeat:line with the file's key-line tolerance (absent = 1, present-but-unreadable = null);newestLaneClaimtakes the seat and filters the rows handed to the reusedlatestClaimComment; 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, absentSeat:⇒ seat 1,· seat Ntitle ⇒ 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 --helpprints no usage and silently runs the full sweep — argv is never validated, so a mistyped--reporeads the wrong repo and looks successful #18369 remains open on that region; whichever lands later mergesorigin/main).Line ratchets (before / after / ceiling)
.claude/skills/pm-dispatch/SKILL.md.claude/skills/pm-dispatch/references/core-rules.md.claude/skills/pm-dispatch/references/seat-post-protocol.mdEvery 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 --commandsderived 47 families from the merge-base changeset;--ranreconciles 47 derived / 47 run / 0 NOT-MEASURED, all exit 0. Named:pnpm check:pm-skill-ratchet0 ·pnpm check:pm-skill-id-lint0 ·pnpm check:skill-frame-sync0 ·pnpm check:skill-frame-freshness0 ·pnpm check:pm-half-states0 (4296 cases) ·pnpm check:nul-bytes0 ·pnpm check:pm-governed-prose0 ·pnpm check:pm-governed-merges0 ·pnpm check:pm-dispatch-gates0.pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3 (prerequisite: unbuilt@objectstack/formula+@objectstack/lintdist — 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/**andscripts/pm/**ship in no packagefiles[]; nothing published moves.Acceptance notes
domain:*split, no new label, nobatchchange, no objectui edit. The objectui mirror ofcheck-half-states.mjsH38 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/mainmoved three commits past the base (588475c3→0c573f09) while this branch was open; none touches the four files here, so no merge was performed — the queue rebuilds as merged.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 nextcheck-half-states.mjstouch.Generated by Claude Code