Skip to content

[finding] record:alert 的谓词管道在自己的 suite 里被整体替成 stub(toPredicateInput + useCondition),该面的 visible 判定零可观测 —— #3871 的缺陷就藏在这里 #3941

Description

@yinlianghui

发现来源

实施 #3871(toPredicateInput 对已是 ${…} 模板的字符串二次包裹)时,按「规则消费半径」
清点 toPredicateInput 的全部调用点。#3871 正文列了七个,实际还有第八个:

  • packages/plugin-detail/src/renderers/record-alert.tsx:140-141
const predicateInput = toPredicateInput(props.visible);
const passesPredicate = useCondition(predicateInput, { record });
// :193
if (predicateInput !== undefined && !passesPredicate) return null;

这一处与其它落点一样中了 #3871:visible: '${…}' 走 fail-soft(不传 throwOnError),
二次包裹后的字符串解析失败被 catch 原样退回,Boolean(非空串) 恒 true —— 一条作者写了
visible 想按条件收起的 record 横幅永远显示。生产端缺陷已由 #3871 的 PR 一并治好
(改的是共享归一器),本单不是那个缺陷。

本单要记录的是:这一面的谓词判定从它自己的测试里根本观察不到

packages/plugin-detail/src/renderers/__tests__/record-alert.test.tsx:32-46 把
@object-ui/react 整个 mock 掉,其中谓词管道的两端一起被替成了替身:

vi.mock('@object-ui/react', () => ({
  // …
  useCondition: (_input: unknown, _scope: unknown) => stub.predicate.passes,
  toPredicateInput: (visible: unknown) => {
    stub.predicate.input = visible;   // 仅记录入参
    return visible;                   // 恒等函数
  },
  // …
}));

于是:

  1. toPredicateInput 被换成恒等函数 —— 归一(以及 toPredicateInput 对已经是 ${…} 模板的字符串二次包裹,动作面的谓词一律判成 true(visible 永远显示 / disabled 永远置灰) #3871 的二次包裹)在这个 suite 里
    根本不发生;
  2. useCondition 被换成常量 stub.predicate.passes —— 求值也不发生。

该面只剩「渲染器有没有把 props.visible 传下去」这一个可断言点(stub.predicate.input),
「这个 visible 会得到什么 verdict」完全不可观测。任意归一器缺陷、任意求值缺陷,在这个
文件里都是绿的。这就是 objectstack#4984 家族(fixture 让坏掉的规则保持绿),而
DeclaredActionsBar.test.tsx:22-34 的注释已经把同一个教训写过一遍 —— 它自己曾把
useCondition 钉成常量真,导致 #3835 的真值性缺陷在那个 suite 眼皮底下活了很久,后来
改成用真实的评估入口。record:alert 是同一形状还没被改的那个。

影响判断(observation-class)

建议修法(未裁)

参照 DeclaredActionsBar.test.tsx 与 packages/components/.../__tests__/ 里几个动作面
gate suite 的做法:保留 dispatch / metadata / components 的替身,但让谓词入口用真的
(@object-ui/react 的 toPredicateInput + useCondition,配 PredicateScopeProvider
喂 scope),补上四种形态(false / true / '' / 表达式,两个极性)与 ${…} 拼法的
verdict 钉子。@object-ui/react 的 barrel 对轻量 dom project 是便宜的(components 自己
的 gate suite 就是不 mock 直接 import 的)。

Related: #3871(发现出处,生产端已修)、#3850 /#3862(「空谓词 / 已声明门」口径分歧的两单)。
未认领。

Activity

  1. claude commented on Aug 9, 2026

    @claude
    Contributor

    Findings triage round (triage seat Routine, ~15:19Z fire): promoted — finding → pm:queue (label change applied with this comment).

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


    Generated by Claude Code

  2. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    CollaboratorAuthor

    【分诊轮复核·晋级】座位 repo:objectui(session_01GTRjn8xBqp75dk7kFupVRt,2026-08-16):finding → pm:queue。复核实测(origin/main c252227):stub 原样在位(record-alert.test.tsx:32-36 的 vi.mock 恒等 toPredicateInput + 常量 useCondition),生产端 :140-141/:193 谓词管道未变形,该 suite 六天零改动 —— 谓词 verdict 至今无活钉。修法方向:该 suite 的谓词用例改走真管道(真 toPredicateInput + useCondition,mock 只留数据层),或按仓内谓词面钉子先例(#3955 族)补真实断言;实施时以现行测试形态为准。


    Generated by Claude Code

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

    @yinlianghui
    CollaboratorAuthor

    【认领】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 11 派发,os-dev 实施。分支:claude/issue-3941-record-alert-predicate-pins。范围:仅 packages/plugin-detail/src/renderers/__tests__/record-alert.test.tsx 的谓词管道去 stub(真 toPredicateInput + useCondition,数据层 mock 保留)+ 四形态×两极性 verdict 钉子;生产文件零触碰。


    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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions