Skip to content

refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 —— 五成员零执行者 (#5552) - #6078

Draft
qq9340100 wants to merge 2 commits into
mainfrom
claude/issue-5552-fieldmapping-transform-retire
Draft

refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 —— 五成员零执行者 (#5552)#6078
qq9340100 wants to merge 2 commits into
mainfrom
claude/issue-5552-fieldmapping-transform-retire

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Fixes #5552

按 01:26Z 维护者裁决执行 B(enforce-or-remove)两步走。A(只修 describe)已被否决,本 PR 不做 describe 镀金。

第一步:四成员消费面实测(裁决要求的前置测量)

constant / cast / lookup / map(以及报单已指出的 javascript)三层测量,基线 origin/main @ efedd28:

层面 结果 证据
声明式(谁写这个键) 全仓 0 处(spec 自身测试除外) examples/ / skills/ / objectui 均无。showcase 唯一的映射写的是 transform: 'map' —— 裸字符串,属另一个 schema
parse 点(谁解析) ,且可达 AutomationEngine.registerConnector / registerDegradedConnectorConnectorSchema.parse,会走到 fieldMappings[](service-automation/src/engine.ts:1692,1771)
运行时执行点(谁执行) fieldMappings 只在 packages/spec 内被拼写;四个 connector 包、automation engine、REST、objectui 都不读它;全仓无任何代码对 transform.type 分支

反查证伪扫描器(零命中时的必要控制):成员专属词在树里都找得到 —— targetType 70 处、keyField 66 处、valueField 260 处。扫描器工作正常,消费者是真的不存在。

cloud 面:未验,如实标注。 本会话对 objectstack-ai/cloud 无读权限(add_repo 返回 "you don't have access"),且 GitHub code search 不索引该仓 —— 控制查询 repo:objectstack-ai/cloud objectstack 返回 0 命中且 incomplete_results: true,即"查不到"不等于"没有"。按 #5540 的处理方式记为未验证,不冒充已验。

结论:全死。 五个成员一起 declared-but-unenforced,不只是报单指出的那一个 —— 于是按裁决走「整个 FieldMappingTransformSchema 联合退役」。

javascript 成员仍是让缺口显形的那一个,报单的三处打架全部复现:describe 推荐的 dialect: "js" 被枚举拒收(js#3278 / ADR-0058 addendum 退役);唯一能过 parse 的裸字符串被 ExpressionInputSchema 包成 dialect: 'cel';而同一行给的例子 value.toUpperCase() 作为 CEL 不成立。

第二步:退役路线选择(裁决要求在正文论证)

这是 authorable 面,不是纯类型面 —— 两个判据都指向同一边:

  1. .parse() 消费:上表第二行,ConnectorSchema.parse 是活的接收者。所以处方有人能收到,不适用 playbook 的「nothing parses it → 两者都不做」那一行(那是 findStream / IStorageService.list 的形状 —— 纯 TS 契约,没有任何东西跑过 .parse())。
  2. 在 authorable-surface 上:shared/FieldMapping:transformintegration/ConnectorFieldMapping:transformdata/ExternalFieldMapping:transform 三行都在。

retiredKey() 墓碑路线,理由是 schema 形态:FieldMappingSchema 与两个 extender 全是普通 z.object(非 .strict())。直接删键会被 zod 静默 strip —— 用一个静默 no-op 替换另一个静默 no-op,正是 #3726 / #3733 那一类。墓碑给出两个通道:tsc 拒绝赋值,parse 抛出处方本身。

⚠️ 一个墓碑 → 三处可作者化拼写:两个 extender 是 .extend(),会把该属性复制进各自的 shape,所以 RETIRED_KEYS_BY_MAJOR 按键逐条登记三条(网关按精确集合成员匹配,不从基类辐射)。这一点单独立了个 pin 测试。

生成物读数 —— 按路线核对,不要反过来

playbook 明确:整 def 删除必须让四张 ratchet 动;枚举值收窄则仪器上不可见。本 PR 是前者,读数如下,并且 json-schema.manifest.json 的 ratchet 先自己开火了,这串输出本身就是路线的证据:

❌ 1 previously published schema(s) disappeared from this build:
     - json-schema/shared/FieldMappingTransform.json

按要求有意删除 manifest 行,并在 RETIRED_DEFS_BY_MAJOR 登记。最终读数:

toMajor: 17,照抄现行 protocol-17 chain step 先例(包版本 17.0.0-rc.2,仍在 rc 窗口内)。

反向验证(sabotage)—— 方向在跑之前就写死了

预测:恢复联合与键之后,[#5552] 系列 pin 全部转红(普通方向,不是反转方向 —— 因为墓碑是这些判决的唯一来源:FieldMappingSchema 是普通 z.object,没有墓碑就只有"接受"或"静默 strip",没有底下的 schema 级拒绝可以兜)。

实测:7 条 pin 转红,失败文本正是"能力被恢复"的签名。其中两条值得单独说:

  • …and a member that used to be VALID fails identicallyexpected '' to contain 'TS2322' —— 恢复后该 probe 零诊断地编译通过。这条 pin 存在的唯一目的就是抓「联合被悄悄恢复」,而它给出的正是最强信号。
  • transform 是 retired —— 恢复后仍有诊断,但换成了另一条(Type '"custom"' is not assignable…,值判决)。所以这条 pin 断言的是具体文本而非"非空":只断言非空的话,它在 sabotage 下会保持绿色,是个 phantom check。成对 probe(一个已退役成员 + 一个原本合法成员)才是让这件事可测的设计。

另有 1 条 pin 在 sabotage 下保持绿色,如实说明:a mapping without the key parses and carries no transform at all —— 它是 strip 正路 pin,没写该键的映射两边都能解析,本来就不该变色。

一处如实修正:墓碑的 tsc 通道不点名该键

第一版 probe 断言 toContain('transform'),实测失败。retiredKey()z.never().optional(),其输入类型是 undefined,tsc 报的是 TS2322: Type '{ … }' is not assignable to type 'undefined' —— 拒绝了,但没有点出键名。处方完整地挂在 parse 通道上。测试里按实测形状钉住并写明了这个差别,而不是按想当然的形状写。

未受影响(⛔ 未碰)

  • ExpressionDialect 本体及其它 schema —— 按指令未动。
  • ExternalLookup.transform —— lookup 级的 { request, response } 管线,与字段映射的 transform 同名不同物。
  • 导入映射 mapping.fieldMapping[].transform —— 这才是活的那条:扁平字符串枚举,由 REST 导入路径逐行执行,liveness ledger 逐键记录在案。它对自己的 javascript 值是直接 400 拒收(服务端无沙箱)。同一个词,相反的处置 —— 一边跑并且说清楚,另一边从来没跑过。data/mapping.zod.ts 的三点差异注释已按此更新。

验证

命令 结果
pnpm --filter @objectstack/spec test 325 files / 8305 tests passed
pnpm --filter @objectstack/spec typecheck PASS(tsc --noEmit + test-typecheck 债本未增长)
pnpm --filter @objectstack/spec check:generated 10/10 PASS
check:liveness / check:empty-state / check:skill-examples / check:exported-any / check:dual-source-exports 全部 PASS
@objectstack/cli test(migrate-meta e2e / chain replay) 87 files / 872 passed
@objectstack/metadata test 25 files / 508 passed
@objectstack/metadata-protocol test 49 files / 487 passed
node scripts/check-nul-bytes.mjs OK(5780 文件,无裸控制字节)

liveness ledger 无需改动:ledger 按元数据类型建档,shared/FieldMapping 家族没有 ledger 行(liveness/mapping.json 记的是 MappingSchema,即上面那条活的导入映射)。check:liveness 绿,既无 UNCLASSIFIED 也无 ORPHAN。


Generated by Claude Code

claude added 2 commits August 6, 2026 15:42
…gTransform 联合 (#5552)

WIP: schema tombstone + D2 conversion + D3 chain step + 两张退役登记表首入。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY
…gTransform 联合 (#5552)

测量结论:五个成员(constant/cast/lookup/javascript/map)无一存在执行者。
fieldMappings 只在 packages/spec 自身被拼写,connector 包/automation engine/REST/
objectui 均不读取,全仓无任何代码对 transform.type 分支。

退役套件:retiredKey() 墓碑(schema 与两个 extender 均为普通 z.object,直接删键会静默
strip)、D2 conversion field-mapping-transform-removed、D3 chain step、
RETIRED_KEYS_BY_MAJOR/RETIRED_DEFS_BY_MAJOR 两表首批条目、生成物重生成、changeset。

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

vercel Bot commented Aug 6, 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 6, 2026 6:02pm

Request Review

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

112 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/tenancy-modes.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 @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/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 @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/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/http-protocol.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/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/apps.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/field-grouping-and-order.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.

Copy link
Copy Markdown
Collaborator Author

CI 状态(截至 19:41Z)

两个必看门禁均已 completed / success,逐 job 读取(非聚合状态):

workflow / job 结论
Lint & Type Check → ESLint ✅ success
Lint & Type Check → TypeScript Type Check ✅ success
Docs Drift Check ✅ success
Duplicate Fix Guard ✅ success
Spec Liveness Check ⏳ 仍 queued
Console Pin Freshness ⏳ 仍 queued
CI ⏳ 仍 queued

TypeScript Type Check 正是承载 spec 八张生成物门禁的那个 job,ESLint 承载家族门禁(check:engine-double-contract / check:error-code-casing / check:route-envelope 等)—— 本 PR 的退役套件如果哪里没配齐,红的会是这两个,现在都是绿的。

后三个仍在排队与本 PR 无关:runner 池今晚整体饱和(18:09 注册后曾出现全仓 90 runs queued / 0 in_progress 持续约一小时的窗口;此刻仍有 52 个排队),排队的是整个仓库的 PR 与 merge queue,不是这一个分支。作为替代证据,Spec Liveness CheckCI 覆盖的内容已在本地跑过并记录在正文的验证表里:check:liveness PASS、spec 全量 325 files / 8305 tests、cli / metadata / metadata-protocol 三个包的测试全绿。ESLint job 的家族门禁也在本地逐条复跑过(lint / check:engine-double-contract / check:error-code-casing / check:route-envelope / check:adr-anchors / check:merge-driver,全 PASS)。

main 在本分支开出后只前进了一个提交(#6027,client-sdk 合规矩阵文档),与本 PR 文件面零重叠,故未做同步合并。

顺带记录的范围外发现

#6085 —— expression.zod.ts 模块 TSDoc 的方言表仍把 js 列为活方言(还配了引擎,"use" 列写着 mapping,正是本 PR 退役掉的那个面),同时漏了真实成员 template;该表逐字流进 content/docs/references/shared/expression.mdx:32。与 #5552 同一缺陷类,但位置在方言表本身。按本单指令 ⛔ 不碰 ExpressionDialect 本体,故仅立单未修,已 unassigned 交三诊。


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shared/mapping.zod.ts 的 javascript 变换 describe 推荐 dialect="js",而 ExpressionDialect 只有 cel/cron/template —— 照着写会被拒

2 participants