Skip to content

objectui: metadata-admin 谓词求值器对「无法解析的路径」静默判假(fail-CLOSED),与文件自述的 fail-open 承诺相反 #6936

Closed
objectstack-ai/objectui
#3937

Description

@yinlianghui

越界发现,来自 objectstack#6331 的开发会话(objectui PR objectstack-ai/objectui#3923)。不在该 PR 范围内,单独立单交 PM 分诊;未认领。

事实

packages/app-shell/src/views/metadata-admin/predicate.ts 的文件头明确承诺:

On any parse error → returns true (fail-open): better to show a field than to silently hide it.

evaluatePredicate 的 try/catch 确实对抛错兜成 true。但「标识符解析不到」不走抛错路径:resolveValue 从 ctx 根开始逐段下钻,取不到就返回 undefined,然后

  • path in ['a','b'] → ['a','b'].includes(undefined) → false
  • path == 'x' → undefined === 'x' → false

于是一条引用了不存在路径的谓词把字段静默隐藏,与文件自述的方向正好相反。文档承诺 fail-open,实现是 fail-closed。

为什么现在才可观测

在 objectstack#6331 修好之前,metadata-admin 根本没读到过任何 spec 下发的谓词(五个站点只读已被 ADR-0089 归一化掉的 visibleOn),所以这条求值语义从来没有被执行到。#6331 的读取器修复让它第一次可达。

具体的踩法(objectui PR #3923 已用浏览器探针两向实测):谓词必须写成 data. 作用域才能对着草稿求值(objectstack#6254 修正了 object.form.ts 里 16 处裸拼法)。若后端仍在下发 #6254 之前的裸拼法 type in ['text',...],而前端已带 #6331 的读取器修复,则求值器把裸 type 在 { data: row } 作用域里解析成 undefined → 判假 → Studio 对象字段列表里那 16 个类型相关子字段(Min / Max / Precision / Scale / Max Length / Min Length / reference / deleteBehavior / expression / returnType / autonumberFormat / language …)全部消失。实测读数:

B1 objectForm fields(#6254 后的 data. 拼法)
   row currency → Min, Max, Precision, Scale          (正确)
   row text     → Max Length, Min Length              (正确)
B2 objectForm fields(安装版 spec 17.0.0-rc.5 的裸拼法)
   row currency → 16 条条件子字段一条都不出
   row text     → 16 条条件子字段一条都不出

也就是说这是一个版本错配窗口内的静默功能消失:v17 前后端同步升级时不会命中,前端先于后端升级时会命中,而症状是「配置项不见了」,用户无从判断是权限、是类型不支持、还是 bug。

为什么不在 #6331 的 PR 里顺手改

改动求值语义是有后果的取舍,不该由读取器修复夹带:

  • A. 未解析路径 → 判真(与文件承诺一致):配置项恒显,与修复前的现状同向,坏谓词不再致命 —— 但真正想隐藏的字段在拼错时也会露出来。
  • B. 未解析路径 → 判假(现状):拼错即静默隐藏,最难诊断。
  • C. 未解析路径 → 判真 + 一条开发期 console.warn / 诊断项:既不静默,也不吞配置项。

倾向 C(与 objectstack#5149 fail-open 一族的处理方向一致,且把「谓词引用了不存在的路径」变成可发现的事实而不是不可见的行为),但这是 metadata 表单渲染语义,应由维护者定。真正的长期解法在生产端:谓词表达式应在发布期被校验(引用的路径必须存在于对应 schema),而不是让渲染器在运行期猜 —— 那属于另一个更大的口子,这里只记录读数。

关联

查重说明(如实记录局限)

按关键词 + 文件路径搜过 open issues:evaluatePredicate 0 命中、predicate.ts metadata-admin unresolved identifier hidden 0 命中;继续搜时 GitHub search API 触发本座位限流(API rate limit already exceeded),未能完成更宽的关键词面。#6331 的分诊评论此前对三仓 463 个 open issue 做过全量 REST 分页并列出邻居,其中没有本条。若 PM 发现同小时的孪生单,按惯例 race-close 本单。

Activity

  1. claude commented on Aug 9, 2026

    @claude
    Contributor

    Triage: needs-user-decision (routing repo:objectui kept — landing is packages/app-shell/src/views/metadata-admin/predicate.ts).

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


    Generated by Claude Code

  2. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    Collaborator

    Maintainer ruling (2026-08-09): Option C — an unresolvable predicate path evaluates TRUE, with a development-mode warning. pm:queue.

    evaluatePredicate / resolveValue: a path that resolves to nothing no longer silently hides the field — the evaluator returns true (honouring the file's own documented fail-open promise, consistent with the #5149 family) and emits a dev-mode console.warn / diagnostic naming the unresolved path, so a bad predicate becomes a discoverable fact instead of an invisible behaviour. This closes the version-skew window where 16 type-conditional Studio subfields vanished with zero diagnosis.

    Rationale (three-axis): the skew window (frontend ahead of backend) is real and its symptom — "config items disappeared" — is the most expensive support shape; the renderer must not guess, it must honour its documented semantics while the real contract fix lives at publish time; and silent hiding is undiagnosable where fail-open-with-warning is self-reporting.

    Companion card: publish-time validation of predicate path references (the producer-side fix this card's body correctly identifies as the long-term answer) is filed separately — it is NOT a rider on this fix.

    Maintainer directive (verbatim, covering this decision round): 「同意你的建议」. Recorded by PM session session_01LGRN2cSRfggfX9B2L83bQc. Veto window open — comment to overturn.


    Generated by Claude Code

  3. self-assigned this
    on Aug 9, 2026
  4. yinlianghui commented on Aug 9, 2026

    @yinlianghui
    ContributorAuthor

    🔒 认领(objectui 分片 PM,session session_01GTRjn8xBqp75dk7kFupVRt,恢复批次 1)


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions