Skip to content

feat(spec)!: contracts 手写 interface 与域内 zod 推导类型收敛(3 簇 11 名,#4535·A3) - #4568

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4538-contracts-interface-convergence
Aug 2, 2026
Merged

feat(spec)!: contracts 手写 interface 与域内 zod 推导类型收敛(3 簇 11 名,#4535·A3)#4568
os-zhuang merged 1 commit into
mainfrom
claude/issue-4538-contracts-interface-convergence

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#4538

单 PR 覆盖 issue 列出的全部名字(按协调人指示;issue 标题写 9 条,正文实际列了 11 个名字/基线行,以正文为准)。逐名做了三仓 import 级扫描(本仓 + cloud + objectui shallow clone)判定真源,基线 11 行全部删除,check:dual-source-exports 归零通过且无新增。

逐名判定与处置

名字真源处置关键证据
NotificationChannelsystem zod enumcontracts 改为 re-export两侧成员集完全相同,纯靠纪律同步;NotificationConfigSchema.channel 消费 schema 侧
ValidationResultkernel zodcontracts 改为 re-export两侧逐字段相同;两侧在 spec 外均无消费方(core 用自己的本地类型)
HealthStatuskernel zodcontracts 改为 re-exportanyunknown 收紧;两侧 spec 外零消费
StartupOptionskernel zodcontracts re-export 两个 tier;orchestrateStartup 参数改 StartupOptionsInputcontracts 旧 interface 就是 input tier 的手写镜像;调用方授权的 options 袋按 input tier 声明
PluginStartupResultkernel zodcontracts 改为 re-export(可序列化投影)两侧 spec 外零消费;活对象 plugin: Plugin + error?: Error 无法被 zod 描述,收敛到可校验形状
JobExecution形状:contracts(durationMs);声明:归 systemsystem schema durationdurationMs 后 contracts 改为 re-export三个 job adapter 全部产出 durationMs,DB 列 duration_ms;system 版 duration 零消费,描述的是从未存在过的记录
JobSchedulecontracts(service 边界形状)删除 system 的 = Schedule 遗留别名别名自注 "backwards compatibility" 且零消费;运行时流动的是 trigger-schedule 归一化出的裸字符串 expression 形状;authoring tier 保留真名 Schedule
AnalyticsQuerydata zod(先对齐语义)schema 去掉 timezone.default('UTC') 后 contracts 改为 re-export/analytics 入口一直拒绝应用该 default(#1982/#2018:缺席=引擎解析 org 时区),default 声明的是运行时拒绝执行的边界;去掉后 schema 全程无 transform,两 tier 合一,contracts/data/cloud 三方消费全部继续编译
DriverCapabilities双方都活 → 改名contracts 侧改名 AnalyticsDriverCapabilities;service-analytics 同步改名两个真概念:data 侧是驱动能力旗标(IDataDriver.supports,contracts/data-driver.ts 自己就 import data 侧),contracts 侧是 analytics 策略链三元组 —— 占名者是后者,证据无歧义
MetadataExportOptionscontracts删除 system 侧 schema+类型MetadataManager.exportMetadata 实现的是 contracts 形状(options.types 驱动导出);system 版(output 目录袋)三仓零消费,是 #4411 家族最后幸存者 —— issue 猜的"改名"经扫描证实为"死侧删除",contracts 保名
MetadataImportOptionscontracts同上manager 解构的就是 conflictResolution/validate/dryRun;system 版(source/strategy)零消费

顺手修正:@objectstack/metadata 的公开 re-export 此前把这两个名字指向 system 死侧(与它自己 manager 实现的形状相反),已改指 ./contracts

基线与生成物

  • dual-source-exports.baseline.json:删除且仅删除上述 11 行(48→38 行,门禁点名的 stale 行与删除行完全一致,无额外 stale)。
  • authorable-surface.json:手删 9 行(两个死 options 袋的 8 键 + JobExecution:duration),durationMs 由 gen 记录 —— 按 refactor(spec)!: remove the kernel metadata-loader envelope family — 11 names declared twice with different shapes (#4411) #4458 先例:运行时 option 袋非可授权 metadata,无 tombstone、无 D2 conversion,changeset 携带 FROM→TO。
  • json-schema.manifest.json −2;api-surface.json、reference docs 经 check:generated --fix 再生。
  • changeset:@objectstack/spec major、@objectstack/service-analytics major、@objectstack/metadata patch,含全部 FROM→TO 与一行修法。

验证

  • pnpm --filter @objectstack/spec build ✅;check:generated 8/8 ✅;check:dual-source-exports ✅(4303 名字/16 入口,无新增,38 条基线)
  • spec:test 286 文件 / 7268 用例全过;typecheck
  • 全仓:pnpm build 71/71 ✅;pnpm typecheck 122/122 ✅;pnpm test 132/132 ✅(131 within one turbo run;@objectstack/dogfood#test 因外层超时被误杀后单独重跑:76 文件 / 443 用例通过)

范围外发现

#4567(未指派):defineJob 解析后的 cron expression 是表达式信封,AppPlugin → CronJobAdapter → croner 全程无人降解,croner 抛 "Pattern has to be of type string" 被 warn 吞掉 —— 声明式 cron job 静默调度失败(showcase 的 HealthSweepJob 即中招)。与本 PR 的类型收敛正交,未在此修。

🤖 Generated with Claude Code

https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL


Generated by Claude Code

…es (#4538)
Each of the 11 baseline rows judged individually against a three-repo
import-level scan (framework, cloud, objectui):
- Converged onto the domain zod declaration, re-exported from ./contracts:
NotificationChannel (system), ValidationResult / HealthStatus /
StartupOptions / PluginStartupResult (kernel), JobExecution (system,
after renaming the schema's dead `duration` to the runtime-true
`durationMs`), AnalyticsQuery (data, after the schema dropped the
`timezone` .default('UTC') the /analytics entry always refused to
apply - absence means the engine resolves org timezone, #1982/#2018).
IStartupOrchestrator.orchestrateStartup now takes StartupOptionsInput.
- Renamed: contracts DriverCapabilities -> AnalyticsDriverCapabilities
(two live concepts shared one name; the data domain's driver
feature-flag record keeps it). @objectstack/service-analytics re-export
renamed in lockstep.
- Removed dead domain-side declarations (zero consumers in all three
repos; last of the #4411 family): system MetadataExportOptions(Schema) /
MetadataImportOptions(Schema) - the contracts IMetadataService
parameter interfaces own the names now - and the system
`JobSchedule = Schedule` back-compat alias (authoring tier keeps its
real name, Schedule). @objectstack/metadata now re-exports the two
Metadata*Options names from ./contracts, the shape its own manager
implements.
All 11 dual-source-exports.baseline.json rows deleted; baselines
(api-surface, authorable-surface, json-schema.manifest, reference docs)
regenerated via check:generated --fix; the authorable-surface lines for
the removed runtime option bags deleted by hand per the #4458 precedent
(not authorable metadata - no tombstone, no D2 conversion).
Out-of-scope finding filed unassigned as #4567 (defineJob cron envelope
vs croner).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
@vercel

vercelBot commented Aug 2, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 2, 2026 5:18am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/metadata, @objectstack/runtime, @objectstack/service-analytics, @objectstack/spec.

116 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 packages/runtime, @objectstack/spec)
  • content/docs/api/data-api.mdx(via @objectstack/service-analytics)
  • 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/runtime, @objectstack/service-analytics, @objectstack/spec)
  • content/docs/api/wire-format.mdx(via @objectstack/runtime)
  • 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 @objectstack/runtime, 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 @objectstack/metadata, @objectstack/runtime, packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/runtime, packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/runtime, @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/index.mdx(via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx(via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx(via @objectstack/runtime)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/deployment/vercel.mdx(via @objectstack/runtime)
  • 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/runtime, @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via packages/metadata, @objectstack/runtime, @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/metadata, @objectstack/service-analytics, @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/runtime)
  • content/docs/permissions/authorization.mdx(via packages/runtime, @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/service-analytics, @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/metadata, @objectstack/runtime, @objectstack/service-analytics, @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/http-protocol.mdx(via @objectstack/runtime)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/metadata-service.mdx(via @objectstack/metadata)
  • 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/runtime, @objectstack/service-analytics, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/metadata, @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/runtime, @objectstack/service-analytics, @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/metadata, @objectstack/service-analytics, @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.

@os-zhuang
os-zhuang marked this pull request as ready for review August 2, 2026 06:19
@os-zhuang
os-zhuang added this pull request to the merge queueAug 2, 2026
Merged via the queue into main with commit 3c7bcc0Aug 2, 2026
21 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4538-contracts-interface-convergence branch August 2, 2026 06:31
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Aug 3, 2026
…./api 侧死删 + 改名 OpenApiWebhookEvent (objectstack-ai#4572) (objectstack-ai#4581)
* feat(spec)!: resolve the WebhookConfig/WebhookEvent dual source — ./api pair removed/renamed, ./integration keeps the bare names (objectstack-ai#4572)
The four objectstack-ai#4535-C1 baseline rows were the objectstack-ai#4411 trap in cross-form: ./api's
WebhookEventSchema was a z.object (OpenAPI 3.1 webhook definition) while
./integration's is a z.enum of connector event types — same names, two
concepts, and which one you got depended only on the import path.
Import-statement-level scan across framework, cloud and objectui:
zero external consumers on either side (each pair's only importer is its
own unit test; cloud and objectui reference neither name).
- api WebhookConfig(Schema): DEAD — wired into nothing, not even
RestServerConfigSchema; no runtime reads a REST webhook config. Deleted
(major window). Its authorable-surface lines deleted by hand per the
objectstack-ai#4458/objectstack-ai#4568 precedent (plugin-config type, not authorable metadata —
no tombstone, no D2 conversion).
- api WebhookEvent(Schema): renamed OpenApiWebhookEvent(Schema) — it is
the OpenAPI 3.1 top-level `webhooks` descriptor and now sits in the
existing OpenApi* family; OpenApi31ExtensionsSchema wiring updated,
authored shape unchanged.
- integration WebhookConfig/WebhookEvent: untouched, now sole owners of
the bare names, so the pair stays one coherent family in one domain.
dual-source-exports.baseline.json: exactly the 4 named rows removed
(35 → 31). json-schema.manifest: api/WebhookConfig retired,
api/WebhookEvent → api/OpenApiWebhookEvent (deliberate rename, not a
silent drop). Changeset: @objectstack/spec major with FROM → TO lines.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
* chore(spec): regenerate api-surface + reference docs for objectstack-ai#4572 (check:generated --fix, 2 proved stale)
api-surface.json: -WebhookConfig(Schema)/-WebhookEvent(Schema) on ./api,
+OpenApiWebhookEvent(Schema). Reference docs: the api/connector.mdx page
(which documented only the removed ./api pair, under a misleading name)
is no longer emitted; rest-server.mdx now documents OpenApiWebhookEvent.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
* test(spec): make the objectstack-ai#4572 bare-name pin compile-time — the runtime barrel import timed out under parallel turbo load
typeof import('./rest-server.zod') is type-level only; if a bare
WebhookEventSchema/WebhookConfigSchema export returns, the conditional
type flips to `true` and `tsc --noEmit` fails the false assignment.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
---------
Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Aug 3, 2026
… ./api,./kernel 侧死删 (objectstack-ai#4587) (objectstack-ai#4603)
* feat(spec)!: resolve the MetadataEvent/MetadataBulkRegisterRequest dual source — ./kernel copies removed, ./api keeps the bare names (objectstack-ai#4587)
The three objectstack-ai#4535-C2 baseline rows were the objectstack-ai#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
objectstack-ai#4570 docs-import concern. Compile-time pin (typeof import conditional type,
objectstack-ai#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 objectstack-ai#4458/objectstack-ai#4568/objectstack-ai#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
* chore(spec): regenerate api-surface + reference docs for objectstack-ai#4587 (check: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
* chore(spec): regenerate reference docs after merging main's import-surface gate (objectstack-ai#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).
---------
Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Aug 3, 2026
…ai#4610) (objectstack-ai#4638)
* feat(spec)!: resolve the notification-vocabulary dual sources — ./ui Notification(Config) removed, ./system NotificationConfig removed, ./api keeps the bare names (objectstack-ai#4610)
The four objectstack-ai#4535-C3 baseline rows were the objectstack-ai#4411 trap on the notification
vocabulary: Notification(Schema) had a second declaration in ./ui diverging
from ./api, and NotificationConfig(Schema) had two declarations (./system vs
./ui) that shared nothing but the name.
Import-statement-level scan across framework, cloud and objectui:
- ./api Notification(Schema) is the live REST inbox-row contract: embedded in
ListNotificationsResponseSchema, part of NotificationProtocol, implemented
by @objectstack/client, served by the runtime notifications domain, and
mirrored by contracts' InboxNotification (ADR-0030: the bell reads this
shape).
- ./ui Notification(Schema) — a toast/banner instance shape — had zero
importers outside its own unit test; objectui pins only the presentation
enums (NotificationType/Position/ActionSchema), which stay.
- ./system NotificationConfig(Schema) — a channel+template+recipients+
schedule+retryPolicy+tracking wrapper — had zero importers, is wired into
no parent schema, predates ADR-0030's accepted delivery model
(NotificationService.emit / NotifyConfigSchema / sys_* objects), and
advertised unenforced capability (objectstack-ai#3197 dead-letter channels).
- ./ui NotificationConfig(Schema) — a toaster global config — had zero
importers.
Disposal (route 1, dead-side delete, v17 major window): the ./ui pair and
BOTH NotificationConfig declarations removed; ./api is the sole owner of the
bare Notification(Schema) names and NotificationConfig left the export
surface entirely. Compile-time pins (typeof import conditional type, objectstack-ai#4581
pattern) keep the bare names out of ./ui and ./system; the surviving ./api
declaration is already covered by api/protocol.test.ts.
dual-source-exports.baseline.json: exactly the 4 named rows removed
(28 -> 24). json-schema.manifest: system/NotificationConfig, ui/Notification
and ui/NotificationConfig retired deliberately; their 25 authorable-surface
rows hand-deleted per the objectstack-ai#4458/objectstack-ai#4568/objectstack-ai#4581/objectstack-ai#4603 precedent. api-surface +
reference docs regenerated via check:generated --fix (2 proved stale; the
api/notification.mdx page folds into api/protocol.mdx where the declaration
lives). docs-import-surface baseline (objectstack-ai#4595): untouched. 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
* docs(audits): 严格性台账跟随 objectstack-ai#4610 —— ui/notification.zod.ts 站点 3 → 1
删除 ./ui 的 Notification / NotificationConfig 两个形状后,台账里
`notification.zod.ts` 那行声明的站点数过期(gate 点名 ledger:454:
declares 3 site(s), found 1)。把它从「3 ea」的合并行拆出单列为 1,
并写明为何掉了两个站点;`ui/` 章节总计 200 → 198 相应收敛。
check:strictness-ledger 恢复绿(67 文件 / 5 目录,站点数与章节总计均衡);
同 job 的其余源码审计(liveness / empty-state / variant-docs /
exported-any / react-declaration-parity / skill-examples)一并复跑通过。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
---------
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:dataprotocol:systemsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[#4535·A3] contracts 手写 interface 与域内 zod 推导类型收敛(3 簇 9 条)

2 participants

@os-zhuang@claude