发现于 #5073 的实施(promote userFilters.allowAddTab 进 spec 契约)。不阻塞 #5073,那条的裁定与落地都成立;这是落地时实测到的、渲染器一侧的独立缺口。
事实(实测,非阅读推断)
objectui/packages/plugin-list/src/UserFilters.tsx 的 TabFilters:同一个 return 里,预设 tab 按钮有 onClick,新增 tab 按钮没有。
预设 tab(:727 起):
< button
key={tabId}
data-testid={`filter-tab-${tabId}`}
onClick={() => handleTabChange(tabId)}
…
> {tab.label} < /button >
allowAddTab 渲染的那个(:742 起):
{allowAddTab && (
< button
className="… hover:text-foreground hover:bg-muted shrink-0"
data-testid="filter-tab-add"
title="Add filter tab"
>
< Plus className="h-3.5 w-3.5" / >
< /button >
)}
没有 onClick,组件里也没有任何 onAddTab / addTab 入参或回调(全仓 grep filter-tab-add / onAddTab 只命中这两行)。它带 hover 态和 title="Add filter tab",看起来完全可点,点下去什么都不发生。
注意别与 app-shell/src/views/metadata-admin/widgets.tsx:1431 的 addTab 混淆 —— 那是 Studio 编辑期的 tabs 编辑器(data-testid="filter-mode-add-tab"),与运行期渲染器的这个按钮无关。
为什么现在值得立案
#5073 把 allowAddTab 提升进了 packages/spec 的 UserFiltersSchema,它因此进了 JSON Schema、Studio SchemaForm 和参考文档 —— 能力从此可被发现,AI 作者会照着 schema 写它。
那条 PR 的 .describe() 已经刻意收窄到只承诺渲染入口:
Render an "add tab" affordance after the presets (tabs element). Page lists only — object views use listViews for named presets
这是按 PD#10 写的(不宣传运行时不交付的能力),所以契约本身没有说谎。但作者写 allowAddTab: true 的意图显然是「让终端用户能加 tab」,而交付的是一个死按钮 —— 一个可见、可 hover、有 tooltip 却无行为的控件,比没有这个按钮更糟:它把「没实现」伪装成「点了没反应的 bug」。
需要裁定的是方向,不是补丁
两个方向都动到已发布契约,所以立案不猜,按 #5022 之后的规矩交给维护者。
参考
发现于 #5073 的实施(promote
userFilters.allowAddTab进 spec 契约)。不阻塞 #5073,那条的裁定与落地都成立;这是落地时实测到的、渲染器一侧的独立缺口。事实(实测,非阅读推断)
objectui/packages/plugin-list/src/UserFilters.tsx的TabFilters:同一个return里,预设 tab 按钮有onClick,新增 tab 按钮没有。预设 tab(
:727起):allowAddTab渲染的那个(:742起):没有
onClick,组件里也没有任何onAddTab/addTab入参或回调(全仓 grepfilter-tab-add/onAddTab只命中这两行)。它带 hover 态和title="Add filter tab",看起来完全可点,点下去什么都不发生。注意别与
app-shell/src/views/metadata-admin/widgets.tsx:1431的addTab混淆 —— 那是 Studio 编辑期的 tabs 编辑器(data-testid="filter-mode-add-tab"),与运行期渲染器的这个按钮无关。为什么现在值得立案
#5073 把
allowAddTab提升进了packages/spec的UserFiltersSchema,它因此进了 JSON Schema、Studio SchemaForm 和参考文档 —— 能力从此可被发现,AI 作者会照着 schema 写它。那条 PR 的
.describe()已经刻意收窄到只承诺渲染入口:这是按 PD#10 写的(不宣传运行时不交付的能力),所以契约本身没有说谎。但作者写
allowAddTab: true的意图显然是「让终端用户能加 tab」,而交付的是一个死按钮 —— 一个可见、可 hover、有 tooltip 却无行为的控件,比没有这个按钮更糟:它把「没实现」伪装成「点了没反应的 bug」。需要裁定的是方向,不是补丁
userFilters的既有语义一致:ADR-0047 说 end-user 的筛选选择 session-scoped、从不落成元数据),还是要写回sys_metadata?后者会把渲染器变成元数据写入方,牵扯权限与 ADR-0047 的作用域承诺,不能顺手做。userFilters.allowAddTab是 objectui 真读、spec 从未声明的活能力 —— promote 还是 reject?(挡住 #4001 批 18 的 UserFiltersSchema 收紧) #5073 刚落地的 spec 声明上做对应处理(tombstone / 收窄 describe / 退役该键)—— 但该键在存量配置里是被写过的,退役要走 spec-property-retirement 那套。两个方向都动到已发布契约,所以立案不猜,按 #5022 之后的规矩交给维护者。
参考
packages/spec/src/ui/view.zod.tsUserFiltersSchema.allowAddTab(userFilters.allowAddTab是 objectui 真读、spec 从未声明的活能力 —— promote 还是 reject?(挡住 #4001 批 18 的 UserFiltersSchema 收紧) #5073)objectui/packages/plugin-list/src/UserFilters.tsx:669(prop)、:182(传入)、:742(渲染)