Skip to content

docs(pm-dispatch): a project-run seat form beside the Routine form — the seat post as a stub, the dispatch order in the card thread, event wake plus one patrol per project, 项目总监 → 总监席 - #25385

Draft
objectstack-fleet[bot] wants to merge 6 commits into
mainfrom
claude/project-thread-hxtlri

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Fixes #25379

Clause-②: no
Metadata-protocol: none

维护者速读(草稿)

  • 改了什么:pm-dispatch 技能里加一种「项目席」形态,与 Routine 席并列:席位会话是车道项目的线程时,座位贴降为存根(只留别的账号要读的四项:在座账号与项目、上任时刻、热文件串行队、指针行,外加可选撞墙注记),姿态、台账、班次叙事与轮报住项目;派发令由协调者写进卡线程开场消息,不再落共享目录;唤醒 = 每张卡 PR 的订阅事件 + 每项目一个 2–4 小时巡查 routine,不再有自绑 cron、send_later 链与跨墙定时器链;轮报 = 卡线程清单,五项健康指标进总监项目的每日摘要;「项目总监」改称「总监席」、「项目协调者」改称「协调者」,GitHub 的 org Project 改称「看板」,并在入口表定义「车道项目」与「总监项目」。第五个提交是卡上预告的跟进:coordinator.md 落地后补指针与改名,两处「派发令文件」改「派发令全文」,巡查行点名前提过时检查,cross-repo 规则 5 的 org Project 也改「看板」。
  • 为什么改:您 2026-10-23 在「车队机制迁往 Projects」线程的原话:「同意,你现在就立卡派发处理。」(对调研备忘推荐字母 1B 2A 3B 4B 5B 与第 9 节命名的同意)。
  • 风险与代价(含回滚):纯规则文本,八个文件行数全部净零、每行 ≤120 字节,无上限抬高;一次 revert 可回。两处要您知道:① 卡上第 3 项「线程开起前先命名分支」实测做不到——分支由平台在线程建立那一刻指定,协调者只能在线程建起之后读到它;您 2026-10-23 11:29 在决裁批 Add Changesets and GitHub Actions automation #4 裁了 1A(协调者开线程即读分支交席位、席位认领、线程核对),第三个提交已照裁写进 runbook 〈卡线程〉与 os-dev.md 规则 1(卡线程不推空分支)。② 为付行数删掉了三条 Routine 席专用规则(自绑 cron、send_later 加速器、跨墙每小时 cron 链),正是卡上点名的付账行;维护者在 UI 建的 Routine 席不受影响;同批 2A 补上直连会话的唤醒规则(按召唤跑,⛔ 无自醒不常驻),写在 SKILL.md 分诊席那一行。
  • 席位意见:(席位复核后填)
  • 你要做的(一个动作):等席位对新 head 的契约复核 PASS、CI 全绿后说一句「可以落地」。

What changed

Nine files under .claude/skills/pm-dispatch/** (references/coordinator.md joins once PR #25255 landed, and references/cross-repo-coordination.md by the seat's one-line widening) plus, after the maintainer's batch-4 ruling, .claude/agents/os-dev.md (the seat widened the claim's file surface by that one file, same Tier S); rule text only; every file lands at the same line count it had, every edited line is at or under 120 bytes, no ratchet ceiling moves (so scripts/pm/check-skill-line-ratchet.mjs is untouched).

File Before After
SKILL.md 红线 org Project 只是视图 看板(org Project)只是视图 — the vocabulary line for GitHub's board; 「任何」 dropped to stay under the byte cap, meaning unchanged
SKILL.md 入口与角色 (the domain row, the director row) lane seat / 「项目总监席」 the lane row defines 「车道项目」 (the project running that lane); the director row reads 「总监席」 and defines 「总监项目」 (the project the director seat sits in). Table rows, under the 342-byte row pin
SKILL.md 入口与角色 bullets 「入座即建唯一自绑 cron Routine…」 and 「轮末 send_later 是可选加速器…」 「席位两形:Routine 席与项目席(会话是车道项目的线程);细则见 references/seat-lifecycle.md」 and 「项目席唤醒 = PR 订阅事件 + 每项目一个巡查 routine;⛔ 无自绑 cron、无 send_later 链」 — the two Routine-seat-only mechanisms the card names as payment are the two lines replaced
SKILL.md 升级与决策 「项目总监席:维护者在所在仓召唤…」 「总监席:…」 (rename only; PR #25255 deletes this line, so its landing takes the deletion)
references/seat-lifecycle.md 〈座位贴协议〉 — +2: the project seat's post is a stub holding only what another account reads (template in seat-post-protocol.md); posture, ledger and round reports live in the project; title, assignee, the seating audit comment and the cross-account hand-over brief stay
references/seat-lifecycle.md 〈轮次报告与节奏〉 — +1: a project seat's round report is the card-thread checklist, ⛔ no per-round chat table; the five health figures go to the 总监项目's daily digest
references/seat-lifecycle.md 〈断粮与跨墙恢复〉 the cross-wall timer chain (fixed-point timer; hourly cron Routine when no reset time; delete the cron after the first good fire) and 「随后重挂常规巡检 → 照常跑轮」 −3: the three timer-chain lines leave (they are the self-bound-cron / send_later chain the card names as payment); the recovery line keeps its steps and ends in 「照常跑轮」 (the 「重挂常规巡检」 clause referred to the deleted chain); +1: the project patrol routine runs the lanes' standby items every 2–4 hours, a wall leaves only a stub note, ⛔ no cross-wall timer chain
references/seat-post-protocol.md 〈贴的四段与派生视图〉 — +2: the stub's four items (seated account and project · seating time · hot-file serial queue · the pointer line) and the optional fifth line (wall note with the expected reset time); the stub is refreshed only on seating, a serial-queue change, a wall and hand-over
references/seat-post-protocol.md 〈交接收尾清单〉 step 8 「list_triggers 清点本会话定时器:删入座 Routine,一次性的逐个清理或随移交物转交」 −1: the step inventoried the self-bound seat Routine and one-off timers that no longer exist in the protocol; steps 9–10 renumbered 8–9. The no-orphan-timer rule itself stays in platform-readings.md 〈断粮检测与跨墙恢复〉
references/seat-post-protocol.md 〈座位 Routine 创建〉 「会话内 create_trigger 的 fresh-session Routine 不挂 repo sources,拿不到 GitHub 工具」 + 「表现为静默零产出;⛔ 不要在会话里 create_trigger 出一个座位 Routine 就当它在跑」 −1: one line — the fact (no GitHub tools, zero output) and the rule (do not treat an in-session create_trigger Routine as a running seat); the 「不挂 repo sources」 mechanism is already the reading in platform-readings.md
references/dispatch-runbook.md 〈卡线程〉 「派发令落项目共享目录 /mnt/project-files/…/dispatch-….md:线程读不到席位 scratchpad」 「派发令由 coordinator 写进卡线程开场消息,⛔ 不落共享目录;卡上派发评论留一行指针」 (item 2)
references/execution-duties.md 〈收集〉 ①② 「巡检首动作 list_triggers 确认 Routine 启用,在飞重挂加速器;唤醒归 Routine,漏挂不断链」 / 「在飞期间主巡检间隔 ≤45 分钟…」 ① scoped to the Routine seat, the accelerator clause gone, and 「项目席由事件与巡查 routine 唤醒」; ② scoped to the Routine seat (its cadence is unchanged)
references/dispatch-runbook.md 〈卡线程〉 handshake (ruling 1A, third commit) 「线程开起后第一动作:向席位报告指定推送分支并等待;⛔ 线程不贴认领、不写 assignee」 / 「席位按 AGENTS.md 的顺序写 assignee+pm:dispatched,再贴带该 Branch: 的认领;之后线程才开工」 「coordinator 开线程即读线程分支交席位(读不到则线程自报);⛔ 线程不认领、不写 assignee」 / 「席位写 assignee+pm:dispatched+带该 Branch: 的认领;线程核对最新认领指向本分支方开工」 — the ruled shape: the coordinator reads the branch from the child's session record at spawn, the seat claims it, the thread starts once the newest claim names its branch; the thread's own report is the fallback
.claude/agents/os-dev.md 基本规则 1 (ruling 1A, third commit) 「建好分支后的第一个动作是推空分支:任何编辑之前 git push -u origin <branch>」 + 「它既是认领评论所指分支的落地标记,又是写路由探针(容器凭据不对称)」 the two probe lines merge into 「建好分支后先推空分支(任何编辑前 git push -u origin <branch>):落地标记兼写路由探针」 and the freed line reads 「卡线程分支由平台指定、harness 推送,⛔ 不推空分支;探针规则只对自建分支」 — the file sits at its 404-line ceiling, so the new rule is paid inside rule 1
SKILL.md 入口与角色 triage-seat line (ruling 2A, third commit) 「分诊席跑普通直连会话、默认判断档;裁决不在本席,归维护者召唤的总监席」 「分诊席跑直连会话、默认判断档;直连会话按召唤跑,⛔ 无自醒不常驻;裁决归总监席」 — the direct-session wake rule the contract review flagged (③-2): summoned only, no self-wake, not resident; 「维护者召唤」 is already the 总监席 line's own text
references/lanes/director.md L1 # 席位章程:项目总监(Project Director) # 席位章程:总监席(Director Seat)
references/coordinator.md title and SKILL.md coordinator row (follow-up commit, after PR #25255) # 项目协调者(Project Coordinator) / 「以项目协调者身份运行…」 # 协调者(Coordinator) / 「以协调者身份运行…」 — the card's naming item for the coordinator
references/coordinator.md L3 (follow-up) 「…跨车道调度的那一席读本文。」 「…跨车道调度的那一席读本文;项目席见 seat-lifecycle.md。」 — the pointer to the project-seat form, folded into the opening line because the file sits at its 49-line ceiling
references/coordinator.md 三 and references/dispatch-runbook.md 〈卡线程〉 candidate lines (follow-up) 「派发令文件」 「派发令全文」 — the word item 2 made stale (the seat hands the coordinator the order's full text, no file)
references/seat-lifecycle.md 〈断粮与跨墙恢复〉 patrol line (follow-up; contract review ③-4) 「…跑各车道待命项;撞墙只留存根注记,⛔ 无跨墙定时器链」 「…跑各车道待命项(含前提过时);撞墙记入存根,⛔ 无 cron 链」 — names the stale-premise check the card's item 4 lists; 「cron 链」 is SKILL.md L72's word for the deleted chain; 119 bytes
references/cross-repo-coordination.md 规则 5 (follow-up; contract review ③-6, surface widened by the seat) 「org Project 只是维护者的聚合视图」 「看板(org Project)只是维护者的聚合视图」
references/lanes/skills.md 「决裁勤务归项目总监席」 「决裁勤务归总监席」
references/rest-channel.md 不可迁移 ② 「Projects field_values:GraphQL-only —— 舰队并不需要它;MCP 服务器端…」 「看板(org Project)field_values:GraphQL-only,舰队不需要它;MCP 服务端…」 — the org-Project naming line the card points at (its L78 citation is this line at L62 on main)

The rule after the change, as the card states it: GitHub keeps what another account reads (six-state labels, assignee, Claim:/Release:, the seat stub, the PR and its ACCEPT, the ruling record); the project keeps the working layer (posture, ledger, orders, round reports, memory). It is written as the two 〈座位贴协议〉 lines, not restated elsewhere.

Acceptance checks on this head: git grep -n '项目总监' -- .claude/skills → no hit; git grep -n '总监席' -- .claude/skills/pm-dispatch/SKILL.md → L56 (the director row), L75 (ruling 2A), L237 (main's, from #25348) and L275–L276 (the old summons line is gone by #25255).

Item 3 — filed as needs_decision, ruled 1A in batch #4, written in the third commit

Ruling record: card comment 6363872862 (maintainer 「同意」 2026-10-23T11:29Z = 1A 2A). The text below is the analysis as filed; the ruled shape is option A, now on dispatch-runbook.md 〈卡线程〉 L141–L142 and os-dev.md rule 1 (see the table above). Item 2 of that batch (2A, the direct-session wake rule) is on SKILL.md L75 (L74 before the merge added the coordinator row).

The card's item 3 (「branch named before the thread opens」: the seat claims first with the Claim: naming the branch the coordinator will give the thread, then asks for the thread) rests on the coordinator being able to name a project thread's branch. Measured on this very thread (A2 below): it cannot. The branch is platform-assigned at thread creation (claude/project-thread- + a random suffix; 27 such heads on origin), the coordinator's opening message carried none, and the thread may push only that branch. So the 〈卡线程〉 handshake lines were left as they were until the ruling; the options as filed, ⛔ none picked by this thread (A was ruled by the maintainer):

  • A. Coordinator reads, seat claims, thread verifies. The coordinator reads the new thread's branch from its session record the moment it is spawned (get_session on the child lists outcomes[].git_info.branches before any push — measured) and hands it to the seat in the same stroke; the seat claims; the thread's first act stays 「verify the newest Claim: names my branch」 and it starts as soon as the claim is up. Cost: one read per thread; the thread still waits for the seat, usually less than today because the read beats the thread's own report.
  • B. Today's handshake minus the probe push. The thread reports its branch and waits; the seat claims; the thread starts. The empty-branch push (os-dev.md rule 1) is dropped for card threads because the branch is platform-designated and the push route is the harness's. Cost: zero protocol change on the seat side; the 5–10 minute wait the card measured stays. (The probe-push drop touches .claude/agents/os-dev.md, outside this card's file surface either way.)
  • C. Claim first with the branch line filled later. The seat claims with Branch: pending and the thread's first report fills it by a body edit of the claim comment. Cost: a claim comment that is edited after it is written, which the claim protocol (「认领评论时间戳是唯一仲裁」) does not foresee.

The PM's mechanism assumptions, measured

  • A1 (hot files; three seat PRs unmerged) — held at the first push (all three open: #25348 at 2bf0113, #25255 at 3e6e35e, #25247 at d062675); #25348 landed 06:19Z and was merged in (7198a099, one adjacent-line conflict in seat-lifecycle.md resolved by keeping both lines; SKILL.md now 319/319, lanes/director.md 70/70). This PR started from main at 448374d and touches none of their hunks: #25348's SKILL.md L30/L106/L212–L222/L234/L264/L267/L276, seat-lifecycle.md L69, dispatch-runbook.md L57/L77/L115/L146, execution-duties.md L103, contract-review.md, triage-duties.md, lanes/director.md L13–L24 and L45–L60 — not touched; #25255's SKILL.md L57 insertion (the coordinator row) and dispatch-runbook.md L136 — not touched; #25247's 〈域车道〉 table and lanes/* other than the two one-line renames — not touched. Two known overlaps, both trivial: #25255 deletes SKILL.md L274, which this PR only renames (the merge takes the deletion); #25247 and #25348 move SKILL.md's count (317 and 319) while this PR leaves it at 318 under the 319 ceiling, so whichever lands last re-measures. #25255, #25247 and #25393 landed 13:14Z and were merged in (bd78f67d): two SKILL.md conflicts, both resolved as foreseen — the director row keeps this PR's rename and #25255's coordinator row is added beneath it; #25255's deletion of the 总监席 summons line wins over this PR's rename of it. The follow-up commit then wrote the deferred items (coordinator.md pointer and rename, 「派发令全文」 in both candidate lines) plus the two review flags (patrol line, cross-repo rule 5).
  • A2 (can the coordinator name the branch?) — disproved. get_session on this thread shows the branch claude/project-thread-hxtlri in session_context.outcomes[].git_repository.git_info.branches at creation (04:51:59Z); the coordinator's opening note named no branch; git ls-remote had no such head until this thread pushed it; the suffix appears in neither the thread id nor the session id. So the branch is readable after spawn, not nameable before it — item 3 goes to the ruling batch as above.
  • A3 (SKILL.md 319/319 once #25348 lands) — holds and is respected: SKILL.md stayed at 318 lines until #25348 landed and sat at 319/319 after the first merge and 318/318 after the second (the ruling-2A clause is in place on L75, net zero). No re-wrap used as payment; the two lines removed are the two mechanisms the card names.
  • A4 (check:pm-skill-id-lint) — holds; the operating text names rules by file and section only; 87 files clean.

Line budget

File Lines Ceiling Net
SKILL.md 318 (319 before #25255/#25247 merged in) 318 0 (2 replaced, 6 edited in place)
references/seat-lifecycle.md 95 (96 before main shrank it) 96 0 (+4 −3 −1, 1 edited)
references/seat-post-protocol.md 91 91 0 (+2 −1 −1)
references/dispatch-runbook.md 241 241 0 (4 edited)
references/execution-duties.md 187 188 0 (2 edited)
references/lanes/director.md 70 (72 before #25348) 70 0 (1 edited)
references/lanes/skills.md 32 33 0 (1 edited)
references/rest-channel.md 82 82 0 (1 edited)
references/coordinator.md 49 49 0 (3 edited in place)
references/cross-repo-coordination.md 51 51 0 (1 edited)
.claude/agents/os-dev.md 404 404 0 (2 edited in place; ruling 1A)

Widest edited prose line 119 bytes; the two edited SKILL.md table rows are 143 and 145 bytes against the 342-byte row pin.

Gates

Head f08bab5c (the follow-up commit, on top of the origin/main merge bd78f67d that brought in #25255, #25247 and #25393): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 22 commands (the 20 of the first head plus pnpm check:agent-model-declared and pnpm check:commit-card-trailers, which .claude/agents/os-dev.md in the change set adds). Every one was run in this worktree with its exit code captured before any pipe and recorded as COMMAND :: exit CODE, then reconciled with --ran: 22 derived, 22 run, 22 × exit 0, 0 NOT-MEASURED, 0 UNRUN (✓ dispatch-gates --ran). Earlier heads, each reconciled the same way: f81aab8a 20/20, the merge head 7198a099 20/20, the ruling head 9700ab9d 22/22; the first pass on 2b1450c had one exit 3 (pnpm --filter @objectstack/lint run check:doc-formula-expressions, a PREREQUISITE — the @objectstack/formula and @objectstack/lint builds absent in a fresh worktree — cleared by building those two packages under scripts/pm/os-verify-lock.sh). The four the dispatch order names on this head: pnpm check:pm-skill-ratchet ✓ (declared cross-file moves 2; SKILL.md 318/318, coordinator.md 49/49, cross-repo-coordination.md 51/51, os-dev.md 404/404, no row moved), pnpm check:pm-skill-id-lint ✓ (87 files clean), pnpm check:skill-frame-sync ✓, pnpm check:skill-frame-freshness ✓. CI on f81aab8a, 7198a099 and 9700ab9d was all green (40, 35 and 42 check runs, none failed); this head has its own check runs. No published package moves (.claude/** only), so skip-changeset rides the create.

Acceptance notes

Governed surface .claude/** (Tier S): draft, awaiting the seat's CONTRACT_REVIEW_TIER review and the maintainer's word; ⛔ not to be flipped ready, queued or armed by this thread.


Generated by Claude Code

…the seat post as a stub, the dispatch order in the card thread, event wake plus one patrol per project, 项目总监 → 总监席

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178pvZcJjqXL36QzPi1jbSX
…the term seat-lifecycle already defines

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

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: f81aab8af16fe3fff4b3234d4acf124cd110f076
Local-runs: probe — the card's acceptance greps (git grep -n '项目总监' -- .claude/skills, git grep -n '总监席' -- .claude/skills/pm-dispatch/SKILL.md) and wc -l on the eight head blobs; read-only, no gate family rerun
Scope: .claude/skills/pm-dispatch/SKILL.md, references/seat-lifecycle.md, references/seat-post-protocol.md, references/dispatch-runbook.md, references/execution-duties.md, references/lanes/director.md, references/lanes/skills.md, references/rest-channel.md + references/platform-readings.md 〈断粮检测与跨墙恢复〉 (the no-orphan-timer rule the deleted hand-over step 8 pointed at), references/seat-lifecycle.md 〈停止条件与待命〉 (the 待命项 the patrol line points at), references/triage-duties.md (human floor, unchanged), references/cross-repo-coordination.md L44, scripts/pm/check-skill-line-ratchet.mjs (ceiling rows and MAX_TABLE_ROW_BYTES, read, not changed)

Spec read: card #25379 body (the maintainer's words 「同意,你现在就立卡派发处理。」, the six Wanted items, the one-sentence rule, Acceptance, out-of-scope) and its one comment (the Claim: with the File surface). Diff read as git diff origin/main...origin/claude/project-thread-hxtlri from merge-base 448374d3. Check-runs on this head read at 2026-10-23T05:25Z.

① Derived judgments

  1. Item 1 (seat post = stub) — lands. seat-lifecycle.md 〈座位贴协议〉 +2 (L27 「项目席的贴是存根,只留他账号要读的;模板见 seat-post-protocol.md」, L28 「存根外的姿态、台账与轮报住项目;标题、assignee、坐席审计评论与跨账号移交简报照旧」) and seat-post-protocol.md 〈贴的四段与派生视图〉 +2 (L17 the four stub items 「在座账号与项目 · 上任时刻 · 热文件串行队 · 指针行「姿态台账住项目」」, L18 the optional wall note 「预计 HH:MM 恢复」 and the four refresh moments). Every element the card lists is present: seated account, project, seating time, serial queue, pointer line, optional wall note; posture/ledger/shift narrative/round reports out of the post; title, assignee, seating audit comment and the cross-account hand-over brief kept. Correct.
  2. Item 2 (dispatch order in the thread's opening message) — lands. dispatch-runbook.md 〈卡线程〉 L140 「派发令由 coordinator 写进卡线程开场消息,⛔ 不落共享目录;卡上派发评论留一行指针」 replaces the shared-directory line. The three parts of the card's item (coordinator writes it when opening, the mount file no longer required, the card's dispatch comment keeps one pointer line) are all there. The PR spells the mount as a prohibition (⛔) where the card said "no longer required"; tighter than asked, consistent with the one-sentence rule (the project keeps the orders). Correct.
  3. Item 3 (branch named before the thread opens) — correctly NOT written. The handshake lines L141–L143 are byte-identical to main; no claim-first order, no probe-push drop, .claude/agents/os-dev.md untouched. The PR body presents options A/B/C and says 「⛔ none picked here」 and 「照派发令交席位汇入决裁批」; the disproof (A2) is measured on this thread. This is the shape the dispatch order asked for and the shape 「必须人工决裁」 requires: the needs_decision goes to the maintainer's ruling batch, not to any ruling thread or delegated path. Verified: no added line in the diff opens, reopens or references a 代裁/自裁/裁决线程 path; the only ruling-adjacent added text is the rename 「决裁勤务归总监席」 (lanes/skills.md L12) and the renamed SKILL.md L274–L276, whose content (「⛔ 无 Routine/cron」, 「总监席是唯一裁决者 … ⛔ 无子代理无自述」) is unchanged. triage-duties.md has zero diff; its human floor (L95–L96, L103, L115, L120) is intact.
  4. Item 4 (wake = events + one patrol per project) — lands, with the deleted lines as payment. SKILL.md L70–L71 「席位两形:Routine 席与项目席(会话是车道项目的线程);细则见 references/seat-lifecycle.md」 / 「项目席唤醒 = PR 订阅事件 + 每项目一个巡查 routine;⛔ 无自绑 cron、无 send_later 链」; seat-lifecycle.md L96 「项目席巡查 routine 每 2–4 小时跑各车道待命项;撞墙只留存根注记,⛔ 无跨墙定时器链」; execution-duties.md 〈收集〉 ①② scoped to 「Routine 席」 with 「项目席由事件与巡查 routine 唤醒」. The subscribe_pr_activity rule (execution-duties L156) is untouched. The payment lines are exactly the three the card names as Routine-seat-only (acceptance bullet 3): the 自绑 cron Routine line, the send_later accelerator line, the three-line cross-wall timer chain (fixed-point timer / hourly cron / delete-after-first-fire), plus hand-over step 8 (list_triggers inventory of the 入座 Routine, which no longer exists in the protocol) and the merge of two 〈座位 Routine 创建〉 fact lines into one (L60; the 「不挂 repo sources」 mechanism remains as the reading in platform-readings.md L446). No rule is lost that the Routine form still relies on: the Routine seat's wake is the maintainer-created UI Routine (seat-post-protocol L58, L65 「档位与 cron 是维护者在 UI 上的可调项」), its liveness read is last_fired/next_run (L26), its 巡检 opener is still list_triggers (execution-duties ①), the no-orphan-timer rule stays at platform-readings L449 「⇒ 绑定会话一死:先删旧 Routine、再从新会话重建,⛔ 永不留孤儿」, and the recovery playbook keeps its steps (L95) ending 「照常跑轮」. One form the card did not name is affected; see ③-2.
  5. Item 5 (round report = thread checklist) — lands. seat-lifecycle.md L71 「项目席轮报 = 卡线程清单,⛔ 不逐轮发聊天表;五项健康指标进总监项目的每日摘要」, placed beside the Routine-form report line L70, with the five figures (L74–L78) unchanged. Correct.
  6. Item 6 (naming) — lands within the claim's file surface. git grep -n '项目总监' -- .claude/skills on the head: no hit (four hits on main: SKILL.md L56, L274, lanes/director.md L1, lanes/skills.md L12). git grep -n '总监席' -- .claude/skills/pm-dispatch/SKILL.md: L56 (the director row, 「以总监席身份运行 … 所在项目即「总监项目」」) and L274–L276, i.e. L56 and L274's successors, as acceptance bullet 2 asks. 「车道项目」 defined on the domain row (L54), 「总监项目」 on the director row (L56). GitHub's board → 「看板(org Project)」 at SKILL.md L33 (红线; 「任何」 dropped to fit the cap, meaning unchanged) and rest-channel.md L62 (the line the card cites as L78). 「项目协调者」 has no hit on this head because coordinator.md does not exist until PR docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 lands; deferred as the card itself foresees. Deviation reported by the dev: cross-repo-coordination.md L44 still says 「org Project 只是维护者的聚合视图」; outside item 6's citation and outside the claim's file surface, so leaving it is correct for this PR (fix in ③-6).
  7. The one-sentence rule (GitHub keeps what another account reads; the project keeps the working layer) is carried by the two 〈座位贴协议〉 lines, not restated elsewhere; consistent with SKILL.md's 「⛔ 不另抄」 discipline.
  8. Line budget, ratchet, byte caps — hold. Per-file wc -l on the head blobs equals the base blobs for all eight: SKILL.md 318/318, seat-lifecycle 96/96, seat-post-protocol 91/91, dispatch-runbook 241/241, execution-duties 187/187, director 72/72, skills 32/32, rest-channel 82/82 (+22/−22). Ceiling rows on main (319, 96, 91, 241, 188, 72, 33, 82) all ≥ landed counts; scripts/pm/check-skill-line-ratchet.mjs is not in the diff and no file shrank, so no row needed lowering. Widest added prose line 119 bytes (cap 120); the two edited SKILL.md table rows 143 and 145 bytes against MAX_TABLE_ROW_BYTES 342 for SKILL.md. The cross-repo-coordination.md rename proposed in ③-6 measures 119 bytes.
  9. Tier H, id-lint, scope. No Tier H path in the diff (AGENTS.md, CLAUDE.md, docs/NORTH-STAR.md, skills/**, .github/workflows/**, CODEOWNERS all absent). No issue number in any added line. No file outside the claim's File surface. Seat posts untouched. .claude/settings.json/.claude/hooks/** untouched.
  10. Pointers resolve. references/seat-lifecycle.md (SKILL.md L70), seat-post-protocol.md (seat-lifecycle L27), references/lanes/director.md (SKILL.md L56), director.md (lanes/skills.md L12) all exist on the head; 「各车道待命项」 (seat-lifecycle L96) resolves to 〈停止条件与待命〉 L89–L90 in the same file.
  11. PR shape. Draft, base main, body first line is the project attribution block then Fixes #25379 (merge should close the card: items 1, 2, 4, 5, 6 land; item 3 is the maintainer's ruling, not an unimplemented half, and the coordinator.md pointer waits on another PR by the card's own text); Clause-②: no; Metadata-protocol: none; ## 维护者速读(草稿) present in Chinese; skip-changeset label on; not flipped ready, not queued.

② Semver level

No published package is touched (.claude/skills/pm-dispatch/** only); Clause-②: no on the body matches a diff with no schema or exports change; skip-changeset is the correct form for a rule-text-only PR in this repo (review-checklist 〈范围与 changeset〉), and the Check Changeset check-run on this head is success. Consistent; no semver level applies.

③ Boundary flags

  1. Item 3 → maintainer's ruling batch, one letter wanted. The PR leaves the 〈卡线程〉 handshake unchanged and names A (coordinator reads the branch from get_session at spawn, seat claims, thread verifies), B (today's handshake minus the probe push; touches .claude/agents/os-dev.md, outside this surface) and C (claim with Branch: pending, filled by body edit; conflicts with 「认领评论时间戳是唯一仲裁」). ⛔ Not picked by the PR, ⛔ not picked here; the seat files it for the maintainer per 「必须人工决裁」. Note for the seat: dispatch-runbook.md L146 on this head still says 「终报 needs_decision ⇒ 席位交 coordinator 开 CONTRACT_REVIEW_TIER 裁决线程」 — that is PR docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348's hunk (revoke delegated rulings), untouched here; this PR's own routing follows the dispatch order, not L146.
  2. The deleted 自绑 cron line was not Routine-form-only by its wording. main SKILL.md L70 read 「入座即建唯一自绑 cron Routine(create_trigger,own_followup)作默认唤醒」 — a default for any seated session. After this PR the two named forms are 「Routine 席」 (maintainer-created UI Routine) and 「项目席」 (project thread); a seat in a plain direct session that is neither — SKILL.md L74 still says 「分诊席跑普通直连会话」 — has no written wake rule. The card ordered this deletion (acceptance bullet 3 names the three lines as the payment), so this is a spec consequence, not a PR defect. Maintainer's word wanted on one of: (a) direct sessions are summoned and manual, as the 总监席 already is (then nothing to write), or (b) a one-line scope note (paid by a deletion) naming the triage seat's form.
  3. Placement vs acceptance bullet 1. 「dispatch-runbook.md 〈卡线程〉 carries items 2–4」: on this head 〈卡线程〉 carries item 2 only; item 4 lives in SKILL.md L71 + seat-lifecycle L96 + execution-duties ①; item 3 is deferred. The "which form applies when" condition is SKILL.md L70's parenthetical 「会话是车道项目的线程」, and seat-lifecycle L27 uses 项目席 without redefining it; the chain resolves through L70's pointer and respects ⛔ no second copy. Acceptable as landed; the seat should say so in its ACCEPT rather than treat the bullet literally.
  4. The patrol line's pointer is slightly narrower than the card's parenthetical. 「跑各车道待命项」 → 〈停止条件与待命〉 L89–L90 covers unlock scan, hold release, awaiting-landing (在飞/已入队 PR 跟到 MERGED), findings, cross-lane memos; the card's 「stale premise」 is the pre-dispatch check at execution-duties L13, not a standby item, and the wall note is carried by L96 itself. Second commit f81aab8a chose the defined term over a new list; no fix demanded, maintainer may accept or ask for 「含前提过时检查」 (fits: L96 is 108 bytes).
  5. Deferred until PR docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 lands (card's own schedule): the coordinator.md pointer and the 「项目协调者」→「协调者」 rename inside it; the stale word 「派发令文件」 at dispatch-runbook.md L135 (beside docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255's L136 hunk). The seat must re-run both acceptance greps and wc -l after that follow-up commit; this record covers head f81aab8a only. Two known merge interactions: docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 deletes SKILL.md L274 (this PR only renames it; the deletion wins), and docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348/docs(pm-dispatch): fold the engine, services and cli lanes into domain:server #25247 move SKILL.md's count (319/317) while this PR holds 318 — re-measure whichever lands last.
  6. Residual 「org Project」 wording outside the surface: references/cross-repo-coordination.md L44 「org Project 只是维护者的聚合视图」. Exact fix, line-neutral, 119 bytes: 「- 规则 5:一块板不设第二跟踪器:pm 标签就是状态机,看板(org Project)只是维护者的聚合视图。」. Fold into the post-docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 follow-up commit or a one-line card; not a FAIL item because item 6 cites only rest-channel.md and the claim's File surface excludes this file.
  7. Red line vs working layer. SKILL.md L33 「⛔ GitHub 之外永不维护跟踪状态」 now sits beside seat-lifecycle L28 「存根外的姿态、台账与轮报住项目」. Read as the card's one-sentence rule intends — 跟踪状态 = the card state machine (labels, assignee, Claim:/Release:), which stays on GitHub; posture/ledger/reports are the working layer — the two do not conflict, but a reader may want 跟踪状态 glossed. Not asked by the card; flagged only.
  8. Dev-reported deviations, both accepted: the body's HTML-comment attribution line (os-dev.md 〈干净收尾〉 forbids HTML comments; the project relay inserts it; measured as kept byte-for-byte on sibling PRs); pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 as a PREREQUISITE on 2b1450c and was cleared by building the two packages — the recorded 20/20 pass is on this head.
  9. Check-runs on this head, read twice. First read 2026-10-23T05:25Z: 31 completed, none failed, 7 in_progress. Second read at 2026-10-23T05:27Z: all 40 completed, none failed — success on Lint & Repo Gates, TypeScript Type Check, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · CI, release & engine gates, Lint · repo & tooling gates, Lint · scoped ×3, Type Check · workspace / source gates / consumer gates / debt ledger, Governed Surface Queue Guard, Check Changeset, Check PR Size, Check Documentation Links, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, The card this PR closes must claim this branch, Auto Label, filter, Test Core, Dogfood Regression Gate; the remainder skipped by path filter (Build Core, Build Docs, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance, the matrix shards, the two opt-in harnesses, and the duplicate-workflow rows). All green on the full set, not the required subset.

Implemented-by: claude/project-thread-hxtlri
Reviewed-by: session_01REMuzhz6MWRjg8uohedMnM

VERDICT: PASS

…-hxtlri

# Conflicts:
#	.claude/skills/pm-dispatch/references/seat-lifecycle.md
…inator reads a card thread's branch at spawn and the seat claims it (no probe push for card threads), and a direct-session seat runs only when summoned

Ruled on the card (batch #4, 1A / 2A): dispatch-runbook 〈卡线程〉 L141–L142 now say the
coordinator reads the new thread's branch from its session record and hands it to the seat
(the thread reports it only when the coordinator cannot read it), the seat writes assignee,
`pm:dispatched` and the `Claim:` naming that branch, and the thread starts once the newest
claim names its branch. os-dev.md rule 1 keeps the empty-branch probe push for self-made
branches and exempts card threads, whose branch the platform designates and the harness
pushes; the two probe lines merge into one so the file stays at its ceiling. SKILL.md's
triage-seat line now carries the direct-session rule: summoned only, no self-wake, not
resident. Every file keeps its line count; every edited line is at or under 120 bytes.

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

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9700ab9d9a3c395b1090b95da9682bf046238a85
Local-runs: probe — read-only reproductions only: git merge-tree --write-tree f81aab8af 5e772c79b (the merge the branch carries) and git merge-tree --write-tree 9700ab9d9 <#25393 head da46dafa> (the open sibling), wc -l on the nine head blobs, and the card's two acceptance greps; no gate family rerun
Scope: .claude/skills/pm-dispatch/SKILL.md, references/dispatch-runbook.md 〈卡线程〉, .claude/agents/os-dev.md 基本规则 1 (the three files commit 9700ab9d touches) + the six other files of the PR as merged through 7198a099 (references/seat-lifecycle.md, seat-post-protocol.md, execution-duties.md, lanes/director.md, lanes/skills.md, rest-channel.md) + references/triage-duties.md (human floor, read, unchanged), scripts/pm/check-skill-line-ratchet.mjs (ceiling rows, read, not changed)

Delta review on top of the PASS record at head f81aab8a (comment 6358117147, 2026-10-23T05:27Z); that record's ①1–11 and ②③ stand for everything the two new commits did not touch. Spec read for the delta: card #25379 comment 6363872862, the maintainer's batch-4 ruling (「同意」 2026-10-23T11:29Z = 1A 2A). Diff read as git diff 5e772c79b 9700ab9d9 (nine files, +27/−27) and git show 9700ab9d9 (three files, +5/−5). Check-runs on this head read at 2026-10-23T11:47Z.

① Derived judgments

  1. Merge 7198a099 is the automatic merge plus one correct adjacent-line resolution. Parents f81aab8a and 5e772c79b (origin/main incl. docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348). git merge-tree --write-tree on the same two parents auto-merges SKILL.md, dispatch-runbook.md, execution-duties.md, lanes/director.md and reports one content conflict in seat-lifecycle.md; the only difference between the merge-tree result and the committed tree is that file, and it is exactly the conflict block: the branch's inserted line L69 「- 项目席轮报 = 卡线程清单,⛔ 不逐轮发聊天表;五项健康指标进总监项目的每日摘要。」 kept, main's docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348 line L70 「- 报告加升级项、呈裁清单、awaiting a human merge 项、逐 PR 熔断命中项(无则 none)。」 kept, the branch's stale copy of the pre-docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348 line 「代裁清单(分诊)」 dropped. Every line docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348 added in the PR's files is present on the merge head (per-line git grep -F, zero missing), and the PR's own +/− line set is identical before and after the merge (448374d3..f81aab8a vs 5e772c79b..7198a099, sorted sets equal). Correct.
  2. Ruling 1A — written as ruled, nothing added. Compared against the ruling's own words: 「the coordinator reads the new thread's branch from its session record the moment it is spawned and hands it to the seat in the same stroke; the seat writes assignee + pm:dispatched + the Claim: naming that branch; the thread's first act stays 「verify the newest Claim: names my branch」 and it starts as soon as the claim is up; if the coordinator cannot read it, the thread reports its branch as today (fallback). The empty-branch probe push is dropped for card threads … one line in .claude/agents/os-dev.md rule 1」. On the head, dispatch-runbook.md L141 「- coordinator 开线程即读线程分支交席位(读不到则线程自报);⛔ 线程不认领、不写 assignee。」 carries the spawn-time read, the hand-over, the fallback and the retained thread prohibitions; L142 「- 席位写 assignee+pm:dispatched+带该 Branch: 的认领;线程核对最新认领指向本分支方开工。」 carries the seat's three writes in that order and the thread's start condition (newest claim names its branch). L143 「分支约定仍是 …」 is byte-identical to main. os-dev.md L31 「- 卡线程分支由平台指定、harness 推送,⛔ 不推空分支;探针规则只对自建分支。」 is the one ruled line. Each ruled element maps to one clause; no clause on the three edited lines maps to nothing in the ruling.
  3. os-dev.md rule 1: the merged line loses no rule; the probe rule still binds self-made branches. Main L30 「建好分支后的第一个动作是推空分支:任何编辑之前 git push -u origin <branch>。」 + L31 「它既是认领评论所指分支的落地标记,又是写路由探针(容器凭据不对称)。」 → head L30 「- 建好分支后先推空分支(任何编辑前 git push -u origin <branch>):落地标记兼写路由探针。」. Kept: push the empty branch first, before any edit, the exact command, both purposes (landing marker, write-route probe). Dropped: the qualifier 「认领评论所指分支的」 (the branch is the one just created per the claim; implicit) and the parenthetical rationale 「(容器凭据不对称)」 (explanation, not an obligation; the probe's consequence rule L32 「探针遇 403 ⇒ 停下报 blocked,⛔ 不进重试循环;只有网络错误才退避重试。」 is unchanged and now follows the exemption line, so it reads as applying to self-made branches). The freed L31 scopes the exemption to 「卡线程」 and states 「探针规则只对自建分支」, so the probe remains mandatory for every claude/issue-<n>-<slug> branch. No rule lost; file 404/404.
  4. Ruling 2A — written as ruled, nothing added. Ruled: 「a direct-session seat is summoned by hand like the 总监席 — it runs one round when called, ⛔ no self-wake, no Routine, not resident … Workload: one clause added in place on SKILL.md L70 or L74, line-neutral」. Head SKILL.md L74 「- 分诊席跑直连会话、默认判断档;直连会话按召唤跑,⛔ 无自醒不常驻;裁决归总监席。」 (106 bytes): 「按召唤跑」 = summoned, 「⛔ 无自醒」 = no self-wake (a self-bound Routine is the self-wake the deleted L70 described, so 「无 Routine」 is covered rather than restated), 「不常驻」 = not resident. 「维护者召唤的」 was trimmed to pay bytes; the fact remains on L275 「总监席:维护者在所在仓召唤 /pm-dispatch director;⛔ 无 Routine/cron;…」 (unchanged). 「PR subscription events still wake it」 is not restated on L74; it is already the general rule at execution-duties.md L156 「报告点名 PR ⇒ 会话席当即 subscribe_pr_activity 并记座位贴」, which names 会话席 without form, so the direct session is inside it. Line-neutral at 319/319. Consistent with the ruling; see ③-2 for the one gloss a reader might want.
  5. Nothing beyond the two rulings. git show 9700ab9d9 is +5/−5 in exactly three files; every changed line is one of: runbook L141, L142 (1A), os-dev.md L30, L31 (1A, the merge paying for the new line), SKILL.md L74 (2A). No other hunk.
  6. Line budget, ceilings, byte caps — hold on the head. wc -l head = main for all nine: SKILL.md 319 (ceiling row 319), seat-lifecycle 96/96, seat-post-protocol 91/91, dispatch-runbook 241/241, execution-duties 187/188, lanes/director 70/70, lanes/skills 32/33, rest-channel 82/82, os-dev 404/404. check-skill-line-ratchet.mjs not in the diff. Widest added prose line 119 bytes (seat-lifecycle); the three ruling lines are 116 / 106 / 114 / 117 / 115 bytes (os-dev L30, L31; SKILL L74; runbook L141, L142); the only >120 added line is the 145-byte SKILL.md director table row, under the 342-byte row pin (as recorded at f81aab8a).
  7. id-lint, Tier H, ruling paths, human floor. No #<n> in any added line. No Tier H path in the nine-file list (AGENTS.md, CLAUDE.md, docs/NORTH-STAR.md, skills/**, .github/workflows/**, CODEOWNERS absent). No added line contains 代裁 / 自裁 / 裁决线程; the only ruling-adjacent text in the diff is the 总监席 rename, and the merge brought in docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348's L146 「终报 needs_decision ⇒ 席位附四维分析与推荐,并入决裁批次呈维护者裁;⛔ 无裁决线程。」, which is the exact route this card's item 3 took (batch Add Changesets and GitHub Actions automation #4). triage-duties.md has zero diff vs main. Acceptance greps re-run on this head: git grep -n '项目总监' -- .claude/skills → no hit; git grep -n '总监席' -- .claude/skills/pm-dispatch/SKILL.md → L56, L74, L237 (main's, from docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348), L275–L277.
  8. PR body is consistent with the head. The 速读 names the batch-4 ruling, the third commit, runbook 〈卡线程〉 and os-dev.md 规则 1 for 1A, SKILL.md 分诊席 line for 2A; the What-changed table has one row per ruled edit with before/after text that matches the head byte for byte; the Line budget table lists nine files with the counts above (os-dev.md 404/404 「2 edited in place; ruling 1A」); the Item-3 section says 「ruled 1A in batch Add Changesets and GitHub Actions automation #4, written in the third commit」 and cites comment 6363872862; Gates names head 9700ab9d. Fixes #25379 stays right: items 1, 2, 4, 5, 6 land, item 3 is now landed as ruled; the remaining coordinator.md work waits on PR docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 by the card's own schedule. Clause-②: no, Metadata-protocol: none, draft, skip-changeset on.
  9. PR shape and widened surface. The claim's File surface (card comment 6357703974) did not list .claude/agents/os-dev.md; the ruling comment on the same card states 「the seat widens the claim's file surface by that one file, same Tier S」, and the PR body repeats it. The No other open PR may claim the same single-writer path check on this head is success. Accepted; see ③-4 for the one-line claim addendum the seat may still post.

② Semver level

Unchanged from the f81aab8a record: no published package touched (.claude/** only), Clause-②: no matches, skip-changeset is the right form for rule-text-only in this repo. No semver level applies.

③ Boundary flags

  1. Deferred until PR docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 lands (card's own schedule; expected absent on this head): the coordinator.md pointer and the 「项目协调者」→「协调者」 rename inside it; the stale word 「派发令文件」 at dispatch-runbook.md L135 「席位随时把候选卡交 coordinator,附优先级、派发令文件与建议 effort,⛔ 不等自己的槽位。」 (beside docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255's L136 hunk). Also still open from the first record: cross-repo-coordination.md L44 「org Project 只是维护者的聚合视图」 (outside the surface; exact 119-byte fix given there). Re-run both acceptance greps and wc -l after that follow-up commit; this record covers 9700ab9d only.
  2. 2A gloss, not a defect. L74 does not spell 「无 Routine」 or 「PR 订阅事件仍唤醒」; the first is subsumed by 「无自醒」 (the deleted self-bound Routine was the self-wake), the second is the general execution-duties.md L156 rule. If the maintainer wants the ruling's two words on the line, 「⛔ 无自醒无 Routine」 fits (L74 is 106 bytes, cap 120) — maintainer's call, no FAIL.
  3. Open PR docs(os-dev): name the harness attribution-line exemption in 〈干净收尾〉; Check Changeset reads the PR body #25393 (head da46dafa) also edits os-dev.md at 404/404 (deletes L128 「cdn.playwright.dev 的 403 …」, rewords L281 「两行同抄进 changeset 正文行首;…」, adds an exemption line at L323 「例外:harness 自写的 PR 正文首行归属注释原样留、只报;…」). git merge-tree --write-tree 9700ab9d9 da46dafac exits 0 with no conflict; the combined os-dev.md is 404 lines and SKILL.md 319, so whichever lands second merges clean and both ceilings hold. Note the two PRs are complementary on the same file: this PR's L31 and docs(os-dev): name the harness attribution-line exemption in 〈干净收尾〉; Check Changeset reads the PR body #25393's new L323 do not touch the same hunk.
  4. Claim addendum. The File-surface widening lives in the ruling comment, not in the Claim: text. The seat may post one line on the card (「Claim addendum: File surface + .claude/agents/os-dev.md 规则 1, per ruling 6363872862 1A」) so a reader of the claim alone sees the nine-file surface; not required for landing since the ruling is on the same card.
  5. 1A trimmed two non-normative words. Runbook L142 no longer says 「按 AGENTS.md 的顺序」; the three writes are still listed in that order on the line, and the order itself is AGENTS.md's. os-dev.md L30 no longer carries the rationale 「(容器凭据不对称)」; the probe and its 403 stop rule stand. Flagged for the record; no fix demanded.
  6. Check-runs on this head, read twice. First read at 2026-10-23T11:44Z: 40 runs, 33 completed, none failed, 7 in_progress (the Lint and Type Check farm). Second read at 2026-10-23T11:47Z: all 42 completed, none failed — success on Lint & Repo Gates, TypeScript Type Check, Lint · PM dispatch-gates, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · docs & code guards, Lint · ESLint, Lint · scoped ×3, Type Check · workspace / source gates / consumer gates / debt ledger, Governed Surface Queue Guard, Check PR Size, Check Documentation Links, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, The card this PR closes must claim this branch, Auto Label, filter, Test Core, Dogfood Regression Gate; the remainder skipped by path filter (Build Core, Build Docs, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance, the matrix shards, the two opt-in harnesses, the duplicate-workflow Auto Label / Check Changeset / Check PR Size rows). All green on the full set, not the required subset.

Implemented-by: claude/project-thread-hxtlri
Reviewed-by: session_01REMuzhz6MWRjg8uohedMnM

VERDICT: PASS

…-hxtlri

# Conflicts:
#	.claude/skills/pm-dispatch/SKILL.md
…on main — 项目协调者 → 协调者, the coordinator's pointer to the project-seat form, 派发令全文, the patrol line names the stale-premise check, and the board is 看板 in cross-repo rule 5

Deferred by the card's own schedule until the coordinator reference landed: its title and
SKILL.md's `coordinator` row read 协调者 (the card's naming item); its opening line points at the
project-seat form in seat-lifecycle.md, paid in place because the file sits at its ceiling; its
candidate line and the runbook's 〈卡线程〉 candidate line say 派发令全文, the word item 2 made
stale. From the contract review's boundary flags: the project patrol line names the stale-premise
check beside the lanes' standby items, and cross-repo-coordination rule 5 calls the org Project
看板 like the other two naming lines. Every file keeps its line count; every edited prose line is
at or under 120 bytes.

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

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: f08bab5c742a98a922145efd0a1fffd17294bfef
Local-runs: probe — read-only reproductions only: git merge-tree --write-tree on the parents of bd78f67d (the merge the branch carries) and on f08bab5c × PR #25427's head b91d5d64, wc -l on the eleven head blobs, the four acceptance greps, and the four skill scripts (check-skill-line-ratchet, check-skill-id-lint, check-skill-frame-sync, check-skill-frame-freshness) run once in a throw-away detached worktree at this head; no gate family rerun
Scope: .claude/skills/pm-dispatch/SKILL.md, references/coordinator.md, references/cross-repo-coordination.md, references/dispatch-runbook.md 〈卡线程〉, references/seat-lifecycle.md 〈断粮与跨墙恢复〉 (the five files commit f08bab5c touches) + the six other files of the PR as merged through bd78f67d (.claude/agents/os-dev.md, references/seat-post-protocol.md, references/execution-duties.md, references/lanes/director.md, references/lanes/skills.md, references/rest-channel.md) + references/execution-duties.md L13 (the 前提过时 term the patrol line now names), references/seat-post-protocol.md L17–L18 (the stub the patrol line writes the wall into), references/triage-duties.md (human floor, read, unchanged), scripts/pm/check-skill-line-ratchet.mjs (ceiling rows and MAX_TABLE_ROW_BYTES, read, not changed)

Delta review on top of the PASS record at head 9700ab9d (comment 6364160459); that record's ①1–9 and ②③ stand for everything the two new commits did not touch, and its ③-1 is the list this delta closes. Spec read for the delta: card #25379 (Wanted items 2, 4, 6 and the Acceptance list) and its batch-4 ruling comment 6363872862 (maintainer 「同意」 2026-10-23T11:29Z = 1A 2A); the first record's ③-4 / ③-6 fix texts (comment 6358117147). Diff read as git diff 77392e90 f08bab5c (eleven files, +32/−32), git show f08bab5c (five files, +7/−7) and the merge replayed with git merge-tree. Check-runs on this head read at 2026-10-23T13:26Z and again at 2026-10-23T13:30Z.

① Derived judgments

  1. Merge bd78f67d is the automatic merge plus the two SKILL.md conflict resolutions the thread reported, and nothing else. Parents 9700ab9d (the previous head) and 77392e90 (origin/main, which carries docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 4e606ce0, docs(pm-dispatch): fold the engine, services and cli lanes into domain:server #25247 b62ca781 and docs(os-dev): name the harness attribution-line exemption in 〈干净收尾〉; Check Changeset reads the PR body #25393 77392e90). git merge-tree --write-tree on the same two parents auto-merges os-dev.md, dispatch-runbook.md, seat-lifecycle.md and reports one file in conflict, SKILL.md, with two blocks. The only difference between the merge-tree result and the committed merge tree is SKILL.md, and it is exactly those two blocks resolved: (a) the 入口与角色 table keeps this PR's L56 「| director | 以总监席身份运行(人工召唤;所在项目即「总监项目」;三职与章程见 references/lanes/director.md) | — |」 and takes main's L57 coordinator row beneath it, main's old 「以项目总监席身份运行」 row dropped; (b) the 升级与决策 line 「- 总监席:维护者在所在仓召唤 /pm-dispatch director;⛔ 无 Routine/cron;未回字 = 不在 = 停。」 is gone, i.e. docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255's deletion wins over this PR's rename of it. No third edit in the resolution.
  2. No text from docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255, docs(pm-dispatch): fold the engine, services and cli lanes into domain:server #25247 or docs(os-dev): name the harness attribution-line exemption in 〈干净收尾〉; Check Changeset reads the PR body #25393 was dropped. Every + line of each of the three merge commits, restricted to the eleven files this PR touches, is present byte for byte on f08bab5c (per-line git grep -F), with exactly four exceptions, all of them lines the follow-up commit deliberately rewrites and item 3 below judges: docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255's coordinator row (「以项目协调者身份运行…」), coordinator.md L1 「# 项目协调者(Project Coordinator)」, L3 「…那一席读本文。」 and L24 「…派发令文件…」. Every − line of the three merge commits in those files is absent on the head (none still present). os-dev.md on the head = main's docs(os-dev): name the harness attribution-line exemption in 〈干净收尾〉; Check Changeset reads the PR body #25393 text plus this PR's two ruled lines at rule 1 (the diff vs main is exactly L30–L31, as at 9700ab9d).
  3. This PR's own hunks survive the merge unchanged apart from the conflict resolution. The sorted set of +/− lines of git diff 5e772c79b 9700ab9d9 (54 lines, the PR against the main it was last reviewed on) and of git diff 77392e90 bd78f67d (52 lines, the PR against the new main) differ by exactly one pair: the −「项目总监席:维护者在所在仓召唤…」 / +「总监席:维护者在所在仓召唤…」 rename of the summons line, which no longer exists on main. Nothing else moved, reworded or vanished.
  4. f08bab5c does the deferred items and the two review flags, and nothing beyond. git show f08bab5c is +7/−7 in five files; every changed line is one of: (a) SKILL.md L57 coordinator row 「以项目协调者身份运行」 → 「以协调者身份运行」 and coordinator.md L1 「# 项目协调者(Project Coordinator)」 → 「# 协调者(Coordinator)」 — card item 6's 「项目协调者」→「协调者」, the Acceptance grep now zero; (b) coordinator.md L3 「…跨车道调度的那一席读本文。」 → 「…跨车道调度的那一席读本文;项目席见 seat-lifecycle.md。」 (117 bytes) — the Acceptance bullet 「coordinator.md (after docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255 lands) points at them, ⛔ no second copy」: a pointer only, no restated rule; (c) coordinator.md L24 and dispatch-runbook.md L135 「派发令文件」 → 「派发令全文」 — the word item 2 (order rides the thread's opening message, no shared-directory file) made stale, both candidate lines, 105 / 117 bytes; (d) seat-lifecycle.md L95 「- 项目席巡查 routine 每 2–4 小时跑各车道待命项;撞墙只留存根注记,⛔ 无跨墙定时器链。」 → 「- 项目席巡查 routine 每 2–4 小时跑各车道待命项(含前提过时);撞墙记入存根,⛔ 无 cron 链。」 (119 bytes) — the first record's ③-4: the card's item 4 parenthetical names 「stale premise」, which is not a 〈停止条件与待命〉 standby item but the pre-dispatch check at execution-duties.md L13 「派发前做前提过时检查…」, so 「含前提过时」 is that file's own term; the wall clause still points at the stub's optional fifth line (seat-post-protocol.md L18 「第五行可选撞墙注记(预计 HH:MM 恢复)…」) and the prohibition still names the deleted chain (see ③-2 for the two words it compresses); (e) cross-repo-coordination.md L44 → 「- 规则 5:一块板不设第二跟踪器:pm 标签就是状态机,看板(org Project)只是维护者的聚合视图。」 — byte-identical to the first record's ③-6 fix text, 119 bytes. No other hunk.
  5. coordinator.md's meaning is unchanged beyond the rename and the pointer. The head file differs from main's (docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255's) text on exactly L1, L3 and L24; L24's only change is the one word; L3 appends a clause after 「;」 and keeps the sentence before it; the other 46 lines are byte-identical. No rule of the seven sections was re-scoped, deleted or restated. Nothing in the follow-up commit touches the 1A / 2A lines (dispatch-runbook.md L141–L142, os-dev.md L30–L31, SKILL.md L75), which stand as reviewed at 9700ab9d.
  6. Line budget, ceilings, byte caps — hold on the head, measured against the ceiling rows at this head. wc -l head = main for all eleven, each at or under its row in scripts/pm/check-skill-line-ratchet.mjs on f08bab5c: SKILL.md 318 (row 318), coordinator.md 49 (49), cross-repo-coordination.md 51 (51), dispatch-runbook.md 241 (241), seat-lifecycle.md 95 (96), seat-post-protocol.md 91 (91), execution-duties.md 187 (188), lanes/director.md 70 (70), lanes/skills.md 32 (33), rest-channel.md 82 (82), os-dev.md 404 (404). The ratchet script is not in the diff. Every added line of the full diff vs main is ≤120 bytes except three SKILL.md table rows (143 / 145 / 148 bytes: the domain, director and coordinator rows), all under MAX_TABLE_ROW_BYTES 341 for SKILL.md (the pin docs(pm-dispatch): fold the engine, services and cli lanes into domain:server #25247 lowered from 342). Widest added prose line 119 bytes (three lines).
  7. Scripts on the head, run once in a detached worktree (the probe named above): check-skill-line-ratchet.mjs exit 0 (declared cross-file moves 2, no row moved); check-skill-id-lint.mjs --self-test and run exit 0 (86 files clean); check-skill-frame-sync.mjs self-test and run exit 0; check-skill-frame-freshness.mjs self-test and run exit 0 (current with origin/main). These are the four the card's Acceptance names; the CI readings of record are in ③-6.
  8. id-lint, Tier H, ruling paths, human floor, acceptance greps. No # followed by a card number, no 代裁, 自裁 or 裁决线程 in any added line of the full diff. No Tier H path in the eleven-file list (AGENTS.md, CLAUDE.md, docs/NORTH-STAR.md, skills/**, .github/workflows/** absent). 「必须人工决裁」 has one hit on head and one on main, the same line (lanes/director.md L22); no ruling path reopened. triage-duties.md has zero diff vs main. Greps on the head: git grep -n '项目总监' -- .claude/skills, '项目协调者', '派发令文件', 'org Project 只是维护者' → no hit, all four; git grep -n '总监席' -- .claude/skills/pm-dispatch/SKILL.md → L56 (the director row), L75 (2A), L237 (main's, from docs(pm-dispatch): revoke every autonomous-adjudication channel — a seat analyses and recommends, every needs_decision goes to the maintainer's ruling batch #25348), L275–L276 — L56 and L274's successors as the card asks (the old L274 summons line itself is gone by docs(pm-dispatch): a project-coordinator reference — the cross-lane scheduling rules a Claude Code project runs by, so its instructions name only its lanes #25255).
  9. PR body is consistent with the head, with line-number drift only. The 速读's last sentence and the What-changed table rows for the follow-up (coordinator title and row, L3 pointer, 派发令全文 ×2, patrol line, cross-repo rule 5) match the head byte for byte; the Line budget table lists all eleven files with the counts above; Gates names head f08bab5c; Fixes #25379 stays right (items 1, 2, 4, 5, 6 landed, item 3 landed as ruled, the deferred coordinator.md work now in); Clause-②: no, Metadata-protocol: none, draft, skip-changeset on. Three SKILL.md line citations in the body are one off since the merge inserted the coordinator row at L57: 「2A … on SKILL.md L74」 is L75, 「SKILL.md L71's word」 (cron 链) is L72, and 「L56 … and L274–L276」 in the acceptance line is L56, L75, L237, L275–L276 on this head (the body's L74 / L71 readings were right at 9700ab9d). Not a defect of the change; see ③-3.
  10. PR shape. Draft, base main, body first line the project attribution block then Fixes #25379; ## 维护者速读(草稿) present; not flipped ready, not queued. The single-writer-path and same-issue claim checks on this head are success.

② Semver level

Unchanged from the f81aab8a and 9700ab9d records: no published package touched (.claude/** only), Clause-②: no matches, skip-changeset is the right form for rule-text-only in this repo. No semver level applies.

③ Boundary flags

  1. The 9700ab9d record's ③-1 deferred list is closed on this head: coordinator.md pointer and rename, 「派发令文件」 at runbook L135 (and the same word at coordinator.md L24), cross-repo L44. Nothing remains deferred; both acceptance greps and wc -l were re-run on this head (①6, ①8).
  2. Two glosses on the patrol line, not defects. 「撞墙只留存根注记」 → 「撞墙记入存根」 drops 「只」; the exclusivity (nothing but the stub note on a wall) is now carried by the line's own 「⛔ 无 cron 链」 plus seat-post-protocol.md L18 (the stub's optional fifth line is the wall note). 「cron 链」 compresses SKILL.md L72's 「⛔ 无自绑 cron、无 send_later 链」 into two words; the deleted chain was the self-bound cron / send_later chain, so the reference is right, but a reader of seat-lifecycle.md alone meets 「cron 链」 undefined. If the maintainer wants the SKILL.md spelling on the line, it does not fit (119 bytes against the 120 cap); maintainer's call, no FAIL.
  3. Body line citations. The three off-by-one SKILL.md line numbers in ①9 (L74→L75, L71→L72, L274→L275) are body prose only; a one-line body edit fixes them, not required for landing.
  4. Open PR docs(pm-dispatch): the project layer — one project form, 「pm-dispatch <席位…>」 as the summon, seats read from the seat posts' 🟢 line, takeover that never waits for a walled account, mailbox PRs, a generated roster board #25427 (card pm-dispatch: project forms — lane project and director project, lanes read from the seat post's 🟢 line, the maintainer's one-sentence assignment, takeover of a walled account, mailbox PRs, generated roster board (maintainer's word 2026-10-23) #25412, head b91d5d64) will re-word 「车道项目 / 总监项目 / 项目席」 after this PR lands — expected, per the card and the body's Acceptance note; not a FAIL. git merge-tree --write-tree f08bab5c b91d5d64 exits 0 with no conflict (tree f3b5ff78). Note docs(pm-dispatch): the project layer — one project form, 「pm-dispatch <席位…>」 as the summon, seats read from the seat posts' 🟢 line, takeover that never waits for a walled account, mailbox PRs, a generated roster board #25427 is based on an older main (merge-base with this head f0fdd45b), so whichever lands second still re-measures SKILL.md and the ratchet rows docs(pm-dispatch): the project layer — one project form, 「pm-dispatch <席位…>」 as the summon, seats read from the seat posts' 🟢 line, takeover that never waits for a walled account, mailbox PRs, a generated roster board #25427 edits (scripts/pm/check-skill-line-ratchet.mjs is in its diff); clean merge today is not a ceiling reading for the combined tree.
  5. 9700ab9d record ③-2 / ③-4 / ③-5 stand unchanged (2A gloss on L75; the claim addendum naming os-dev.md; the two trimmed non-normative words in 1A). None was taken up by the follow-up commit; none is required.
  6. Check-runs on this head, read twice. First read at 2026-10-23T13:26Z: 40 runs, 33 completed, none failed, 7 in_progress. Second read at 2026-10-23T13:30Z: all 42 completed, none failed — success on TypeScript Type Check, Lint & Repo Gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · ESLint, Lint · scoped ×3, Type Check · workspace / source gates / consumer gates / debt ledger, Governed Surface Queue Guard, Check PR Size, Check Documentation Links, Part-of PR must not also close its card, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, The card this PR closes must claim this branch, Auto Label, filter, Test Core, Dogfood Regression Gate; the remainder skipped by path filter (Build Core, Build Docs, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance, the matrix shards, the two opt-in harnesses, the duplicate-workflow Auto Label / Check Changeset / Check PR Size rows). All green on the full set, not the required subset.

Implemented-by: claude/project-thread-hxtlri
Reviewed-by: session_01REMuzhz6MWRjg8uohedMnM

VERDICT: PASS

This branch has not been deployed

No deployments
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/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants