Skip to content

feat(spec)!: 双源 C2 收敛 — MetadataEvent / MetadataBulkRegisterRequest 归 ./api,./kernel 侧死删 (#4587) - #4603

Merged
os-zhuang merged 5 commits into
mainfrom
claude/issue-4587-metadata-event-dual-source
Aug 2, 2026
Merged

feat(spec)!: 双源 C2 收敛 — MetadataEvent / MetadataBulkRegisterRequest 归 ./api,./kernel 侧死删 (#4587)#4603
os-zhuang merged 5 commits into
mainfrom
claude/issue-4587-metadata-event-dual-source

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4587

#4535 C2:基线 31 条中的 3 条 —— MetadataEvent(Schema) / MetadataBulkRegisterRequestSchema./api./kernel 各有一份不同声明,消费者拿到哪个形状只取决于 import 路径(#4411 陷阱)。issue 的「kernel 侧可能是 #4411 家族残留」线索,已按手册以 import 语句级扫描重新判定,未照抄前科。

判真源:三仓 import 语句级扫描

framework(本仓)、/workspace/cloud(HEAD bce2bec)、objectui(浅克隆,HEAD d3584c6):

  • cloud:0 处引用;objectui:0 处 import(仅 ResourceHistoryPage.tsx 一行注释提及 MetadataEvent[],指的是 metadata-core 的第三个同名概念,非消费)。
  • ./kernel 侧三个名字:三仓唯一 importer 是自己的单测(metadata-plugin.test.ts)。packages/metadata@objectstack/spec/kernel import 了一串名字(MetadataQuery/MetadataBulkResult/…),不含这三个。
  • ./api MetadataEvent(type):packages/client/src/realtime-api.tspackages/client-react/src/realtime-hooks.tsximport type { MetadataEvent } from '@objectstack/spec/api' —— 活的 SDK 合同。
  • 事件词表的字符串级复核(不只看 import):api 词表 metadata.{type}.{created|updated|deleted} 有真实生产者 —— MetadataManager 的 register/unregister 路径向 realtime service 发布 `metadata.${type}.created` / `.deleted`,client 的 subscribeMetadata 按同词表过滤。kernel 词表(metadata.registered/…/exported)在三仓零生产者、零消费者
  • 第三个同名概念 @objectstack/metadata-coreMetadataEvent(ADR-0008 仓库变更日志事件)不在 spec 入口、不归本 gate 管,未触碰;handwritten docs(concepts/metadata-lifecycle.mdx、ADR-0008)引用的都是它,无需改。

逐字段 diff(判定依据)

MetadataEvent(Schema) —— 同名两个信封,kernel 侧已死:

./api(events.zod.ts) ./kernel(metadata-plugin.zod.ts,已删)
判别字段 type: enum metadata.{13 类型}.{created|updated|deleted}(39 值) event: enum metadata.registered/updated/unregistered/validated/deployed/overlay.applied/overlay.removed/imported/exported(9 值)
独有字段 id(uuid,必填)、definition?userId? namespace?actor?payload?(record)
共有字段 metadataType(z.string)、namepackageId?timestamp metadataTypeMetadataTypeSchema(枚举),其余同名
消费方 client / client-react(import type);realtime 生产者按其词表发布 仅自己的单测

MetadataBulkRegisterRequestSchema —— 同概念近重复,kernel 侧已死且偏离强制路径:

./api ./kernel(已删)
items 元素 {type, name, data} {type, name, data, namespace?}
其余 continueOnError=falsevalidate=true 完全一致 同左;另导出 type MetadataBulkRegisterRequest = z.input(kernel 独有,不在基线)
强制路径 IMetadataService.bulkRegisterMetadataManager.bulkRegister 的 item 形状都是 {type, name, data},无 namespace —— 与 api 侧一致;namespace 平台级弃用(军规 #6) 无任何 runtime 读它
消费方 自己的单测 + POST /api/meta/bulk/register 合同族(json-schema/docs 发布面) 仅自己的单测

处置(手册路线 1:死侧删除,v17 major 窗口)

  1. ./kernel MetadataEventSchema / MetadataEvent → 死删。零消费方、词表零生产者。运行时 watch 事件另有 MetadataWatchEvent(./system),不受影响。
  2. ./kernel MetadataBulkRegisterRequestSchema / MetadataBulkRegisterRequest → 死删MetadataBulkResultSchema(活,packages/metadata 消费)原地保留。
  3. ./api 两族原样不动,成为裸名唯一属主。唯一新增:./api 补导出 MetadataBulkRegisterRequest = z.input<…> 类型别名 —— 名字延续到真源;该文件族本就每个 Schema 配推断类型(bulk 对是仅有的例外),且 build-docs 剥 Schema 后缀生成 import 示例(build-docs.ts 用「剥掉 Schema 后缀」推导 import type 示例,类型别名不存在时生成的文档引用无法编译 #4570),api/metadata 文档此前宣传的这个 import 现在真实存在。z.input 保留 kernel 侧原语义(authoring 形状,continueOnError/validate 可省略)。
  4. 收敛 ≠ 无行为变化,逐字段核实过:对 ./api 消费者零变化;从 ./kernel 迁来的消费者(三仓实测为零)是形状变化:event/actor/payload/namespace 字段不复存在、bulk item 不再接受 namespace —— changeset FROM → TO 各带一行修法与形状差说明。
  5. 回归防护:编译期 pin(typeof import('./metadata-plugin.zod') 条件类型,feat(spec)!: 双源 C1 收敛 — WebhookConfig / WebhookEvent 归 ./integration,./api 侧死删 + 改名 OpenApiWebhookEvent (#4572) #4581 先例,不吃 vitest 超时)钉死 kernel 模块不再声明这两个裸名;./api 幸存声明补了此前缺失的单测(events.test.ts:词表模式、client 订阅的三个事件名、kernel 退休词表不再 parse;metadata.test.ts:z.input 形状 + item 无 namespace 的类型级断言)。
  6. json-schema.manifest:kernel/MetadataEventkernel/MetadataBulkRegisterRequest 两键蓄意退休删行(gate 点名后删,非静默下架);authorable-surface 的 11 行按 refactor(spec)!: remove the kernel metadata-loader envelope family — 11 names declared twice with different shapes (#4411) #4458/feat(spec)!: contracts 手写 interface 与域内 zod 推导类型收敛(3 簇 11 名,#4535·A3) #4568/feat(spec)!: 双源 C1 收敛 — WebhookConfig / WebhookEvent 归 ./integration,./api 侧死删 + 改名 OpenApiWebhookEvent (#4572) #4581 先例手工删除(插件 TS 类型,schema 本体已删,不存在「父 schema 静默剥离」路径 —— 不适用 tombstone / D2 conversion,误用者在 import 处编译期即失败)。

基线

dual-source-exports.baseline.json 恰好删除 gate 点名的 3 行(31 → 28,不多删不漏删):

  • MetadataBulkRegisterRequestSchema — [./api (const)] ≠ [./kernel (const)]
  • MetadataEvent — [./api (type)] ≠ [./kernel (type)]
  • MetadataEventSchema — [./api (const)] ≠ [./kernel (const)]

验证

  • pnpm --filter @objectstack/spec build
  • check:dual-source-exports ✅(self-test 通过;4308 名字 / 16 入口,基线 28)
  • check:generated 8/8 up to date ✅(api-surface + reference docs 经 --fix 定向再生,单独 commit;api-surface 净变化:kernel −4、api +1)
  • spec typecheck ✅;spec test 288 文件 / 7274 用例全过
  • 全仓 pnpm build 71/71 ✅、pnpm typecheck 122/122 ✅、pnpm test 132/132 ✅(首轮 service-datasource 的 sqlite-wasm 文件回环用例在并行负载下超时一次 —— /tmp mkdir ENOENT,环境性;单跑 197/197 全过,复跑全仓 132/132 绿,与本改动无关)
  • 合并 origin/main(b3235b5,来向不触 spec)后按 §10 范围复验:spec build + check:generated 8/8 + 基线 28 复确认 ✅

Changeset

@objectstack/spec major:两条 FROM → TO 迁移(kernel MetadataEvent → api,含形状差与 MetadataWatchEvent/metadata-core 的指路;kernel MetadataBulkRegisterRequest(Schema) → api,含 namespace 不再 parse 与 z.input 语义说明)。不改 content/docs/releases/

范围外发现

🤖 Generated with Claude Code

https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL


Generated by Claude Code

claude added 3 commits August 2, 2026 09:25
…al source — ./kernel copies removed, ./api keeps the bare names (#4587)

The three #4535-C2 baseline rows were the #4411 trap on the kernel metadata
family: MetadataEvent(Schema) and MetadataBulkRegisterRequestSchema each had
a second, different declaration in ./kernel, and which shape a consumer got
depended only on the import path.

Import-statement-level scan across framework, cloud and objectui:

- ./kernel copies: zero importers outside their own unit test in all three
  repos. The kernel MetadataEvent lifecycle vocabulary
  (metadata.registered/.../exported) has NO producer anywhere; the kernel
  bulk-register per-item `namespace` field matches no enforced write path
  (IMetadataService.bulkRegister and MetadataManager.bulkRegister both take
  {type,name,data} items only).
- ./api MetadataEvent is the live realtime contract: MetadataManager
  publishes metadata.{type}.{created|deleted} events and
  @objectstack/client / client-react subscribe against the type.
- ./api MetadataBulkRegisterRequestSchema is the POST /api/meta/bulk/register
  contract whose item shape matches the runtime.

Disposal (route 1, dead-side delete, v17 major window): both kernel copies
removed; ./api is the sole owner of the bare names. Name continuity for the
kernel-only type alias: `MetadataBulkRegisterRequest` (z.input) is now
exported from ./api beside its schema, per the family convention and the
#4570 docs-import concern. Compile-time pin (typeof import conditional type,
#4581 pattern) keeps the bare names out of ./kernel; new events.test.ts
covers the surviving ./api declarations.

dual-source-exports.baseline.json: exactly the 3 named rows removed
(31 -> 28). json-schema.manifest: kernel/MetadataEvent and
kernel/MetadataBulkRegisterRequest retired deliberately; their 11
authorable-surface rows hand-deleted per the #4458/#4568/#4581 precedent
(plugin TS types, schema bodies deleted — no silent-strip path, misuse fails
at the import site at compile time). Changeset: @objectstack/spec major with
FROM -> TO migration lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
…:generated --fix, 2 proved stale)

api-surface.json: ./kernel loses MetadataEvent(type)/MetadataEventSchema and
MetadataBulkRegisterRequest(type)/MetadataBulkRegisterRequestSchema; ./api
gains the MetadataBulkRegisterRequest type alias beside its schema.
Reference docs: the api/metadata-plugin.mdx page (which documented the
removed kernel pair under the api section and advertised a then-nonexistent
./api type import) is no longer emitted; api/events.mdx now documents
MetadataEvent, api/metadata.mdx documents MetadataBulkRegisterRequest, and
kernel/metadata-plugin.mdx drops the removed schemas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 2, 2026 10:02am

Request Review

claude added 2 commits August 2, 2026 09:54
…rface gate (#4595)

The merge brought in build-docs' new import-surface ratchet. This PR's
MetadataBulkRegisterRequest type alias on ./api closes the gap the fresh
baseline had accepted, so its line is deleted (shrink-only ratchet).
@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/l labels Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec 双源 C2:MetadataEvent / MetadataBulkRegisterRequestSchema —— ./api ≠ ./kernel(3 条,#4535 C 组)

2 participants