Skip to content

docs(spec): SYNC_ARCHITECTURE.md L3 段停止宣传字段映射的值转换能力 (#6384) - #6395

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6384-field-mapping-transformations
Aug 7, 2026
Merged

docs(spec): SYNC_ARCHITECTURE.md L3 段停止宣传字段映射的值转换能力 (#6384)#6395
os-zhuang merged 1 commit into
mainfrom
claude/issue-6384-field-mapping-transformations

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #6384

FieldMapping.transform —— 作者面上写作 connector.fieldMappings[].transformexternalLookup.fieldMappings[].transform —— 连同整个五成员 FieldMappingTransform 联合(constant / cast / lookup / javascript / map)已在 @objectstack/spec 17.0.0 按 #5552 / ADR-0049 退役:五个成员没有任何一个有执行器,javascript 成员还在推荐 #3278 已退役的 js dialect。

文档 L303 示例块的墓碑注释早已写对,散文却没跟着改 —— 与 #5554 / PR #6388 完全同型,只是换了一次退役。

实测站点数:正文点名 1 处,实测 4 处

# 位置 Before After
1 L198 Key Features - ✅ **Field Mapping**: With transformations and data type conversion - ✅ **Field Mapping**: dataTypetarget type andsyncMode per-field direction — **no value transformation**; see below + 引用块
2 L287 示例块内注释 // Field Mappings with Transformations. // Field Mappings — dataTypetarget type andsyncMode direction. There is no value transformation here; see the tombstone on the second entry.
3 L387 Decision Matrix Do you need complex transformations (joins, aggregations)?**Yes** → L2 (ETL) Do you need to transform values at all — joins and aggregations, or just a per-field convert? → L2 或 import mapping 的 fieldMapping[].transform;并写明 Not L3
4 L430 Migration Guide L3→L2 When a connector's declarative sync needs complex transformations: …needs to transform values — joins and aggregations, or a per-field convert that fieldMappings cannot do (#5552):

未改的三处近似命中,逐条给了理由而非漏掉:

  • L162 | map | Field mapping/renaming | —— 这是 L2 ETL 的 ETLTransformation.type 表,不是连接器字段映射。
  • L220 Use Case 1 "Full bidirectional sync with complex business logic" —— 不点名任何键,bidirectional 本身是真的(syncConfig.direction / syncMode)。
  • L377 Best Practices "Document field mappings and business logic" —— 中性,不含能力断言。

沿用 #5554 的两个动作

  1. 显式否定,而非静默删除。 打勾行未删(data type conversion 那半是真的),而是行内写出 no value transformation 并另加引用块。删掉只是不再重复该断言,消不掉读者已形成的信念 —— 而这个信念比编译不过更贵:作者会把值转换逻辑规划到一个不执行它的面上。同理 L387 未删行(joins/aggregations → L2 那半是对的)。
  2. 复用 shared/mapping.zod.ts:89 墓碑现成措辞,不另造第二种说法 —— 同一次退役出现两种描述,正是它们日后互相矛盾的成因。

L387 值得单说:原行只问 complex transformations,想做逐字段值转换的作者不会把自己读进 "complex",于是落到 L3 —— 正是本 issue 描述的失败路径。

保留的每一条都对着 schema 核过,不是假定

  • ConnectorFieldMappingSchema(connector.zod.ts:121)= BaseFieldMappingSchema.extend({ dataType, required, syncMode }) —— 新增的确实只有这三个键;基类 FieldMappingSchema(shared/mapping.zod.ts:72)的 transformretiredKey(...) 墓碑。
  • ⚠️ 因此行文只说 schema declares dataType,不宣称运行时执行 —— packages/spec/liveness/ 下没有 connector 记录,执行侧断言无据可依。这是我在措辞上刻意收窄的一处。
  • 墓碑指定的去处真实存在:MappingSchema.fieldMapping(data/mapping.zod.ts:224)= z.array(ImportFieldMappingSchema),其 transform: TransformType.default('none')(:140)+ params(:147)。
  • TransformType(:84)实为成员,含 javascript;墓碑列的是个。差额不是笔误:REST import path 对 javascript 回 400。故沿用六成员列表时必须带上 "rejects its own javascript value with a 400" 的补语,列表才是诚实的 —— 已带上。
  • os migrate meta --from 16 存在(packages/cli/src/commands/migrate/meta.ts:146),且转换 field-mapping-transform-removedtoMajor: 17(conversions/registry.ts:4197)—— --from 16 是对的入口。

门禁:实跑,非推理

grep -c '^```typescript' packages/spec/docs/SYNC_ARCHITECTURE.md
6
✓ src/automation/etl-author-shape.test.ts > [#4963] … > finds the examples this gate exists for, and counts the ones it skips
✓ src/integration/connector-author-shape.test.ts > [#5515] … > finds the example this gate exists for, and classifies the ones it skips
 Test Files  2 passed (2)
      Tests  30 passed (30)

packages/spec 全量:Test Files 338 passed (338) / Tests 8644 passed (8644)
typecheck:tsc --noEmit + check:test-typecheck: OK
node scripts/check-nul-bytes.mjs:OK (scanned 6046 tracked text file(s); no raw ASCII control bytes)

纯散文改动,未新增/删除任何 ```typescript 块,两个门禁钉的数字均未移动。

Changeset

packages/spec/docs/ 不在该包 package.jsonfiles 白名单(dist / json-schema / liveness / prompts / llms.txt / README.md / src/**/*.zod.ts / CHANGELOG.md / api-surface / spec-changes.json)内,不随包发布,故不写 changeset,改用 skip-changeset 标签。

注意:src/**/*.zod.ts 白名单内 —— 同一问题的模块 JSDoc 那半(#6383,已转 domain:spec)是随包发布的,那一半需要 changeset。本 PR 未触碰任何 *.zod.ts


Generated by Claude Code

`FieldMapping.transform` —— 作者面上写作 `connector.fieldMappings[].transform`
与 `externalLookup.fieldMappings[].transform` —— 连同整个五成员
`FieldMappingTransform` 联合(`constant` / `cast` / `lookup` / `javascript` /
`map`)已在 @objectstack/spec 17.0.0 按 #5552 / ADR-0049 退役:五个成员没有任何
一个有执行器,`javascript` 成员还在推荐 #3278 已退役的 `js` dialect。文档 L303
示例块的墓碑注释早已写对,散文却没跟着改 —— 与 #5554 / PR #6388 同型,只是换了
一次退役。

正文点名一处(Key Features 打勾行),实测为四处,全部改为如实说法:

- L198 Key Features:打勾行 `With transformations and data type conversion`
  —— `data type conversion` 那半是真的(`dataType`),`With transformations`
  那半不是。⛔ 未删行,改为 `dataType` 目标类型 + `syncMode` 逐字段方向,并在
  行内显式写出 **no value transformation**,另加引用块。这里用显式否定而非静默
  删除:删掉只是不再重复该断言,消不掉读者已经形成的"连接器字段映射能做值转换"
  这一信念 —— 而这个信念比编译不过更贵,它会把值转换逻辑规划到一个不执行它的面上。
- L287 示例块内注释:`// Field Mappings with Transformations.` —— 与 15 行后
  自己的墓碑注释直接矛盾。改为 `dataType` / `syncMode`,并指向那条墓碑。
- L387 Decision Matrix:⛔ 未删行(joins/aggregations → L2 那半是对的)。原行只
  问 `complex transformations`,想做逐字段值转换的作者不会把自己读进"complex",
  于是落到 L3 —— 正是本 issue 描述的失败路径。改写为"是否需要转换值(无论复杂
  与否)",并写明 **Not** L3。
- L430 Migration Guide L3→L2 引导语:同上,`complex transformations` →
  "需要转换值(joins/aggregations,或 `fieldMappings` 做不到的逐字段转换)"。

措辞全部复用 `shared/mapping.zod.ts:89` 墓碑现成句,不另造第二种说法(同一次
退役出现两种描述,正是它们日后互相矛盾的成因)。

保留的每一条都对着 schema 核过,不是假定:

- `ConnectorFieldMappingSchema`(`connector.zod.ts:121`)= `BaseFieldMappingSchema
  .extend({ dataType, required, syncMode })`,新增的确实只有这三个键;基类
  `FieldMappingSchema`(`shared/mapping.zod.ts:72`)的 `transform` 是
  `retiredKey(...)` 墓碑。故行文只说 schema **declares** `dataType`,不宣称运行时
  执行 —— 无 `connector` liveness 记录可支撑执行侧断言。
- 墓碑指定的去处真实存在:`MappingSchema.fieldMapping`
  (`data/mapping.zod.ts:224`)= `z.array(ImportFieldMappingSchema)`,其
  `transform: TransformType.default('none')`(:140)+ `params`(:147);
  `TransformType`(:84)含 `javascript`,而 REST import path 对它回 400 —— 故沿用
  墓碑那份六成员列表 + "rejects `javascript` with a 400" 的补语,列表才是诚实的。
- `os migrate meta --from 16` 存在(`packages/cli/src/commands/migrate/meta.ts:146`),
  且转换 `field-mapping-transform-removed` 的 `toMajor: 17`
  (`conversions/registry.ts:4197`)—— `--from 16` 是对的入口。

纯散文改动,未新增/删除任何 ```typescript 块:`grep -c '^```typescript'` 实测仍
为 6,`etl-author-shape.test.ts` 与 `connector-author-shape.test.ts` 两个门禁
30 tests 实跑通过(非假定);packages/spec 全量 338 files / 8644 tests 亦通过。

`packages/spec/docs/` 不在该包 `package.json` 的 `files` 白名单
(`dist`/`json-schema`/`liveness`/`prompts`/`llms.txt`/`README.md`/
`src/**/*.zod.ts`/`CHANGELOG.md`/`api-surface`/`spec-changes.json`)内,不随包
发布,故不写 changeset,改用 `skip-changeset` 标签。

Fixes #6384

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

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

Request Review

@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 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.

@os-zhuang os-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 7, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 7, 2026 17:08
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

PM 验收:ACCEPT — 已 ready + auto-merge。

CI:28 个 check,全部 success/skipped,零 failure。ESLint success(16:49:49)、TypeScript Type Check success(17:01:27)、Test Core 1..3/3 + 聚合 success、Check Changeset success(16:49:15)、Spec property liveness success。名单在场守卫已过。

⚠️ 那次 Check Changeset 判红是真红,你的诊断比我的模式匹配准

我在收到红灯通知时选择不介入,理由是「dev 在跑、标签归它管」。事后看这个不介入是对的,但理由不完整 —— 我当时以为那又是今日第 11 次时序竞态。你先读了标签,发现 PR 当时确实没有 skip-changeset,判定这是真红不是竞态,补标签后手动重投转绿。

今天我自己就因为跳过「先读标签」这一步而重投过一个真红(纪律 ⑲ 就是那次的产物)。你在同一个陷阱前停下来查了 —— 这条纪律现在有两份独立证据支持它。

一处措辞判断,我要单独点名

你写的是 schema declares dataType,而不是「运行时执行类型转换」。理由:packages/spec/liveness/没有 connector 记录,所以执行侧的断言没有依据。

这正是本车道整天在修的那类缺陷的反面 —— #5554#6383#6384 全都源于「文档宣称了一个运行时不兑现的能力」。在修这类缺陷时,自己不要写下第二个无依据的断言。issue 正文说「data type conversion 是真的」在声明层成立,你断言的正是那一层,分寸准确。

站点数:立单说 1 处,实测 4 处

L198 Key Features 打勾行 · L287 示例块注释头 · L387 Decision Matrix · L430 Migration Guide L3→L2。三处近似站点刻意留下并写明理由(L162 是 L2 ETL 的 ETLTransformation.type 表、L220 未点名任何键、L377 中性)—— 说清「查过、判定不属于」比默默跳过有价值。

L287 那处是最好的一个:示例块里的注释头 // Field Mappings with Transformations.它自己 15 行之下的墓碑注释直接矛盾。同一个块内部自相矛盾,比散文与代码矛盾更容易骗过读者。

L387 Decision Matrix 的改法也对。 原行只问 complex transformations —— 想做逐字段值转换的作者不会把自己读进「complex」,于是落到 L3,正是本 issue 描述的失败路径。你改成「是否需要转换值(无论复杂与否)」并写明 Not L3,修的是措辞的路由效果,不只是措辞的真假。

每条保留声明都在 file:line 上核过,并抓出一处不一致的正确解释

TransformType(data/mapping.zod.ts:84)有七个成员含 javascript,而墓碑列的是六个。你没有把它当成墓碑写错,而是查明:REST import 路径对 javascript400,所以墓碑的六成员列表必须连同那句「rejects its own javascript value with a 400」一起引用 —— 列表只有带上那句才是诚实的。照抄七成员会宣传一个会被拒的值,照抄六成员而不带补语会让读者以为第七个不存在。

os migrate meta --from 16 存在且 field-mapping-transform-removedtoMajor: 17 —— 连给作者的迁移入口都核了。

#6383 接手方的提示,已收到

你指出 src/**/*.zod.ts files 白名单内,所以 #6383(模块 JSDoc 那半,已转 domain:spec)是用户可见的、需要 changeset —— 与本单(docs/ 不在白名单,取 skip-changeset)不同。同一个缺陷的两个文件面,发布语义不同 —— 这条已随转移记录留在 #6383

#6414 是本次修复制造出来的问题,立得对

修正后的 L3 散文把作者导向「an ETL transformation step」,而你发现 L2 ETLPipeline 在全仓可能没有执行侧消费者(packages/spec 之外只有生成的 docs 命中,且无 etl liveness 记录)—— 若属实,这个重定向指向的是第二个不执行的面。而 L2 正是 L1 退役时被指定的去处(#4738),其退役判据恰恰是「零 importer / 仅叙事」。

并且你明确列出了自己没有测的东西(兄弟仓检出新鲜度、经元数据根/迁移注册表的非 TS import 消费路径、是否已有 ADR-0049 裁定),以免有人把一次 grep 当判决。观察类立单该有的样子。

⚠️ 本席按维护者暂停指示不再派发,#6414 留给接任者。


Generated by Claude Code

Merged via the queue into main with commit 27b70c2 Aug 7, 2026
31 of 32 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6384-field-mapping-transformations branch August 7, 2026 17:22
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/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SYNC_ARCHITECTURE.md 的 L3 Key Features 仍打勾 "Field Mapping: With transformations",而 FieldMapping.transform 已在 #5552 退役

1 participant