Skip to content

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

Closed as not planned

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(解析路径),右侧走 parseLiteral。parseLiteral 对「既不是引号串、也不是数字/布尔/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 本单。

Activity

  1. added
    repo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 9, 2026
  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Finding-triage ruling: Promote — finding to pm:queue, scoped to the diagnostic-only leg (the card's option B).

    metadata-admin's predicate evaluator resolves the left side of == / != but parses the right side as a string literal (predicate.ts:175-176, :269 fallthrough), so data.a == data.b is always false with zero diagnostics — the no-silent-misjudgment invariant #6936 restored is still open on this leg (its warning hangs on resolveValue, which the right side never reaches). Semantic options A/C/D stay undecided and are out of scope for the queued card.

    Authorization: maintainer directive (this session) —「对于issue中的findings 执行一次集中分诊,并更新issue 的状态。」Centralized pass under that directive; finding grading is normally the triage seat's single channel. Round: objectstack#4949 finding-triage, 2026-08-10.
    Session: 01JaVVMrSxt7Tgi1uwEuDtH7


    Generated by Claude Code

  3. added
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 10, 2026
  4. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Migrated to objectstack-ai/objectui#4049 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.


    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

    Labels

    pm:queueReady for the PM dispatch looprepo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions