Skip to content

check-react-blocks-conformance 比的是两份声明,不是声明↔实现——#4413 全程它都是绿的(Prime Directive #10 落在门禁自己身上) #4472

Description

@os-zhuang

packages/spec/scripts/check-react-blocks-conformance.ts 的文件头声称(原文大写强调):

Spec ↔ frontend conformance report (ADR-0081 follow-up). Confirms the objectui components ACTUALLY implement the props the spec protocol declares for each curated react block. The spec is the protocol; the frontend must conform.

它不做这件事。 它比对的是两份声明

spec zod schema 的 props(specProps()z.toJSONSchema 注册表配置声明的 inputs(manifestInputs()

右边那份来自 objectui scripts/dump-public-manifest.mjsmanifestFromConfigs(getPublicConfigs()),而 manifestFromConfigspackages/sdui-parser/src/index.ts)的实现是:

inputs: (c.inputs ?? []).map((i) => ({ name: i.name, type: , required: i.required,}))

——直接读注册表配置的 c.inputs纯声明,与渲染器读不读毫无关系。

已证实的后果:#4413 全程绿灯

#4413 里四个 block 的 objectName/recordId 没有任何渲染器读,页面渲染成空。而合并前(ebb209c 之前)的 packages/spec/react-conformance.baseline.json 长这样:

"RecordDetails":     { "frontendOnly": [], "missing": false },
"RecordHighlights":  { "frontendOnly": [], "missing": false },
"RecordRelatedList": { "frontendOnly": [], "missing": false },
"RecordPath":        { "frontendOnly": [], "missing": false }

四个完全不工作的块,门禁报"零分歧"。 因为两边都老老实实声明了 objectName——两份声明各自都不算撒谎,谎言在于渲染器两份都没实现,而这道门禁的视野里根本没有渲染器。

#4413 是靠人肉读 objectui 渲染器发现的,不是靠它。

为什么这比任何单个 block 重要

这是 Prime Directive #10(declared ≠ enforced)落在门禁自己身上的实例,和 #1475「spec 声明 9 种校验规则、执行器只认 3 种」是同一形状,只不过这次撒谎的是那个本该抓撒谎的东西。

一道报绿的假门禁比没有门禁更危险:没有门禁时人会去人肉核对;有一道自称"ACTUALLY implement"的绿灯时,人不会。#4413 存续期间没人怀疑过这四个块,这就是代价。

公平地说,它并非无用

它能看见的是真的,别一并推翻:

所以问题不是"门禁没用",是它的名字和文件头承诺了一个它给不了的保证,而团队按那个承诺信任了它。

次要发现(一并记录)

  1. 它在 console 构建里是 warn-onlyscripts/gen-sdui-manifest.sh:71-78 调用时没传 --strict,分歧只打印 。注释也写明了"Warn-only here — run check:react-conformance --strict to gate"。所以即便它看得见的那部分,也没有真正 gate。
  2. 只在 console 构建时跑(manifest 只在那时存在),不是 PR 门禁——这是脚本自己写明的成本取舍,本身合理,但和上一条叠加后,"分歧被记录"和"分歧被拦住"之间的距离比读文件头感觉到的更远。

候选方向(不预设结论,检测手段需要设计)

(a) 先把话说回来——本仓库内即可做,最便宜。 改文件头与报告用词,把"ACTUALLY implement"降级为它真正做的事(声明一致性 / declaration parity),并写明它看不见"声明了但不读"这一类。不解决检测问题,但立刻消除误信任——按 #10 的处置顺序(fix it / trim it / file it),这是"trim the claim"。

(b) 行为式冒烟测试——我认为最有希望。 #4413 的症状是渲染器吐出 designer placeholder(record:details — bind a record to preview)。一个"把每个 public block 按其声明的必需绑定挂载在裸 SchemaRendererProvider 下、断言输出不是 placeholder / 不为空"的测试,四个块会全部亮红。它直接命中这一类,不需要静态分析,而且天然属于 objectui 侧。

(c) 让 manifest 携带使用证据。 扩展 objectui 的 manifest,给每个 input 标注"渲染器是否消费"(对渲染器源码做 AST pass,或运行时探针)。能复用现有比对框架,但是启发式——props 可能经 spread / 转发 / helper 读取,假阴性假阳性都要评估。

(d) 只对 kind:'binding' 收紧。 一个不被读的绑定 prop 永远是 bug(块没连上数据),而一个不被读的装饰 prop 可能只是冗余。若检测手段有假阳性成本,先只在 binding 上开火,信噪比最好。

(a) 与 (b)/(c)/(d) 不互斥:(a) 现在就能做且必须做(门禁不该继续撒谎),其余按检测手段的设计结论再选。

参考

/cc objectstack-ai/objectui((b)/(c) 的实现侧)

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions