Skip to content

Commit 123ff6f

Browse files
docs(pm-dispatch): objectui keeps two lanes, domain:ui and domain:skills; its domain:spec, domain:devx and domain:tooling retire (#25213)
<!-- claude-projects-attribution: {"github_login":"os-bill"} --> _Requested by **Bill** · [project thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgFHoc5JJkFBsksRzhkiLVAW)_ Fixes #25191 Clause-②: no Metadata-protocol: none ## What changed The maintainer ruled on 2026-10-22, quoted verbatim from the card: 「objectui 只有 skills 是特殊的,他本身没有 spec 的概念。devx 我感觉可以和 ui 合并」, and on the options 「甲,现在做」. After this PR, objectui has exactly two lanes: - `domain:ui` — all objectui code: the published library and `apps/*`; `packages/types`, the schema corpus and the spec-pin coupling; `.github/`, `scripts/`, the build and release pipeline and the gate tools; docs, which follow the surface they document. - `domain:skills` — the published `skills/**`. `domain:spec`, `domain:devx` and `domain:tooling` retire **in objectui only**. objectstack's own lanes are untouched. The protocol stays objectstack `domain:spec`'s: a cross-layer feature keeps rule 2 (a parent plus per-layer children, spec and backend first), and its objectui child is now a `domain:ui` card. `domain:cloud` stays a parking label, unchanged. | File | Change | Lines | |:--|:--|:--| | `.claude/skills/pm-dispatch/references/cross-repo-coordination.md` | the three 「三流」 lines become: two-lane routing · the retirement · protocol stays objectstack `domain:spec` | 51 → 51 (ceiling 51) | | `.claude/skills/pm-dispatch/references/lanes/ui.md` | the seat's scope is the whole objectui code face in the card's four bullets, plus the protocol line; the former `packages/spec` line is folded into it | 38 → 38 (ceiling 38) | | `.claude/skills/pm-dispatch/references/lanes/devx.md` | the objectui scope line is deleted | 36 → 35 | | `.claude/skills/pm-dispatch/references/lanes/spec.md` | the objectui scope line is deleted | 43 → 42 | | `scripts/pm/ensure-pm-labels.sh` | the objectui `domain:devx` / `domain:spec` rows are gone; the objectui `domain:ui` description names the whole scope (93 characters, under the 100 cap); the block and the header record the retirement with the ruling's words and date | — | | `scripts/pm/check-half-states.mjs` | the H38 sibling-board fixture is re-spelled from `domain:devx @ objectui` to `domain:ui @ objectui` (the docblock keeps the census provenance) | — | `SKILL.md` has zero edits: its only objectui mention is the 域车道 table's unanchored row (`repo:objectui` for UI defects); there is no 多仓协调 line about devx / spec pulls on objectui, so nothing to restate (card item 4, re-measured on `origin/main` at `e5f194b`). **Why re-spell the H38 fixture.** It is a fixture, not a rule, and either choice passes the self-test. Re-spelled because a retired lane name standing as the canonical example of a sibling-board seat title is exactly the trap the label script's own header names for `area:*`: a retired name surviving a `git grep` as though it were still a value, for the next AI to copy. Immediate retirement, no dual spelling. **Label objects on objectui.** The relay op table (`scripts/pm/fleet-write/ops.mjs`) carries no label-object op at all — `labels_add` / `labels_remove` act on an issue's labels, not on the objects — and this session cannot read objectui (the API answers 403 for the repository), so the live objects' current state is NOT MEASURED here. The script stops creating `domain:devx` / `domain:spec` on objectui; the object cleanup is the separate PM act the script's header describes, with the exact strokes in the report comment on the card. ## 维护者速读(草稿) **改了什么。** objectui 仓从三条流(devx / spec / ui)收成两条车道:`domain:ui` 管 objectui 全部代码,`domain:skills` 管仓根发布的 `skills/**`。objectui 的 `domain:spec` / `domain:devx` / `domain:tooling` 退役(仅 objectui);objectstack 自己的车道不动。改的是 PM 技能参考四个文件、标签词表脚本与半态巡查的一个夹具。 **为什么改。** 你 2026-10-22 的裁决 甲:objectui 本身没有 spec 的概念,devx 与 ui 合并。实测 10-08 → 10-22 期间 objectui 的 spec 卡全是本仓 `packages/types`、docs、widget 追协议,devx 卡全是本仓 CI、分片、pin 与发版工具,都由 objectui 的人在做;协议本体只在 objectstack。 **风险与代价(含回滚)。** 零发布面,`skip-changeset`。风险只在车道表:座位每次选卡都读这几行,改错会把 objectui 卡派错席。回滚 = revert 本 PR;objectui 上已被分诊改贴到 `domain:ui` 的 4 张卡不受本 PR 影响。标签对象的清理是落地时席位另一笔动作,本 PR 不碰 objectui。 **席位意见。**(席位定稿时填写) **你要做的。** 无:`.claude/**` 是 Tier S,席位做达档契约复核 PASS 后入队落地。 ## Acceptance notes - `lanes/devx.md` (36 → 35) and `lanes/spec.md` (43 → 42) now sit one line under their ceilings in `scripts/pm/check-skill-line-ratchet.mjs`; lowering the two rows is legitimate any time and is left out of this PR to keep the file surface the claim declared. - The roster creates no objectui `domain:skills` object; the card names that lane as staying, so the object presumably already exists on objectui. Not measured here (403); if absent, a row with its named reader is a one-line follow-up. - `check-half-states.mjs`: no test file outside the script names it (`git grep` over `scripts/**` tests and `test/**` found none), so its own `--self-test` is the whole suite owed by the edit. ## Gates Local subset at head `db3b205`, each exit captured before any pipe (the full derived list and the `--ran` reconciliation are in the report comment on the card): | Gate | Exit | |:--|:--| | `pnpm check:pm-skill-ratchet` | 0 — every ceiling held (cross-repo 51/51, ui 38/38, devx 35/36, spec 42/43), every line ≤120 bytes | | `pnpm check:pm-skill-id-lint` | 0 — 87 files clean | | `pnpm check:pm-governed-prose` | 0 | | `pnpm check:pm-label-desc-cap` | 0 — 38 descriptions ≤100 chars | | `pnpm check:skill-frame-sync` | 0 | | `pnpm check:pm-half-states` (the edited script's own self-test) | 0 | | `pnpm check:pm-dispatch-gates` | 0 | | derived union (`dispatch-gates.mjs --commands` on the diff, 51 families) | 51 run, 0 NOT-MEASURED, 0 UNRUN (`--ran` reconciliation) | CI families run by the PR's check-runs; the seat's ACCEPT reads those. --- _Generated by [Claude Code](https://claude.ai/code/session_01FRiDG7bG4jkZL2tQKpJgGv)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 15764cd commit 123ff6f

6 files changed

Lines changed: 52 additions & 32 deletions

File tree

‎.claude/skills/pm-dispatch/references/cross-repo-coordination.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
- 新仓登记是一张清单:座位贴、标签、类别归属、门禁盘点、写身份锁移植(deny + hooks)。
1212
- 新仓准入判据一句:这个仓真的需要常设席位吗。
1313
- hotcrm 收卡判据与宪章见 `references/lanes/hotcrm.md`。
14-
- objectui 卡按修复落点分流三流,`domain:ui` 是唯一新增标签。
15-
- `domain:devx`(工程面)与 `domain:spec`(契约面)跨仓归各自车道。
16-
- 其余(发布库与 apps)归 `domain:ui` 执行席;症状位置不改流向,docs 随所记录的面走。
14+
- objectui 卡按修复落点分两条车道:`domain:ui`(全部代码)与 `domain:skills`(仓根发布 `skills/**`)。
15+
- objectui 的 `domain:spec`、`domain:devx`、`domain:tooling` 已退役:⛔ 不贴、不认领、不再创建。
16+
- 协议恒归 objectstack `domain:spec`;跨层功能照规则 2,objectui 子单归 `domain:ui`。
1717
- 车道可分席(席号 `· seat N`,或域×仓):忙时一车道开多席,闲时收归一席;每席独立座位贴。
1818
- 认领评论带 `Seat: domain:X#N` 行申报席号(缺省席 1);同席认领互斥,他席认领不触发自退。
1919
- 拆分触发预登记:单轮逼近 fire 周期,或某仓在全序下持续断粮 ⇒ 按仓拆回多席。

‎.claude/skills/pm-dispatch/references/lanes/devx.md‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
## 范围
66

77
- 本席路径面全量在 SKILL.md 域车道表 `domain:devx` 行,⛔ 不另抄。
8-
- objectui 的本域面同辖:`.github/`、`scripts/`、构建与发布管线、门禁工具。
98
- 边界:守护 skills 的门禁脚本在 `scripts/` 下时归本席,判据是被改文件的路径。
109
- SUBJECT 例外与 spec 三面切分在 SKILL.md 域车道表;`.claude/workflows/` 不是 `.claude/skills/`。
1110
- 范围内的文件不等于范围内的卡:归属按卡的 `domain:*` 判,反向亦然。

‎.claude/skills/pm-dispatch/references/lanes/spec.md‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
- 含 `packages/spec/scripts/**`、`packages/spec/docs/**`。
1111
- 同含围着 spec 契约转的工具链:门禁、生成器、lint 规则、报错散文、references 管线。
1212
- 一般开发工具面留 devx;`packages/spec` 恒归本席,不论谁需要它。
13-
- objectui 的契约面同辖:`packages/types`、schema 与 `$schema` 语料、spec pin 耦合与契约决策卡。
1413

1514
## 席内分派参考
1615

‎.claude/skills/pm-dispatch/references/lanes/ui.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010

1111
## 范围
1212

13-
- 三流分流的残余流归本席:发布库 `@object-ui/*` 与 `apps/*`,判据见 cross-repo-coordination.md。
14-
- objectui 的 `domain:devx` 与 `domain:spec` 卡归各自跨仓车道,⛔ 不归本席。
13+
- objectui 全部代码归本席:发布库 `@object-ui/*` 与 `apps/*`;`packages/types`、schema 语料与 spec pin;
14+
- `.github/`、`scripts/`、构建与发布管线、门禁工具;docs 随所记录的面走。
15+
- 协议恒归 objectstack `domain:spec`,新 `packages/spec` 工作同此;跨层功能的 objectui 子单归本席。
1516
- 落点不明留分诊首触,⛔ 不猜、不代判。
1617

1718
## 常设承诺
1819

1920
- 构建产物经 `pnpm objectui:refresh` 回流,见 cross-repo-coordination.md。
2021
- 回流后的 console pin bump 是 objectstack 的单张卡,⛔ 永不做本仓 PR 的 rider。
21-
- 新 `packages/spec` 工作恒归 `domain:spec` 席,已派发卡 ⛔ 不因此转席,见 cross-repo-coordination.md。
2222
- `scripts/pm/**` 单写手恒在 objectstack 侧 ⇒ 本席的工具需求走上游卡带 `Blocked-by:` 回链。
2323
- 本仓标签/assignee 写走 objectstack `label-write.mjs --repo`,⛔ 不 MCP `issue_write`;被拒转有通道席。
2424
- 受管面五项含仓根发布 `skills/**`,清单、判据与禁令见 objectui AGENTS.md §9 受管面段。

‎scripts/pm/check-half-states.mjs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7437,7 +7437,8 @@ export function seatDeclaresWait(markerBody) {
74377437
* three measured shapes (2026-08-25 census, all 12 open seat posts):
74387438
*
74397439
* `domain:engine` — a lane on THIS board
7440-
* `domain:devx @ objectui` — a lane on a SIBLING board
7440+
* `domain:ui @ objectui` — a lane on a SIBLING board (the census read
7441+
* `domain:devx`; objectui retired it 2026-10-22, keeping `domain:ui` and `domain:skills`)
74417442
* `repo:cloud` / `skills` / `triage (objectstack-wide)`
74427443
*
74437444
* plus the free-claim multi-seat shape the protocol added afterwards:
@@ -30166,8 +30167,8 @@ async function selfTest() {
3016630167
t('H38 seat: …and is not foreign', seatLane(seat38(seat2Title)).foreign, false);
3016730168
t('H38 seat: …and carries the seat number', seatLane(seat38(seat2Title)).seat, 2);
3016830169
t('H38 seat: a bare title is seat 1', seatLane(seat38()).seat, 1);
30169-
t('H38 seat: a numbered seat on a SIBLING board is still foreign', seatLane(seat38('[PM seat] domain:devx · seat 3 @ objectui — 🟢 os-b')).foreign, true);
30170-
t('H38 seat: …and still carries its number', seatLane(seat38('[PM seat] domain:devx · seat 3 @ objectui — 🟢 os-b')).seat, 3);
30170+
t('H38 seat: a numbered seat on a SIBLING board is still foreign', seatLane(seat38('[PM seat] domain:ui · seat 3 @ objectui — 🟢 os-b')).foreign, true);
30171+
t('H38 seat: …and still carries its number', seatLane(seat38('[PM seat] domain:ui · seat 3 @ objectui — 🟢 os-b')).seat, 3);
3017130172
t('H38 seat: a numbered seat still buys the H32 comment fetch', h32NeedsSeatComments(seat38(seat2Title)), true);
3017230173
t('H38 seat: an unparseable title has no seat', seatLane(seat38('not a seat title')).seat, null);
3017330174
t('H38 seat: a claim with no `Seat:` line is seat 1', claimSeatNumber('Claim: x\nBranch: `claude/issue-1-a`'), 1);

‎scripts/pm/ensure-pm-labels.sh‎

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
# deliberately ABSENT — recreating a retired label puts an ownerless lane back
5252
# into GitHub's autocomplete. Their leftover label OBJECTS may still exist in
5353
# the repos; deleting those objects is a separate, deliberate PM action.
54+
# The objectui-repo STREAM labels domain:spec / domain:devx / domain:tooling,
55+
# retired in objectui only on 2026-10-22 (maintainer ruling 「甲,现在做」), are
56+
# recorded beside the objectui domain:ui row further down, for the reason the
57+
# next paragraph gives for `repo:objectstack`.
5458
#
5559
# ⛔ One RETIRED ROUTING label is held on those same two terms — deliberately
5660
# absent, object deliberately kept — but is recorded beside the `repo:*` rows
@@ -460,28 +464,45 @@ gh label create domain:cloud -R objectstack-ai/objectui -c bfd4f2 -d "Cloud-s
460464
gh label create status:parked -R objectstack-ai/objectstack -c cfd3d7 -d "Parked — exempt from the PM sweep and half-state patrol until its owner migrates it (e.g. cloud PM)" 2>/dev/null || true
461465
gh label create status:parked -R objectstack-ai/objectui -c cfd3d7 -d "Parked in objectui — exempt from the PM sweep until the cloud PM migrates it (with domain:cloud)" 2>/dev/null || true
462466

463-
# objectui workload streams — maintainer rulings 2026-08-21, quoted verbatim:
467+
# objectui workload lanes — TWO since the maintainer's ruling of 2026-10-22,
468+
# quoted verbatim: 「objectui 只有 skills 是特殊的,他本身没有 spec 的概念。devx
469+
# 我感觉可以和 ui 合并」, and on the options put to them, 「甲,现在做」. The
470+
# three-stream vocabulary it replaces (maintainer rulings 2026-08-21, verbatim:
464471
# 「B:两车道」→「现在本身就有 domain:devx」→「不要搞出那么多车道名称」→「也有
465-
# domain:spec」「其他就是 domain:ui ?」, naming finalized 「按 domain:ui 定稿」.
466-
# objectui cards are streamed by the domain of the surface their FIX lands on
467-
# (never by symptom location; docs cards follow the surface they document):
468-
# domain:devx (engineering face — .github/, scripts/, build/publish/release
469-
# pipeline, gate tooling) and domain:spec (contract face — packages/types, the
470-
# schema corpus, @objectstack/spec pin coupling) reuse the EXISTING cross-repo
471-
# lane names and are worked by those lanes exactly as main-repo cards are;
472-
# domain:ui is the ONE new label, named for the repo's own trade — the published
473-
# library (components, plugin-*, fields, layout, core) and the apps — worked by
474-
# the objectui execution seat. Cards whose landing surface is undetermined stay
475-
# unstreamed for triage first-touch rather than guessed. These rows create
476-
# objectui-repo label OBJECTS: the main-repo lane roster (the loop above) is
477-
# untouched, and the retired main-repo domain:ui lane stays retired there (see
478-
# the header). Named consumers: the objectui execution seat's candidate query
479-
# and the devx / spec lanes' cross-repo pulls (SKILL.md 多仓协调). Streaming
480-
# the existing objectui backlog is a triage duty once the vocabulary lands —
481-
# by file-path evidence, never guessed — not this script's.
482-
gh label create domain:devx -R objectstack-ai/objectui -c bfd4f2 -d "objectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo" 2>/dev/null || true
483-
gh label create domain:spec -R objectstack-ai/objectui -c bfd4f2 -d "objectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane" 2>/dev/null || true
484-
gh label create domain:ui -R objectstack-ai/objectui -c bfd4f2 -d "objectui ui stream: fix lands on the published library or apps — objectui execution seat" 2>/dev/null || true
472+
# domain:spec」「其他就是 domain:ui ?」, naming finalized 「按 domain:ui 定稿」)
473+
# streamed objectui cards by the surface their FIX lands on into domain:devx
474+
# (engineering face), domain:spec (contract face) and domain:ui (the rest).
475+
# Measured on objectui, 2026-10-08 → 2026-10-22: every domain:spec card was
476+
# objectui's own packages/types, docs and widgets catching up with the protocol
477+
# and was worked by objectui hands — the protocol itself lives only in
478+
# objectstack — and every domain:devx card was objectui CI, test shards, pin
479+
# and release tooling, worked by ui seats. So objectui has exactly two lanes:
480+
# domain:ui — ALL objectui code: the published library (components,
481+
# plugin-*, fields, layout, core) and the apps; packages/types,
482+
# the schema corpus and the @objectstack/spec pin coupling;
483+
# .github/, scripts/, the build/publish/release pipeline and
484+
# the gate tooling; docs, which follow the surface they
485+
# document. Worked by the objectui execution seat.
486+
# domain:skills — the published skills/** (a governed surface). No objectui
487+
# row here: this file has never created that object; a row
488+
# arrives by PR with the reader that names it.
489+
# ⛔ RETIRED in objectui only, 2026-10-22: domain:spec, domain:devx and
490+
# domain:tooling. This script stops creating the first two (domain:tooling was
491+
# never a row here); their leftover label OBJECTS on objectui are cleaned up by
492+
# the separate, deliberate PM act the header describes — a "retired, use
493+
# domain:ui" description, or deletion. objectstack's own domain:spec and
494+
# domain:devx lanes are untouched: the retirement is per repo. The protocol
495+
# stays objectstack domain:spec's — a cross-layer feature keeps its parent plus
496+
# per-layer children, spec and backend first, and its objectui child is now
497+
# domain:ui. Cards whose landing surface is undetermined stay unstreamed for
498+
# triage first-touch rather than guessed. The row below creates the objectui-
499+
# repo label OBJECT: the main-repo lane roster (the loop above) is untouched,
500+
# and the retired main-repo domain:ui lane stays retired there (see the
501+
# header). Named consumer: the objectui execution seat's candidate query
502+
# (.claude/skills/pm-dispatch/references/lanes/ui.md). Re-laning the open
503+
# objectui backlog onto domain:ui was triage's act on the ruling's day, by
504+
# file-path evidence — not this script's.
505+
gh label create domain:ui -R objectstack-ai/objectui -c bfd4f2 -d "objectui ui lane: all objectui code — library, apps, packages/types, .github/, scripts/, docs" 2>/dev/null || true
485506

486507
# The FEATURE AXIS — `area:*`, one per card, eleven values. It is the PLANNING
487508
# axis: priority is judged on it, and `domain:*` beside it decides only which

0 commit comments

Comments
 (0)