Repository navigation
SchemaRenderer 的 hidden / hiddenOn 是 #3862 的反极性孪生:hidden: '' / null / 空 source 信封在通用渲染路径上让节点永久消失 #3955
Copy link
Copy link
Closed
Labels
Description
Activity
Triage:
pm:blocked,Blocked-by: #3850added to the body (defect-class card; queue on unlock).- Classification: concrete defect with a measured six-value probe table — the
hidden/hiddenOnlegs ofSchemaRenderer'sshouldHidereturnevaluateCondition(...)un-negated, so the evaluator's empty-predicate defaulttruemeans HIDE:hidden: ''/null/ an empty CEL envelope makes the node permanently disappear. Anchors re-verified onorigin/main@69becd2(SchemaRenderer.tsx,shouldHideblock: fourvisible*legs negate,hidden/hiddenOndo not). - Why blocked, not queued: the card's prescribed fix reads
hasDeclaredPredicatefrom@object-ui/core's evaluator (packages/core/src/evaluator/declaredPredicate.ts) — that file does not exist onorigin/mainyet; today the helper lives only as a local function inActionRunner.ts:636. The sinking is part of 「空谓词」在三处有三种范围:disabled: { dialect: 'cel', source: '' } 仍被判成已声明的门 → 永久置灰(#3842 修完后的残留,需先裁) #3850/SchemaRenderer 的 disabled 门用第三种拼法 !== undefined:disabled: '' / disabled: null 在通用渲染路径上永久置灰 #3862's in-flight pair (bothpm:dispatched, branchclaude/issue-3850-3862-empty-predicate-gate). Dispatching now would either race that branch or force the inline!== ''patch the card explicitly forbids. On unlock, re-verify the file face at the merged ref — the merge that unblocks this is also the one most likely to have already fixed it in passing. - Dedup: SchemaRenderer 的 disabled 门用第三种拼法 !== undefined:disabled: '' / disabled: null 在通用渲染路径上永久置灰 #3862 is the
disabled-polarity sibling (explicitly fenced: its ruling keeps thevisiblefamily untouched, and thehiddenlegs' un-negated polarity is exactly what that fence does not cover); 「空谓词」在三处有三种范围:disabled: { dialect: 'cel', source: '' } 仍被判成已声明的门 → 永久置灰(#3842 修完后的残留,需先裁) #3850 is the ruling/sinking card. No open card covers thehidden/hiddenOnlegs. Clean. - Flags for the objectui seat (not this seat's production): ① both siblings 「空谓词」在三处有三种范围:disabled: { dialect: 'cel', source: '' } 仍被判成已声明的门 → 永久置灰(#3842 修完后的残留,需先裁) #3850/SchemaRenderer 的 disabled 门用第三种拼法 !== undefined:disabled: '' / disabled: null 在通用渲染路径上永久置灰 #3862 carry
target:v17and this card's consequence (silent node disappearance on real compiled metadata shapes) is arguably heavier than the grey-out twin — worth a board grading when it unblocks; ② body is in Chinese — per the maintainer's 2026-08-08 ruling (finding(docs): core/app-schema.mdx's "Global Actions" snippet imports the wrong same-namedMenuItem#6692 precedent), re-author in English at claim time, carrying every anchor unchanged. - No
domain:*label — objectui is a whole-repo seat.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Classification: concrete defect with a measured six-value probe table — the
PM 分诊(session_01GTRjn8xBqp75dk7kFupVRt):晋级
pm:queue,方向代裁 ——hidden/hiddenOn按 #3850 既定语义收敛:空谓词(''/null/纯空白/空信封)= 没有门 = 不隐藏,改读下沉后的hasDeclaredPredicate,⛔ 不新增本地拼法。这是 #3862 反极性孪生在同一裁决线上的机械延伸,无需维护者另裁。排程:与 #3960、#3957 三单结对一 PR(文件面互相重叠:
declaredPredicate.ts/SchemaRenderer.tsx/core/actions,分开派必然三轮串行),Blocked-by PR #3966(同文件面,其 documented-divergence 钉需要同步更新)—— PR3966 合入后即派。
Generated by Claude Code
🔒 认领(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt,批次 4)—— 与 #3957、#3960 三单结对一 PR(分诊评论既定,前置 PR #3966 已 MERGED @ main
ab3ad4f3f)。- 分支:
claude/issue-3955-3957-3960-predicate-scope-converge - 三单方向均已在各自分诊评论代裁:本单 hidden/hiddenOn 改读
hasDeclaredPredicate(空谓词=无门=不隐藏);「空谓词」的第四种拼法:{ dialect: 'cel', source: ' ' }(source 只有空白)仍被判成已声明门 → disabled 侧仍永久置灰、执行入口仍拒执行(#3850 裁决枚举未覆盖) #3960 空判据 trim 扩到信封 source(同步更新 ActionRunner.execute 的 disabled 门把「空谓词」当已禁用,拦掉执行(实测 handler 不跑),且与渲染器判定不一致 #3848 执行门的钉与 documented-residue 用例);[finding] ActionEngine 的 visible 过滤仍用自己的「空/非谓词」范围:visible: 0 / NaN / ' ' 在引擎面隐藏、在渲染面显示 —— #3850 收敛后剩下的最后一处分叉 #3957 ActionEngine visible 过滤改读唯一定义(A 案)。 - 文件面(声明给 in-flight check):
packages/core/src/evaluator/declaredPredicate.ts(或toPredicateInput)、packages/core/src/actions/{ActionRunner,ActionEngine}.ts及其测试、packages/react/src/SchemaRenderer.tsx;与在飞 packages/layout:page-header注册缺isContainer: true,而PageHeader有意渲染schema.children—— sdui-parser 对文档认可的写法报not-a-container#3900/[app-shell] ActionParamDialog 的 boolean 分支不下发id,于是同一个控件被两个同文本 label 引用(可访问名重复),而它自己的通用分支一直是对的 #3962/[fields] 复合/分组 field widget 丢弃或错投 host 下发的控件 id:address / geolocation 的表单 labelfor悬空,checkboxes / radio / rating / file 的for落在不可 label 的 div 上 #3961 不相交。
Generated by Claude Code
- 分支:
Blocked-by: #3850
来源
发现自 #3850 + #3862 的结对实施(PR 分支
claude/issue-3850-3862-empty-predicate-gate)。给SchemaRenderer的disabled链写「visible 家族等价钉」时,顺手把同一个useMemo里 可见性链的另一极性 也量了一遍,发现hidden/hiddenOn两条腿有与 #3862 完全同构的缺陷,而且后果比置灰更重:节点整个消失。不在 #3850 / #3862 的修法面:那两单裁决的落点是「已声明门」定义的下沉 +
disabled/disabledOn两条腿改读,visible家族一侧被明确裁为保持!== undefined不动(它的true被取反,与「没有门」同结果,且改动会改变别名优先级)。hidden腿的true不被取反,所以同一个「空谓词 →evaluateCondition答true」在这里意味着 HIDE。故独立成单,未认领。机理
packages/react/src/SchemaRenderer.tsx(origin/main@65bb513dc073deb4e72950c287eef32cb56bf8ce),shouldHide块(287 行起)的最后两条腿:ExpressionEvaluator.evaluateCondition对「没有条件」的唯一默认是return true(意为 visible/enabled)。前四条腿(visible/visibleWhen/visibleOn/visibility)都写成!evaluateCondition(...),那个true取反后落在「不隐藏」,与「没有门」同结果 —— 良性。hidden/hiddenOn直接返回,于是true= 隐藏:空谓词让节点消失,与 #3862 在disabled上的true= 置灰是同一个不对称的第二个出口。拼法同样是最宽的那一格
!== undefined,所以hidden: null也命中(null !== undefined为真)。实测(worktree @
65bb513dc,一次性探针,未提交)同一个 probe 组件,只换 key,
rendered/HIDDEN是节点是否出现在 DOM:false/true两行都正确(声明了 verdict 就按 verdict 走),坏的正是四行「空」。为什么值得管
{ dialect, source: '' }是@objectstack/spec的ExpressionInputSchema对任何已授权谓词归一后的产物,也是objectstack build在「作者把谓词留空」时编译出的形状 —— 这是真实元数据里最可能出现的空拼法(「空谓词」在三处有三种范围:disabled: { dialect: 'cel', source: '' } 仍被判成已声明的门 → 永久置灰(#3842 修完后的残留,需先裁) #3850 已为此裁过一次)。evaluatedSchema的useMemo里无条件执行,不带任何 type 判定,覆盖走SchemaRenderer的全部节点。hidden命中时节点根本不渲染 —— 作者看到的是「我写了个空的hidden,整块内容不见了」,界面上无法与「元数据本意」区分。修法(机械,已有唯一定义可读)
#3850 的裁决已经把「已声明门」下沉为
@object-ui/core的hasDeclaredPredicate(packages/core/src/evaluator/declaredPredicate.ts,该 PR 落地),disabled/disabledOn两条腿已改读它。这里同样改读即可:⛔ 不要就地补
&& !== ''—— 那是把第 N 种「空」拼法写进第 N 个消费者,#3842 / #3849 / #3850 三单合掉的正是这类分身。需要注意的一处非等价:
hidden腿改读后,hidden: ''会继续往下落到hiddenOn(而不是在空谓词上短路),这与disabled链在 #3862 修后的行为一致,但它改变了别名优先级,应作为行为变更钉住而不是当作等价。另外前四条visible腿是否也统一改读,是一个独立的判断:那侧空谓词良性,改读会改变别名优先级(如visible: ''+hidden: 'true'的组合),收益是「一个概念一处定义」,代价是行为变更 —— 建议与本单一起裁,而不是在本单里顺手改。Related: #3862(同一文件、同一
useMemo、disabled极性的同族半边)、#3850(「已声明门」范围裁决与定义下沉)、#3842 / #3849 / #3848(动作面与执行入口的同族)、#3492(不变量出处)。未认领。Generated by Claude Code