Skip to content

@objectstack/spec 仍锁在 17.0.0-rc.0:升到 rc.1 会产生双版本 spec 图,并打红 check:spec-symbols #3182

Description

@os-zhuang

结论

本仓当前 lockfile 把 @objectstack/spec 解析到 17.0.0-rc.0,而 registry 上 rc tag 已经是 17.0.0-rc.1。升级不是改个 range 就完事 —— 实测有两个硬阻塞。

现状

package.json 里的 range 是 ^17.0.0-rc.0(root + 24 个包),本身已经允许 rc.1,只是 lockfile 钉在 rc.0:

$ ls node_modules/.pnpm | grep '^@objectstack'
@objectstack+client@17.0.0-rc.0
@objectstack+core@17.0.0-rc.0
@objectstack+formula@17.0.0-rc.0
@objectstack+lint@17.0.0-rc.0
@objectstack+sdui-parser@17.0.0-rc.0
@objectstack+spec@17.0.0-rc.0

阻塞 1 —— 双版本 spec 图

client / core / formula / lint 对 spec 的依赖是精确版本,不是 caret:

@objectstack/client@17.0.0-rc.0  -> spec "17.0.0-rc.0"
@objectstack/core@17.0.0-rc.0    -> spec "17.0.0-rc.0"
@objectstack/formula@17.0.0-rc.0 -> spec "17.0.0-rc.0"
@objectstack/lint@17.0.0-rc.0    -> spec "17.0.0-rc.0"

所以只升 spec 之后:

$ pnpm update -r @objectstack/spec@17.0.0-rc.1
$ # 图里同时存在两份 spec:
spec copies in graph: @objectstack+spec@17.0.0-rc.0, @objectstack+spec@17.0.0-rc.1
client -> sees spec 17.0.0-rc.0
core   -> sees spec 17.0.0-rc.0
formula-> sees spec 17.0.0-rc.0
lint   -> sees spec 17.0.0-rc.0

即 objectui 自己的代码看 rc.1,@objectstack/* 内部看 rc.0。这对本仓特别危险,因为多处 guard 依赖 引用同一性 / 同一份 .d.ts:

  • scripts/check-spec-symbol-derivation.mjsspec-symbol-parity.test.ts 都用 createRequire 去解析 spec 的 .d.ts 再过 TS checker —— 拿到哪一份取决于解析顺序。
  • spec-subschema-parity.test.ts 明确以引用同一性区分 re-export 与 fork(见 check-spec-symbol-derivation.mjs 头部关于 objectui#3003 的说明);两份 spec 会让 zod schema 对象不再是同一个引用。

结论:spec 不能单独升,必须整个 @objectstack 家族 rc.0 → rc.1 同步升(client / core / formula / lint / sdui-parser 的 rc tag 都已是 17.0.0-rc.1)。

阻塞 2 —— check:spec-symbols 由绿转红

baseline(rc.0):

$ pnpm check:spec-symbols
✅  spec symbol derivation: 1200 files scanned against 4231 spec export names;
    6 declared dialects, 77 untriaged collisions in 18 packages.
$ echo $?
0

升到 rc.1 后:

$ pnpm check:spec-symbols
❌  a spec-named symbol is hand-written, not derived:

    • @object-ui/app-shell declares 1 spec-named symbol the spec already owns:
        interface `InboxNotification`  packages/app-shell/src/layout/inboxGrouping.ts:16
        (exported by `@objectstack/spec/contracts`)

    • @object-ui/types declares 1 spec-named symbol the spec already owns:
        interface `FieldNode`  packages/types/src/data-protocol.ts:226
        (exported by `@objectstack/spec/data`)

    • @object-ui/types lists 1 symbol in DEBT that no longer collide — `JoinNode`.
    • @object-ui/react lists 1 symbol in DEBT that no longer collide — `PerformanceConfig`.
$ echo $?
1

也就是 rc.1 新增InboxNotification(contracts)、FieldNode(data)两个导出名,同时移除/改名JoinNodePerformanceConfig。四处都得对账(前两个 import/derive/rename/ALLOW 四选一,后两个从 DEBT 台账删除,--ledger 可重生成)。

另需注意 —— rc.1 收紧了 schema 严格性

rc.1 把一批 zod schema 从 $strip 翻成 $strict(strict 会拒绝未知键,而不是静默丢弃):

subpath rc.0 rc.1
automation $strict=0 $strip=160 $strict=19 $strip=152
ui $strict=3 $strip=286 $strict=6 $strip=287

共约 22 个 schema 变严。以前能通过的元数据现在可能直接抛错 —— 升级 PR 里需要专门验证 automation / ui 侧的解析路径,不能只看编译通过。

建议

单独开一个「@objectstack 家族 rc.0 → rc.1 同步升级」PR,内容至少包括:

  1. client / core / formula / lint / sdui-parser / spec 一并升到 17.0.0-rc.1,确认 node_modules/.pnpm 里只剩一份 spec。
  2. 处理 check:spec-symbols 的四处对账。
  3. 针对 $strip → $strict 的 22 个 schema 做解析回归验证。
  4. 按 AGENTS.md「版本号策略」,changeset 标 minor(不要标 major,fixed 组会整组被推走)。

影响

objectstack-ai/objectstack#4562(把 DecisionOutputDef 收敛成 spec 的纯 re-export)被本 issue 阻塞:required 只在 spec rc.1 才被建模,rc.0 没有。在当前解析的 rc.0 下收敛会直接编译失败:

src/utils/decisionOutputParams.ts(128,50): error TS2339:
  Property 'required' does not exist on type
  '{ key: string; label?: string; type?: "text" | "position" | "user" | "department" | "team"; multiple?: boolean; }'.

已备好的改动在分支 claude/issue-4562-decision-output-collapse(在 rc.1 下实测 app-shell tsc --noEmit 全绿),等本 issue 落地后即可开 PR。


发现于 objectstack-ai/objectstack#4562 的实施过程中,属于该 issue 范围外,故单独记录,未指派。

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions