refactor(spec)!: retire dashboard.widgets[].responsive (#4876) - #4995
Merged
Conversation
ADR-0049 enforce-or-remove, mirroring #3896's handling of the identical `view.responsive`: authorable, parsed, and never read by any renderer. Re-measured 2026-08-03 — no objectui code reads `widget.responsive` (DashboardRenderer/DashboardEditor/plugin-designer mention it in comments only; the real per-breakpoint consumer `useResponsiveConfig` is fed by `page.components[].responsive`), and zero authored instances repo-wide. It survived the #3896 sweep through a liveness drill gap, not evidence: `dashboard.json` declares no `children` on `widgets`, so no widget-level key has ever been classified (#4956, separate). - `retiredKey()` tombstone carrying the migration prescription; the key stays declared so `.strict()` answers with the prescription rather than a generic "unrecognized key" - D2 conversion `dashboard-widget-responsive-removed` (retiredFromLoadPath) + D3 chain step at major 17; own entry, not folded into the #3896 one - shared `ResponsiveConfigSchema` and its `page.zod.ts` embed untouched — pinned as a control - baselines: authorable-surface KEY-level only (`[RETIRED]`); manifest / api-surface / api-surface-signatures unchanged by construction Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The merge of origin/main resolved `authorable-surface.json` to this branch's side, silently dropping the 16 rows #4974 (#4001 批 11) added for `automation/Webhook` and `integration/WebhookConfig` — main's own committed baseline had them. Regenerating via `gen:schema` (the gate's own proof path, never a hand edit) restores both sides: the sibling's webhook rows and this branch's `ui/DashboardWidget:responsive [RETIRED]`. Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
xuyushun441-sys
marked this pull request as ready for review
August 3, 2026 19:19
This was referenced Aug 3, 2026
Open
xuyushun441-sys
pushed a commit
that referenced
this pull request
Aug 3, 2026
Conflict was `liveness/dashboard.json`'s `_note` only; both sides kept and reconciled. #4876/#4995 recorded that `widgets[].responsive` deliberately carries NO ledger row because one would be an ORPHAN — true only while `widgets` was undrilled. The retiredKey tombstone keeps the key in the walked shape, so with the drill landed the row is REQUIRED (omitting it reports UNCLASSIFIED); it is present with the dead verdict the #3896 sweep never got to record. check:liveness green on the merged tree is the arbiter. os-regen four-step done: generated artifacts taken wholesale from origin/main, rebuilt, check:generated clean on the merged source, and every #4995 sibling entry asserted present (authorable-surface [RETIRED], spec-changes, upgrade guide, conversions registry, tombstone, changeset). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
This was referenced Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4876
按维护者 2026-08-03 的裁决 A(评论 5169512655)执行:退役
DashboardWidgetSchema.responsive,镜像 #3896 对同名view.responsive的处置。原单的「按断点重建模」方案(选项 C)已在裁决中排除,本 PR 不再涉及。为什么是退役
该键可授权、可校验、然后什么也不做。开工前按 origin/main 重新实测,三条依据全部复现:
widget.responsive——DashboardRenderer/DashboardEditor/plugin-designer只在注释里出现这个词;真正吃按断点配置的useResponsiveConfig由page.components[].responsive供给,不由 widget 供给。dist/objectstack.json里 3 个 dashboard、37 个 widget,携带responsive的为 0。POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 以完全相同的理由退役了字面同名的view.responsive。它当初漏网,不是因为有 liveness 证据,而是仪器有洞:台账
dashboard.json的widgets没有声明children,而 liveness 走查只沿显式children下钻一层 —— 所以 22 个 widget 级键从未被分类过。该缺口是 #4956,独立跟进,不在本 PR 修。不退役的话,v17 里同一个词会有两种命运(view.responsive报 tsc 错、widgets[].responsive静默放行),而这个键今天两侧都接收任意内容,正是 AI 授权元数据出错后藏身的地方。刻意收窄的范围
⛔ 共享的
ResponsiveConfigSchema不动,page.zod.ts:151的嵌入点不动。 只摘掉 widget 这一个嵌入。ResponsiveConfig仍然导出、仍然在page.components[].responsive上是活的 —— 没有任何 import 会断,需要断点行为的作者有真实去处。测试里为此专门留了对照 pin。同样刻意不碰:
DashboardWidgetOptionsSchema保持 passthrough;compareTo/.layout的 strip 站点属批 14,本 PR 不顺车。退役套件
retiredKey()带迁移处方。DashboardWidgetSchema是.strict()的 —— 直接删键也会报错,但只是通用的 "unrecognized key"。保留键声明才能让拒绝携带处方,并让tsc先一步把键判成never。有 pin 断言报错文案是处方且 不含Unrecognized key。dashboard-widget-responsive-removed(retiredFromLoadPath),os migrate meta --from 16从作者源码删键,存量 dashboard 重放即净化,不必在 load 时撞墓碑。独立条目,未并入dashboard-inert-keys-removed—— 后者的身份是POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 那次 sweep,本次基于自己的 2026-08-03 实测,应在spec-changes.json与升级指南里如实署名。POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 处理widgets[].performance一致:在 liveness:DashboardWidgetSchema的 ~22 个 widget 级键从未被台账分类,而 dashboard.json 的 _note 声称它们已分类 #4956 补上下钻之前,widget 级的行只会是 ORPHAN 而不是分类。_note记录了退役事实与「为何没有行」。authorable-surface.json新增ui/DashboardWidget:responsive [RETIRED];json-schema.manifest.json/api-surface.json/api-surface-signatures.json按构造零变化 —— 没有 def 停止 emit,没有导出被移除。全部经生成器自证路径产出,无手改。验证
check:*闸门 PASS(含check:strictness-ledger、check:liveness、check:generated);pnpm check:i18nOK。pnpm --filter @objectstack/spec test7480 passed;cli 588 passed;lint 980 passed;全仓pnpm typecheck122/122。validate全 PASS。ResponsiveConfigSchema.optional()后,新 pin 立刻转红(expected '' to match /dashboard\.widgets\[\]\.responsive/—— 值被静默接收);还原墓碑后 25/25 绿。responsive:后命中 1,路径为dashboards[0].widgets[0].responsive,键被剥离且 widget 其余部分逐字节不变。即「零命中」是真实的干净,不是探针失灵。合并 main 时的一个发现(已在本 PR 内修好)
合并
origin/main时,git 把packages/spec/authorable-surface.json整体取了本分支一侧,静默丢掉了 #4974(#4001 批 11)为automation/Webhook与integration/WebhookConfig新增的 16 行(main 自己的基线是有的)。已按 os-regen 纪律整体重新生成(不手改),两侧共存 —— 仓库的os-regen钩子也确认该产物「merged WITHOUT a text merge」并在重新生成后清除标记。这条单独一个 commit,便于审阅。跨分片知会
objectui 分片:本单结局是退役,不是回退条款 —— objectui#3235 的条件项永久除名,无需排入下个大版本重新建模;objectui 侧该键写明原因的
any声明可按你们自己的节奏清理。🤖 Generated with Claude Code
https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
Generated by Claude Code