Skip to content

Commit e781cf8

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/project-thread-qresy5
2 parents bc69c4a + 9c12140 commit e781cf8

111 files changed

Lines changed: 2923 additions & 455 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@object-ui/components': minor
4+
'@object-ui/types': minor
5+
'@object-ui/plugin-detail': minor
6+
---
7+
8+
feat(spec)!: the action blocks spell the destructive variant `danger`, the word `ActionSchema.variant` uses
9+
10+
An action's variant was spelled in two dialects. `ActionSchema.variant`, the declaration the action runner dispatches, takes `primary | secondary | danger | ghost | link`. The four action blocks (`action:button`, `action:icon`, `action:group`, `action:menu`) and the group/menu members took the Button primitive's `default | destructive | outline | secondary | ghost | link` (plus `primary` on the button, the icon and the members) and refused `danger`. So one destructive action was `danger` as a declaration and `destructive` as a block, and each block renderer translated between the two.
11+
12+
The block rows now take `danger` in place of `destructive`: `default | danger | outline | secondary | ghost | link`, plus `primary` where it was accepted before. `danger` draws the destructive button (a red item in a dropdown or `action:menu`) and asks a `confirmText` question through the destructive confirm button. `destructive` is refused at `variant` with the rename. Other components that draw the Button primitive directly (`element:button`, toasts, alerts, badges and the like) keep `destructive`, the primitive's own word, and are not touched.
13+
14+
The four block renderers forward `danger` to the runner as it is and draw it as the primitive's `destructive`. They no longer read `destructive`: stored pages are rewritten by the conversion below, so no renderer keeps a bridge for the old word. `UIActionSchema.variant` (`@object-ui/types`) follows the rows by reference. The record detail views' Delete entry in the `⋯` menu is spelled `danger` too.
15+
16+
This replaces the variant sentences of the #26665 entry in this release: the action blocks no longer translate `destructive` to `danger` at their forward to the runner, and `danger` is the spelling they accept (`UIActionSchema.variant` included). That entry's confirm-dialog behaviour is unchanged: a destructive block with a `confirmText` asks through the destructive confirm button, now when it is declared `variant: 'danger'`.
17+
18+
Stored rows and older built artifacts: the ADR-0087 D2 conversion `page-action-block-variant-destructive-to-danger` rewrites `variant: 'destructive'` to `'danger'` on the four blocks' `properties.variant` and on each `action:group` / `action:menu` member's `variant`, at every position a page nests a component (regions, slots, nested containers). It renames an `action:bar`'s own `variant` and the `variant` of each `actions` / `systemActions` member as well. The bar has no props row, so nothing refuses `destructive` on it, but it draws each member through the block renderers, which no longer read that word. A stored `page` row is rewritten when it is rehydrated, so it keeps drawing the destructive button and confirming through the destructive confirm button. The conversion is retired from the load path, so a source that still writes `destructive` on a block is refused, not rewritten. The D3 entry `ui-page-action-block-variant-destructive-refused` carries the judgment for `os migrate meta`.
19+
20+
Clause-②: no (narrowing) — the action block rows refuse `destructive`, a value they used to accept. `danger` takes its place on the same rows.
21+
22+
Metadata-protocol: narrowed (`variant: 'destructive'` is refused on the action blocks and their members; write `danger`)
23+
24+
<!-- adr-0087: registered page-action-block-variant-destructive-to-danger, ui-page-action-block-variant-destructive-refused -->
25+
26+
**BREAKING** for an author who wrote `variant: 'destructive'` on an action block.
27+
28+
**`destructive` → `danger`.**
29+
30+
- **Before.** `{ type: 'action:button', properties: { label: 'Purge', actionType: 'script', variant: 'destructive' } }` parsed; `variant: 'danger'` was refused.
31+
- **Now.** `destructive` is refused at `variant` (or at `actions.N.variant` on a group or menu member) with a message naming the rename.
32+
- **Fix.** Write `variant: 'danger'` on the block or member. Nothing else changes: it draws the same destructive button. `os migrate meta --from 17 --write` applies the rename to your sources.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@object-ui/app-shell': minor
4+
---
5+
6+
feat(spec)!: a form view's `type` is its layout only — `simple` (the default), `tabbed` or `wizard`; `split`, `drawer` and `modal` are retired, and the split-only `sections[].pane`, `splitSize` and `splitResizable` keys go with them
7+
8+
Clause-②: no (narrowing)
9+
10+
Metadata-protocol: narrowed (`FormViewSchema.type` refuses `split`, `drawer` and `modal`; `FormSectionSchema.pane`, `FormViewSchema.splitSize` and `FormViewSchema.splitResizable` are tombstones)
11+
12+
<!-- adr-0087: registered form-view-presentation-types-removed, ui-form-view-type-layout-only -->
13+
14+
**BREAKING** accept-set narrowing on the form view surface (`@objectstack/spec`), ADR-0050.
15+
16+
The model: `type` says how the form lays out its sections. Where a form opens is decided by whoever opens it, so `drawer` and `modal` were never the form's to declare, and a side-by-side split is a reader's preference since `navigation.mode` dropped `split`.
17+
18+
- **FROM → TO.** `type: 'split'` → `type: 'tabbed'` (one tab per section) or delete the value for `simple`; delete each section's `pane` and the form's `splitSize` / `splitResizable`; declare `subforms` to edit child records beside the parent. `type: 'drawer'` or `type: 'modal'` → delete the value for `simple`, or write the layout you want. A list opens a clicked record as its `navigation.mode` says (the drawer by default), and the console's New and Edit entries open the record form themselves, sized by the form's `modalSize`.
19+
- **The one-line fix.** Delete the retired value and the three split-only keys. `os migrate meta --from 17` lists the edits for existing sources, and `--write` applies them. A stored `sys_metadata` row is converted when it is read (the `form-view-presentation-types-removed` conversion), so a form view saved with one of the three values keeps loading as a `simple` form.
20+
- **What the parse says.** Each retired value is refused by name with its prescription, for example "'modal' was removed from the form view `type` enum in @objectstack/spec 18.3.0 (ADR-0050) — …", at every form view door (a view's `form` and `formViews.*`, a form view item record, a flattened form overlay) and at `defineStack` as `STACK_SCHEMA_INVALID` / 422. `pane`, `splitSize` and `splitResizable` are refused on every layout. TypeScript rejects each at the authoring site. A misspelt value keeps zod's own message.
21+
- **Unchanged.** `splitDirection`, `drawerSide`, `drawerWidth` and `modalSize` stay declared: the console reads `modalSize` for its record dialog, and the React `ObjectForm` block contract still takes the other three from this schema until its renderer follows.
22+
23+
The console (`@object-ui/app-shell`): Studio's New View form offers the three form layouts only. It offered all six, and a form view created with `split`, `drawer` or `modal` would now be refused when saved.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@objectstack/metadata-protocol': minor
4+
'@objectstack/rest': patch
5+
'@object-ui/data-objectstack': patch
6+
'@object-ui/app-shell': patch
7+
'@object-ui/i18n': patch
8+
---
9+
10+
feat(spec): a draft's per-key provenance records writes made through the MCP build door, and the OAuth client that made them
11+
12+
Clause-②: yes (widening)
13+
Metadata-protocol: added
14+
15+
A pending draft's `draftChanges` (the strict draft read's per-key provenance) could tell Studio's AI copilot from a person in Studio and from any other caller, but not an AI agent outside the console building through a deployment's MCP build door. Such a write was recorded as `api`, and nothing said which agent it was.
16+
17+
- **Spec.** `MetadataAuthoringSurfaceSchema` gains `mcp`: an AI agent outside the console writing on a person's behalf through the MCP build door. A new `MetadataAuthoringClientSchema` (`{ id, name? }`) is the OAuth client the person consented to. A `draftChanges` entry carries it as an optional `client`, present only beside `by: 'mcp'`. `SaveMetaItemRequestSchema` gains an optional `client`, stated only by the MCP build door, in-process, from the token it verified.
18+
- **The save.** A draft save with `surface: 'mcp'` stamps `by: 'mcp'` and its `client` on every key path it changes. A `client` beside any other surface, or of the wrong shape, is refused `400 INVALID_REQUEST` before anything is written. `actor` is still the person the agent writes for.
19+
- **The HTTP doors.** `?surface=mcp` is refused `400 VALIDATION_ERROR`, as `?surface=copilot` is: only the MCP build door may state it. No HTTP door reads a `client`.
20+
- **Studio.** The properties' draft chip and source line mark an `mcp` write as they mark the copilot's, and name the client: 「由 MCP 客户端「Claude」在 2 分钟前作为草稿加入」 / "Added as a draft by the MCP client "Claude" 2 min ago". A client that registered no name is shown as an unnamed MCP client, never by its id. The pending-changes sheet's drill-in lists which AI tools drafted part of the item, in all ten console locales.
21+
22+
Nothing to do for existing callers: a save that states no surface is still recorded as `api`, and an entry without `client` reads as before. The MCP build door starts stating `mcp` and its client in a later change.

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
7171
- 项目席唤醒 = PR 订阅 + 每项目一个自建自绑巡查 routine(总监席除外);⛔ 无 `send_later` 链。
7272
- 探针先行:fire 的第一动作是一次最便宜的车道盘点查询,⛔ 在它之前不读任何长文本。
7373
- 队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
74-
- 分诊席跑直连会话、默认判断档;直连会话按召唤跑,⛔ 无自醒不常驻;裁决归总监席。
74+
- 分诊席与车道席常驻,断粮即换账号重开该席与信箱;分诊席默认判断档;裁决归总监席。
7575
- 子代理裁决逐份过转录核验采信。
7676

7777
## 阶段细则索引
@@ -158,8 +158,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
158158
| 标签 | 包家族 |
159159
|:--|:--|
160160
| `domain:server` | 服务端:引擎 + 服务插件 + CLI/运行时;`objectql core formula metadata* platform-objects drivers/* services/* connectors/* triggers/* plugin-* embedder-openai knowledge-* cli runtime verify types rest mcp observability client* cloud-connection create-objectstack adapters/*`;详见 `references/lanes/server.md` |
161-
| `domain:devx` | `sdui-parser`、`packages/qa`、`content/docs`、`apps/docs`、`docs/qa`、`.githooks`、`docker/README.md`、`examples/**` 仅测试基建面;`packages/lint`、`scripts`(门禁类)、`.github/workflows`(接线)三者按锚定规则归 `domain:spec`,门禁按 SUBJECT:governed 面归 skills,代码/文档质量归本域 |
162-
| `domain:skills` | governed 面全量(含本文件;统一定义见「governed 面统一定义」行);非门禁的 `scripts/pm/**`(PM 循环工具);governed 面的治理执行文件:`.github/CODEOWNERS` + SUBJECT 是 governed 面本身的门禁/审计(现为 `scripts/pm/check-governed-merges.mjs`) |
161+
| `domain:devx` | `sdui-parser`、`packages/qa`、`content/docs`、`apps/docs`、`docs/qa`、`.githooks`、`.github/workflows/**`(接线、CI 性能)、`docker/README.md`、`examples/**` 仅测试基建面;`packages/lint`、`scripts`(门禁类)按锚定规则归 spec,门禁按 SUBJECT:governed 面归 skills,代码/文档质量归本域 |
162+
| `domain:skills` | 规则文本:`AGENTS.md`+`CLAUDE.md`+`.claude/**`(含本文件)+`skills/**`+`docs/adr/**`+`docs/NORTH-STAR.md`;非门禁的 `scripts/pm/**`(PM 循环工具);governed 面的治理执行文件:`.github/CODEOWNERS` + SUBJECT 是 governed 面本身的门禁/审计(现为 `scripts/pm/check-governed-merges.mjs`) |
163163
| `domain:spec` | `packages/spec` 整包:schema 形状、`contracts/**`、退役行为半边、strictness 台账;describe/JSDoc/墓碑散文/错误 guidance 与 alias 表;`packages/spec/scripts/**`、`packages/spec/docs/**` 及按锚定规则的例外归本域的工具链(域边界枚举与席内分派见 `references/lanes/spec.md`) |
164164
| `domain:ui` | `ui/**` 全部代码:`@object-ui/*` 库与 `ui/apps/*`、`ui/packages/types` 与 schema 语料、`ui/scripts` 与门禁工具、文档随所记录的面走;`packages/console`(dist 由 `pnpm console:build` 生成 ⛔ 不手改);协议恒归 `domain:spec`,受管面归 `domain:skills`;详见 `references/lanes/ui.md` |
165165
| `domain:cloud` | 涉 cloud 即整卡归 cloud PM(`repo:cloud` 席,同挂 `repo:cloud`):读或改 cloud 代码、生产方、事实或带 cloud 半边;本仓车道 ⛔ 不认领;cloud PM 跟到关卡,余下纯本仓活由它写明 cloud 事实后另立卡;判据见 `references/cross-repo-coordination.md` |
@@ -180,7 +180,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
180180

181181
- **ACCEPT 之后的路径分叉**:翻 ready / 挂 auto-merge / 入队前先取一次 PR 的路径面。
182182
- 路径面用 `get_files` 取,⛔ 不看报告自述;动手之前先分,不是事后对照。
183-
- governed 面统一定义:`docs/adr/**`+`.claude/**`(全量)+`skills/**`+`docs/NORTH-STAR.md`+`.github/workflows/**`。
183+
- governed 面(定 Tier,非车道):`docs/adr/**`+`.claude/**`+`skills/**`+`docs/NORTH-STAR.md`+`.github/workflows/**`。
184184
- governed 面同含 `AGENTS.md`+`CLAUDE.md`;`GOVERNED_REPOS` 同治理、行可限仓,执行席恒随落地仓车道。
185185
- 另含 `ui/docs/adr/**`+`ui/.claude/**`+`ui/skills/**`+`ui/AGENTS.md`+`ui/CLAUDE.md`+`ui/.github/workflows/**`。
186186
- 路径面命中 Tier H ⇒ ACCEPT 换终局四件套,混合 diff ⛔ 不按比例判;要拆让 dev 单独开 PR。

‎.claude/skills/pm-dispatch/references/execution-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
- 分诊折叠提议仅是建议,点名各卡皆无 open PR 才有效;否则各卡各自落地,拒折理由记一行。
3535
- 并行纪律四条(常规,非豁免):① 认领申报文件面到区域级,拿不准就串行。
3636
- ② 开 PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队列仲裁,⛔ 不手动排序。
37-
- 文件面不相交只保证文本可合并;跨文件语义耦合由队列 CI 逮住,⛔ 不读作不可能冲突。
3837
- 阻塞解除后延后单重定价:前一单派发词必答 #X 变简单、变难、不必要或无影响。
3938
- 派发后一单前用该回答重读它的选项与成本,⛔ 不沿用立单时那份。
4039
- 在飞卡衍生三分:不修它验收过不过;in-scope ⇒ 父卡 sub-issue,认领席自有、优先级继承。
@@ -51,6 +50,7 @@
5150
- 标签序:`priority:p0` > `pm:blocking` > 功能点位次 > `target:` 板上项 > p1 > p2 > p3 > 无级。
5251
- `pm:blocking` 级内先按解锁扇出(从 `Blocked-by:` 反向索引现算,⛔ 扇出数不落标签)。
5352
- 全序每级现读/现算,零逐卡维护;同级先 `Bug` 再卡龄;无级/缺 `Path:` 轮报记分诊缺口。
53+
- 一车道多席按全序交替取卡:席 1 奇位、席 2 偶位;只为破交替才发 `split`;认领戳仲裁。
5454
- 解锁那一刻 PM 自己的判断最不可信:裁决收窄或关掉了那张卡是假设不是前提。
5555
- 该假设以机制假设身份进派发令,被证伪就在同一张卡公开更正。
5656

‎.claude/skills/pm-dispatch/references/project-forms.md‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66

77
- 车队项目 = 任一账号上、指令行指向 pm-dispatch 的 Claude Code 项目;⛔ 不分项目类型。
88
- 项目做什么只由它坐的席位决定;车道席、总监席、分诊席都是席位,由维护者召唤。
9-
- 车道席:认领、派发、PR、跨账号复审;总监席:决策箱与决裁批、发版、日报、总表。
10-
- 分诊席:只写标签与审计评论;分诊与总监可召进任一项目,⛔ 不绑定项目。
11-
- 唯一不变量在账号不在项目:批准账号永不跑席位(SKILL.md 全体座位的不变量);本文不另加。
129
- 规则与指派只写角色词(总监账户、车道账户);登录名只在裁决记录里作既往事件的证据。
1310

1411
## 指令行即召唤
@@ -23,32 +20,35 @@
2320
## 席位是读出来的,不是配出来的
2421

2522
- 项目的席位 = 🟢 行写本账号的座位贴(车道、总监、分诊同此);派发前先读座位贴。
26-
- 一张也没有 ⇒ 项目闲置;每席恰一条席位线程、恰一车道,一席一贴。
2723
- 指令行就是指派:维护者在项目里写下或改写这一行,是唯一的指派动作。
2824
- 项目聊天里的长句(「本账户坐 X;Y 的 PR 由本账户复审」)是等价写法。
29-
- 协调者每次开场把指令行与座位贴对照:逐席按 `seat-post-protocol.md` 坐席或接管。
3025
- 坐席即把本账号写进 🟢 行、每席开一条席位线程;⛔ 无花名册文件。
3126
- 首次坐席自建本项目的 routine:巡逻默认每小时;分诊席加每小时裸卡轮;总监席不建。
32-
- 总监席只被维护者召唤与 PR 订阅唤醒;摘要与收件箱扫描在召唤内做;见 `lanes/director.md`。
33-
- 并发上限是维护者在该项目定的姿态;⛔ 不是协议常量,本文不写数字。
3427

3528
## 接管不等撞墙账号
3629

3730
- 🟢 行写着别的账号 ⇒ 指令行即维护者强制接管令,含在飞卡。
38-
- 撞墙账号写不出任何东西,接管永不等它的注记或简报。
39-
- 跨账号 `Release:` 点名旧会话与出处三件;新 `Claim:` 带 `Resume-from: BRANCH@SHA`,新 dev 续旧分支。
4031
- 四件形状见 `execution-duties.md` 认领节;台账 = 标签 + assignee + `Claim:` + `head:claude/` PR。
4132
- 台账按 `assignee:<旧登录名>` 读;⛔ 项目记忆与共享目录永不是台账,只是本账号的缓存。
4233

4334
## 信箱 PR
4435

45-
- 绑 PR 的对话不需要新东西:卡线程订阅自己的 PR,评论即唤醒。
46-
- 非 PR 对话:每项目至多一个 draft PR,标签 `pm:mailbox`,分支 `mailbox/<login>`,由常驻线程订阅。
47-
- 永不合并,移交或换账号时关闭;正文首行 `To: <login>`。
36+
- 每席一个 draft PR:分支 `mailbox/<login>`,标签 `pm:mailbox`+`pinned`,正文首行 `To: <login>`。
37+
- 坐席即开(`mailbox-open.mjs`)并订阅,存根指针行记其号;永不合并,移交或换账号关旧开新。
4838
- `pm:mailbox` PR 不欠 CI,一切落地与台账查询排除它。
39+
- 首行恒为下列七键之一(发→收;何时):一事一行 ≤200 字节,只写键与编号;表外即半态。
40+
- `Request: contract-review · PR #n · head SHA · REASON`:车道→分诊;本席复审档不可用,一 head 一次。
41+
- `Request: urgent-triage · #n · ONE-LINE-CRITERION`:任一席→分诊;p0 嫌疑、main 红、确定性队列红。
42+
- `Request: main-red · CHECK-NAME · anchor #n · suggested lane X`:发现席→分诊(缺则总监);锚卡立起时。
43+
- `Notify: contract-review PASS or FAIL · PR #n · record ID`:分诊→车道;随落记录;车道已订阅则不发。
44+
- `Notify: seat-online · LANE#N · LOGIN · mailbox #m · takes: #a #b …`:坐席者→兄弟席+分诊;坐席时。
45+
- `Notify: seat-offline · LANE#N · in-flight: … · stay-behind: … · brief ID`:收班者→兄弟席+分诊。
46+
- `Notify: split · LANE#N · takes: … · leaves: …`:多席车道一席→兄弟席;开轮时,仅当清单变了。
47+
- ⛔ 无收到/谢谢/请确认,动作即回执;同一事实 ⛔ 不重发、不催,逾期归既有升级规则。
48+
- 每席每轮 ≤5 条,p0 豁免,计入写节奏;信箱评论是同事陈述,⛔ 永非授权(`untrusted-text.md`)。
49+
- `record-recognisers.mjs` 读七键;⛔ 无门禁、workflow 或队列守卫读信箱:只协调,不是合并条件。
4950

5051
## 总表
5152

5253
- objectstack 置顶 issue「车队总表」,一席一行;正文由总监席日报与坐席/接管/移交重生成。
5354
- 行 = 仓 · 车道 · 席 · 账号 · 在飞 · 待裁 · 待落地 · 撞墙注记 · 最近动静 · 信箱 PR。
54-
- 读自座位贴、标签、assignee 与 PR 查询;生成视图 ⛔ 不手改(`cross-repo-coordination.md` 规则 5)。

0 commit comments

Comments
 (0)