Repository navigation
Commit ea33919
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)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9D9LYrYMoW5HPuB2zqqkLsgb)_
Fixes #25412
Clause-②: no
Metadata-protocol: none
## 维护者速读(草稿)
- **改了什么**:pm-dispatch 技能新增一份参考 `references/project-forms.md`(54
行),把「项目层」写进仓库:只有一种车队项目,项目做什么全看它坐了哪些席;总监席、分诊席与车道席都是席位,由您在任一项目里写一行「pm-dispatch
<席位…>」(如「pm-dispatch 总监」「pm-dispatch ui skills」)召唤;首词固定 `pm-dispatch`(不用
`fleet`,它已是 bot 与中继的名字);席位从座位贴的 🟢 行读出来、不另配;这一行写下或改写即指派;🟢
写着别的账号时这一行就是强制接管令,含在飞卡,不等撞墙账号写任何东西;台账只在 GitHub;每项目至多一个 `pm:mailbox` 信箱
PR 做跨账号非 PR 对话;置顶 issue「车队总表」是生成视图、永不手改;并发上限是您按项目定的姿态,不写进协议。SKILL.md
索引表加一行指向它,入口行旁注明项目指令行;另外三个参考各就地改一行、`lanes/director.md` 改两行,棘轮加一条封顶行。
- **为什么改**:您 2026-10-23 在「车队机制迁往 Projects」线程的原话:「如果我同意这一整套机制,相关的 skills
是不是都要修改,文件应该落在仓库中」「你立卡并派发处理所有相关任务,跟踪落地」;再按
12:25「为什么我们需要区分项目类型?任何一个项目中都可以召唤总监啊,任何一个项目中也可以召唤分诊」与 12:27「我直接写
pm-dispatch 总监,pm-dispatch ui,pm-dispatch 分诊,这种应该都可以吧?」两次修正写成。
- **风险与代价(含回滚)**:纯规则文本,不碰代码与门禁逻辑;每个文件行数不变或为新文件,每行 ≤120 字节,无上限抬高;一次
revert 可回。三处要您知道:① #25385(#25379 的 PR)还没合,它把 SKILL.md
入口表写成「车道项目」「总监项目」两种项目,而您 12:25 已说只有一种;本 PR 避开它的 hunk,排在它之后落;它 14:44Z
合入后本 PR 已合 main 并补了一个提交(91e8600)把那四处改成单一形态;② 为付 SKILL.md 的一行,删了「一 PM
恰管一车道,一车道由一组座位管,一席一贴」这一行,三个子句分别住 `cross-repo-coordination.md` 规则 4
与分席行、`seat-post-protocol.md`,以及新文件的「每席恰一条席位线程、恰一车道,一席一贴」;③
`lanes/director.md` 改了两行而非一行:「⛔ 无 Routine/cron」与「未回字 = 停,⛔
无巡检」都只对直连会话成立,否则项目里的总监席就跑不了每日摘要与每小时收件箱扫描。
- **席位意见**:席位 2 对 head b91d5d6 的契约复核 PASS(评论 6366112222);其边界项 1(席位词随
`lanes/server.md`)与 3(在飞卡按卡面无条件接管)已在跟进提交 91e8600 里改好,待席位对新 head 增量复核。
- **你要做的(一个动作)**:无。您 14:14Z 已在席位线程授权「按 pm-dispatch 复核通过的 PR 都可以落地」;席位对新
head 复核 PASS、检查全绿后由席位落地。
## What changed
| File | Change |
|:--|:--|
| `.claude/skills/pm-dispatch/references/project-forms.md` (new, 54
lines) | The project layer above the seats, six sections in the card's
order: 一种项目形态 (one project form; what a project does is decided by the
seats it holds; the only invariant is on the account and is already
SKILL.md's 「批准账号永不跑席位」, restated in one line; role words only, logins
only as evidence in ruling records) · 指令行即召唤 (the one-line instruction
`pm-dispatch <席位> [<席位>…]`, first token = the skill directory name, ⛔
not `fleet`; the seat-word mapping 总监 = `lanes/director.md`, 分诊 =
`lanes/triage.md`, the rest by lane file name; several seat posts in one
lane → the one whose 🟢 names this account, else the vacant one, else ask
once; ⛔ no template pasted, ⛔ no account-level skill copy) ·
席位是读出来的,不是配出来的 (seats = the seat posts whose 🟢 names this account; none
⇒ idle; the instruction line is the only assignment act, the long chat
sentence is an equivalent form; on every coordinator start the line is
compared with the posts, seat or take over per `seat-post-protocol.md`,
one seat thread per seat; first seating creates the patrol routine every
2–4 h, the 总监席 adds the daily digest and hourly inbox scan, the 分诊席 the
hourly bare-card run, shareable when both sit in one project; ⛔ no
roster file; concurrency is a per-project posture, ⛔ not a protocol
constant) · 接管不等撞墙账号 (a 🟢 naming another account makes the line the
维护者强制接管令, in-flight cards included; cross-account `Release:` + new
`Claim:` with `Resume-from: BRANCH@SHA`, shape in `execution-duties.md`;
ledger = labels + assignee + `Claim:` + `head:claude/` PRs read by
`assignee:<old login>`, ⛔ never project memory) · 信箱 PR (PR-bound talk
needs nothing new; one draft PR per project labelled `pm:mailbox` on
`mailbox/<login>`, subscribed by a resident thread, never merged, closed
on handover, first body line `To: <login>`, owes no CI, excluded from
landing and ledger queries) · 总表 (pinned 「车队总表」 issue, one row per seat,
regenerated by the 总监席 digest and every seat/takeover/handover, a
generated view ⛔ never hand-edited, `cross-repo-coordination.md` 规则 5).
|
| `.claude/skills/pm-dispatch/SKILL.md` | +1 〈阶段细则索引〉 row for the new
file (reader: the coordinator on every start; a seat before seating,
takeover, handover and opening a mailbox PR); the 〈入口与角色〉 opening line
now reads 「`/pm-dispatch [args]` 或项目指令行 `pm-dispatch <席位…>`,…」 (93
bytes, in place); −1: the 〈全体座位的不变量〉 line 「一 PM 恰管一车道,一车道由一组座位管,一席一贴;PM
Y 管什么恰一个答案」 — 一人恰一车道 and 一车道可坐多席 are `cross-repo-coordination.md` 规则 4
and its 分席 line, 一席一贴 is `seat-post-protocol.md` 〈贴的四段〉 L9, and the new
reference carries 「每席恰一条席位线程、恰一车道,一席一贴」. 319/319. |
| `references/seat-post-protocol.md` 〈贴的四段与派生视图〉 | 「多场席(总监):`🟢`
后写召唤账号,状态块逐场一行(会话 ID + 锚);无在任者、无接管」 → 「直连多场总监席:`🟢` 后写召唤账号,逐场一行;项目席 🟢
即指派,接管见 `project-forms.md`」 (118 bytes, in place): the 🟢 account is the
assignment and takeover is the maintainer's instruction line. Dropped
from that line: 「(会话 ID + 锚)」 (format detail) and 「无在任者、无接管」, which
`lanes/director.md` L8 and `seat-lifecycle.md` 〈开轮互斥〉 L12 both still
state. 91/91. |
| `references/seat-lifecycle.md` 〈座位贴协议〉 | 「维护者强制接管令取席位、队列、未起工卡与待落地 PR;⛔
不取在飞卡,由原认领者跟完」 → 「…;在飞卡归原认领者,不可达才接」 (118 bytes, in place): the takeover
order reaches an in-flight card only when its claimer is unreachable
(the walled-account case the card names; the reachable claimer keeps the
card). **Rewritten in the follow-up commit** (seat review ③-3) to
「…取席位、队列、在飞卡、未起工卡与待落地 PR;⛔ 不等原认领者注记」 (118 bytes), the unconditional
in-flight takeover the card's Wanted 5 states. Also L70 (from #25385):
「五项健康指标进总监项目的每日摘要」 → 「…进总监席的每日摘要」. 95/96. |
| `references/lanes/director.md` 〈授权与形态〉 | L7 「授权面 = 人工定期召唤,…;⛔ 无
Routine、无 cron、无舰队位」 → 「授权面 = 人工召唤,任一项目可召;…;直连 ⛔ 无 Routine/cron」; L16
「未回字 = 不在 = 停,⛔ 无巡检…;⛔ 无任何例外」 → 「…;例外 = `../project-forms.md` 例行」. Two
lines instead of the card's one, both in place (114 / 120 bytes): with
only one of them edited, the 「两条细则冲突 ⇒ 按更严的一条」 rule would switch the
project 总监席's digest and inbox scan off. 70/70. |
| `scripts/pm/check-skill-line-ratchet.mjs` | A `CEILINGS` row for the
new file at its landed count (54) and a `MAX_TABLE_ROW_BYTES` pin of 0
(no table row), placed beside `filing-gate.md` so they sit in no open
PR's hunk. A new file is not a raise and funds nothing; no other row
moves. |
## Serial constraints and the landing order
- **This PR lands after #25385** — merged 2026-10-23T14:44Z as
`6c2699b3`, now merged into this branch (`7dd4eb61`, clean). Every hunk
of the first commit is outside #25385's: SKILL.md L49, L82 and L97 vs
its L33, L54, L56, L70–L71, L74, L275; `seat-lifecycle.md` L28 vs its
L3, L26–L27, L92–L95; `seat-post-protocol.md` L13 vs its L17–L18,
L51–L53, L58–L60; `lanes/director.md` L7/L16 vs its L1. `git merge-tree
--write-tree` of this head against #25385's head: clean (checked before
the push).
- **Two of the card's one-line edits are already #25385's and are not
repeated here**: `dispatch-runbook.md` 〈卡线程〉 (the dispatch order in the
thread's opening message) and `rest-channel.md` (GitHub org Project →
「看板」). `cross-repo-coordination.md` 规则 5 reads 「org Project 只是维护者的聚合视图」
on `main`, but #25385's head already carries 「看板(org Project)只是维护者的聚合视图」
at L44, so nothing is left for the seat there.
- **Follow-up commit `91e8600b`** (after the `main` merge): #25385's
four two-project-type lines, the vocabulary the maintainer withdrew at
12:25Z, now read one-form, in place and line-neutral — SKILL.md
`<domain>` row 「承办它的是坐该席的车队项目」, `director` row 「人工召唤,任一车队项目可召」, the 席位两形
bullet 「会话是车队项目的线程」, `seat-lifecycle.md` 「五项健康指标进总监席的每日摘要」; `git grep
'车道项目\|总监项目' -- .claude/skills` → no hit; 「项目席」 (a seat form) stays. The
same commit rewrites `project-forms.md` L19 to
「ui、skills、devx、server、spec、hotcrm」 (review ③-1: #25247 folded
`cli`/`engine`/`services` into `lanes/server.md`) and
`seat-lifecycle.md` L28 to the unconditional in-flight takeover (review
③-3).
- #25255 and #25247 landed before the `main` merge; the ratchet on the
merged tree reads SKILL.md 318/318.
- Sibling card #25414 (the review/landing rule, triage duties, the
decision inbox) lands after this PR, as its own body says.
## Line budget
| File | Lines | Ceiling | Net |
|:--|--:|--:|--:|
| `references/project-forms.md` | 54 | 54 (new row) | new (1 edited in
place in the follow-up) |
| `SKILL.md` | 318 (319 before `main` shrank it) | 318 | 0 (+1 row, −1
line, 4 edited in place) |
| `references/seat-post-protocol.md` | 91 | 91 | 0 (1 edited in place) |
| `references/seat-lifecycle.md` | 95 | 96 | 0 (2 edited in place) |
| `references/lanes/director.md` | 70 | 70 | 0 (2 edited in place) |
Widest added or edited prose line 120 bytes (`lanes/director.md` L16);
the new file's widest line 120 bytes; the one added table row is 208
bytes against SKILL.md's 342-byte pin. No re-wrap used as payment.
## Gates
On head `91e8600b` (`b91d5d6` + the `origin/main` merge `7dd4eb61` at
`6c2699b3` + the follow-up commit), run in this checkout with each exit
code captured before any pipe; the same 42 commands were run the same
way on `b91d5d6` with the same result:
- The four the card names: `pnpm check:pm-skill-ratchet` ✓ (self-test
164 cases; `project-forms.md` 54/54, SKILL.md 318/318, widest row 0/0;
total ceilings unchanged, no row moved), `pnpm check:pm-skill-id-lint` ✓
(self-test 23), `pnpm check:skill-frame-sync` ✓ (91 markdown files
scanned, 1 declared copy), `pnpm check:skill-frame-freshness` ✓. Also
`pnpm check:pm-governed-prose` ✓.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack <the six changed paths>` derives 42 commands;
every one was run with its exit code captured before any pipe. First
pass on a checkout with no `node_modules`: 31 exit 0, 11 PREREQUISITE
(`yaml` / `typescript` not installed, one 240 s cap). After `pnpm
install --frozen-lockfile`: 41 exit 0, and `pnpm --filter
@objectstack/lint run check:doc-formula-expressions` still exit 3 as a
PREREQUISITE (`@objectstack/formula` and `@objectstack/lint` unbuilt in
a fresh checkout — the reading the sibling skill PRs recorded); after
`pnpm exec turbo run build --filter=@objectstack/formula
--filter=@objectstack/lint` it exits 0. **42 derived, 42 run, 42 × exit
0, 0 NOT-MEASURED.** CI's check-runs on this head are the record either
way.
- `git grep -n 'os-bill\|hotlong\|os-elon-musk' --
.claude/skills/pm-dispatch/references/project-forms.md` → no hit
(acceptance bullet 3).
- No published package moves (`.claude/**` and one `scripts/pm` ledger
row), so `skip-changeset` applies.
## Acceptance notes
- The body's first line is the HTML-comment attribution block the
project session requires; `os-dev.md` 〈干净收尾〉 forbids HTML comments in
GitHub text. Reported as a deviation, not hidden.
- `lanes/director.md` carries two in-place edits where the claim's File
surface says 「one line each」; the reason is in the table above. Reported
as a deviation.
- The card's 「Edits elsewhere」 list names `dispatch-runbook.md` 〈卡线程〉
and `rest-channel.md`; both lines already exist on #25385's head and are
not duplicated here (see Serial constraints).
- Both commits carry the model-free trailer pair the pre-push hook
requires and no card trailer; the merge commit is git's default message;
the card relation is this body's `Fixes` line only.
- Governed surface `.claude/**` (Tier S): draft, awaiting the seat's
`CONTRACT_REVIEW_TIER` re-read of `91e8600b`; landing by the seat under
the maintainer's 14:14Z authorization in the seat thread; ⛔ not to be
flipped ready, queued or armed by this thread.
- Opened through the GitHub MCP, so the PR author is the login rather
than the fleet bot; the seat ruled it stays as is, and every later write
to this PR goes through the relay.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01UJebcS3m7vf3CYnTfBD5oH)_
---------
Co-authored-by: os-elon-musk <elon@objectstack.ai>
Co-authored-by: Claude <noreply@anthropic.com>1 parent f7d6f5b commit ea33919
6 files changed
Lines changed: 71 additions & 10 deletions
File tree
- .claude/skills/pm-dispatch
- references
- lanes
- scripts/pm
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
| 71 | + | |
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
| |||
95 | 96 | | |
96 | 97 | | |
97 | 98 | | |
98 | | - | |
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
70 | | - | |
| 70 | + | |
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1335 | 1335 | | |
1336 | 1336 | | |
1337 | 1337 | | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
1338 | 1344 | | |
1339 | 1345 | | |
1340 | 1346 | | |
| |||
2133 | 2139 | | |
2134 | 2140 | | |
2135 | 2141 | | |
| 2142 | + | |
2136 | 2143 | | |
2137 | 2144 | | |
2138 | 2145 | | |
| |||
0 commit comments