Skip to content

feat(spec)!: 通知模板孤儿语汇退役 —— ./system 不再导出 EmailTemplate/SMSTemplate/PushNotification/InAppNotification (#4616) - #4809

Merged
os-zhuang merged 5 commits into
mainfrom
claude/issue-4616-notification-orphan-schemas
Aug 3, 2026
Merged

feat(spec)!: 通知模板孤儿语汇退役 —— ./system 不再导出 EmailTemplate/SMSTemplate/PushNotification/InAppNotification (#4616)#4809
os-zhuang merged 5 commits into
mainfrom
claude/issue-4616-notification-orphan-schemas

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #4616

ADR-0049 enforce-or-remove,在 v17 破坏窗口内按「移除」处置。EmailTemplateSchema / SMSTemplateSchema / PushNotificationSchema / InAppNotificationSchema 及其四个类型别名,只作为 NotificationConfigSchema.template 联合的成员形状存在过;#4610(#4535 C3)删掉那个联合之后,它们从任何父 schema、任何 metadata-type 根都不可达 —— 声明了 runtime 从不读取的投递能力。

一、消费方复核(三仓):立单前提被证伪了一处半,结论反而更稳

复核方式与立单时不同:按裸名扫描,而不是按 import 语句扫描。这一处差别改变了答案。

仓库版本:objectstack main、cloud 5df2c69、objectui 785b8a5

名字 结论 证据
SMSTemplate(Schema) 零消费方 ✅ 三仓除自身声明、自身单测、生成物外无任何引用
PushNotification(Schema) 零消费方 ✅ 同上
InAppNotification(Schema) 零消费方 ✅ 同上
EmailTemplateSchema 有一个消费方,且是 bug ⚠️ objectui packages/app-shell/src/views/metadata-admin/clientValidation.ts:89
ui NotificationSeveritySchema 证伪 —— 是活的,本 PR 不动 objectui 四处消费,见下

1.1 EmailTemplateSchema 有一个消费方 —— 而它本身就是缺陷

objectui 的 metadata-admin 客户端草稿校验,把 email_template 这个 kind 注册到了被降级的遗留 schema:

email_template: async () => (await import('@objectstack/spec/system')).EmailTemplateSchema as unknown as ZodLikeSchema,

这是动态 import + 属性访问,立单时的 import 语句级扫描看不见它 —— 这正是 skill §1「build 才是裁判,台账只是输入」那一条要防的形态。

但它不是「保留理由」,恰恰相反:该 kind 的规范 schema 是 EmailTemplateDefinitionSchema(BUILTIN_METADATA_TYPE_SCHEMAS 解析的就是它),两者形状不相交(id vs name+locale;body+bodyType vs bodyHtml/bodyText)。结果是一份合法草稿在 Studio 里被报 id/body 缺失,而它真正的键因非 strict 被静默剥离。

这与 spec 7.1.0 在框架侧修过的是同一个缺陷 —— 当时 changelog 原文说,注册遗留 schema「which is why all the new fields (name, label, category, locale, bodyHtml, bodyText, …) were reported as 'declared in form layout but missing from schema'」,框架侧改指到了 Definition,objectui 侧从未跟进

按 issue 自己的判据(待决项 2:「若某渠道实现确要用 spec 级模板 shape 校验,应先有消费方 PR 再谈保留」),一个误接的站点不构成消费方。移除是更正确的处置:它把静默错校验变成恰好落在需要修改的那一行上的编译错误。已按 Prime Directive #10 单独立案 #4807(未指派),不在本 PR 内修。

1.2 ui NotificationSeveritySchema:立单正文的顺带处置建议被证伪

issue 说「objectui 只 pin 了 Type/Position/Action 三个枚举」。实查为假,objectui 有四处消费:

  • packages/types/src/index.ts re-export 该 类型;
  • packages/core/src/protocols/NotificationProtocol.ts 消费该类型;
  • packages/types/src/__tests__/spec-ui-schema-reexports.test.ts pin 了该 schema 名;
  • packages/components/src/notifications/severity.tsapp-shell/src/chrome/notificationToast.tsx 把 severity→tone 映射写成 Record<NotificationSeverityLevel, …>,注释明写「so a new severity in the spec NotificationSeveritySchema fails type-check here until it has a tone」。

它是活的,本 PR 一个字节都不动 packages/spec/src/ui/ 为免下次审计照着 issue 正文再来一遍,pin 测试里加了一条断言:NotificationSeveritySchema / NotificationSeverity 必须仍由 ./ui 独占持有(sabotage S3 实测会红,见下)。

1.3 短信 / 邮件功能不受影响(维护者质询的复核)

自行 import 级复核确认 PM 结论:service-messaging/src/sms-channel.ts(topic, 'sms', locale)sys_notification_template 行,provider 侧是 service-sms 里阿里云预注册的 TemplateCode;邮件走 EmailTemplateDefinitionSchemasys_email_template。三条链路都不经过本 PR 移除的任何 schema。service-messaging / service-sms / plugin-email 三个包的测试全绿(见下)。

二、退役形态:#4650 路径 3(整 def 消失),不是 retiredKey() 墓碑

判据不是照搬先例,而是门禁实跑输出retiredKey() 墓碑必须挂在一个存活的 schema 形状上;这里四个 def 整体消失,没有形状可挂。gen:schema 自己给出了裁定:

ℹ️  4 baseline deletion(s) since 25784cfec4a3 carry their own proof (#4650):
     - system/EmailTemplate:* (6 line(s)) — def no longer emitted by this build; whole-schema
       removals are adjudicated by json-schema.manifest.json (#2978) and check:api-surface.
     - system/InAppNotification:* (6 line(s)) — def no longer emitted by this build; ...
     - system/PushNotification:* (6 line(s)) — def no longer emitted by this build; ...
     - system/SMSTemplate:* (4 line(s)) — def no longer emitted by this build; ...

所以 authorable-surface.json 的 22 行与 json-schema.manifest.json 的 4 个键是在本 PR 内刻意删除的(C10/C16/C3 谱系),删除由 #4650 route 3 自证。中途 gate 两次拦下并给出正确路径,都在预期内:先是 manifest ratchet(「4 previously published schema(s) disappeared」),再是 check (a)(「22 authorable key(s) disappeared from the contract」)。

三、ADR-0087 conversion:逐条评估后不需要,三种先例对照

先例 是否需要 conversion 为何
#4734 需要 被删 key 挂在 root-reachable schema 上,作者源里真的写着它,os migrate meta 有东西可改写
#4767 / #4783 不需要 同本单形态
本单 #4616 不需要 四个 def 从任何 metadata-type 根都不可达 —— computeSurfaceReachability 的 BFS 证明了这一点,门禁也据此放行

展开:D2 conversion 改写的是作者源或已存 sys_metadata。没有任何 metadata 文档曾按这四个 def 解析过,所以 os migrate meta 无匹配目标,注册一条只会得到一个永远不触发的 walker 和一个必须与全表 disjoint 的 fixture。D3 semantic[] 是给「响应面上、无源可改写」的 key 用的(EnhancedApiError.fieldErrors 是范例),这四个也从不在响应面上。#4610同一个文件做同样的事时同样未注册 conversion。

破坏面因此纯粹是 TypeScript 导出面:changeset 承载 FROM → TO,api-surface.json 承载机器可读的删除记录。

四、changeset 定级:major(据 #4535 §5 逐条自证,不照抄别簇)

  • TS2305 / TS2339? —— 。任何从 @objectstack/spec/system 取这八个名字的消费方编译失败;objectui clientValidation.ts:89 就是一个现存实例。
  • 元数据迁移? —— 。见第三节,无源可改写。
  • 形状变更? —— 。存活的 NotificationChannelSchema 逐字节未变。

@objectstack/spec: major。changeset 逐个给出 FROM → TO,并明写 EmailTemplateDefinitionSchema形状变更而非改名(键名映射列了表),以及另外三个「无替代品、也不需要替代品」各自的真实机制。

五、pin:TypeScript compiler API 符号身份解析 + 4 组 sabotage 实跑

pin 写在 packages/spec/src/system/notification.test.ts:

  • exports-map 枚举全入口 —— 从 package.jsonexports 读出全部 16 个 TS 入口,新增入口无法悄悄逃逸;
  • 防空转守卫 —— 入口集合必须含 . / ./system / ./ui / ./contracts / ./api;入口数 > 10;每个 module symbol 必须解析成功;./system > 400、./ui > 200、./contracts > 100 个导出;
  • holders 精确相等 —— 断言的是 holdersOf(name) 恒等于 [](而非「./system 不含它」),所以从任何别的入口顶名 re-export 同样会红;存活侧则断言精确持有者集合与声明出处(NotificationChannel = ['./contracts','./system'] 且两者共享同一声明)。

顺带把 #4610 留下的 typeof import 条件类型 pin 折叠进来 —— #4642 已确认那种 pin 在本包是空转(tsconfig.json exclude 了 **/*.test.ts,vitest 从不开 typecheck),留着是一个不可能失败的门禁。

sabotage 实跑证据

# 破坏动作 结果
S1 notification.zod.ts 复活 SMSTemplateSchema 声明 🔴 AssertionError: SMSTemplateSchema must not be exported by any entry point: expected [ { sub: './system', …(1) } ] to deeply equal [](compiler-API + runtime 两条都红)
S2 禁止路线:从另一个入口 ./contracts 顶名导出 EmailTemplateSchema(./system 仍不导出) 🔴 AssertionError: EmailTemplateSchema must not be exported by any entry point: expected [ { sub: './contracts', …(1) } ] to deeply equal [] —— 注意 runtime 那条保持绿(它只探 ./system/./ui),正好证明 compiler-API pin 才是这条路线上承重的那个
S3 按 issue 正文的建议真的退役 ui NotificationSeveritySchema 🔴 AssertionError: NotificationSeveritySchema is LIVE in objectui — must stay ./ui-owned: expected [] to deeply equal [ './ui' ]
S4 空转检验:把 ./system barrel 清空 🔴 AssertionError: ./system must export a non-trivial surface: expected 0 to be greater than 400 —— 在任何 not.toContain 之前就拦下,证明断言不会因解析失败而空过

四次 sabotage 后全部还原,工作树干净。

六、顺带修正的混淆源头

packages/spec/src/kernel/metadata-plugin.zod.ts:116 原本写着 'email_template', // Outbound email templates (EmailTemplateSchema) —— 括号里指错了声明(注册表解析的是 EmailTemplateDefinitionSchema)。这一条括号正是维护者本次质疑、以及 objectui 误接的共同源头,改正并留了说明。同时在 notification.zod.ts 留下按渠道展开的「真正在投递的是什么」注释块,免得下一位读者再推导一遍。

七、验证(全部实跑)

检查 结果
check:generated 8/8 up to date
check:authorable-surface ✅ PASS
check:api-surface ✅ PASS(./system 精确 −8 行:4 const + 4 type,零新增)
check:dual-source-exports ✅ PASS
源码审计组 check:liveness / check:empty-state / check:variant-docs / check:strictness-ledger / check:exported-any / check:react-declaration-parity / check:skill-examples ✅ 全 PASS(system/ 不在 strictness ledger 的 5 个受治理目录内,故无台账行需要改;ui 侧未触碰,ui/ 的 198 计数不变)
pnpm --filter @objectstack/spec test 293 files / 7359 tests passed
pnpm --filter @objectstack/spec typecheck ✅ PASS
全仓 pnpm typecheck 122/122 tasks successful
全仓 pnpm build ✅ 71/71
pnpm check:i18n ✅ OK(9 packages,all bundles in sync)—— 首次报 extract failed 是 stale-dist 陷阱,全仓 build 后转绿
受影响 service 包 service-sms 28、service-messaging 160、plugin-email 76,全通过

content/docs/releases/ 未触碰content/docs/references/system/notification.mdxgen:docs 重生成(自动生成物)。

八、合并前状态

git merge origin/main(⛔ 未 rebase、未 force-push)。进来的 3 个提交(#4799 / #4798 / #4794)完全不触碰 packages/spec,四张 ratchet 也都没动;合并后重跑 spec build + check:generated(8/8)+ 源码审计组 + spec test/typecheck,全绿。相对 origin/main 的 ratchet delta 精确为本 PR 的一处改动:

packages/spec/authorable-surface.json    | 22 ----------------------
packages/spec/json-schema.manifest.json  |  4 ----
packages/spec/dual-source-exports.baseline.json     (未变)
packages/spec/docs-import-surface.baseline.json     (未变)

入队请排在 C7 #4789 之后(文件不相交,可并行实施,但按 PM 指定的顺序落地)。draft / ready 与合并归 PM,本 PR 不 auto-merge。

九、范围外发现


Generated by Claude Code

claude added 2 commits August 3, 2026 07:54
…./system (#4616)

ADR-0049 enforce-or-remove, resolved by REMOVE in the v17 breaking window.
`EmailTemplateSchema`, `SMSTemplateSchema`, `PushNotificationSchema` and
`InAppNotificationSchema` (+ their four type aliases) existed ONLY as the
member shapes of the `NotificationConfigSchema.template` union that #4610
(#4535 C3) deleted. Since then they have been reachable from no parent schema
and from no metadata-type root — declared delivery capability the runtime
never read.

Three-repo consumer review (objectstack, cloud @ 5df2c69, objectui @ 785b8a5),
by bare name rather than by import statement — which is what changed the
answer:

- SMSTemplate / PushNotification / InAppNotification: zero references outside
  their own declaration, their own unit tests and the generated artifacts.
- EmailTemplateSchema: NOT consumer-free. objectui's metadata-admin registers
  it as the client-side validator for the `email_template` kind through a
  DYNAMIC import (app-shell/src/views/metadata-admin/clientValidation.ts:89),
  which an import-statement scan cannot see. That registration is itself the
  bug: the canonical schema for the kind is `EmailTemplateDefinitionSchema`,
  and validating an authored definition against the legacy shape reports its
  real keys as missing — the same defect spec 7.1.0 fixed on the framework
  side when it demoted `EmailTemplateSchema` to "an inline sub-shape inside
  `Notification`". Filed separately; removing the legacy export turns that
  silent mis-validation into a compile error at the one site that needs it.
- ui `NotificationSeveritySchema`: REFUTED. The issue proposed retiring it in
  the same sweep on the premise that objectui pins only Type/Position/Action.
  objectui re-exports the type (packages/types), consumes it in
  core/src/protocols/NotificationProtocol.ts, pins the schema name in
  packages/types/src/__tests__/spec-ui-schema-reexports.test.ts, and types two
  severity->tone maps as Record<NotificationSeverityLevel, ...> precisely so a
  new spec severity fails type-check downstream. It is untouched, and the pin
  below asserts it stays ./ui-owned so the claim is not re-litigated.

Route: whole-def removal (#4650 route 3), not a `retiredKey()` tombstone — a
tombstone lives on a surviving schema's shape and none survives here.
gen:schema adjudicates the four defs itself ("def no longer emitted by this
build; whole-schema removals are adjudicated by json-schema.manifest.json and
check:api-surface"), which is why the 22 authorable-surface lines and the 4
manifest keys are deleted in this commit. No ADR-0087 D2 conversion,
deliberately: a conversion rewrites authored or stored sources, and no
metadata document was ever parsed against these defs, so `os migrate meta`
would have nothing to match — same disposition as #4610 in this module, and
as #4767/#4783.

Also corrects `kernel/metadata-plugin.zod.ts`'s `email_template` comment,
which named `EmailTemplateSchema` where the registry resolves
`EmailTemplateDefinitionSchema`. That one parenthetical is the documented
source of the confusion, including objectui's.

The pin is a TypeScript compiler-API test over the package.json exports map
(all 16 entries), asserting each removed name has ZERO holders anywhere — not
merely that ./system omits it — with anti-vacuity guards on entry resolution
and surface size. #4642 established that the conditional-type pin #4610 left
here is a no-op (tsconfig excludes **/*.test.ts), so it is folded in rather
than left as a gate that cannot fail.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 3, 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 3, 2026 8:35am

Request Review

@github-actions github-actions Bot added the size/l label Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 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 @objectstack/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.

claude added 2 commits August 3, 2026 08:27
…rename must not ride out on this branch

`git merge origin/main` brought in #4789 (kernel PackageDependencySchema ->
ResolvedPackageDependencySchema, dual-source C7), which touches the same three
generated artifacts this branch does. The merge reported NO conflicts and left
NO conflict markers, and it was wrong in all three:

  api-surface.json         re-added `PackageDependency (type)` +
                           `PackageDependencySchema (const)` and dropped
                           `ResolvedPackageDependency(Schema)`
  authorable-surface.json  re-added the 4 `kernel/PackageDependency:*` lines and
                           dropped the 4 `kernel/ResolvedPackageDependency:*` ones
  json-schema.manifest.json re-added `kernel/PackageDependency` and dropped
                           `kernel/ResolvedPackageDependency`

json-schema.manifest.json is routed to the `merge=os-regen` driver, which defers
rather than regenerates, so nothing textual signals this — the C17/C10 silent
revert, reproduced. `git merge-tree` does not run external merge drivers and so
cannot see it either.

Resolved the way #4783 did, without any textual merge: reset all three (plus
api-surface-signatures.json) to origin/main, re-applied ONLY this PR's own
deletion to the two hand-ratcheted files, then re-ran the generators over the
merged source. The 22 authorable-surface lines and 4 manifest keys are once
again deliberate deletions, now anchored at merge base ffab803, which
gen:schema re-proved under #4650 route 3 ("def no longer emitted by this
build").

Delta vs origin/main is now pure deletion in all three, with #4789's rename
intact:

  api-surface.json          -8  (4 const + 4 type), 0 insertions
  authorable-surface.json  -22  lines,              0 insertions
  json-schema.manifest.json -4  keys,               0 insertions

check:dual-source-exports reports 0 accepted dual-source (#4789's shrink to []
survives; this branch does not carry it back to 2). renamed-defs.ts is
byte-identical to main and keeps all 6 entries including #4789's.

Co-Authored-By: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

已合入 #4789,三张 ratchet 按 #4783 干净路线重做 —— 静默回退实测复现了,不是理论风险

分支已推到 d1086e64f。合并途中 main 又前进了两次(#4806 也落地),都已合入,详见末节。

0. 先说结论:你警告的那个形态,这次是实测的,不是推测

git merge origin/main(带 #4789)退出码 0、零冲突标记,然后三张表全错:

文件 干净合并干了什么
api-surface.json 重新加回 PackageDependency (type) + PackageDependencySchema (const),删掉 ResolvedPackageDependency(Schema)
authorable-surface.json 重新加回 4 条 kernel/PackageDependency:*,删掉 4 条 kernel/ResolvedPackageDependency:*
json-schema.manifest.json 重新加回 kernel/PackageDependency,删掉 kernel/ResolvedPackageDependency

三张全部是 #4789 改名成果被整体吞掉。json-schema.manifest.jsonmerge=os-regen 驱动 —— 驱动只延迟不重生成,所以文本上一点信号都没有。你说 git merge-tree 不跑外部 driver 因而不构成证据,是对的:这次连跑了 driver 的真实 merge 也一样无声。

补一个佐证:按你的路线修完后 commit,pre-commit 自己把这件事说了出来 ——

os-regen: 3 generated artifact(s) were merged WITHOUT a text merge and must be regenerated from the merged tree before this commit.
  ✓ packages/spec/json-schema.manifest.json, packages/spec/authorable-surface.json — current
  ✓ packages/spec/api-surface.json — current
os-regen: all deferred artifacts are current — marker cleared.

1. 处置:零文本合并

git checkout origin/main -- api-surface.json api-surface-signatures.json authorable-surface.json json-schema.manifest.json → 只把本 PR 那一处删除重新落到两张手工 ratchet 上 → 在合并后的源码上整体重跑生成器。⛔ 未 rebase、未 force-push。

gen:schema新的 merge base 上重新给出 #4650 路径 3 自证:

ℹ️  4 baseline deletion(s) since ffab8033b3ab carry their own proof (#4650):
     - system/EmailTemplate:* (6 line(s)) — def no longer emitted by this build; whole-schema
       removals are adjudicated by json-schema.manifest.json (#2978) and check:api-surface.
     - system/InAppNotification:* (6 line(s)) — def no longer emitted by this build; ...
     - system/PushNotification:* (6 line(s)) — def no longer emitted by this build; ...
     - system/SMSTemplate:* (4 line(s)) — def no longer emitted by this build; ...

2. 逐条核对读数(你要的四项)

check:dual-source-exports = 0,不是 2

✅  self-test: flags same-name different-declaration exports, and nothing else.
✅  no new dual-source exports: 4278 names across 16 entry points — 173 re-exported (single declaration), 0 accepted dual-source (baseline).

dual-source-exports.baseline.json 文件内容:"entries": [](0 条),与 main 逐字节一致。#4789 清到 0 的成果没被本分支带回 2。

json-schema.manifest.json 相对 main 只少我的 4 个 system/*

-    "system/EmailTemplate",
-    "system/InAppNotification",
-    "system/PushNotification",
-    "system/SMSTemplate",

零新增。键存在性抽查:

PRESENT kernel/ResolvedPackageDependency     ← #4789 的改名结果仍在
ABSENT  kernel/PackageDependency             ← #4789 删掉的旧名仍不在
PRESENT cloud/PackageDependency              ← ./cloud 侧的裸名归属未受影响
PRESENT kernel/PackageDependencyConflict
total schemas: 1658

authorable-surface.json / api-surface.json 同理,delta 精确等于我的删除

authorable-surface.json 相对 main:纯删除 22 行(6+6+6+4),零新增,kernel/ResolvedPackageDependency:* 4 条原样保留、kernel/PackageDependency:* 0 条。

api-surface.json 相对 main:纯删除 8 行,零新增 ——

-    "EmailTemplate (type)",         -    "EmailTemplateSchema (const)",
-    "InAppNotification (type)",     -    "InAppNotificationSchema (const)",
-    "PushNotification (type)",      -    "PushNotificationSchema (const)",
-    "SMSTemplate (type)",           -    "SMSTemplateSchema (const)",

api-surface-signatures.json 与 main 逐字节一致(我本来就不该动它)。

三张表的 numstat,一目了然:

api-surface.json                       +0 -8
authorable-surface.json                +0 -22
json-schema.manifest.json              +0 -4
dual-source-exports.baseline.json      (与 main 逐字节一致)
docs-import-surface.baseline.json      (与 main 逐字节一致)

renamed-defs.ts 与 main 逐字节一致,6 条齐全

未发生冲突,无需二选一。6 条:

integration/RateLimitConfig     → integration/ConnectorRateLimitConfig
integration/FieldMapping        → integration/ConnectorFieldMapping        // 7 keys carried
data/FieldMapping               → data/ImportFieldMapping                  // 4 keys carried
integration/ConflictResolution  → integration/ConnectorConflictResolution
studio/ActionLocation           → studio/ActionContributionLocation
kernel/PackageDependency        → kernel/ResolvedPackageDependency         // 4 keys carried  ← #4789

3. 全量复跑(合并后)

检查 读数
check:generated All 8 generated artifacts are up to date.
check:dual-source-exports 0 accepted dual-source
源码审计组 check:liveness / check:empty-state / check:variant-docs / check:strictness-ledger / check:exported-any / check:react-declaration-parity / check:skill-examples / check:authorable-surface / check:api-surface 全 PASS
spec test Test Files 294 passed (294) / Tests 7362 passed (7362) ——(293→294、7359→7362 是 #4789 带进来的 package-dependency-dual-source.test.ts,它和我的 pin 同时绿)
spec typecheck ✅ PASS
全仓 pnpm typecheck Tasks: 122 successful, 122 total —— #4789 动了 kernel/cloud 导出面,我的 pin 枚举全 16 入口,确认无交叉影响
全仓 pnpm build ✅ 71/71
pnpm check:i18n OK (9 package(s), all bundles in sync)
受影响 service 包 service-sms 28/28 · service-messaging 160/160 · plugin-email 76/76

4. 期间 main 又前进了两次,都已合入

你看到的 tip 是 7e05d8ef(#4789)。我 fetch 时已是 ffab8033b(多了 #4803 i18n-extract configs),推送前共享 .git 的 ref 又被别的 agent 更新到 8bd437f4b(多了 #4806 plugin-auth OTP)。两者都已 merge:

分支当前 tip d1086e64f,与 origin/main 无冲突。content/docs/releases/ 全程未触碰。

等你 un-draft + 入队。


Generated by Claude Code

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 protocol:system size/l tests tooling

Projects

None yet

2 participants