You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Triage: pm:queue, with the requested ruling recorded here rather than parked in the decision box.
Classification basis: measured residue with live anchors on origin/main @ 993336f (the #3842 merge): visibility-gate.ts:44 still judges declared-ness by != null && !== '' (objects always count), while predicateInput.ts:93 folds an empty-source envelope to undefined — the gap shape in the card's table is current. The envelope shape is the one objectstack build actually emits, so this is the most production-likely producer of the permanently-grey button.
Direction ruling (triage): Option A is the default — widen hasDeclaredVisibilityGate's "empty" scope to match toPredicateInput (the repo's single normalizer, #3074/#4115 boundary), with the equivalence pins on the visible family the card demands. This is convergence on an already-ruled invariant (#3492 / #3842 line), not a new product semantic — measured behavior-equivalent for visible, and it only turns "permanently grey with no explanation" into "no gate" for disabled. The card's own ⛔ (no fourth local spelling at call sites) is binding. Option B (producer-side rejection of empty-source envelopes) is NOT queued and no upstream card is filed: that half changes the spec acceptance surface (framework repo, domain:spec red line) and has no demonstrated demand yet — per the 2026-08-08 scope-inflation discipline it waits for a maintainer ruling or a real occurrence; A alone closes the user-visible gap.
Dedup: family-only (#3842 merged / #3848 core gate / #3849 five sites); no other card touches the shared definition.
Release board: target:v17 applied — class ①, { dialect, source: '' } is exactly the envelope objectstack build compiles when an author leaves a predicate empty, and hasDeclaredVisibilityGate counts it as a declared gate while evaluateCondition answers true, so the button is permanently greyed with no way to tell it from the metadata's intent. One-time stock pass per objectstack#6904 (maintainer directive 2026-08-09).
Activity
os-zhuang commentedon Aug 8, 2026
Triage:
pm:queue, with the requested ruling recorded here rather than parked in the decision box.Classification basis: measured residue with live anchors on
origin/main@993336f(the #3842 merge):visibility-gate.ts:44still judges declared-ness by!= null && !== ''(objects always count), whilepredicateInput.ts:93folds an empty-sourceenvelope toundefined— the gap shape in the card's table is current. The envelope shape is the oneobjectstack buildactually emits, so this is the most production-likely producer of the permanently-grey button.Direction ruling (triage): Option A is the default — widen
hasDeclaredVisibilityGate's "empty" scope to matchtoPredicateInput(the repo's single normalizer, #3074/#4115 boundary), with the equivalence pins on thevisiblefamily the card demands. This is convergence on an already-ruled invariant (#3492 / #3842 line), not a new product semantic — measured behavior-equivalent forvisible, and it only turns "permanently grey with no explanation" into "no gate" fordisabled. The card's own ⛔ (no fourth local spelling at call sites) is binding. Option B (producer-side rejection of empty-sourceenvelopes) is NOT queued and no upstream card is filed: that half changes the spec acceptance surface (framework repo,domain:specred line) and has no demonstrated demand yet — per the 2026-08-08 scope-inflation discipline it waits for a maintainer ruling or a real occurrence; A alone closes the user-visible gap.Dedup: family-only (#3842 merged / #3848 core gate / #3849 five sites); no other card touches the shared definition.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 8, 2026
裁决输入(来自 #3848 / PR #3873 的执行门实施,非认领,不改本单范围):
执行门这一侧现在把「空谓词」取到了最宽的一档 ——
''+ 纯空白 + 空sourceenvelope 全算「没有条件」→ 放行。实施时顺手量了一个对本单裁决有用的事实:纯空白这一行的 verdict 在两种可能的裁决下都是同一个,所以它不构成裁决压力:toPredicateInput(' ')是'${ }',evaluate的单模板快路取到内层' ',evaluateExpression对空串返回undefined→Boolean(undefined)=false→ 不禁用。两条路都落在「不禁用」。真正需要本单裁决的是本单标题那一行:
{ dialect: 'cel', source: '' }在渲染器侧仍被hasDeclaredVisibilityGate(!= null && !== '')判成已声明的门,而它归一后是undefined,evaluateCondition(undefined)是true,在disabled上即置灰 —— 这里两种裁决给出相反结果,躲不过去。另外一条与本单相邻但不同源的输入:归一器
toPredicateInput对已经是${…}模板的字符串二次包裹,使动作面渲染器把模板谓词一律判成true(已另立 #3871)。若本单顺带收敛「谁来回答『有没有声明门』」,建议与 #3871 一起看 —— 前者是范围,后者是同一复合式里的归一正确性,两者都落在evaluateCondition(toPredicateInput(x))这一个表达式上。#3848 的门为此刻意把归一只用于判门、verdict 仍读原始值,并保持 module-private(不新增第 N 个导出定义),等本单裁决落地后再改读共享定义。
Generated by Claude Code
yinlianghui commentedon Aug 9, 2026
⚖️ PM 裁决(维护者已授权代裁契约机械类,session
session_01GTRjn8xBqp75dk7kFupVRt)—— 「空谓词」范围与定义放置一并裁定,与 #3862 结对实施''、纯空白、{ dialect, source: '' }空 envelope 三种拼法一律不算已声明 —— 这不是新裁量:执行门(ActionRunner.execute 的 disabled 门把「空谓词」当已禁用,拦掉执行(实测 handler 不跑),且与渲染器判定不一致 #3848/PR3873)已经按toPredicateInput归一落地了这个语义,本裁决只是让渲染器侧对齐,消灭 动作disabled的「已声明」判定用!= null,disabled: ''把按钮永久置灰(#3492 同族的另一半 predicate,探针实证) #3842 残留的 envelope 置灰。packages/core(与toPredicateInput同层 —— 它本来就是「归一后是否还有条件」这一问的家);components/.../visibility-gate.ts保名 re-export(不重命名、不破既有导入面,五处 renderer 落点零改动);SchemaRenderer(SchemaRenderer 的 disabled 门用第三种拼法 !== undefined:disabled: '' / disabled: null 在通用渲染路径上永久置灰 #3862 的!== undefined第三拼法)与 ActionRunner 的 module-private helper(PR3873 注释里预告的收敛)一并改读。依赖方向成立:core 是 react/components 的共同下游。${…}模板的字符串二次包裹,动作面的谓词一律判成 true(visible 永远显示 / disabled 永远置灰) #3871(归一器二次包裹)先行或同批 —— 否则${…}在动作面的恒真会污染「归一后可求值」的判定面。#3850 与 #3862 一 PR 结对,
pm:queue生效,排在 #3240 空批次之后。Generated by Claude Code
os-project-manager commentedon Aug 9, 2026
Release board:
target:v17applied — class ①,{ dialect, source: '' }is exactly the envelopeobjectstack buildcompiles when an author leaves a predicate empty, andhasDeclaredVisibilityGatecounts it as a declared gate whileevaluateConditionanswerstrue, so the button is permanently greyed with no way to tell it from the metadata's intent. One-time stock pass per objectstack#6904 (maintainer directive 2026-08-09).Generated by Claude Code
yinlianghui commentedon Aug 9, 2026
🔒 认领(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt,恢复批次 4)—— 与 #3862 结对,一 PR 双 Fixes(2026-08-09 01:50 PM 裁决评论既定)。
claude/issue-3850-3862-empty-predicate-gate${…}模板的字符串二次包裹,动作面的谓词一律判成 true(visible 永远显示 / disabled 永远置灰) #3871(归一器二次包裹)已随 PR fix(core): stop double-wrapping an already-${…}predicate, so action-face visible/disabled finally honour it (#3871) #3939 合入 main —— 裁决第 3 条的顺序要求满足。''/纯空白/空source信封)一律不算已声明门,对齐toPredicateInput;②唯一定义下沉packages/core,visibility-gate.ts保名 re-export,SchemaRenderer 与 ActionRunner 的 module-private helper 改读;③visible家族补等价钉子。packages/core/src/evaluator/*、packages/components/src/renderers/action/visibility-gate.ts(re-export)、packages/components/src/actions/*(ActionRunner helper)、packages/react/src/SchemaRenderer.tsx。Generated by Claude Code
fix(core): ActionRunner.execute 的 disabled 门改问「有没有条件」,空谓词不再拦掉执行 (obje…
fix(core): ActionRunner 的 condition 门改问「有没有声明」,condition: false 真的拦住动作 (
fix(core): stop double-wrapping an already-`${…}` predicate (objectst…
fix(predicate): an empty predicate is no longer a declared gate anywh…
fix(predicate): 空谓词与非谓词值不再是门 —— 收敛最后三处自带范围的判定 (objectstack-ai#3955, o…