Skip to content

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

Description

@os-zhuang

发现于 #5515(修 SYNC_ARCHITECTURE.md L3 示例的 transform.type: 'custom')时,给示例挑真实联合成员的过程中量到,不在该 PR 范围内。

事实

packages/spec/src/shared/mapping.zod.ts 的 FieldMappingTransformSchema,javascript 分支:

z.object({
  type: z.literal('javascript'),
  expression: ExpressionInputSchema.describe('JS expression (dialect="js" recommended). e.g. value.toUpperCase()'),
}).describe('Custom JavaScript transformation'),

而 packages/spec/src/shared/expression.zod.ts:42:

export const ExpressionDialect = z.enum(['cel', 'cron', 'template']);

没有 js。'js' 这个方言在 #3278 就退役了(ADR-0058 addendum,同文件 40 行的注释自己写着)。所以 describe 让作者写的那个显式信封 —— expression: { dialect: 'js', source: 'value.toUpperCase()' } —— 会被 ExpressionSchema 的枚举直接拒收。

实测(ConnectorFieldMappingSchema,同一个 FieldMappingTransformSchema):

transform: { type: 'javascript', expression: 'value / 100' }
→ parse 成功,规范化为 { type: 'javascript', expression: { dialect: 'cel', source: 'value / 100' } }

也就是说:唯一走得通的写法是裸字符串简写,而它落到的方言是 cel,不是 JS。describe 里那句 value.toUpperCase() 作为 CEL 表达式也是不成立的(CEL 没有这个方法)。一个成员叫 javascript、describe 说 dialect 用 js、实际只能是 cel —— 三处互相打架,而 describe 是会流进生成文档和 JSON Schema 的那一处。

影响

describe 文本进 content/docs/references/** 和 gen:schema 产物,是 AI 作者最直接读到的一行。这正是 Prime Directive #10 的反面:宣传了一个运行时不兑现的方言名。

未验证 / 需要裁定的部分

FieldMappingTransform 目前在 objectstack 全仓没有任何消费者(grep FieldMappingTransform 只有 mapping.zod.ts 自己的 z.infer 别名一行),即整个变换联合是 declared-but-unenforced,javascript 成员尤其如此 —— 没有任何运行时会去执行这个表达式。所以本单的处置有两条路,需要裁定:

倾向 B 的方向判断,但联合里其余四个成员(constant / cast / lookup / map)的存活状态没量过,先记事实。

Activity

  1. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    分诊:needs-user-decision,预挂 domain:spec。

    • 为什么进决策箱而不是队列:issue 自己已把两条路摆清 —— A(只修 describe,成本最低但把跑不起来的成员写得更像能跑)vs B(按 ADR-0049 enforce-or-remove 处理整个 javascript 变换成员乃至整个变换联合)。B 是移除一个已声明的可作者化成员,属「removing a shipped capability」类,须维护者拍板,分诊不代裁。
    • 事实核验(origin/main 实测):mapping.zod.ts:71 的 dialect="js" describe 仍在;FieldMappingTransform 在 packages/ 下除 spec 自身外零消费者(仅 plugin-sharing CHANGELOG 提及)—— declared-but-unenforced 判断成立,这正是「生产者在哪」形状:没有任何引擎执行该表达式。
    • 裁决后走向:选 A → 一行 describe 修正,回 pm:queue(spec 车道);选 B → 按 spec-property-retirement 路数立退役单,联合其余四成员(constant/cast/lookup/map)的存活状态需一并量。
    • 查重:三仓无 FieldMappingTransform / dialect="js" 影子单。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    维护者裁决(2026-08-06,经本会话转达):取 B(enforce-or-remove),两步走:第一步实测 constant / cast / lookup / map 四成员的消费面(三仓 grep 声明式 + parse 点 + 运行时执行点,零命中用邻近词反查);第二步按测量结果——全死则整个 FieldMappingTransform 联合按退役流程走,有活成员则只退役 javascript 成员并顺手把 describe 改为如实(裸字符串→cel 包装)。A(只修 describe)否决:给跑不起来的成员镀金。conversion 的 toMajor 由 spec 座位按发版窗口定。needs-user-decision → pm:queue,归 spec 座位。会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions