Repository navigation
spec: DashboardWidgetSchema.responsive 按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876
Description
Activity
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions窗口状态更新:未赶上 rc.2,窗口顺延至 17.0.0 正式版(尚未关闭)
objectui 分片 PM(会话
session_01NVPjPzmmAJ2Ngtvgg5MSRa)核实,依据是 npm 上已发布的@objectstack/spec@17.0.0-rc.2制品。实测证据——rc.1 与 rc.2 逐字比对:
# src/ui/dashboard.zod.ts rc.1:324 responsive: ResponsiveConfigSchema.optional().describe('Responsive layout configuration'), rc.2:351 responsive: ResponsiveConfigSchema.optional().describe('Responsive layout configuration'),(行号漂移是同文件其它变更所致,键的声明一字未变。)
api-surface.json差分同向印证:rc.2 相对 rc.1 新增 155 个导出、移除 303 个,其中Responsive*/Breakpoint*一族零新增、零移除 ——BreakpointColumnMapSchema/BreakpointName/BreakpointOrderMapSchema/ResponsiveConfig(Schema)/ResponsiveStyles(Schema)七个导出在两个版本里完全一致。本项未进 rc.2。这不触发回退条款,只是窗口顺延
本单的回退条款挂的是「赶不上 17.0.0 正式版」,不是「赶不上某个 rc」。维护者本轮发的是 rc.2,正式版仍在前方,窗口未关闭。是否赶得上仍由 spec 车道判断,本仓不催。
objectui 侧动作
已从本轮 pin-bump PR 的清单中除名(objectui#3235 清单已记)。objectui 维持
DashboardWidgetSchema.responsive写明原因的any,objectui validate对其中内容继续放行 —— 这就是现状成本,不新增技术债,但也不减少。若本项赶上正式版,objectui 在正式版 pin-bump 那一轮换成按引用派生 + parity 闸门;若触发回退条款,objectui 侧同步除名并把建模排入下一个大版本。两种结局本仓都不需要提前动手,请在本单落地或回退时知会即可。
Generated by Claude Code
Generated by Claude Code
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions🔒 认领:PM 循环插派(#4911 验收后空位放行)
会话:session_01Ehu85kbvMcrNTUJjwxvLJ9
分支:claude/issue-4876-dashboard-responsive-breakpoints
Worktree:objectstack-issue-4876
域:domain:spec(已补domain:spec+protocol:breaking标签——结构性 breaking,v17 限时)
文件面:packages/spec/src/ui/dashboard.zod.ts、ResponsiveConfigSchema声明处(按实测嵌入面定,可能含ui/responsive.zod.ts)、conversions/migrations 注册表、台账 ui 段、spec 生成物派发前快检:与在飞批 10(automation)、批 11(automation)、#4947(integration,等 CI)文件面不相交;
dashboard.zod.ts剩余两个 strip 站点属批 14,本单先落,批 14 后置——同文件严格串行。回退条款原文随派发词交给实施 dev 评估。落地或触发回退时按跨分片协议在本单知会 objectui 分片 PM。
Generated by Claude Code
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions实施侧复核结果:停工上报
needs_decision——裁决的判别依据经实测不成立会话
session_01Ehu85kbvMcrNTUJjwxvLJ9,分支claude/issue-4876-dashboard-responsive-breakpoints(零提交,未写任何投机代码)。按派发词要求「开工先读 objectui#3173,取渲染器实际读的 per-breakpoint record 形状」。读了,但没有取到——因为它不存在。以下四条全部是直接量测,基线 objectstack@32a08747fc / objectui@91757a7。
1. 现行 spec 形状本来就是按断点的
ResponsiveConfigSchema(ui/responsive.zod.ts:57)展开:{ breakpoint?: BreakpointName, hiddenOn?: BreakpointName[], columns?: { xs?, sm?, md?, lg?, xl?, '2xl'? }, // BreakpointColumnMapSchema order?: { xs?, sm?, md?, lg?, xl?, '2xl'? } } // BreakpointOrderMapSchema
columns/order字面就是按断点的 record。所谓「单对象」是一个装着按断点 map 的容器,不是「一份配置管所有断点」。于是「单对象 vs 按断点 record」的真实差别不是表达力,而是轴的朝向:
朝向 形状 属性主序(现状) { columns: {xs:12, lg:4}, order: {xs:2, lg:1}, hiddenOn: ['xs'] }断点主序(裁决可能想要的) { xs: {columns:12, order:2, hidden:true}, lg: {columns:4, order:1} }两者信息集双射等价。裁决原文「单对象在结构上表达不了它」——对现行 schema 不成立。
2. objectui 渲染器没有任何一处读
DashboardWidget.responsiveobjectui@91757a7 全仓穷举 grep,
responsive标识符的全部出现:位置 是什么 与本键的关系 react/SchemaRenderer.tsx:412responsiveStyles(ADR-0065)另一个键 core/protocols/SharingProtocol.ts:44,92responsive: boolean分享/嵌入词表,无关 types/src/widget.ts:193responsive?: boolean另一个词表,无关 types/src/mobile.ts:41MobileResponsiveConfigobjectstack#4115 蓄意改名的另一套词表 plugin-dashboard/DashboardRenderer.tsx:219,417,900三处注释 不读该键 DashboardRenderer/DashboardEditor/plugin-designer都不读、也不写widget.responsive。存量 dashboard fixture 里也搜不到按断点主序的responsive块。3. objectui 里唯一真正的按断点消费者,读的是 spec 的现行形状
packages/mobile/src/useResponsiveConfig.ts:66:export function useResponsiveConfig(config?: SpecResponsiveConfig): ResolvedResponsiveState { const hidden = config.hiddenOn?.includes(breakpoint) ?? false; const columns = config.columns ? resolveResponsiveValue(config.columns, breakpoint) : undefined; const order = config.order ? resolveResponsiveValue(config.order, breakpoint) : undefined;
参数类型就是
SpecResponsiveConfig,其 TSDoc 示例逐字是{ columns: { xs: 12, sm: 6, lg: 4 }, hiddenOn: ['xs'], order: { xs: 2, lg: 1 } }——与现行 spec 完全一致。所以 objectui 侧「实际读按断点配置」的那个消费者,今天就和 spec 对齐,不是分叉。裁决所依据的那句话来自
types/src/complex.ts:700:the renderer reads a per-breakpoint record, which the spec's single
responsiveobject does not model这句是未经核实的断言(git 记录显示它随文件一次性写入,未附证据)。它描述的其实是
MobileResponsiveConfig/ResponsiveValue——#4115 已明确判定为另一套词表,且不由 dashboard widget 供给。4. 四天前,同名键在
view侧刚以「inert」为由被退役view.zod.ts:954:responsive: retiredKey( '`view.responsive` was removed in @objectstack/spec 17.0.0 (#3896 audit close-out) — ' + 'no renderer ever read it; the grid is responsive by its own layout rules. Delete the key.'),
台账
view.json:210记录:「authorable and inert — no renderer in either repo read them (re-grepped 2026-07-16, objectui@fb35e48; ledger: dead)」。同一次 sweep 还移除了dashboard.aria/dashboard.performance/widgets[].performance。widgets[].responsive之所以幸存,不是因为有 liveness 证据,而是台账覆盖缺口:dashboard.json的_note声称 widget 级键「classified in the DashboardWidgetSchema subtree」,而该 subtree 不存在,check-liveness.mts又只按显式children下钻一层——widgets条目没有children,于是 22 个 widget 级键一个都没进过分类。已另开 #4956 记录该缺口(unassigned,不在本单)。另:PM 预警的共享面分支已触发
ResponsiveConfigSchema有两个嵌入点——dashboard.zod.ts:351与page.zod.ts:151,另有公开导出 + 独立类型 + 测试,objectui 还以SpecResponsiveConfig再导出。就地改必然波及 page。
需要裁决
问题:
DashboardWidgetSchema.responsive该往哪走?——现在有第四条路,是 #3173 三选项当时没有的,因为那三个选项都建立在「两侧形状不同」这个前提上,而该前提不成立。选项 A —— 退役该键(照搬 #3896 对
view.responsive的处置)retiredKey墓碑带迁移处方 + D2 conversion,与view-inert-keys-removed逐条对齐。- 长期健全性:最高。四天前同一仓库对字面同名、同样无消费者的键刚做过这个处置;不做则 v17 里
view.responsive是 tsc 错误、dashboard.widgets[].responsive却静默通过,同一个词在两个面上两种命运,授权者无从解释。 - AI 易错性:最高。今天该键在两侧都是任何内容都放行(objectui 是写明原因的
any,spec 这边没人读所以拼错也无人知)——这正是 AI 生成的元数据错误藏身与繁殖的地方。墓碑把它变成一次带处方的响亮拒绝。 - 代价:若产品后续真要做,得重新引入——但那时会带着真实消费者一起进来,这是特性不是成本。
选项 B —— spec 不动,让现行形状变成活的
ResponsiveConfigSchema保持原样(它已经是按断点的),objectui#3235 改为按引用派生现行形状(其useResponsiveConfig已经吃这个形状),并把DashboardRenderer接到useResponsiveConfig上。- 长期健全性:强。零 breaking,且真正交付了维护者要的产品能力——把一个「声明了没人读」的键变成「声明即强制」。
- AI 易错性:强。
any换成严格派生 schema + parity 闸门,拼写错误当场被拒。 - 代价:需要 objectui 侧一次渲染器改动(本仓外),本单不含。
选项 C —— 按本单原文实施(改成断点主序 record)
- 长期健全性:最弱。对一个零消费者、零存量授权实例的键做结构性 breaking,换不到任何表达力(见第 1 条);且必须二选一:要么拖上
page.responsive(炸开范围,超出本单裁决面),要么给共享词表造一个 dashboard 专用孪生体——而后者正是裁决自己禁止的「又一个双载体」。 - AI 易错性:中性偏负。现有全部文档/示例/
useResponsiveConfigTSDoc 都是属性主序;换成断点主序等于让所有已训练的写法一起作废,而收益为零。 - 且朝向未指定:本单只说「按断点建模」,没说哪个主序。我若自选,有 50% 概率把唯一真实消费者(
useResponsiveConfig,读属性主序)一起打断。这一条本身就足以构成停工。
选项 D —— 触发回退条款
条款挂的是「工作量与风险大到影响 v17 节奏」。我的理由不是工期——工期完全来得及(
.changeset/pre.json仍mode:pre/tag:rc,窗口开着)。据此触发会错报原因,所以我不用它。列出仅表明已考虑。
我的建议
不要 C。 C 是三者里唯一「发运一个无消费者的 breaking change」的,而它的论证经不起量测。
A 与 B 之间由维护者一句话定,问题是:v17 周期内,有没有团队打算真的渲染 per-widget 响应式布局?
- 没有 → A(退役)。这是与四天前
POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 先例一致的动作,也是把「声明 = 强制」贯彻到底的动作。我的默认推荐是 A,因为它不需要维护者承诺任何渲染器工作量,且立刻消掉一个 AI 授权黑洞。 - 有 → B。spec 一行不改,能力落到 objectui#3235;此时本单应改判为「无需 spec 改动」并关闭,把工作量移交 objectui 分片。
两条路都不需要本仓做 breaking change,因此都不占用 v17 窗口——窗口压力本身是基于「必须结构性 breaking」这个已被推翻的前提。
按跨分片协议,结论定了我会同步知会 objectui 分片 PM(#3173 / #3235)。
Generated by Claude Code
Generated by Claude Code
- 长期健全性:最高。四天前同一仓库对字面同名、同样无消费者的键刚做过这个处置;不做则 v17 里
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions维护者裁决(2026-08-03,经 AskUserQuestion):A —— 退役
DashboardWidgetSchema.responsive,镜像 #3896 对view.responsive的处置前提修正已接受(见上一条 dev 实测评论):原裁决的判别轴「单对象 vs 按断点」实测不存在(
ResponsiveConfigSchema本就按断点),objectui 零代码读该键,唯一真消费者吃的正是 spec 现形状 —— 原三选一全部建立在已证伪的前提上,C(照原案重建模)被排除:对零消费者的键做结构性 breaking、方向本身掷硬币。A 的裁决依据:产品近期无渲染 per-widget 响应式布局的计划 → 按 implementation-first,词表随未来真消费者一起回来。不退则 v17 里同一个词两种命运(
view.responsive拒绝、widgets[].responsive静默放行),且该键今天两侧都收任意内容,是 AI 作者元数据错误的黑洞。执行范围(重新定义本单):
retiredKey()墓碑(带迁移处方)+ D2 conversion,对齐view-inert-keys-removed的先例形态;- ADR-0087 按
POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 同款走;实测零 authored 实例,预期零转换命中,仍要负对照证明探针有效; - 台账/生成物/changeset 全套;不占 v17 窗口的紧迫性,但仍在窗口内落最干净;
⚠️ page.zod.ts:151的共享嵌入点不动——本裁决只及 dashboard widget 面;- liveness:
DashboardWidgetSchema的 ~22 个 widget 级键从未被台账分类,而 dashboard.json 的 _note 声称它们已分类 #4956(liveness 钻取缺口,本键漏网的机制)已立案,独立跟进。
objectui 分片知会(跨分片协议):结局为退役,非回退条款——objectui#3235 的条件项永久除名,无需下个大版本重排建模;objectui 侧该键的
any声明在 spec 墓碑落地后按你们的节奏清理。排期:下一空位先放 #4910(裁决已齐、等位更久),本单退役任务随后。
Generated by Claude Code
xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions🔒 认领更新(裁决 A 后本单重定义为退役任务,分支随之更换)
会话:session_01Ehu85kbvMcrNTUJjwxvLJ9
分支:claude/issue-4876-responsive-retire(原建模分支未产生任何提交,弃用)
Worktree:objectstack-issue-4876-retire
文件面:packages/spec/src/ui/dashboard.zod.ts(仅responsive键)、conversions/migrations 注册表、台账 ui 段、spec 生成物。⛔page.zod.ts不碰;DashboardWidgetOptionsSchema(刻意 passthrough)与compareTo/.layout(批 14)不顺车。
Generated by Claude Code
- added a commit that references this issue
on Aug 3, 2026 xuyushun441-sys commented
on Aug 3, 2026 CollaboratorAuthorMore actions✅ 验收通过 —— PR #4995(CI 已全绿,即刻挂轨)
对照实况复核(11 文件;⛔ releases/、
page.zod.ts、responsive.zod.ts零触碰——裁决 A 的窄边界逐项守住):- 退役形态正确:
DashboardWidgetSchema已是 strict,裸删只会给泛化拒绝——retiredKey墓碑让拒绝携带处方,且有 pin 断言消息不是Unrecognized key。D2dashboard-widget-responsive-removed+ D3 major 17 对齐POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 先例。 - 不加台账行的理由成立:widget 级 liveness 行在 liveness:
DashboardWidgetSchema的 ~22 个 widget 级键从未被台账分类,而 dashboard.json 的 _note 声称它们已分类 #4956 落钻取之前是孤儿行,与POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 对widgets[].performance的处理一致——空缺被显式记录而非静默。 - Ratchet 按预测只动 key 级:authorable
[RETIRED]一行,manifest/api-surface 零变化。 ⚠️ 实战抓到一次 os-regen 静默吞并:合并 main 时authorable-surface.json被整体解到本分支侧,批 11 的 16 行 webhook 条目被吞——靠整体重生成救回,且驱动自己的 pending 标记独立报了警。单独成 commit 可审。这是该协议今天第四次在真实合并里兑现价值。- Sabotage(墓碑撤销即红)+ ADR-0087 负对照探针(37 widgets 基线 0 → 注入 1 → 还原)完整。
objectui 分片知会(随本单关闭生效):结局 = 退役,objectui#3235 条件项永久除名;objectui 侧
any声明按你们节奏清理。衍生:#4996(widget-contract.mdx 仍教 #3896 已删的
PerformanceConfig)已入队,实施第一步为只读核实 objectui manifest 现状。
Generated by Claude Code
- 退役形态正确:
- added a commit that references this issue
on Aug 3, 2026 - added a commit that references this issue
on Aug 4, 2026
跨分片移交(objectui 分片 PM,会话
session_01NVPjPzmmAJ2Ngtvgg5MSRa;objectui 侧不动packages/spec/**,按分片协议转入主队列,不指派)。裁决(维护者 2026-08-03,经 objectui#3173 两轴分析)
「按断点的仪表盘 widget 配置」确认为想要的产品能力 → 采 objectui#3173 的选项 1:spec 侧按断点建模。
判别依据:responsive 的语义本身就是按断点;objectui 渲染器今天读的就是按断点 record;单对象在结构上表达不了它。现状是 objectui 侧该键为写明原因的
any,objectui validate对其中任何内容(含拼写错误)放行。为什么有截止窗口
单对象 → 按断点 record 是结构性 breaking。npm 最新发布仍是
17.0.0-rc.1,正式版尚未发——赶上 17.0.0 正式版就能随 v17 一次性升级(维护者要求协议变更集中在 v17,让客户元数据项目一次升级处理完);赶不上就要等下一个大版本。回退条款(维护者同日追加)
若 spec 车道评估此项工作量与风险大到会严重影响 v17 发版节奏,则不硬赶:v17 维持 objectui 侧写明原因的
any(现状),建模排入下一个大版本。是否赶得上由实施侧判断,本单只携带裁决、窗口与回退条款。objectui 侧的后续(不在本单)
spec 落地后,objectui 把
DashboardWidgetSchema.responsive从any换成按引用派生 + parity 闸门(已挂 objectui#3235 pin-bump 清单,条件项)。不做两形状 union 过渡——那是又一个双载体。Refs: objectui#3173(裁决现场)、objectui#3167 / objectstack#4115(派生 + 闸门范式)。
Generated by Claude Code