Skip to content

objectui: metadata-admin 谓词求值器把 == 右侧的路径当字符串字面量,data.a == data.b 恒假且无诊断 #7066

Description

@yinlianghui

越界发现,来自 objectstack#6936 的开发会话(objectui PR objectstack-ai/objectui#3937)。不在该 PR 范围内(#6936 的裁决只覆盖「解析不到的路径 → fail-open + 告警」),单独立单交 PM 分诊;未认领。

事实

packages/app-shell/src/views/metadata-admin/predicate.ts== / != 分支左侧走 resolveValue(解析路径),右侧走 parseLiteralparseLiteral 对「既不是引号串、也不是数字/布尔/null/数组」的输入原样返回该字符串(该函数末尾 return s;)。于是右侧写路径时,比较的是路径的字面文本,不是它的值。

实测读数(objectui worktree,origin/main @ 230ffd8 + PR #3937 分支;临时 vitest 探针,已删):

ctx = { data: { a: 'x', b: 'x' } } // 两侧值相等
data.a == data.b -> false // 期望 true
data.a != data.b -> true // 期望 false
ctx = { data: { a: 'x', b: 'y' } } // 两侧值不等
data.a == data.b -> false // 恰好"对",但理由是错的
data.a == 'x' -> true // 字面量对照组,正常

data.a == data.b恒假data.a != data.b恒真,与两侧实际值无关:'x' === 'data.b'

为什么是 observation-class(建议 finding,未打 pm:queue)

今天没有生产者踩到:安装版 @objectstack/spec 17.0.0-rc.5 里 metadata-admin 会渲染的四张表单(objectForm / pageForm / viewForm / actionForm)的谓词全部是 path == 字面量 / path in [字面量…] 形状,右侧无路径。文件头也明确写了它只支持一个子集("Supported subset (covers everything used in spec *.form.ts today)"),所以严格说这是已声明的子集边界,不是违约。

但它与 #6936 刚修掉的那条同族、且不被#6936 的新告警覆盖:告警挂在 resolveValue 的根标识符检查上,而右侧根本不经过 resolveValue。所以一旦将来 spec 下发一条 data.a == data.b 形状的谓词,症状仍然是静默的错误结论(字段该显示时不显示),控制台一片安静 —— 正是 #6936 花一整张卡换掉的那种不可诊断形状。严重度按 filing-time 判断不可靠,交 PM 分诊定级。

可能的方向(不在此单里做决定)

倾向 B + D(渲染器只把边界说清,语义修正交给 C/D,避免在消费端加宽容),但这是求值语义取舍,应由维护者定。

查重说明

搜过 open issues:evaluatePredicate(仅命中 #6936 本身)、parseLiteral predicate.ts 0 命中、metadata-admin predicate right-hand identifier 0 命中、谓词 求值器 字面量 仅命中 PM 登记表 #4604、objectui 仓 predicate literal right side 0 命中。若有同小时孪生单,按惯例 race-close 本单。

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